绕过非英文字母和数字getshell
前言
绕过不是英文字母,不是数字的验证。
1 | preg_match ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] ) : int |
preg_match()
返回 pattern 的匹配次数。 它的值将是0次(不匹配)或1次,因为preg_match()
在第一次匹配后 将会停止搜索。preg_match_all()
不同于此,它会一直搜索subject 直到到达结尾。 如果发生错误preg_match()
返回 FALSE。
正文
题目源码
1 |
|
可以看到这段代码中,要求而传入的参数不能带有数字和英文字母,
所以我们要绕过A-Za-z0-9
这些常规数字、字母字符串的传参。将非字母、数字的字符经过各种变换,最后能构造出 a-z 中任意一个字符,并且字符串长度小于40。然后再利用 PHP允许动态函数执行的特点,拼接处一个函数,然后执行这个函数getshell
。
如何构造
在PHP中,两个字符串执行异或操作以后,得到的还是一个字符串。所以,我们想得到a-z中某个字母,就找到某两个非字母、数字的字符,他们的异或结果是这个字母即可。
1 |
|
A的ASCII值是65,对应的二进制值是01000001
?的ASCII值是63,对应的二进制值是00111111
异或的二进制的值是10000000,对应的ASCII值是126,对应的字符串的值就是~了
以此可以构造webshell
1 |
|
为了节省字符长度,这里字符可以一起异或使用
1 |
|
最终payload
1 | $_="`{{{"^"?<>/";${$_}[_](${$_}[__]);&_=assert&__=print_r(scandir('/')) |