日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

常见的Java审计代码函数关键字_转载:Java代码审计汇总系列(一)——SQL注入

發布時間:2023/12/1 java 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 常见的Java审计代码函数关键字_转载:Java代码审计汇总系列(一)——SQL注入 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原文鏈接:https://cloud.tencent.com/developer/article/1534109

一、代碼審計

相比黑盒滲透的漏洞挖掘方式,代碼審計具有更高的可靠性和針對性,更多的是依靠對代碼、架構的理解;使用的審計工具一般選擇Eclipse或IDEA;審計工作過程主要有三步:風險點發現——>風險定位追蹤——>漏洞利用,所以審計不出漏洞無非就是find:“找不到該看哪些代碼”和judge:“定位到代碼但判斷不出有沒有問題”。而風險點發現的重點則在于三個地方:用戶輸入(入參)處+檢測繞過處+漏洞觸發處,一般審計代碼都是借助代碼掃描工具(Fortify/Checkmarx)或從這三點著手。

本系列選取WebGoat作為案例,講解漏洞的特征發現、定位技巧、調試及觸發利用的具體過程,盡量涵蓋所有的挖掘場景,最后補充實戰挖掘案例。

二、SQLi漏洞挖掘

1、介紹

SQLi是最著名也是影響最廣的漏洞之一,注入漏洞都是程序把用戶輸入的數據當做代碼執行,發現的關鍵有兩個,第一是用戶能夠控制輸入;第二是用戶輸入的數據被拼接到要執行的代碼中從而被執行。

2、挖掘過程

這里以webgoat的數字型注入講解SQLi漏洞的挖掘過程:

1) 定位特定功能模塊的代碼

了解不同框架特性,本系統的Springboot注解:

@RequestMapping(path= PATH)

@GetMapping(path= PATH)

@PostMapping(path= PATH)

通過抓取請求數據包獲取path特征SqlInjection/assignment5b:

使用IDEA的全局搜索功能(SHIFT+CTRL+F)定位到代碼:

2) 代碼分析

SqlInjectionLesson5b.java類代碼如下:

@PostMapping("/SqlInjection/assignment5b")

@ResponseBody

public AttackResult completed(@RequestParam String userid, @RequestParam String login_count, HttpServletRequest request) throws IOException {

return injectableQuery(login_count, userid);

}

protected AttackResult injectableQuery(String login_count, String accountName) {

String queryString = "SELECT * From user_data WHERE Login_Count = ? and userid= " + accountName;

try {

Connection connection = DatabaseUtilities.getConnection(getWebSession());

PreparedStatement query = connection.prepareStatement(queryString, ResultSet.TYPE_SCROLL_INSENSITIVE,

ResultSet.CONCUR_READ_ONLY);

這是一個典型的動態拼接用戶輸入和防范案例,系統接收兩個參數login_count和userid,其中login_count通過“+”直接拼接,而userid首先通過類型轉換為Integer賦值給count,并經過了預編譯(參數化請求)處理,不存在SQLi漏洞。

3)漏洞驗證

最后構造路徑及參數POC驗證漏洞存在:

3、漏洞分類挖掘技巧

根據挖掘經驗,白盒挖掘層面大致可以將SQLi的類型分為六類:

1、入參直接動態拼接;

2、預編譯有誤;

3、框架注入(Mybatis+Hibernate);

4、order by 繞過預編譯;

5、%和_繞過預編譯;

6、SQLi檢測繞過

1) 參數直接拼接

最明顯的“+”拼接,思路一般有二:通過關鍵字定位到SQL語句,回溯參數是否是用戶可控;或通過跟蹤用戶輸入,是否執行SQL操作,搜索的關鍵詞有:

Select|insert|update|delete|java.sql.Connection|Statement|.execute|.executeQuery|jdbcTemplate|queryForInt|queryForObject|queryForMap|getConnection|PreparedStatement|Statement|execute|jdbcTemplate|queryForInt|queryForObject|queryForMap|executeQuery|getConnection

