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,从而攻击者可以使用错误的用户及密码登陆系统,如下图:

    image-20200920235312260

    通常情况下在用户系统发布文章后会在数据库中产生一条记录,并生成一个固定的文章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,如下图:

    image-20200921000001434

    由于攻击的Payload中包含了union、select、user()、version()、database()敏感关键字,大部分的WAF都能够识别此类SQL注入。

    但如果攻击者将注入语句改为检测语句:100001-1的时候页面会输出文章id100000的文章,由于id参数存在注入,数据库最终查询到的文章id100001-1也就是id100000的文章,请求:

    几乎可以绕过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的文章,请求:

    image-20200921000501695

    大多数数据库支持使用()来包裹一个整数型的字段值,但是99%WAF和极大多数的产品是无法识别此类型的注入攻击的。

    示例-存在SQL注入漏洞的代码示例(JSON传参方式):