4.1 SQL注入的原理及审计思路
SQL注入漏洞是非常常见的Web漏洞类型,也是迄今为止破坏性最大的漏洞类型之一。产生SQL注入漏洞的原因是Web代码中可控的参数没有进行过滤或没有进行有效的过滤,与程序中原有的SQL语句拼接,被带入SQL模板中编译执行,造成了漏洞,漏洞点就在与数据库的交互处。
SQL注入漏洞造成的危害大小,主要取决于攻击目标的权限。危害大的可获取WebShell,乃至执行系统命令,服务器提权,进入内网,获取数据库的所有数据,删除数据库中数据甚至删除整个库等操作;危害小的则获取数据库版本信息、账号登录、篡改小范围数据等。
4.1.1 产生SQL注入的条件
产生SQL注入的条件有如下几点。
1)可控参数。在业务应用系统中,有很多功能是需要前端和后端交互的,软件工程师要定义交互过程的数据传输参数,在没经过安全测试的状态下,存在安全隐患的概率是很大的。例如,/index.php/artcle?id=1,id=1表明是当前网站的第1页,如果换成id=2就会变成网站的第2页,以此类推。我们很容易明白该id参数与后面数字的作用。那么在测试过程当中就可以尝试加入其他SQL语句,例如and 1=2。
2)参数未过滤或过滤不严谨。交互必然要经过后端,如果没有经过“危险内容”过滤,会大概率导致SQL注入漏洞的产生,过滤“危险内容”不严谨也会造成安全隐患。
3)可控参数能够与数据库交互,且与原有的SQL语句拼接。数据经过服务端必然要根据业务系统设计者所需要的需求操作数据库,这个过程最容易与原有SQL拼接。一旦被执行,就会造成安全隐患。
4.1.2 SQL注入漏洞类型
SQL注入漏洞可以按以下三种方式进行分类。
●根据注入的可控参数的类型,可分为数字型注入和字符型注入。
●根据注入产生的位置,可分为GET注入、POST注入、cookie注入、header头注入等。
●根据攻击的手法,可分为普通注入、延时注入、盲注、报错注入、宽字节注入、二次注入等。
下面介绍几个常见的SQL注入漏洞发生场景。
●GET请求。一般对应的程序功能是查询搜索、列表、详情等,尤其是在多字段查询的情况下,要认真查看参数有没有进行过滤行为,或使用预编译的占位符进行参数绑定。列表、详情功能中可能存在数字型注入或者字符型注入。
●POST请求。一般对应的程序功能是提交、更新、查询,如登录、忘记密码找回处,验证用户名是否存在等功能。按照GET请求搜寻SQL注入漏洞的方式进行判断。
●Header头。比如cookie注入、IP伪造注入等。一般注册、登录处会有IP获取,后端一般是采用HTTP_CLIENT_IP或者X-FORWARD-FOR(也就是XFF)进行获取,而这种是可以伪造的。若此处没有过滤,就有可能出现多次注入。在搜寻此处位置漏洞的时候一定要查看是否进行标准IP类型过滤。
●$_SERVER。如果目标程序使用GPC转义的话,是不会对$_SERVER的值进行转义的,所以在$_SERVER与数据库交互的时候,也要检查是否进行过滤(按照GET请求方式检测)。
4.1.3 审计思路
涉及SQL注入的功能太多,从数据库里获取数据显示、验证数据、写入数据、修改数据、删除数据的功能点等,都可能存在SQL注入。换句话说,只要跟数据库进行交互,SQL注入漏洞就有可能存在。在审计SQL注入漏洞是否存在之前,最好先查看一下是否有防御SQL注入的方法。
4.1.4 防御建议
一般采用预编译机制来防御SQL注入。
1)用参数值规则防御。参数传递时要设置参数值的规则,例如用户名,检查其程序是否有命名规则,如果有则按命名规则进行防御,比如用户名只能为字母或者有长度限制。如传递时间参数的形式为“2018-09-12 21:21:21”,那就可以使用针对此种写法的正则去防御。检查用正则的时候是否用^$来匹配字符串的开始与结束位置,如果没有则可能会出现注入漏洞。
2)危险关键词防御,也就是设置黑名单。这种防御方法、防御类库在网上都有很多优秀的示例,防御机制主要是拦截可控参数中带有select、union、updatexml等恶意关键词的传参。
3)预编译机制。对于搜索等功能,可以使用预编译机制,进行参数绑定来拦截非法传参。
下面用案例剖析SQL注入漏洞。