大柚子

这世界不过如此

一、概述

在解释型语言中,如果程序与用户进行交互。用户就可以构造特殊的输入来拼接到程序中执行,从而使得程序依据用户输入执行有可能存在 恶意行为的代码。

例如:在于用户交互的程序中,用户的输入拼接到SQL语句中,执行了与原定计划不同的行为,从而产生了SQL注入的漏洞。

前提:

用户可以输入,并且用户可以控制

用户输入的内容会跟数据库交互,会拼接到sql语句中。


Java中典型的会产生SQL注入的代码如下:
<code>String query = "SELECT * FROM user_data WHERE last_name='" + accountName + "'";
ResultSet results = statement.executeQuery(query);
查询语句拼接了用户输入的字符串accountName。如果攻击者输入字符串“anyName' OR 'a'='a”,那么构造语句就会变成: Select * FROM user_data WHERE last_name = 'anyName' OR 'a'='a'; 附加条件 OR 'a' = 'a' 使WHERE 从句永真,逻辑上等同于: SELECT * FROM user_data; 这样攻击者绕过用户名验证,查询结果能返回表格所有用户条目。

二、SQL注入代码分析

1、启动WebGoat环境,进入sql注入漏洞利用界面

2、发现登录框,尝试发送正常请求,然后F12查看网络元素,获取请求的真正接口,接口如下:

http://127.0.0.1:8080/WebGoat/SqlInjection/assignment5b

3、根据获取到的接口,在idea直接搜索该接口的实现代码,在源码中实现类是:org.owasp.webgoat.sql_injection.introduction.SqlInjectionLesson5b
其实现方法为“completed”方法:

4、查看”completed”方法,传入两个参数“userid” 和“login_count”,返回值调用injectableQuery方法,并把两个参数传入此方法,跟进

5、查看injectableQuery方法,首先定义了查询语句变量”queryString“,并对其中的”login_Count”进行了占位。接着将SQL查询语句代入”prepareStatement“方法执行,进行查询数据库的操作。其中“prepareStatement”方法是以预编译的方法查询数据库。

6、继续跟进,该方法会将”login_count“变量强制转换为整数类型,如果不能强制转换成整数类型,直接return退出,不会执行后面的语句,故“login_count”必须是整数类型。

7、最后是将SQL语句代入到数据库中执行,并将查询结果返回展示。

8、代码实现流程大致如下:

(1)查询数据库时,用的是预编译的方法,但是“queryString”构造查询语句时,只对”Login_Count”变量使用了占位符,“accountName“还是直接拼接在查询语句中。但在预编译中,只会对占位符对应的变量进行预编译。所以对”accountName“变量没有任何过滤。

(2)其次,后面的代码也只是对”Login_Count”变量进行了处理和过滤,依旧没有对“accountName“进行处理。

(3)故漏洞点在与”accountName“变量处,此变量在completed方法中对应的变量为userid,F12在页面中查到对应这个参数的是”User_Id”。

(4)在“User_Id”,输入payload:11 or 1=1,可以成功利用该SQL注入漏洞,最后拼接的SQL语句为


select * from user_data where Login_Count=1 and userid= 1 or 1=1

三、SQL注入代码审计技巧

1、从功能点出发,查看常见需要查询数据库取数据的功能,如登录、搜索、显示产品等。

2、查找关键字,如执行sql语句的类和方法(executeQuery、createStatement、PreparedStatement、connection等)和自定义封装的数据库操作类和方法。



Print Friendly, PDF & Email

发表回复

您的电子邮箱地址不会被公开。