1.发现要json格式
JSON的输入格式主要有对象(用花括号括起来,包含键值对)和数组(用方括号括起来,值之间用逗号分隔)两种基本结构,键必须是字符串,值可以是多种数据类型。例如对象格式:{"name": "John", "age": 30},数组格式:[1, 2, 3]等。
尝试输入{"cmd":"ls"}
发现index.php
2 .发现命令正常执行,准备查看根目录的文件,由于是get
传参,所以空格先编码为%20
,但是发现回显hacking
,经过测试发现是对/
进行了过滤
{"cmd":"ls%20/"}
3.既然不能使用/,那就直接使用cat
命令查看一下index.php
文件,发现还是不行,尝试更改cat
的格式进行绕过,发现还是不行。
{"cmd":"cat%20index.php"}

4.仔细想想,既然存在过滤,多半碰到的函数都是preg_match,该函数可以通过换行符%0a和数组进行绕过,因为该函数只会匹配第一行数据,除非设置了参数。所以默认为preg_match函数过滤,构建paylaod{%0a"cmd":"cat%20index.php"%0a}。发现还是不行,但是可以执行ls /命令了,证明前面猜测没问题,还绕过来了过滤
注意:用url传参,不然会在输入框输入进行url编码,导致无法识别
{%0a"cmd":"ls%20/"%0a}

5.那为什么cat
命令还不行执行呢,都已经绕过了过滤。其实在没有限制的情况下命令还不能执行,只能是该命令被屏蔽了,但是使用其他查看文件的命令也都不可以。
6.那可能就是环境变量被更改了,需要使用命令的绝对路径来执行,也就是/bin/cat
。再次构建paylaod{%0a"cmd":"/bin/cat%20index.php"%0a}
。成功回显了文件内容。
{%0a"cmd":"/bin/cat%20index.php"%0a}
7.发现过滤函数确实是preg_match
,代码的一开始就将环境变量修改了,既然flag
不在根目录下,那很可能就在这个环境变量中,查看环境变量目录结构,发现了flag
目录,cat
命令直接拿下flag
注:因为cat命令类似于exe文件,配置环境变量就可以在任何地方使用
{%0a"cmd":"ls%20/home/rceservice"%0a}
{%0a"cmd":"/bin/cat /home/rceservice/flag"%0a}
总结
RCE绕过
- 环境变量绕过 /bin/cat
- 正则匹配绕过 %0a 数组
JSON
JSON的输入格式主要有对象(用花括号括起来,包含键值对)和数组(用方括号括起来,值之间用逗号分隔)两种基本结构,键必须是字符串,值可以是多种数据类型。例如对象格式:{"name": "John", "age": 30},数组格式:[1, 2, 3]等
使用url传参
使用输入框传参会进行编码,url无法识别