文章目录

  • SQL注入漏洞原理
  • 结合简单的代码案例分析SQL注入漏洞是如何产生的
  • 判断是否存在注入
  • 最原始的判断是否存在注入的方式
  • 传入的字符对页面内容存在影响极有可能存在注入
  • 如何过滤、修复SQL注入漏洞
  • 判断SQL注入时,URL地址要符合什么条件? -->有参数


SQL注入漏洞原理

SQL注入漏洞产生的原理就是在开发人员针对代码编写开发web应用程序过程中,未对攻击者输入的可控参数的合法性进行有效的过滤和判断,从而造成攻击者利用可控的恶意参数带入数据库中执行,从而因造成了恶意的SQL语句对数据库执行的任意操作行为。

从原理上我们可以看出,造成SQL注入漏洞的两个关键条件。

1、用户/攻击者能够控制传参参数变量,即传参变量值用户可控。

2、WEB应用未进行严格过滤,从而造成攻击者的恶意参数代入到数据库中执行,从而参数可带入数据库中进行操作。

SQL注入原则上就是对数据库的数据进行操作,实现自己的目的,常见的操作就是利用SQL注入获得当前数据库的管理员账号密码,这仅仅是常见的一种攻击情况。


题外话:SQL注入点的存在和脚本语言没有关系,只会和数据库类型有关系。就像PHP和JAVA,为什么说PHP开发的WEBSQL注入漏洞多一些,JAVA开发的WEB端注入点就少一些,这是语言特性决定的。由于JAVA语言的预编译机制,就代表着基于JAVA开发的WEB站点很少会发现SQL注入漏洞。但是一旦爆出SQL注入漏洞,它不会说和语言有任何关系,只会和数据库类型有关系,这也是为什么说SQL注入漏洞的存在和脚本语言没有关系的原因。


结合简单的代码案例分析SQL注入漏洞是如何产生的


SQL注入 参数校验 java 验证sql注入_php


SQL注入 参数校验 java 验证sql注入_SQL_02


SQL注入 参数校验 java 验证sql注入_数据库_03


SQL注入 参数校验 java 验证sql注入_SQL注入 参数校验 java_04


通过数据库和访问本地的URL地址链接,我们知道当$id=100000/100001时,URL
对应的参数与相应的数据库id相等时,页面展示对应的title与content的信息。

我们看一下两个URL

http://127.0.0.1:8081/test.php?id=100000
http://127.0.0.1:8081/test.php?id=100001

http://127.0.0.1:8081/	为url地址端口
test.php 				为文件名
?id						为变量参数名
100000/100001			为$id变量参数且可控

再结合PHP代码,得出结论。当"100000"和"100001"作为参数赋值给$id带入SQL组合语句执行查询时,分别执行的SQL为

$sql="select * from sys_article where id = $id";  
$sql="select * from sys_article where id = 100000";

$sql="select * from sys_article where id = $id";  
$sql="select * from sys_article where id = 100000";

试想一下,如果说在传参的时候如果我们传输的值为 "100000 union select"又会怎样?此时的SQL组合查询语句就变成了

$sql="select * from sys_article where id = 100000 union select";

这里的union是分割两条及两条以上的SQL语句进行联合查询,用于合并两个或多个 SELECT 语句的结果集。如果说union 
后面的select 查询语句被原有的SQL查询语句带入数据库中,就会得到两条select语句的查询结果集

(这里是因为代码中未对SQL组合语句进行过滤,所以可以正常使用union进行联合查询,若果说存在过滤的话,则无法正常执行正常的查询操作)


由此我们得出结论,SQL注入的原理就是用户可控变量的传参受控,用户可以自定义SQL组合语句赋值实现自己想要查询的信息。
至于如何发现可控变量,有源码的话,可以分析源码。没有源码黑盒情况下,根据URL进行猜解实验,尝试发现可控变量。

判断是否存在注入

最原始的判断是否存在注入的方式

and 1=1 页面正常
select * from sys_article where id = 100000 and 1=1

and 1=2 页面错误(表示可能存在SQL注入)
select * from sys_article where id = 100000 and 1=2

判断是否存在注入的原理为逻辑运算符的判断原理

或  且  非
or and xor
真 或 真 =真
真 或 假 =真
真 且 假 =假


