1. 程式人生 > >Java代碼審計連載之—SQL註入

Java代碼審計連載之—SQL註入

問題 連載 edi 初學者 epo lte where color 用戶

前言
近日閑來無事,快兩年都沒怎麽寫代碼了,打算寫幾行代碼,做代碼審計一年了,每天看代碼都好幾萬行,突然發現自己都不會寫代碼了,真是很DT。想當初入門代碼審計的時候真是非常難,網上幾乎找不到什麽java審計的資料,摸索了很長時間,搜到的也僅僅講了點原理,為了給想學java代碼審計的朋友門一點入門資料,就開始寫《java代碼審計連載》系列文章,本文章適合初學者,大牛留下腳印後請繞過,若代碼有什麽其他問題請忽略,因為那不是重點,此片只講述SQL註入。本次寫了兩個簡單的頁面,一個登陸頁面,一個查詢id界面,如下:
技術分享

技術分享廢話不多說,開始!
SQL註入原理
先看下百度百科對SQL註入的介紹:
所謂SQL註入,就是通過把SQL命令插入到Web表單提交或輸入域名或頁面請求的查詢字符串,最終達到欺騙服務器執行惡意的SQL命令。具體來說,它是利用現有應用程序,將(惡意的)SQL命令註入到後臺數據庫引擎執行的能力,它可以通過在Web表單

中輸入(惡意)SQL語句得到一個存在安全漏洞的網站上的數據庫,而不是按照設計者意圖去執行SQL語句。比如先前的很多影視網站泄露VIP會員密碼大多就是通過WEB表單遞交查詢字符暴出的,這類表單特別容易受到SQL註入式攻擊。

SQL註入的表現形式
原理說的很正式,但是對初學者來說很籠統,對代碼審計的來說也是不怎麽明白。你那麽總結起來,SQL註入在代碼中體現的有以下3點:
1、傳遞的參數為用戶可控;
什麽叫參數為用戶可控?其實前端傳入的一切參數均為用戶可控,包括:
技術分享

這裏的一切數據,參數傳入後臺後,接收的形式是什麽樣的呢?代碼如下

技術分享
request.getParameter("searchWord")是從前端獲取參數的一種方式(當然還有其他方式,此處不贅述),而從前端獲取的參數名為“searchWord”,也就是此處jsp頁面中input標簽中的id為“searchWord”

的值,如下:
技術分享
因此“searchWord”就是前端我們輸入的“id”值。

2.系統未對傳入後臺的參數做任何特殊字符過濾,或者字符過濾不全。
什麽是特殊字符,對SQL註入而言,特殊字符包括(註意大小寫):
--,#,//(註釋符)
and
or
select
update
delete
drop
declare
insert
xp_shell
(,)括號
||,+, (空格) 連接符
‘ 單引號
|(豎線符號)
& (& 符號)
;(分號)
$(美元符號)
%(百分比符號)
@(at 符號)
‘(單引號)
"(引號)
\‘(反斜杠轉義單引號)
\"(反斜杠轉義引號)
<>(尖括號)
CR(回車符,ASCII 0x0d)
LF(換行,ASCII 0x0a)
,(逗號)
\(反斜杠)

3、SQL語句是以拼接的形式執行,代碼如下所示:
技術分享

SQL語句一旦以拼接的方式執行,就表示拼接的參數“word”是表示一個SQL語句,而不僅僅是作為一個參數執行,什麽意思呢?詳細如下:
如果word的值為1,那麽SQL語句變成:
Select * from test where id = 1
如果word的值為1’ and ‘a’=’a,那麽SQL語句變成:
Select * from test where id = 1’ and ‘a’=’a

最後在數據庫中執行的時候就是
技術分享

想必大牛們都明白這一點,就不贅述了。
以上3點就是造成SQL註入產生的根本原因。

SQL頁面展示
下面貼上SQL註入漏洞頁面:
搜索框輸入:1
技術分享

查看執行結果:
技術分享
搜索框輸入:1’
查看執行結果:
技術分享搜索框輸入:1’ and ‘a’=’a
查看執行結果:
技術分享

嘗試爆出數據庫長度(過程忽略):

技術分享
技術分享表示數據庫長度為:8
順便貼上SqlMap截圖:

技術分享
技術分享
剩下的不深入,你們比我懂。

SQL註入的修復
SQL註入在java代碼中的修復其實也是非常簡單,主要有兩個方式:
1、添加全局過濾器,過濾特殊字符;方式如下:
Web.xml:
技術分享
SQLFilter.java中:
技術分享

2.SQL語句使用參數化查詢方式,代碼如下:
技術分享
使用參數化查詢才是SQL註入最根本的修復方式。
修復後SqlMap截圖:

技術分享

結論:
本篇文章沒有多少技術含量,希望對安全開發人員和學習代碼審計人員有一點可取之處。本《java代碼審計連載篇》會繼續編寫,希望大家多多支持,若有錯誤和不足之處,請指出來,謝謝!

Java代碼審計連載之—SQL註入