news 2026/4/30 18:01:32

CTF实战:用php_mt_seed爆破Web25靶场种子,手把手教你从零到拿Flag

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
CTF实战:用php_mt_seed爆破Web25靶场种子,手把手教你从零到拿Flag

CTF实战:从零爆破Web25靶场种子与Token构造全解析

在CTF竞赛中,PHP伪随机数漏洞一直是Web安全赛道的经典考点。本文将带您深入ctf.show的Web25靶场,通过实战演示如何利用php_mt_seed工具逆向破解mt_srand种子值,并最终构造出正确的Token获取Flag。不同于简单的工具使用教程,我们将从攻击者视角完整还原"信息收集→随机数捕获→种子爆破→Token计算→Payload构造"的完整攻击链。

1. 靶场环境侦察与漏洞分析

打开Web25靶场首先看到的是一段PHP代码审计界面。通过system('cat /proc/version')可以获取服务器基础信息,但更关键的是以下代码段:

error_reporting(0); include("flag.php"); if(isset($_GET['r'])){ $r = $_GET['r']; mt_srand(hexdec(substr(md5($flag), 0,8))); $rand = intval($r)-intval(mt_rand()); if((!$rand)){ if($_COOKIE['token']==(mt_rand()+mt_rand())){ echo $flag; } }else{ echo $rand; } }

这段代码揭示了三个关键点:

  1. 种子生成逻辑mt_srand(hexdec(substr(md5($flag), 0,8)))表明种子来源于Flag的MD5前8位十六进制转换
  2. 验证机制:需要满足两个条件:
    • GET参数r的值减去第一个mt_rand()结果等于0
    • COOKIE中token的值等于第二、第三个mt_rand()之和
  3. 信息泄露点:当$rand不为0时,会直接输出差值,这将成为我们的突破口

使用Wappalyzer插件可以确认目标服务器运行的是PHP 7.4.x版本——这个信息对后续种子爆破至关重要,因为不同PHP版本的MT算法实现存在差异。

2. 获取初始随机数与种子爆破

根据代码逻辑,我们首先需要获取第一个mt_rand()的值。通过发送?r=0的GET请求:

GET /?r=0 HTTP/1.1 Host: web25.ctf.show

服务器返回一个负数值,例如-123456789。这个值实际上是0 - mt_rand()的结果,因此第一个随机数就是123456789

现在我们需要使用php_mt_seed工具爆破出生成这个随机数的种子。在Kali Linux中操作步骤如下:

# 编译安装php_mt_seed git clone https://github.com/openwall/php_mt_seed.git cd php_mt_seed make # 开始爆破随机数123456789 ./php_mt_seed 123456789

爆破过程可能需要几分钟到几小时不等,取决于硬件性能。最终我们会得到几个可能的种子值,例如:

Found 0, trying 0x90000000 - 0xa0000000, speed 106225 seeds per second Found 0, trying 0x8c000000 - 0x8d000000, speed 106240 seeds per second Found 1, trying 0x8cf00000 - 0x8d000000, speed 106240 seeds per second Found 1, trying 0x8cf80000 - 0x8d000000, speed 106240 seeds per second Found 1, trying 0x8cfc0000 - 0x8d000000, speed 106240 seeds per second Found 1, trying 0x8cfe0000 - 0x8d000000, speed 106240 seeds per second Found 1, trying 0x8cff0000 - 0x8d000000, speed 106240 seeds per second Found 1, trying 0x8cff8000 - 0x8d000000, speed 106240 seeds per second Found 1, trying 0x8cffc000 - 0x8d000000, speed 106240 seeds per second Found 1, trying 0x8cffe000 - 0x8d000000, speed 106240 seeds per second Found 1, trying 0x8cfff000 - 0x8d000000, speed 106240 seeds per second Found 1, trying 0x8cfff800 - 0x8d000000, speed 106240 seeds per second Found 1, trying 0x8cfffc00 - 0x8d000000, speed 106240 seeds per second Found 1, trying 0x8cfffe00 - 0x8d000000, speed 106240 seeds per second Found 1, trying 0x8cffff00 - 0x8d000000, speed 106240 seeds per second Found 1, trying 0x8cffff80 - 0x8d000000, speed 106240 seeds per second Found 1, trying 0x8cffffc0 - 0x8d000000, speed 106240 seeds per second Found 1, trying 0x8cffffe0 - 0x8d000000, speed 106240 seeds per second Found 1, trying 0x8cfffff0 - 0x8d000000, speed 106240 seeds per second Found 1, trying 0x8cfffff8 - 0x8d000000, speed 106240 seeds per second Found 1, trying 0x8cfffffc - 0x8d000000, speed 106240 seeds per second Found 1, trying 0x8cfffffe - 0x8d000000, speed 106240 seeds per second Found 1, trying 0x8cffffff - 0x8d000000, speed 106240 seeds per second Seed = 0x8cffffff = 2363123205 (PHP 7.1.0+)

注意:PHP版本不同会导致相同的种子产生不同的随机数序列。这就是为什么之前确认PHP版本如此重要。

3. Token计算与Payload构造

获得种子值2363123205后,我们可以预测后续的随机数序列。编写以下PHP脚本计算所需的Token值:

