PHP由mb_strpos与mb_substr执行差异导致的小trick

EddieMurphy-blogs / 2024-07-19 / 原文

前言

这个其实不算啥大洞,主要是我遇到两次了,第一次是在黄河流域做那个题的时候,还有一次是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的:

参考:

Joomla: PHP Bug Introduces Multiple XSS Vulnerabilities | Sonar (sonarsource.com)

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

 

后言

最后提一嘴,估计这是我在博客园最后的blog了,博客园都要似了,害怕我写了那么多东西都死在服务器里,也很感谢博客园里大家的陪伴,博客迁移搞好了会贴出来的。同时博客园这个平台也很干净很纯粹,很喜欢,所以作为我第一次写blog的地方。

接下来呢,就还是将一些后续想做想学习的东西和一些有价值的搬到新blog里。

然后过两天就是国赛Final了,祝我成功吧,江湖再会!