2) 預編譯有誤

并不是使用了預編譯PreparedStatement一定就可以防止SQL注入,動態拼接SQL同樣存在SQLi注入,這也是實際審計中高發的問題,下面代碼就是典型的預編譯有誤:

String query = "SELECT * FROM usersWHERE userid ='"+ userid + "'" + " AND password='" +password + "'";

PreparedStatement stmt =connection.prepareStatement(query);

ResultSet rs = stmt.executeQuery();

定位預編譯可以通過搜索關鍵函數:

setObject()、setInt()、setString()、setSQLXML()

3) 框架注入

Hibernate典型的注入代碼為:

session.createQuery("from Book wheretitle like '%" + userInput + "%' and published = true")

或形如:

{

StringBuffer queryString = newStringBuffer();

queryString.append(“from Test where id=’”);

queryString.append(id);

queryString.append(‘\’’);

}

定位此框架的SQL注入首先需要在xml配置文件或import包里確認是否使用此框架,然后使用關鍵字createQuery,session.save(,session.update(,session.delete進行定位。

Mybatis有兩種變量方法,不安全的寫法為:

select * from books where id= ${id}

安全的寫法為JDBC預編譯:

select * from books where id= #{id}

此外like、in和order by語句也需要使用#,挖掘技巧則是在注解中或者Mybatis相關的配置文件中搜索 $。

4) order by 繞過預編譯

類似下面sql語句 order by 后面是不能用預編譯處理的只能通過拼接處理,只能手動進行過濾,詳見案例。

String sql = “Select * from news where title =?”+ “order by‘” + time + “’asc”

5) %和_繞過預編譯

預編譯是不能處理%,需要手動過濾,否則會造成慢查詢和DOS。

6) SQLi檢測繞過

若SQL在處理過程中經過黑/白名單(正則)或Filter檢測,通常檢測代碼存在缺陷則可進行檢測繞過。

4、漏洞防御

OWASP官方推薦的SQLi防御方案有四種:

1)預編譯(參數化查詢)

PreparedStatement stmt =connection.prepareStatement("SELECT * FROM users WHERE userid=? ANDpassword=?");

stmt.setString(1, userid);

stmt.setString(2, password);

ResultSet rs = stmt.executeQuery();

2)存儲過程

使用CallableStatement對存儲過程接口的實現來執行數據庫查詢,SQL代碼定義并存儲在數據庫本身中,然后從應用程序中調用,使用存儲過程和預編譯在防SQLi方面的效果是相同的。

String custname =request.getParameter("customerName");

try {

CallableStatement cs = connection.prepareCall("{callsp_getAccountBalance(?)}");

cs.setString(1, custname);

ResultSet results = cs.executeQuery();

} catch (SQLException se) {

}

3)黑/白名單驗證

屬于輸入驗證的范疇,大多使用正則表達式限制,或對于諸如排序順序之類的簡單操作,最好將用戶提供的輸入轉換為布爾值,然后將該布爾值用于選擇要附加到查詢的安全值。