<?php mt_srand(2363123205); // 设置已知种子 $first_rand = mt_rand(); // 消耗第一个随机数(已通过r=0获取) $token = mt_rand() + mt_rand(); // 计算第二、第三个随机数之和 echo "Token: ".$token; ?>

执行后得到Token值,例如3546321857。现在我们需要构造完整的HTTP请求:

  1. 首先发送GET请求获取正确的r值(即第一个随机数):

    GET /?r=123456789 HTTP/1.1 Host: web25.ctf.show
  2. 然后带上计算出的Token发送最终请求:

    GET /?r=123456789 HTTP/1.1 Host: web25.ctf.show Cookie: token=3546321857

使用HackBar或Burp Suite重放这个请求,服务器将返回Flag内容。

4. 实战中的变体与防御措施

在实际CTF比赛中,这类题目可能会出现多种变体:

  1. 种子隐藏方式不同

    • 使用时间戳作为种子
    • 使用固定字符串的哈希值
    • 使用多个随机数的组合
  2. 验证逻辑变化

    • 要求多个连续随机数的特定组合
    • 使用随机数作为加密密钥
    • 随机数参与更复杂的运算

防御此类攻击的最佳实践包括:

  • 使用random_int()替代mt_rand()
  • 避免暴露随机数生成序列
  • 对关键操作使用多重验证机制
  • 定期更新随机数种子

5. 工具链扩展与自动化思路

对于需要批量处理的情况,可以编写自动化脚本整合整个流程:

import requests import subprocess # 第一步:获取初始随机数 response = requests.get("http://web25.ctf.show/?r=0") first_rand = abs(int(response.text)) # 第二步:爆破种子 process = subprocess.run(["./php_mt_seed", str(first_rand)], capture_output=True) seed = int(process.stdout.split()[-2], 16) # 提取种子值 # 第三步:计算Token php_code = f"""<?php mt_srand({seed}); mt_rand(); echo mt_rand() + mt_rand(); ?>""" token = subprocess.run(["php", "-r", php_code], capture_output=True).stdout # 第四步:获取Flag cookies = {"token": token.decode().strip()} response = requests.get(f"http://web25.ctf.show/?r={first_rand}", cookies=cookies) print(response.text)

这个脚本完整实现了从信息收集到最终获取Flag的全自动化过程,在实战中可以显著提高效率。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/30 18:01:32

深度学习注意力机制:原理、架构与应用实践

1. 注意力机制架构全景解析在深度学习领域&#xff0c;注意力机制已经彻底改变了我们处理序列数据的方式。2017年Transformer架构的横空出世&#xff0c;就像给整个NLP领域装上了涡轮增压引擎——机器翻译质量一夜之间提升了超过28个BLEU值。但Transformer只是注意力机制应用的…

作者头像 李华
网站建设 2026/4/30 18:00:25

LLM微调实战:基于DPO的金融风险分析优化

1. 项目概述&#xff1a;基于偏好优化的LLM微调技术实战在金融风险分析领域&#xff0c;传统BERT类模型常面临复杂推理任务的性能瓶颈。我在欧洲银行业风险事件分类任务中发现&#xff0c;即使经过精心设计的prompt engineering&#xff0c;基于BERT的模型F1-score始终徘徊在55…

作者头像 李华
网站建设 2026/4/30 17:58:37

多智能体协作:核心模式与实现解析

1. 智能体间通信&#xff1a;Agentic Patterns的崛起在AI领域&#xff0c;我们正经历一场从单一智能体向多智能体协作的范式转变。过去那种"一个智能体解决一个问题"的孤立模式正在被淘汰&#xff0c;取而代之的是让多个智能体通过标准化方式进行发现、通信和协调的新…

作者头像 李华
网站建设 2026/4/30 17:58:32

构建本地化交易记忆系统:从对话记录到技能固化的实战框架

1. 项目概述&#xff1a;一个为交易者打造的“第二大脑” 如果你和我一样&#xff0c;在交易这条路上摸爬滚打了好几年&#xff0c;最头疼的恐怕不是找不到机会&#xff0c;而是“记不住”。今天复盘时觉得某个错误似曾相识&#xff0c;但就是想不起上次是怎么栽的跟头&#xf…

作者头像 李华
网站建设 2026/4/30 17:57:30

新手做直播如何低成本起步?2026五款数字人直播工具选型参考

对于想入门直播却预算有限的新手来说&#xff0c;传统真人直播门槛确实不低&#xff1a;主播成本动辄每月数万&#xff0c;还要配备运营、场控等团队&#xff0c;新手小白的试错成本太高。近年来数字人直播技术逐渐成熟&#xff0c;越来越多商家开始用数字人直播工具替代真人出…

作者头像 李华
网站建设 2026/4/30 17:54:50

三步掌握Mitsuba-Blender插件:在Blender中解锁专业物理渲染能力

三步掌握Mitsuba-Blender插件&#xff1a;在Blender中解锁专业物理渲染能力 【免费下载链接】mitsuba-blender Mitsuba integration add-on for Blender 项目地址: https://gitcode.com/gh_mirrors/mi/mitsuba-blender 想要在Blender中实现电影级的物理渲染效果吗&#…

作者头像 李华