从phpinfo着手,初步认定是opcache的漏洞
参考文章https://www.anquanke.com/post/id/83844
叫phpinfo对应的参数丢进脚本里算出system id
在本地写一个php来使opcache生成对应的bin文件
因为opcache.validate_timestamps => On
写个简单脚本计算出文件创建的时间戳
依照文章将bin的system id和时间戳改一下,需要注意的是这里是64位,改40h的数据(赛后写的wp,时间戳没对上)
http://202.120.7.217:9527/?action=shell&dir=/var/www/html/flag获取flag文件夹的文件名
http://202.120.7.217:9527/?action=shell&a=$a=base64_encode(gzcompress(file_get_contents(%22/var/www/html/flag/93f4c28c0cf0b07dfd7012dca2cb868cc0228cad%22)));;echo%20$a;
将文件压缩并用base64编码显示出来
本地进行反操作获得bin,在opcache后面加个0x00修复文件
利用github的工具将bin反汇编成伪代码
用vld看更清晰点:
根据opcode写PHP代码并解密
关键几点:
题目不允许post带有#()字符,通过构造数组可以绕过;它把post的变量名直接放正则了;
并不知道password的完整字段名,我是用(function(a){for(var k in a){if(k[0]=='p')return a[k]}})(this)过的;无论返回什么都会显示OK,但发生错误时没响应。
payload:
.*[0]=#reg#®[0]=] || 33<(function(a){for(var k in a){if(k[0]=='p')return a[k]}})(this)[0].charCodeAt() || asdasd || ([
(asdasd用来报错)
效果:
然后就是盲注了
Flag:flag{13fc892df79a86494792e14dcbef252a}
Nc连上去输出一段文本,把文本弄下来,发现内容来自维基百科中关于TCP的定义,手动去掉多余空格之后,使用010editor的compare进行比较,发现差异处:
逐个提取即为flag:flag{h1dden_7cp_m5g_lol}