public String someMethod(boolean sortOrder) {

String SQLquery = "someSQL ... order by Salary " + (sortOrder ? "ASC" :"DESC");`

4) 輸出轉義

將用戶輸入放入查詢之前對其進行轉義,OWASP企業安全性API(ESAPI)是一個免費的開源Web應用程序安全控制庫。

CodecORACLE_CODEC = new OracleCodec();

Stringquery = "SELECT user_id FROM user_data WHERE user_name = '"

+ESAPI.encoder().encodeForSQL( ORACLE_CODEC,req.getParameter("userID"))

+ "'and user_password = '"

+ ESAPI.encoder().encodeForSQL( ORACLE_CODEC,req.getParameter("pwd")) +"'";

5)框架修復:

對于Mybatis框架:

select * from news where tile like concat(‘%’,#{title}, ‘%’),

select * from news where id in

#{item}

Mybatis的order by語句可以選擇在java層做映射或過濾用戶輸入進行防御。

對于Hibernate(HQL)框架預編譯:

方法一:

Query query=session.createQuery(“from Useruser where user.name=:customername and user:customerage=:age ”);

query.setString(“customername”,name);

query.setInteger(“customerage”,age);

方法二:

String hql ="FROM User user where user.name=? and user.age=?";

Query q =session.createQuery(hql);

q.setString(0, name);

q.setInteger(1,age);

5、實戰案例

1) Mybatis框架

對文章刪除功能進行審計,articelId參數前端可控:

@RequestMapping("/delete")

public ModelAndView delete(HttpServletRequestrequest) {

ModelAndView model = newModelAndView();

try {

model.setViewName(this.getRequestUri(request));

String[] aridArr = request.getParameterValues("articelId");

if (aridArr != null&& aridArr.length > 0) {

this.deleteArticle(aridArr);

}

} catch (Exception e) {

model.setViewName(this.setExceptionRequest(request,e));

logger.error("AdminArticleController.delete()--error",e);

}

return model;

}

順著變量的走向進行審計,articelId賦值給aridArr,而后進行了為空的判斷,不為空則執行deleteArticle操作,跟蹤定位此函數:

private void deleteArticle(String[]artidArr) {

//刪除數據中記錄

articleService.deleteArticleByIds(artidArr);

EHCacheUtil.remove(CacheConstans.ARTICLE_GOOD_RECOMMEND);

繼續跟蹤操作,articleService類的deleteArticleByIds函數,繼而進入DAO層,在ArticleDaoImpl.java內:

public void deleteArticleByIds(StringarticleIds) {

this.delete("ArticleMapper.deleteArticleByIds",articleIds);

}

進入ArticleMapper.xml,最終追蹤到deleteArticleByIds的SQL語句,使用了$拼接,典型的Mybatis注入:

DELETEFROM EDU_ARTICLE WHERE EDU_ARTICLE.ARTICLE_ID IN (${value})

除了順向思維,還可以通過逆向思維挖掘,pom.xml中看到系統使用的是Mybatis框架,可以直接去審查Maper.xml文件,查看是否使用$拼接:

UTF-8

3.2.12.RELEASE

3.2.7

1.7.3

1.7

2) Order by繞過預編譯

Webgoat一個order by的案例:

order by的參數orderExpression可以是一個selectExpression也可以是一個函數,比如使用一個case語句。

案例中可以根據IP或ID對數據進行排序:

對應代碼為Server.java:

@GetMapping(produces =MediaType.APPLICATION_JSON_VALUE)

@SneakyThrows

@ResponseBody

public List sort(@RequestParamString column) {

Connection connection = DatabaseUtilities.getConnection(webSession);

PreparedStatement preparedStatement =connection.prepareStatement("select id, hostname, ip, mac, status, descriptionfrom servers where status <> 'outof order' order by " + column);

ResultSet rs = preparedStatement.executeQuery();

List servers = Lists.newArrayList();

while (rs.next()) {

Server server = new Server(rs.getString(1), rs.getString(2),rs.getString(3), rs.getString(4), rs.getString(5), rs.getString(6));

servers.add(server);

}

雖使用了預編譯但仍拼接了order by參數column,使用case探測語句探測:(case when (true) then id else ip end),如果真則以id排序,結果為:

3) 預編譯有誤

查看FAQ頁面數據功能getFaqPage函數,前端獲取page等參數:

publicFaqPageInfo getFaqPage(String tenantId, Map conditions,int page, int pageSize, String like) {

try {

tenantId= WebUtil.getLoginTenantId();

FaqPageInfo fpi =FAQ_IO_SERVICE.getPageInfo(tenantId, conditions, page, pageSize, like);

for (FaqModel fm : fpi.getData()) {

fm.setWhitelistIds(WHITELIST_SERVICE.getWhiteListOnFaq(tenantId,fm.getId()));

}

return fpi;

}

跟蹤FAQ_IO_SERVICE.getPageInfo,調用FaqSqlAccess.queryByPage進行處理:

public FaqPageInfo getPageInfo(StringtenantId, Map conditions, int page, int pageSize, Stringlike)

throws SQLException {

FaqPageInfo pageInfo = new FaqPageInfo();

pageInfo.setData(FaqSqlAccess.queryByPage(tenantId, conditions, page,pageSize, like));

pageInfo.setTotalSize(FaqSqlAccess.queryCount(tenantId, conditions,like));

return pageInfo;

}

找到FaqSqlAccess.java里的queryByPage方法,追蹤到SQL語句:

public static ListqueryByPage(String tenantId, Map conditions, int page,int pageSize, String like)

throws SQLException {

List models = new ArrayList<>();

String language = conditions.get("language");

Connection connection = null;

PreparedStatement stmt = null;

try {

connection = MysqlUtils.getConnection();

String sql = "select id, name, description, language, update_time,is_on from TOC_FAQ where tenant_id=?";

if (!CommonUtils.isEmptyStr(language))

sql += " andlanguage='" + language + "'";

if (!CommonUtils.isEmptyStr(like))

sql += " and name like'%" + like + "%'";

sql += " order by update_time desc limit ?,?";

stmt = connection.prepareStatement(sql);

stmt.setString(1, tenantId);

stmt.setInt(2, (page - 1) * pageSize);

stmt.setInt(3, pageSize);

ResultSet resultSet = stmt.executeQuery();

發現此處使用了預編譯,但language和like參數實際是直接拼接,存在SQL注入,對于getFaqPage功能構造參數"language":"'-if(substring(user(),1,1)=0x01,sleep(5),0)-'"}進行驗證。

簡單或復雜的SQL注入漏洞原理和審計方法相同,只是對于業務繁雜的系統,數據的走向和處理過程會比較復雜,調用鏈跟蹤難度會稍大一些,需要更多耐心。

一、代碼審計

相比黑盒滲透的漏洞挖掘方式,代碼審計具有更高的可靠性和針對性,更多的是依靠對代碼、架構的理解;使用的審計工具一般選擇Eclipse或IDEA;審計工作過程主要有三步:風險點發現——>風險定位追蹤——>漏洞利用,所以審計不出漏洞無非就是find:“找不到該看哪些代碼”和judge:“定位到代碼但判斷不出有沒有問題”。而風險點發現的重點則在于三個地方:用戶輸入(入參)處+檢測繞過處+漏洞觸發處,一般審計代碼都是借助代碼掃描工具(Fortify/Checkmarx)或從這三點著手。

本系列選取WebGoat作為案例,講解漏洞的特征發現、定位技巧、調試及觸發利用的具體過程,盡量涵蓋所有的挖掘場景,最后補充實戰挖掘案例。

二、SQLi漏洞挖掘

1、介紹

SQLi是最著名也是影響最廣的漏洞之一,注入漏洞都是程序把用戶輸入的數據當做代碼執行,發現的關鍵有兩個,第一是用戶能夠控制輸入;第二是用戶輸入的數據被拼接到要執行的代碼中從而被執行。

2、挖掘過程

這里以webgoat的數字型注入講解SQLi漏洞的挖掘過程:

1) 定位特定功能模塊的代碼

了解不同框架特性,本系統的Springboot注解:

@RequestMapping(path= PATH)

@GetMapping(path= PATH)

@PostMapping(path= PATH)

通過抓取請求數據包獲取path特征SqlInjection/assignment5b:

使用IDEA的全局搜索功能(SHIFT+CTRL+F)定位到代碼:

2) 代碼分析

SqlInjectionLesson5b.java類代碼如下:

@PostMapping("/SqlInjection/assignment5b")

@ResponseBody

public AttackResult completed(@RequestParam String userid, @RequestParam String login_count, HttpServletRequest request) throws IOException {

return injectableQuery(login_count, userid);

}

protected AttackResult injectableQuery(String login_count, String accountName) {

String queryString = "SELECT * From user_data WHERE Login_Count = ? and userid= " + accountName;

try {

Connection connection = DatabaseUtilities.getConnection(getWebSession());

PreparedStatement query = connection.prepareStatement(queryString, ResultSet.TYPE_SCROLL_INSENSITIVE,

ResultSet.CONCUR_READ_ONLY);

這是一個典型的動態拼接用戶輸入和防范案例,系統接收兩個參數login_count和userid,其中login_count通過“+”直接拼接,而userid首先通過類型轉換為Integer賦值給count,并經過了預編譯(參數化請求)處理,不存在SQLi漏洞。

3)漏洞驗證

最后構造路徑及參數POC驗證漏洞存在:

3、漏洞分類挖掘技巧

根據挖掘經驗,白盒挖掘層面大致可以將SQLi的類型分為六類:

1、入參直接動態拼接;

2、預編譯有誤;

3、框架注入(Mybatis+Hibernate);

4、order by 繞過預編譯;

5、%和_繞過預編譯;

6、SQLi檢測繞過

1) 參數直接拼接

最明顯的“+”拼接,思路一般有二:通過關鍵字定位到SQL語句,回溯參數是否是用戶可控;或通過跟蹤用戶輸入,是否執行SQL操作,搜索的關鍵詞有:

Select|insert|update|delete|java.sql.Connection|Statement|.execute|.executeQuery|jdbcTemplate|queryForInt|queryForObject|queryForMap|getConnection|PreparedStatement|Statement|execute|jdbcTemplate|queryForInt|queryForObject|queryForMap|executeQuery|getConnection

2) 預編譯有誤

并不是使用了預編譯PreparedStatement一定就可以防止SQL注入,動態拼接SQL同樣存在SQLi注入,這也是實際審計中高發的問題,下面代碼就是典型的預編譯有誤:

String query = "SELECT * FROM usersWHERE userid ='"+ userid + "'" + " AND password='" +password + "'";

PreparedStatement stmt =connection.prepareStatement(query);

ResultSet rs = stmt.executeQuery();

定位預編譯可以通過搜索關鍵函數:

setObject()、setInt()、setString()、setSQLXML()

3) 框架注入

Hibernate典型的注入代碼為:

session.createQuery("from Book wheretitle like '%" + userInput + "%' and published = true")

或形如:

{

StringBuffer queryString = newStringBuffer();

queryString.append(“from Test where id=’”);

queryString.append(id);

queryString.append(‘\’’);

}

定位此框架的SQL注入首先需要在xml配置文件或import包里確認是否使用此框架,然后使用關鍵字createQuery,session.save(,session.update(,session.delete進行定位。

Mybatis有兩種變量方法,不安全的寫法為:

select * from books where id= ${id}

安全的寫法為JDBC預編譯:

select * from books where id= #{id}

此外like、in和order by語句也需要使用#,挖掘技巧則是在注解中或者Mybatis相關的配置文件中搜索 $。

4) order by 繞過預編譯

類似下面sql語句 order by 后面是不能用預編譯處理的只能通過拼接處理,只能手動進行過濾,詳見案例。

String sql = “Select * from news where title =?”+ “order by‘” + time + “’asc”

5) %和_繞過預編譯

預編譯是不能處理%,需要手動過濾,否則會造成慢查詢和DOS。

6) SQLi檢測繞過

若SQL在處理過程中經過黑/白名單(正則)或Filter檢測,通常檢測代碼存在缺陷則可進行檢測繞過。

4、漏洞防御

OWASP官方推薦的SQLi防御方案有四種:

1)預編譯(參數化查詢)

PreparedStatement stmt =connection.prepareStatement("SELECT * FROM users WHERE userid=? ANDpassword=?");

stmt.setString(1, userid);

stmt.setString(2, password);

ResultSet rs = stmt.executeQuery();

2)存儲過程

使用CallableStatement對存儲過程接口的實現來執行數據庫查詢,SQL代碼定義并存儲在數據庫本身中,然后從應用程序中調用,使用存儲過程和預編譯在防SQLi方面的效果是相同的。

String custname =request.getParameter("customerName");

try {

CallableStatement cs = connection.prepareCall("{callsp_getAccountBalance(?)}");

cs.setString(1, custname);

ResultSet results = cs.executeQuery();

} catch (SQLException se) {

}

3)黑/白名單驗證

屬于輸入驗證的范疇,大多使用正則表達式限制,或對于諸如排序順序之類的簡單操作,最好將用戶提供的輸入轉換為布爾值,然后將該布爾值用于選擇要附加到查詢的安全值。

public String someMethod(boolean sortOrder) {

String SQLquery = "someSQL ... order by Salary " + (sortOrder ? "ASC" :"DESC");`

4) 輸出轉義

