此处介绍一些mysql注入的基础知识
注入的分类
基于从服务器接收到的响应
- 基于错误的SQL注入
- 联合查询的类型
- 堆查询注入
- SQL盲注
- 基于布尔的SQL盲注
- 基于时间的SQL盲注
- 基于报错的SQL盲注
基于如何处理输入的SQL查询(数据类型)
- 基于字符串
- 数字或整数为基础的
基于程度和顺序的注入(哪里发生了影响)
- 一阶注入
- 二阶注入
一阶注射是指输入的注射语句对 WEB 直接产生了影响,出现了结果;二阶注入类似存
储型 XSS,是指输入提交的语句,无法直接对 WEB 应用程序产生影响,通过其它的辅助间
接的对 WEB 产生危害,这样的就被称为是二阶注入
基于注入位置上的
- 通过用户输入的表单域的注入
- 通过cookie注入
- 通过服务器变量注入。(基于头部信息的注入)
系统函数
介绍几个常用函数
- version()——MySQL版本
- user()——数据库用户名
- datebase()——数据库名
- @@datadir——数据库路径
- @@version_compile_os——操作系统版本
字符串连接函数
- concat(str1,str2,…)——没有分隔符地连接字符串
- concat_ws(separator,str1,str2,…)——含有分隔符的连接字符串
- group_concat(str1,str2,…)——连接一个组的所有字符串,并以逗号分隔每一条数据说着比较抽象,其实也并不需要详细了解,知道这三个函数能一次性查出所有信息就行了
一般用于尝试的语句
ps:–+可以用#替换,url提交过程中url编码后的#为%23
1 | or 1=1--+ |
一般的代码为:
1 | $id=$_GET['id']; |
此处考虑两个点,一个是闭合前面你的 ‘ 另一个是处理后面的 ‘ ,一般采用两种思路,闭合后面的引号或者注释掉,注释掉采用–+ 或者 #(%23)
union操作符的介绍
UNION 操作符用于合并两个或多个 SELECT 语句的结果集。请注意,UNION 内部的 SELECT
语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的
列的顺序必须相同。
SQL UNION 语法
1 | SELECT column_name(s) FROM table_name1 |
注释:默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。
SQL UNION ALL 语法
1 | SELECT column_name(s) FROM table_name1 |
另外,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是恒成立的,所以结果自然就为真了。因此上述的语句就是恒真了
1 | ①Select * from users where id=1 and 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 值反推回字符。(运用较少)