前言
- 正则绕过知识总结
一、换行符绕过
1 |
<?php |
二、数组绕过
preg_match只能处理字符串,当传入的subject是数组时会返回false
三、%5c绕过
1 |
|
题目要求我们需要绕过正则才可以任意命令执行
正则的意思:/^[a-z0-9_]*$/isD
1 |
/i不区分大小写 |
payload
1 |
http://127.0.0.1/test.php?action=\create_function&arg=return%271%27;}phpinfo();/* |
四、PHP利用PCRE回溯次数限制绕过某些安全限制
参考文章Leavesongs
1 |
|
正则表达式是一个可以被“有限状态自动机”接受的语言类。
“有限状态自动机”,其拥有有限数量的状态,每个状态可以迁移到零个或多个状态,输入字串决定执行哪个状态的迁移。
而常见的正则引擎,又被细分为DFA(确定性有限状态自动机)与NFA(非确定性有限状态自动机)。他们匹配输入的过程分别是:
- DFA: 从起始状态开始,一个字符一个字符地读取输入串,并根据正则来一步步确定至下一个转移状态,直到匹配不上或走完整个输入
- NFA:从起始状态开始,一个字符一个字符地读取输入串,并与正则表达式进行匹配,如果匹配不上,则进行回溯,尝试其他状态
由于NFA的执行过程存在回溯,所以其性能会劣于DFA,但它支持更多功能。大多数程序语言都使用了NFA作为正则引擎,其中也包括PHP使用的PCRE库。
回溯的过程
1 |
所以,我们题目中的正则<\?.*[(`;?>].*,假设匹配的输入是<?php phpinfo();//aaaaa,实际执行流程是这样的: |
1 |
见上图,可见第4步的时候,因为第一个.*可以匹配任何字符,所以最终匹配到了输入串的结尾,也就是//aaaaa。但此时显然是不对的,因为正则显示.*后面还应该有一个字符[(`;?>]。 |
PHP的pcre.backtrack_limit限制利用
1 |
PHP为了防止正则表达式的拒绝服务攻击(reDOS),给pcre设定了一个回溯次数上限pcre.backtrack_limit。我们可以通过var_dump(ini_get('pcre.backtrack_limit'));的方式查看当前环境下的上限: |
可见,回溯次数上限默认是100万。那么,假设我们的回溯次数超过了100万,会出现什么现象呢?比如:
那么这道题的答案就呼之欲出了,我们通过发送超长字符串的方式,使正则执行失败,最后绕过目标对PHP语言的限制。
对应的POC如下:
1 |
import requests |
我的个人博客
孤桜懶契:http://gylq.gitee.io
FROM:gylq.gitee Author:孤桜懶契
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论