and 1=1  页面正常 
举例:select * from table_name where id = 1 and 1=1
其中“select * from table_name where id = 1”是结果为真的SQL语句;“and 1=1”也是结果为真。这样就是上面的 “真 且 真 =真”,返回“真”,页面正常。

and 1=2  页面错误
举例:select * from table_name where id = 1 and 1=2
其中“select * from table_name where id = 1”是结果为真的SQL语句;“and 1=2”也是结果为假。
这样就是上面的 “真 且 假 =假”,返回“假”,页面即错误,返回报错信息
(不一定报错就一定会返回错误信息,根据DBA对数据库的配置,也存在即使报错,页面也不会返回任何报错日志的情况)。


那么为何不选择 or 1=1 或者 or 1=2 呢?

我们来看一下 or 的逻辑运算结果

or 1 = 1
真 或 真 = 真
真 或 假 = 真

发现两个结果都是真,这种情况下就无法判断对网站是否有影响,也无法判断是否接收数据,看不出差异又无法判断是否真的存在注入。
这就是不适用 or 进行判断的原因。

传入的字符对页面内容存在影响极有可能存在注入

前文我们提到的URLhttp://127.0.0.1:8081/test.php?id=100000,如果在可控变量参数后加入一些乱码呢?

见下图:


SQL注入 参数校验 java 验证sql注入_php_05


分析原理,$id变量的可控参数包含的乱码被带入了数据库进行SQL语句的执行,无法正确的匹配该乱码产生了报错的信息,既然被带进了数据库,说明有接受这个乱码参数,如果不接收,网页又怎么可能受到影响呢?当然就存在注入的可能性啦,所以不一定通过某些特定的参数,直接在可控变量后面加上一堆乱七八糟的数据,查看页面是否受到影响即可。(该方法只是判断的方式之一,并不是百试百灵,只是在一些特定的条件下会产生该判断方式,后续会又其他的判断方式)

如何过滤、修复SQL注入漏洞

以上文的代码为例,已知SQL注入漏洞存在的情况下,即当前可控变量受控。我们可以针对SQL注入漏洞的关键字进行过滤修复,如果说检测到类似 “union”、“and”、“exec”、“select"等关键字即返回错误信息;或者针对”$id"变量的参数进行类型锁死的判断,当发现非"$id"变量的类型同样返回错误提示,也是一种过滤的方式;

还有一种方法就是安装WAF软件,现有的WAF软件一般都会集成有防注入和其他恶意攻击的代码层、行为检测策略,同样可以起到防止SQL注入的效果。

一种比较通用的字符串过滤方法(JAVA)

public static boolean sql_inj(String str){
 
	String inj_str = "'|and|exec|insert|select|delete|update|count|*|%|chr|mid|master|truncate|char|declare|;|or|-|+|,";
 
	String inj_stra[] = split(inj_str,"|");
 
	for (int i=0 ; i < inj_stra.length ; i++ ){
 
		if (str.indexOf(inj_stra[i])>=0){
 
		return true;
 
		}
	 
	}
 
return false;
 
}

判断SQL注入时,URL地址要符合什么条件? -->有参数

单参数

http://219.153.49.228:48105/new_list.php?id=1 可能存在注入点

http://219.153.49.228:48105/ 可能无法注入

http://219.153.49.228:48105/new_list.php 可能无法注入 看数据包 有可能参数没有在URL显示 但是在数据包有




多参数
http://219.153.49.228:48105/new_list.php?id=1&x=1&page=1
比如AWVS爆出参数id存在SQL注入,手工注入该注意哪些地方?

http://219.153.49.228:48105/new_list.php?id=1&x=1&page=1 and 1=1 错误
http://219.153.49.228:48105/new_list.php?id=1&x=1&page=1 and 1=2 错误


判定注入语句给了哪个变量 参数名
http://219.153.49.228:48105/new_list.php?id=1 and 1=1&x=1&page=1 正确
http://219.153.49.228:48105/new_list.php?id=1 and 1=2&x=1&page=1 正确


涉及到工具呢?SQLMAP毕竟是工具无法像人一样判断多参数的情况下具体哪个变量存在注入点
http://219.153.49.228:48105/new_list.php?x=1&page=1&id=1 and 1=1 正确

黑盒思路:筛选可存在漏洞URL(带参数),对参数进行传入参数值进行判断