0%

sqli-labs-Background-1 基础知识

此处介绍一些mysql注入的基础知识

注入的分类

基于从服务器接收到的响应

  1. 基于错误的SQL注入
  2. 联合查询的类型
  3. 堆查询注入
  4. SQL盲注
    • 基于布尔的SQL盲注
    • 基于时间的SQL盲注
    • 基于报错的SQL盲注

基于如何处理输入的SQL查询(数据类型)

  1. 基于字符串
  2. 数字或整数为基础的

基于程度和顺序的注入(哪里发生了影响)

  1. 一阶注入
  2. 二阶注入

    一阶注射是指输入的注射语句对 WEB 直接产生了影响,出现了结果;二阶注入类似存
    储型 XSS,是指输入提交的语句,无法直接对 WEB 应用程序产生影响,通过其它的辅助间
    接的对 WEB 产生危害,这样的就被称为是二阶注入

基于注入位置上的

  1. 通过用户输入的表单域的注入
  2. 通过cookie注入
  3. 通过服务器变量注入。(基于头部信息的注入)

系统函数

介绍几个常用函数

  1. version()——MySQL版本
  2. user()——数据库用户名
  3. datebase()——数据库名
  4. @@datadir——数据库路径
  5. @@version_compile_os——操作系统版本

字符串连接函数

函数具体介绍

  1. concat(str1,str2,…)——没有分隔符地连接字符串
  2. concat_ws(separator,str1,str2,…)——含有分隔符的连接字符串
  3. group_concat(str1,str2,…)——连接一个组的所有字符串,并以逗号分隔每一条数据说着比较抽象,其实也并不需要详细了解,知道这三个函数能一次性查出所有信息就行了

一般用于尝试的语句

ps:–+可以用#替换,url提交过程中url编码后的#为%23

1
2
3
4
5
6
7
or 1=1--+
'or 1=1--+
"or 1=1--+
)or 1=1--+
')or 1=1--+
") or 1=1--+
"))or 1=1--+

一般的代码为:

1
2
$id=$_GET['id'];
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";

此处考虑两个点,一个是闭合前面你的 ‘ 另一个是处理后面的 ‘ ,一般采用两种思路,闭合后面的引号或者注释掉,注释掉采用–+ 或者 #(%23)

union操作符的介绍

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

SQL UNION 语法

1
2
3
SELECT column_name(s) FROM table_name1
UNION
SELECT column_name(s) FROM table_name2

注释:默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。

SQL UNION ALL 语法

1
2
3
SELECT column_name(s) FROM table_name1
UNION ALL
SELECT column_name(s) FROM table_name2

另外,UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。

sql中的逻辑运算

首先提出一个问题

1
Select * from users where id=1 and 1=1;

上面这条语句为什么能够选择出id=1的内容,and 1=1到底起了什么作用?这里就要清除sql语句执行顺序了。同时这个问题我们在使用万能密码的时候会用到。

1
Select * from admin where username=’admin’ and password=’admin’

我们可以用’ or 1=1#作为密码输入。原因是为什么?这里涉及到一个逻辑运算,当使用上述所谓的万能密码后,构成的sql语句为:

1
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是恒成立的,所以结果自然就为真了。因此上述的语句就是恒真了
image

1
2
3
①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 值反推回字符。(运用较少)