將用戶輸入放入查詢之前對其進行轉義,OWASP企業安全性API(ESAPI)是一個免費的開源Web應用程序安全控制庫。

CodecORACLE_CODEC = new OracleCodec();

Stringquery = "SELECT user_id FROM user_data WHERE user_name = '"

+ESAPI.encoder().encodeForSQL( ORACLE_CODEC,req.getParameter("userID"))

+ "'and user_password = '"

+ ESAPI.encoder().encodeForSQL( ORACLE_CODEC,req.getParameter("pwd")) +"'";

5)框架修復:

對于Mybatis框架:

select * from news where tile like concat(‘%’,#{title}, ‘%’),

select * from news where id in

#{item}

Mybatis的order by語句可以選擇在java層做映射或過濾用戶輸入進行防御。

對于Hibernate(HQL)框架預編譯:

方法一:

Query query=session.createQuery(“from Useruser where user.name=:customername and user:customerage=:age ”);

query.setString(“customername”,name);

query.setInteger(“customerage”,age);

方法二:

String hql ="FROM User user where user.name=? and user.age=?";

Query q =session.createQuery(hql);

q.setString(0, name);

q.setInteger(1,age);

5、實戰案例

1) Mybatis框架

對文章刪除功能進行審計,articelId參數前端可控:

