SQL注入原理
在数据交互中,前端的数据传入到后台进行处理时,没有做严格的判断,过滤。导致传入的“数据”拼接到SQL语句中后,被当作SQL语句的一部分执行。从而导致数据库受损(被脱裤、数据被删除、甚至整个服务器权限沦陷)。
SQL注入常用的函数
version()数据库版本load_file()读取文件@@datadir数据库路径ascii()字符串的ascii代码@@basedir数据库安装路径ord()返回字符串第一个的ascii码mid()返回字符串的一部分count()返回结果的数量substr()返回字符串的一部分left()返回字符串左边的几个字符floor()返回小于或等于X的最大整数rand()返回0-1的随机数
sleep()让此语句运行几秒钟if()三个参数,条件,两种不同的结果 if(1>2,2,3)char()返回ascii码对应的字符串strcmp()比较两个字符串ascii值的大小(大小写不敏感)group_concat()连接所有字符串并逗号分割concat_ws()含有分隔符的链接字符串user()用户名database()数据库名
SQL注入常用语句
- 查库
select schema_name from imformation_schema.schemata;
- 查表
select schema_table from information_schema.tables where schema_name='security';
- 查字段
select colunm_name from information_schema.colunms where table_name=users and table_schema='security';
SQL注入的分类
1.可显注入
攻击者可以直接在当前界面内容中获取想要获得的内容。
2.报错注入
数据库查询返回结果并没有在页面中显示,但是应用程序将数据库报错信息打印到了页面中,所以攻击者可以构造数据库报错语句,从报错信息中获取想要获得的内容。
12种报错注入函数
1、通过floor报错,注入语句如下:
and (select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a);
2、通过extractvalue报错,注入语句如下:
and (extractvalue(1,concat(0x7e,(select user()),0x7e)));
3、通过updatexml报错,注入语句如下:
and (updatexml(1,concat(0x7e,(select user()),0x7e),1));
4、通过exp报错,注入语句如下:
and exp(~(select * from (select user () ) a) );
5、通过join报错,注入语句如下:
select * from(select * from mysql.user ajoin mysql.user b)c;
6、通过NAME_CONST报错,注入语句如下:
and exists(selectfrom (selectfrom(selectname_const(@@version,0))a join (select name_const(@@version,0))b)c);
7、通过GeometryCollection()报错,注入语句如下:
and GeometryCollection(()select *from(select user () )a)b );
8、通过polygon ()报错,注入语句如下:
and polygon (()select * from(select user ())a)b );
9、通过multipoint ()报错,注入语句如下:
and multipoint (()select * from(select user() )a)b );
10、通过multlinestring ()报错,注入语句如下:
and multlinestring (()select * from(selectuser () )a)b );
11、通过multpolygon ()报错,注入语句如下:
and multpolygon (()select * from(selectuser () )a)b );
12、通过linestring ()报错,注入语句如下:
and linestring (()select * from(select user() )a)b );
3.盲注
数据库查询结果无法从直观页面中获取,攻击者通过使用数据库逻辑或使数据库库执行延时等方法获取想要获得的内容。
4.时间盲注
常用函数 sleep ()
分割函数 substr、substring、left
分割函数编码后可不用引号,ascii () hex ()
一般时间盲注我们还需要使用条件判断函数
if(expre1,expre2,expre3)
当 expre1 为 true 时,返回 expre2,false 时,返回 expre3
5.布尔盲注
这种注入会出现在 注册、ip 头、留言板等等需要写入数据的地方,如用 sqlmap 会产生大量垃圾数据。尝试性插入、引号、双引号、转义符 \ 让语句不能正常执行,然后如果插入失败,更新失败,然后深入测试确定是否存在注入。
6.二次注入:
sql 语句的变量并不是直接传入的变量,而是通过其它的方式保存到了数据库,形成二次注入。没有单引号的 sql 语句中,进行 16 进制编码,这样就不会带有单引号。
7.宽字节注入:
字符注入的时候我们需要逃逸单引号,但是 php 提供了魔术引号开关 magic_quotes_gpc 和 addslashes (),iconv () 函数作为防御,特点是自动给传入的参数如单引号,双引号,反斜杠,%00 前面加一个反斜杠,进行转义,避免单引号进行逃逸。单引号转义为 ‘ , mysql 会将 \ 编码为 %5c ,宽字节中两个字节代表一个汉字,所以把 % df 加上 %5c 就变成了一个汉字 “運”,从而绕过转义。如果数据库是 GBK 格式而非默认的 UTF-8 格式,则我们利用两个 url 编码是一个汉字的特点,组合一个汉字从而解决”\“问题,完成单引号的逃逸。
8.数字型注入
当我们访问页面时经常会出现 http:xxx.admin.com?id=1 这种形式的 url,这个时候我们输入 and 1=1 与 and 1=2, 进行判定看是否会出现 and 1=1 回显正常,and 1=2 回显不正常的情况。如果出现了我们一般就认为这里存在注入,并且是数字型注入。如果没有出现那么并不能排查这里没有注入,只是排除这里不存在数字型的注入。
9.字符型注入
url 后输入’ and 1=1 and ‘1’=’1,’ and 1=2 and ‘1’=’1。看是否会出现报错的现象。如果存在我们可以进一步的闭合我们的语句。
10.http 头部注入
user-agent: 判定用户使用的操作系统,以及使用的浏览器的版本。
cookie: 判定用户的身份,进行 session 跟踪可以存储在用户本地终端上的数据,简单理解为用户的一张身份辨别卡。
x-forwarded-for: 是用来识别通过 HTTP 代理或负载均衡方式连接到 Web 服务器的客户端最原始的 IP 地址的 HTTP 请求头字段。
client-ip: 数据库保存客户端 IP 的参数。
rerferer: 浏览器向 web 端表明自己从哪个连接而来。
host: 客户端指定自己想访问的 WEB 服务器的域名 / IP 地址和端口号。
SQL注入的危害
1.数据库信息泄漏︰数据库中存放的用户的隐私信息的泄露。
2.网页篡改:通过操作数据库对特定网页进行篡改。
3.网站被挂马,传播恶意软件︰修改数据库一些字段的值,嵌入网马链接,进行挂马攻击。
4.数据库被恶意操作︰数据库服务器被攻击,数据库的系统管理员帐户被窜改。
5.服务器被远程控制︰被安装后门。经由数据库服务器提供的操作系统支持,让黑客得以修改或 控制操作系统。
6.破坏硬盘数据,瘫痪全系统。
SQL注入如何防御
1、在代码层面使用过滤函数正则表达式等对传入的参数进行一个过滤、检测、处理,使得传入的恶意数据无法按照预想方式执行
2、预编译sql语句
3、使用waf,安全狗,阿里云盾等waf进行防护
4、经常进行基线检查、漏洞扫描等工作
5.网络安全狗:防木马、防SQL注入
6.网络拓扑里使用WEB应用防火墙
SQL二次注入原理
在第一次进行数据库插入数据的时候,仅仅只是使用了 addslashes 或者是借助 get_magic_quotes_gpc 对其中的特殊字符进行了转义,在后端代码中可能会被转义,但在存入数据库时还是原来的数据,数据中一般带有单引号和#号,然后下次使用在拼凑SQL中,所以就形成了二次注入。
过程
插入1‘#
转义成1\’#
不能注入,但是保存在数据库时变成了原来的1’#
利用1’#进行注入,这里利用时要求取出数据时不转义
二次注入的条件
(1)用户向数据库插入恶意语句(即使后端代码对语句进行了转义,如mysql_escape_string、mysql_real_escape_string转义)
(2)数据库对自己存储的数据非常放心,直接取出恶意数据给用户
利用
:以sqli-lab24为例
1正常来说无法通过注入来登录admin,因为用户输入会被转义
2注册admin ‘#
3登录admin ‘# 转义成admin\’#,则登录的是admin’#
4修改admin ‘# 由于这里不会被转义,故可以直接利用,这个时候就变成了修改了admin的密码了
防御
1 解决SQL注入最推荐的方法还是预处理+数据绑定。
2 另一个防御的点就是 对输入一视同仁,无论输入来自用户还是存储,在进入到 SQL 查询前都对其进行过滤、转义