本文为个人学习与实战过程中的思路总结,旨在分享技术探索经验,若有疏漏之处,欢迎交流指正。
好靶场简介
漏洞复现学习由"好靶场"支持

前期准备
我们开启靶场先看描述

这道题的描述是:"作为安全人员,Python是你的必修课,UA头有的时候需要指定为你需要的内容才可以进行后续操作"
此处注意需要有python环境
实战
官方解题思路

写一个python脚本,通过Python requests模块以post方式并指定题目要求的ua头信息和请求体中的数据进行请求地址即可:
此处要注意把我给的代码中的xxxxxx改为你对应的地址呢内容
python
import requests
# 新的靶场URL
url = "http://xxxxxxxx.haobachang1.loveli.com.cn:8888/flag"
# 请求体数据
data = {'flag': '1'}
# 请求头信息,包含特定的User-Agent
headers = {
'User-Agent': 'mozilla/5.0 (windows nt 10.0; win64; x64; rv:143.0) gecko/20100101 firefox/143.0'
}
try:
# 使用POST方法请求并携带数据和请求头
response = requests.post(url, data=data, headers=headers)
response.raise_for_status() # 检查请求是否成功
print("获取Flag成功:")
print(response.text)
except requests.exceptions.RequestException as e:
print(f"获取Flag失败:{e}")