@RequestMapping("/delete")

public ModelAndView delete(HttpServletRequestrequest) {

ModelAndView model = newModelAndView();

try {

model.setViewName(this.getRequestUri(request));

String[] aridArr = request.getParameterValues("articelId");

if (aridArr != null&& aridArr.length > 0) {

this.deleteArticle(aridArr);

}

} catch (Exception e) {

model.setViewName(this.setExceptionRequest(request,e));

logger.error("AdminArticleController.delete()--error",e);

}

return model;

}

順著變量的走向進行審計,articelId賦值給aridArr,而后進行了為空的判斷,不為空則執行deleteArticle操作,跟蹤定位此函數:

private void deleteArticle(String[]artidArr) {

//刪除數據中記錄

articleService.deleteArticleByIds(artidArr);

EHCacheUtil.remove(CacheConstans.ARTICLE_GOOD_RECOMMEND);

繼續跟蹤操作,articleService類的deleteArticleByIds函數,繼而進入DAO層,在ArticleDaoImpl.java內:

public void deleteArticleByIds(StringarticleIds) {

this.delete("ArticleMapper.deleteArticleByIds",articleIds);

}

進入ArticleMapper.xml,最終追蹤到deleteArticleByIds的SQL語句,使用了$拼接,典型的Mybatis注入:

DELETEFROM EDU_ARTICLE WHERE EDU_ARTICLE.ARTICLE_ID IN (${value})

除了順向思維,還可以通過逆向思維挖掘,pom.xml中看到系統使用的是Mybatis框架,可以直接去審查Maper.xml文件,查看是否使用$拼接:

UTF-8

3.2.12.RELEASE

3.2.7

1.7.3

1.7

2) Order by繞過預編譯

