php异或计算绕过preg_match()

Posted cimuhuashuimu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了php异或计算绕过preg_match()相关的知识,希望对你有一定的参考价值。

原理
以制作免杀马为例:
     在制作免杀马的过程,根据php的语言特性对字符进行!运算会将字符类型转为bool类型,而bool类型遇到运算符号时,true会自动转为数字1,false会自动转为数字0,如果将bool类型进行计算,并使用chr()函数转为字符,使用"."进行连接,便可以绕过preg_match匹配。
详情了解php不同于其他语言部分
     但是很多的preg_match会过滤掉".",所以需要使用异或运算进行绕过,很多的免杀马都是这样制作的。php对字符进行异或运算是先将字符转换成ASCII码然后进行异或运算,并且php能直接对一串字符串进行异或运算,例如"123"^"abc"是"1"与"a"进行异或然后"2"与"b"进行异或,以此类推,在异或结束后就获得了想要的字符串。
     注意点:进行异或运算时要将数字转换成字符形式,如果数字(int)和字符异或的话,结果只会是数字,例如1^"a"=1,"a"^2=2,将数字转换成字符串可以使用trim()函数。
拓展:
php特性use of undefined constant,会将没有引号的字符都自动视为字符串,ASCII码大于0x7F的都会被当作字符串,由此可知可以简化异或过程,任何字符与0xff异或都会取相反,这样就能减少运算量了。

以GET或POST传入字符绕preg_match为例:
    php的eval()函数在执行时如果内部有类似"abc"^"def"的计算式,那么就先进行计算再执行,我们可以利用再创参数来实现更方便的操作,例如传入?a=$_GET[b],由于b不受限制就可以任意传值了,不过  
    注意1:在测试过程中发现问题,类似phpinfo();的,需要将后面的();放在第个参数的后面,例如url?a=_GETb();&b=phpinfo,也就是?a=$%ff%ff%ff%ff^%a0%b8%ba%ab%ff();&%ff=phpinfo,在传入后实际上为$????^?????();但是到了eval()函数内部就会变成$_GET?();成功执行。
    注意2:测试中发现,传值时对于要计算的部分不能用括号括起来,因为括号也将被识别为传入的字符串,可以使用代替,原因是php的use of undefined constant特性,例如$_GETa这样的语句php是不会判为错误的,因为使用来界定变量的,这句话就是会将_GET自动看为字符串,也就是$_GET[‘a‘]

Demo
Suctf easyphp
<?php
$hhh = @$_GET[‘_‘];
if (!$hhh)
    highlight_file(__FILE__);

if(strlen($hhh)>18)
    die(‘One inch long, one inch strong!‘);

if ( preg_match(‘/[\x00- 0-9A-Za-z\‘"\`~_&.,|=[\x7F]+/i‘, $hhh) )
    die(‘Try something else!‘);
$character_type = count_chars($hhh, 3);
if(strlen($character_type)>12) die("Almost there!");
eval($hhh);
?>
用户传入?_=$%ff%ff%ff%ff^%a0%b8%ba%ab%ff();&%ff=phpinfo
成功显示phpinfo页面

以上是关于php异或计算绕过preg_match()的主要内容,如果未能解决你的问题,请参考以下文章

XCTF-攻防世界CTF平台-Web类——18favorite_number(命令注入)(php5.5.9整数溢出preg_match正则表达式绕过)

XCTF-攻防世界CTF平台-Web类——18favorite_number(命令注入)(php5.5.9整数溢出preg_match正则表达式绕过)

[羊城杯2020]easyphp --- 伪协议的使用时机,---python上传.htaccess的利用 -- preg_match绕过

[SUCTF 2019]EasyWeb

BUU-日刷-[红明谷CTF 2021]write_shell-call_简单绕过和??

绕过PHP代码执行中的过滤限制详解