代码解析
核心代码逐句解释
python
try:
# 使用POST方法请求并携带数据和 headers
response = requests.post(url, data=data, headers=headers)
response.raise_for_status() # 检查请求是否成功
print("获取Flag成功:")
print(response.text)
except requests.exceptions.RequestException as e:
print(f"获取Flag失败:{e}")
- try:
如果中间出错了,不会直接崩溃,而是跳到下面的 except 里告诉你错在哪。
- response = requests.post(url, data=data, headers=headers)
requests.post→ 发送 POST 请求(像表单提交、登录、拿 flag 都用它)url→ 发给哪个网址data=data→ 带上你要提交的数据 `{'flag':'1'}headers=headers→ 带上身份信息(UA 等)
- response.raise_for_status() 检查网站有没有正常响应
- 如果返回 404 / 500 / 403 等错误
- 这里会直接触发异常,跳到失败代码
拓展
其它思路
按照我们python get请求和python post请求思路尝试
通过抓包修改UA头,请求体数据,post请求方式,flag目录来拿到flag

修改里面的参数
此处请求头写完数据后空一行再写请求体

并没有返回flag,并有提示

在ua中加入python-request/2.31.0,还是不行
尝试把flag:1改为flag=1,尝试后发现也不行
然后我就想到一个办法,是否能使用python发送请求使用bp拦截,看看python发包到底是什么样
我们需要先对python修改

看一下自己bp代理地址和端口


在原有代码的基础上加入这些内容
python
import requests
proxies = {
"http": "http://127.0.0.1:8080",
"https": "http://127.0.0.1:8080"
}
# 新的靶场URL
url = "http://xxxxxxx.haobachang1.loveli.com.cn:8888/flag"
# 请求体数据
data = {'flag': '1'}
# 请求头信息,包含特定的User-Agent
headers = {
'User-Agent': 'mozilla/5.0 (windows nt 10.0; win64; x64; rv:143.0) gecko/20100101 firefox/143.0'
}
try:
# 使用POST方法请求并携带数据和请求头
response = requests.post(url, data=data, headers=headers,proxies=proxies,verify=False)
response.raise_for_status() # 检查请求是否成功
print("获取Flag成功:")
print(response.text)
except requests.exceptions.RequestException as e:
print(f"获取Flag失败:{e}")
在允许python脚本前开启拦截,然后运行python脚本

python
POST /flag HTTP/1.1
Host: xxxxxx.haobachang1.loveli.com.cn:8888
User-Agent: mozilla/5.0 (windows nt 10.0; win64; x64; rv:143.0) gecko/20100101 firefox/143.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
Content-Length: 6
Content-Type: application/x-www-form-urlencoded
flag=1
我们可以看到请求头中的内容还是蛮有差距的,所以此处目前看是不能够直接使用bp修改请求体获取到flag,我们需要等等深入学习一下这些请求头和相关参数,应该可以改成目标所想要的请求头。
其它
相似靶场
还有一个是要求以post方式提交,请求体中携带{"flag": "1"}

python
json_data = {'flag': '1'}
response = requests.post(url, json=json_data)
其实就是在我们上面的脚本上删除掉ua信息的设置,请求条数据data改为json_data
python
import requests
# 新的靶场URL
url = "http://xxxxx.haobachang1.loveli.com.cn:8888/flag"
# 请求体数据
json_data = {'flag': '1'}
try:
# 使用POST方法请求并携带数据
response = requests.post(url, json=json_data)
response.raise_for_status() # 检查请求是否成功
print("获取Flag成功:")
print(response.text)
except requests.exceptions.RequestException as e:
print(f"获取Flag失败:{e}")
然后发包请求即可获得flag
下面我们学习一下这些请求头请求体及其参数
请求数据包知识点解析
1. HTTP 基本方法:GET / POST 区别
| 特性 | GET | POST |
|---|---|---|
| 数据位置 | 放在 URL 的?后面(明文,有长度限制) |
放在 ** 请求体(Body)** 里(更安全,无长度限制) |
| 用途 | 查数据、获取资源(比如打开网页、搜索) | 提交数据、修改资源(比如登录、发请求) |
| 有无 Body | 天生无 Body(规范不推荐带) | 可以带 Body,是我们打靶的核心操作对象 |
2. Content-Type 概念
它是HTTP 请求头里的一个字段,作用是:告诉服务器,我发的请求体是什么格式的,服务器会按这个格式解析数据。
常见格式:
application/x-www-form-urlencoded:普通表单格式(key=val&key2=val2)application/json:JSON 格式({"key":"val"})multipart/form-data:文件上传格式
3. JSON 语法规则
JSON 是前后端最常用的数据格式,必须严格遵守:
- 键名(key)、字符串(value)必须用双引号,不能用单引号
- 整个对象用花括号
{}包裹 - 键值对用逗号
,分隔 - 正确示例:
{"flag":"1", "username":"test"}
4. Python requests 库的关键用法
-
requests.post(url, json=dict):自动帮你做两件事- 自动在请求头加
Content-Type: application/json - 自动把 Python 字典(dict)序列化成标准 JSON 格式
- 自动在请求头加
-
对比:
requests.post(url, data=dict)会发表单格式,不会自动加 JSON 头,服务器会按表单解析,直接报错 400
5. 常见 HTTP 状态码含义
200 OK:请求成功,正常返回数据(我们要的 flag 就是 200 返回的)400 Bad Request:请求格式错误(比如 JSON 写错、Content-Type 不对)404 Not Found:请求的 URL / 路径错误,服务器找不到资源
6:Burp 里怎么手动构造这个请求?
如果你用 Burp 抓包 / 手动发包,正确的请求应该是这样:
POST /flag HTTP/1.1
Host: xxxxxxx.haobachang1.loveli.com.cn:8888
Content-Type: application/json
Content-Length: 11
{"flag":"1"}
- 必须有
Content-Type: application/json头 - 请求体是标准 JSON,双引号、花括号都不能错
Content-Length要和 Body 的字节数一致(Burp 会自动修正)
然后此时我突然就想到,我们只要构造成目标网站想要的信息不就好了,对于实战中可能会很难,成功几率低,但对于靶场已经明确的说出了需求,我们直接根据需求写
当我写完这句话我在靶场页面看到这样一句话

靶场已经包后端校验方式给发出来了,我根据这个写请求头请求体信息
post请求方式,flag目录,json格式,请求体中用json格式写flag=1

获取flag
我们除了使用bp还可以使用yakit(资源已上传,有需要的可以到主页查看资源)

打开一个项目

点击启动劫持

点击免配置启动


转到这个界面后把我们的靶场url粘贴并写上flag目录进行访问(点击开始劫持)

然后就会在页面中看到多了一条信息
点击这一条就会弹出一个窗口

右键左下方窗口,发送到web fuzzer

然后把请求体请求头中的信息改为网站后端校验需求,发送请求获取flag

reqable也是可以的

选择post,添加上flag目录
然后这个请求头是隐藏的,我们点击那个眼睛


把没有得到勾选给取消掉

去掉不掉的把内容删掉以免受影响
然后此处不需要加入content-type和lengthl,会自动获取

然后把请求头的类型改为json,输入数据


然后我们看前面它自己写了这两个请求头信息
然后点击发送,获取flag
本篇完 | 实践出真知,交流共进步
每一篇文章都是一次沉淀,感谢你的阅读。技术没有捷径,唯有不断积累、不断输出。期待下次继续与你分享更多实战经验,一起前行。
《法律与责任声明》
本内容仅用于网络安全漏洞的技术研究、学习与交流。
一、合法性要求
- 严格遵守《中华人民共和国网络安全法》及相关法律法规,严禁将所学技术用于非法活动,如未经授权的攻击、窃取信息等。例如,不得对未授权的真实生产环境网站做漏洞测试。
- 漏洞测试须在合法授权环境进行,可使用自己搭建的靶场或获书面授权的目标系统,否则将担法律责任。
二、风险与责任
- 若因参考本内容对第三方造成损失,本人不承担法律责任,使用者自行担责。
三、传播限制
- 禁止将本内容用于恶意传播,如制作恶意教程、培训非法黑客组织,应维护良好网络安全环境。
- 发现有人利用本内容非法活动,应及时举报。
四、版权声明
本文为本人独立创作,有完整知识产权。未经书面许可,任何单位或个人不得转载、复制或以其他方式使用,违者依法追责。
阅读并使用本文章内容即表示同意声明条款