sql注入的实例和sqlmap使用

事情经过:

前几个月有一个云端管理后台项目上限,在做接口审计的时候,竟然发现了一个高危的sql注入漏洞。

因为之前我们业务线服务端业务主要是做APP接口相关,可自定义输入的位置并不过。而且研发的安全编码培训一直做的提高,服务端开发人员也比较稳定,对于sql注入的防范一直没有出过问题。

此次管理后台发现sql注入确实让我挺惊讶,可能是由于开发是新人,编码习惯和安全培训不到位,再加上项目周期比较紧张,才出现了这种低级失误。

具体的是一个云报表后台,事件分析的接口。存在SQL注入问题,攻击者可以通过sql注入获取或者删除数据库信息,被列为高危漏洞。

漏洞产生原因:

问题接口的数据来源于数据库表event_daily,即接口请求https:/xxxx/event_data/group_date?order=4&start_time=2023-07-21&end_time=2023-07-27&dids=2876携带的参数便会作为从event_daily表获取数据的查询条件。但是当时程序代码的sql语句没有用?来传入参数,而是直接把接收到的did参数通过字符串拼接到sql上了,也就是sql语句最终大概为:

String sql = "select * from eevent_daily where did='" + did + "'";

这也意味着,只要往里面插入一段sql就可以改变原有的语法结构。

比如插入如下代码:

28562';delete from event_analysis_dept_daily where id='2

此时SQL注入就产生了,最终的sql会变成如下:

select * from event_analysis_dept_daily where did='28562';delete from event_analysis_dept_daily where id='2'

这就造成查询了数据,还删了一条数据。

至此可看出,SQL注入漏洞就是指由于代码没有对用户输入项进行验证和处理便直接拼接到查询语句中,攻击者可以在查询语句中插入自己的SQL代码并传递给后台SQL服务器加以解析并执行,可导致数据库被拖,重要数据泄露。如果数据库的用户权限足够大,攻击者可以上传webshell,执行系统命令,进而控制服务器。

解决方式:

sql注入漏洞非常容易修复,即运用参数化查询的方式与数据库交互。参数化查询也叫做预处理语句,建立一个包含用户输入的SQL语句时分为以下两步。

1)指定查询结构,用户输入预留占位符。

2)指定占位符的内容。

那么上面的SQL注入问题就可以通过此方式解决,我们把上面sql换成预编译,如下:

//定义查询结构

String sql = "select * from event_analysis_dept_daily where did=?";

//预处理

PreparedStatement ps = conn.prepareStatement(sql);

//将用户输入添加到第一个占位符

ps.setString(1, request.getParameter("did"));

ps.executeQuery();

为什么这样就可以防止SQL注入?

原因就是上面的SQL语句”select * from event_analysis_dept_daily where did=?” 会预先编译好,也就是SQL引擎会预先进行语法分析、产生语法树并生成执行计划,即数据库执行sql语句可以理解为按照关键字来编译sql语句;也就是说,预编译后数据库肯定就不再重复编译了,那么后面你输入的参数,无论输入的是什么,比如再传什么 AND, OR都只会当成普通字符串来处理,都不会影响该SQL语句的语法结构了,因为语法分析已经完成了。而上面的SQL注入正是因为破坏了原有的SQL语法结构,才造成了SQL注入。

最后,原理就是:提前把要执行的sql进行了预编译,执行阶段只是把输入参数作为数据处理,而不再对SQL语句进行解析,因此也就避免了SQL注入问题。

除了预编译以外,对输入的强制类型转换、输入长度限制,输入内容正则匹配等方式,也可以有效的避免sql注入。

sqlmap的使用方式


sql注入的测试,可以由手工或者使用工具辅助测试。手工就是手动修改接口请求,在怀疑存在注入漏洞的位置输入注入的字符串,例如 or 1=1" 

手动测试比较繁琐,而且覆盖度也不够,一般是用来初步排查或者用来手工构造一些更复杂的sql注入场景。更多的,是采用像sqlmap这种成熟的工具来排查检测sql注入问题。

SQLMap是一个自动化的SQL注入工具,其主要功能是扫描、发现并利用给定URL的SQL注入漏洞。SQLMap内置了很多绕过插件,支持多种数据库。并且支持多种注入方式,例如基于联合查询的注入方式,基于布尔类型,基于时间的盲注等等。

1.判断是否存在注入

假设目标注入点是http://XXXX/id=?,用如下命令判断其是否存在注入:

python sqlmap.py -u http://XXXX/id=?

-u 命令执行后,sqlmap工具会在参数位置自动插入多种类型的注入字符串,通过返回语句,命令执行时间等方式,判断是否存在注入漏洞,并把相关信息输出。

2,存在注入的前提下,查询相关信息

如果接口存在sql注入漏洞,sqlmap提供了各种参数,可以获取数据库的相关信息。

-dbs 是确定网站存在注入后,用于查询当前用户下的所有数据库,命令如下:

pythonsqlmap.py -u url --dbs

-tables的作用是在查询完数据库后,查询指定数据库中所有的表名,命令如下:

pythonsqlmap.py -u"url"-D security --tables

-columns 的作用是在查询完表名后,查询该表中所有的字段名,命令如下:

pythonsqlmap.py -u"url "-D security -T users --columns

--referer:HTTP Referer头。

SQLMap可以在请求中伪造HTTP中的Referer,通过这种方式,绕过API对于refer的校验


一般在我们进行API接口审计的时候,判断是否存在sql注入,可以通过源代码审计+sqlmap工具配合使用的方式来进行。sqlmap作为一款非常强大并且开源的sql注入工具,还有很多非常强大的功能,包括对注入字符通过各种方式进行编码绕过waf,对数据库账号密码进行爆破等等功能,就不在这里一一讨论了,有兴趣的同学可以去自行学习。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容