Webgoat一個order by的案例:

order by的參數orderExpression可以是一個selectExpression也可以是一個函數,比如使用一個case語句。

案例中可以根據IP或ID對數據進行排序:

對應代碼為Server.java:

@GetMapping(produces =MediaType.APPLICATION_JSON_VALUE)

@SneakyThrows

@ResponseBody

public List sort(@RequestParamString column) {

Connection connection = DatabaseUtilities.getConnection(webSession);

PreparedStatement preparedStatement =connection.prepareStatement("select id, hostname, ip, mac, status, descriptionfrom servers where status <> 'outof order' order by " + column);

ResultSet rs = preparedStatement.executeQuery();

List servers = Lists.newArrayList();

while (rs.next()) {

Server server = new Server(rs.getString(1), rs.getString(2),rs.getString(3), rs.getString(4), rs.getString(5), rs.getString(6));

servers.add(server);

}

雖使用了預編譯但仍拼接了order by參數column,使用case探測語句探測:(case when (true) then id else ip end),如果真則以id排序,結果為:

3) 預編譯有誤

查看FAQ頁面數據功能getFaqPage函數,前端獲取page等參數:

publicFaqPageInfo getFaqPage(String tenantId, Map conditions,int page, int pageSize, String like) {

try {

tenantId= WebUtil.getLoginTenantId();

FaqPageInfo fpi =FAQ_IO_SERVICE.getPageInfo(tenantId, conditions, page, pageSize, like);

for (FaqModel fm : fpi.getData()) {

fm.setWhitelistIds(WHITELIST_SERVICE.getWhiteListOnFaq(tenantId,fm.getId()));

}

return fpi;

}

跟蹤FAQ_IO_SERVICE.getPageInfo,調用FaqSqlAccess.queryByPage進行處理:

public FaqPageInfo getPageInfo(StringtenantId, Map conditions, int page, int pageSize, Stringlike)

throws SQLException {

FaqPageInfo pageInfo = new FaqPageInfo();

pageInfo.setData(FaqSqlAccess.queryByPage(tenantId, conditions, page,pageSize, like));

pageInfo.setTotalSize(FaqSqlAccess.queryCount(tenantId, conditions,like));

return pageInfo;

}

找到FaqSqlAccess.java里的queryByPage方法,追蹤到SQL語句:

public static ListqueryByPage(String tenantId, Map conditions, int page,int pageSize, String like)

throws SQLException {

List models = new ArrayList<>();

String language = conditions.get("language");

Connection connection = null;

PreparedStatement stmt = null;

try {

connection = MysqlUtils.getConnection();

String sql = "select id, name, description, language, update_time,is_on from TOC_FAQ where tenant_id=?";

if (!CommonUtils.isEmptyStr(language))

sql += " andlanguage='" + language + "'";

if (!CommonUtils.isEmptyStr(like))

sql += " and name like'%" + like + "%'";

sql += " order by update_time desc limit ?,?";

stmt = connection.prepareStatement(sql);

stmt.setString(1, tenantId);

stmt.setInt(2, (page - 1) * pageSize);

stmt.setInt(3, pageSize);

ResultSet resultSet = stmt.executeQuery();

發現此處使用了預編譯,但language和like參數實際是直接拼接,存在SQL注入,對于getFaqPage功能構造參數"language":"'-if(substring(user(),1,1)=0x01,sleep(5),0)-'"}進行驗證。

簡單或復雜的SQL注入漏洞原理和審計方法相同,只是對于業務繁雜的系統,數據的走向和處理過程會比較復雜,調用鏈跟蹤難度會稍大一些,需要更多耐心。

總結

以上是生活随笔為你收集整理的常见的Java审计代码函数关键字_转载:Java代码审计汇总系列(一)——SQL注入的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。