sqli-lab之第一章--基础知识

2019-09-30  本文已影响0人  江南小虫虫

第一章 基础知识

在我们的应用系统使用 sql 语句进行管理应用数据库时,往往采用拼接的方式形成一条完整的数据库语言,而危险的是,在拼接 sql 语句的 时候,我们可以改变 sql 语句。从而让数据执行我们想要执行的语句,这就是我们常说的 sql 注入

本章将介绍一些 mysql 注入的一些基础知识, 可能知识有点多, 希望大家认真看一遍, 实操一遍.

学习篇

0x01 注入的分类

下面这个是阿德玛表哥的总结的,现在理解不了可以跳过

0x02 系统函数

这里介绍几个常用函数, 自己实操的话, 可以直接点击Kitematic的EXEC运行一个终端, 然后使用mysql -uroot进入mysql

  1. version()——MySQL 版本

  2. user()——数据库用户名

  3. database()——数据库名

  4. @@datadir——数据库路径

  5. @@version_compile_os——操作系统版本

0x03 字符串连接函数

在select数据时, 我们往往需要将数据进行连接后进行回显. 很多的时候想将多个数据或者多行数据进行输出的时候, 需要使用字符串连接函数. 而在mysql中,常见的字符串连接函函数有concat(), group_concat(), concat_ws().

举个例子, 不使用字符串连接函数时

但是这里存在的一个问题是, 当使用union联合注入时, 我们都知道, 联合注入要求前后两个选择的列数要相同, 这里id, username是两个列, 当我们要一个列的时候, (即回显位只有一个)该怎么办? 这时候就需要用到字符串连接函数了

concat()

语法如下:

concat(str1,str2,...)
--没有分隔符地连接字符串
--返回结果为连接参数产生的字符串
--如有任何一个参数为NULL, 则返回值为 NULL
--可以有一个或多个参数

一般的我们都要用一个字符(这里是逗号)将各个项隔开, 便于数据的查看. 见下图:

下图是参数中有NULL的情况

concat_ws()

语法如下:

concat_ws(separator,str1,str2,...)
--含有分隔符地连接字符串, 分隔符的位置会放在要连接的两个字符串之间
--Separator为字符之间的分隔符, 可以是一个字符串, 也可以是其它参数
--如果分隔符为 NULL, 则结果为 NULL
--函数会忽略任何分隔符参数后的 NULL 值

下图是忽略NULL的情况

group_concat()

语法如下:

group_concat(str1,str2,...)
--连接一个组的所有字符串,并以`逗号`分隔每一条数据.

0x04 一般用于尝试的语句

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";

此处考虑两个点

  1. 一个是用一个单引号闭合前面的 '
  2. 另一个是处理后面的', 一般采用两种思路, 闭合后面的引号或者注释掉,注释掉采用--+ 或者 #(%23)

0x05 union 操作符的介绍

UNION 操作符用于合并两个或多个 SELECT 语句的结果集。请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同。

SQL UNION 语法

SELECT column_name(s) FROM table_name1 UNION
SELECT column_name(s) FROM table_name2

ps:默认地,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语句中的列名。

0x06 sql 中的逻辑运算

这里讨论一下逻辑运算的问题

有一个问题 elect * 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。三个条件用 andor 进行连接。在 sql 中,我们 and 的运算优先级大于 or 的运算优先级。因此可以看到 第一个条件(用 a 表示)是真的,第二个条件(用b 表示)是假的,a and b = false, 第一个条件和第二个条件执行 and 后是假,再与第三个条件 or 运算,因为第三个条件 1=1 是恒成立的,所以结果自然就为真了。因此上述的语句就是恒真了。

(1) select * from users where id=1 and 1=1;
(2) select * from users where id=1 && 1=1;
(3) select * from users where id=1 & 1 =1;

上述三者有什么区别?

Ps:此处进行的位运算。我们可以将数转换为二进制再进行与、或、非、异或等运算。必要的时候可以利用该方法进行注入结果。例如将某一字符转换为 ascii 码后,可以分别与
1,2,4,8,16,32.。。。进行与运算,可以得到每一位的值,拼接起来就是 ascii 码值。再从ascii 值反推回字符。(运用较少)

0x07 information.schema数据库

use information_schema;

0x08 注入流程

实战篇

Less-1

为了方便学习查看,可以在源码中的$sql下一句语句写以下php语句(就是输出拿到数据库查询的完整语句是怎么样的)

echo "你的 sql 语句是:".$sql."<br>";  

Less-2

Less-3

Less-4

上一篇下一篇

猜你喜欢

热点阅读