SQL注入防御漏洞
检测数据库最短的的Payload是:'
或者"
,而利用SQL注入实现攻击的最短Payload(Mysql
)是:'=0#
。
示例-用户登陆存在注入代码(login.jsp
):
访问:http://localhost:8000/modules/jdbc/login.jsp,如下图:
攻击者通过在密码参数处输入:'=0#
即可使用SQL注入的方式改变查询逻辑,绕过密码认证并登陆系统,因此用于检测用户账号密码是否存在的SQL语句变成了:
select id,username,password from sys_user where username = 'admin' and password = ''=0#'
其中的password
的值预期是传入用户密码,但是实际上被攻击者传入了可改变查询逻辑的SQL语句,将运算结果改变为true
,从而攻击者可以使用错误的用户及密码登陆系统,如下图:
通常情况下在用户系统发布文章后会在数据库中产生一条记录,并生成一个固定的文章ID,用户浏览文章信息只需要传入文章ID,即在后端通过文章ID查询文章详情信息。
示例-存在SQL注入的文章详情代码:
访问示例程序并传入参数id=100001
后会显示文章详情,请求:
攻击者在ID处构造并传入恶意的SQL注入语句后,可以轻松的读取出数据库信息,如将请求中的参数值改为100001 and 1=2 union select 1,2,user(),version(),database(),6
,服务器端将会返回数据库名称、请求:http://localhost:8000/modules/jdbc/article.jsp?id=100001%20and%201=2%20union%20select%201,2,user(),version(),database(),6,7,如下图:
由于攻击的Payload中包含了union、select、user()、version()、database()
敏感关键字,大部分的WAF
都能够识别此类SQL注入。
但如果攻击者将注入语句改为检测语句:100001-1
的时候页面会输出文章id
为100000
的文章,由于id
参数存在注入,数据库最终查询到的文章id
为100001-1
也就是id
为100000
的文章,请求:
几乎可以绕过99%
的WAF
和大部分的产品了,此类SQL注入攻击属于不具有攻击性的探测性攻击。
部分攻击者使用了数据库的一些特殊函数进行注入攻击,可能会导致WAF
无法识别,但是RASP具备特殊函数注入攻击的精准检测和防御能力。
例如上述示例中攻击者传入的id
参数值为:(100001-1)
或者(100001)
用于探测数据表中是否存在id
值为100000
的文章,请求:http://localhost:8000/modules/jdbc/article.jsp?id=(100001),如下图:
或者传入的id
参数值为:(select 100000)
来探测数据库是否存在id
值为100000
的文章,请求:
大多数数据库支持使用()
来包裹一个整数型的字段值,但是99%
的WAF
和极大多数的产品是无法识别此类型的注入攻击的。
示例-存在SQL注入漏洞的代码示例(JSON传参方式):