1、SQL注入簡介
Sql注入即攻擊者利用web應用程式對使用者輸入資料的合法性判斷或過濾不嚴,構造非法sql語句在管理者不知情的情況下擷取資料庫敏感資料,如使用者隐私、管理者賬号密碼等的一種網絡攻擊手段。
2、SQL注入的類型
數字型注入:輸入參數資料類型為整型時,如資料庫中的年齡、分值等,存在注入漏洞則其為數字型注入。例:
在url位址中輸入:http://xxx.xx.xx/index.php?id=1 and 1=1 頁面傳回正常
在url位址中輸入:http://xxx.xx.xx/index.php?id=1 and 1=2 頁面傳回錯誤
字元型注入:輸入參數資料類型為字元型時,如資料庫中的名字、密碼等,存在注入漏洞則其為字元型注入。例:
在url位址中輸入:http://xxx.xx.xx/index.php?id=1’ and ‘1’=’1 頁面傳回正常
在url位址中輸入:http://xxx.xx.xx/index.php?id=1’ and ‘1’=’2 頁面傳回錯誤
兩者差別:數字型注入不需要單引号閉合,而字元型注入一般需要單引号來閉合。
3、注入手法
基于布爾的盲注:利用web頁面傳回值隻有true和false,根據傳回值判斷是否存在注入點,以便擷取資料庫資訊。
基于時間的盲注:在某些場合下,頁面隻有一種傳回結果,需要使用具有延時功能的函數sleep()、benchmark()等,通過判斷這些函數是否正常執行來擷取資料庫中的資料。即利用web頁面響應的時間差來判斷是否存在注入點。例如http://xxx.xx.xx/index.php?id=1’ and if(1=1,sleep(8),1)# 當’and 1=1為真時延遲8秒傳回 ,假則直接傳回,由此測試是否存在注入點。
基于錯誤資訊的注入:有些web頁面在會傳回錯誤提示資訊,根據錯誤資訊對代碼中的SQL語句的結構進行猜測與驗證,回顯有用的相關資料庫錯誤資訊,引導進一步注入。
聯合查詢注入:即将兩表合并查詢,但需要滿足以下條件:存在注入點且有回顯位;列數和資料類型要一緻。
堆查詢注入:利用分号 ; 結束一條SQL語句的原理,構造多條SQL語句,以執行任意非法操作。不過受環境局限很大。
4、注入一般流程
(1)SQL注入點探測;
(2)收集背景資料庫資訊;
(3)猜解使用者名和密碼;
(4)查找Web背景管理入口;
(5)入侵和破壞。
5、簡單手工判斷是否存在注入點
(1)加 ‘ 或 “ 如果傳回頁面錯誤則存在注入點
(2)加 and 1=1 或 ‘ and 1=1 --+ 或 ’) and 1=1 或 “) and 1=1 或者and ’1’ = ‘1傳回正确
加 and 1=2 或 ‘ and 1=2 --+ 或 ’) and 1=2 --+ 或 “) and 1=2 --+或者and ’1’ = ‘2傳回錯誤
(--(後面有個空格,因為不加空格,--直接和系統自動生成的單引号連接配接在了一起,會被認為是一個關鍵詞,無法注釋掉系統自動生成的單引号。)與 # 表示注釋,在get請求傳參注入時常使用--+的方式來閉合;如果是post請求,則可以直接使用#來進行閉合。其中#的urlencode編碼為%23)
6、SQL注入工具——sqlmap
手工注入無疑是對一個信安學者對SQL注入的掌握程度的考驗,但注入手段層出不窮,防注入手段也日新月異,光靠手工注入太耗人力成本了。sqlmap作為一個自動化的注入工具,可以輕易的幫助我們掃描、發現并利用給定URL的SQL注入漏洞,并且自帶多個腳本,支援多種資料庫如MySQL 、Oracle 、PostgreSQL 、Microsoft SQL Server、Microsoft Access 、IBM DB2, SQ Lite 、Firebird 、Sybase和SAPMaxDB等。學注入不學Sqlmap,簡直就像出門不帶手機。
6.1、 Sqlmap的五個探索等級
在sqlmap中一共有五個探測等級,預設等級為一。
等級為一時會測試get和post的資料。
等級為二時會測試HTTP頭的cookie注入。
等級為三時會測試HTTP的user-agent、referer頭、xff頭等的注入
等級越高,包含的playload越多,探測範圍越廣,探測時間也相對較長。
6.2、Sqlmap 指令的使用:
-u 指定目标URL (可以是http協定也可以是https協定)
-d 連接配接資料庫
--dbs 列出所有的資料庫
--current-db 列出目前資料庫
--tables 列出目前的表
--columns 列出目前的列
-D 選擇使用哪個資料庫
-T 選擇使用哪個表
-C 選擇使用哪個列
--dump 擷取字段中的資料
--batch 自動選擇yes
--smart 啟發式快速判斷,節約浪費時間
--forms 嘗試使用post注入
-r 加載檔案中的HTTP請求(本地儲存的請求包txt檔案)
-l 加載檔案中的HTTP請求(本地儲存的請求包日志檔案)
-g 自動擷取Google搜尋的前一百個結果,對有GET參數的URL測試
-o 開啟所有預設性能優化
--tamper 調用腳本進行注入
-v 指定sqlmap的回顯等級
--delay 設定多久通路一次
--os-shell 擷取主機shell,一般不太好用,因為沒權限
-m 批量操作
-c 指定配置檔案,會按照該配置檔案執行動作
-data data指定的資料會當做post資料送出
-timeout 設定逾時時間
-level 設定注入探測等級
--risk 風險等級
--identify-waf 檢測防火牆類型
--param-del="分割符" 設定參數的分割符
--skip-urlencode 不進行url編碼
--keep-alive 設定持久連接配接,加快探測速度
--null-connection 檢索沒有body響應的内容,多用于盲注
--thread 最大為10 設定多線程
6.3、Sqlmap 自帶腳本相關資訊
apostrophemask.py 用UTF-8全角字元替換單引号字元
apostrophenullencode.py 用非法雙位元組unicode字元替換單引号字元
appendnullbyte.py 在payload末尾添加空字元編碼
base64encode.py 對給定的payload全部字元使用Base64編碼
between.py分别用“NOT BETWEEN 0 AND #”替換大于号“>”,“BETWEEN # AND #”替換等于号“=”
bluecoat.py 在SQL語句之後用有效的随機空白符替換空格符,随後用“LIKE”替換等于号“=”
chardoubleencode.py對給定的payload全部字元使用雙重URL編碼(不處理已經編碼的字元)
charencode.py 對給定的payload全部字元使用URL編碼(不處理已經編碼的字元)
charunicodeencode.py 對給定的payload的非編碼字元使用Unicode URL編碼(不處理已經編碼的字元)
concat2concatws.py 用“CONCAT_WS(MID(CHAR(0), 0, 0), A, B)”替換像“CONCAT(A, B)”的執行個體
equaltolike.py 用“LIKE”運算符替換全部等于号“=”
greatest.py 用“GREATEST”函數替換大于号“>”
halfversionedmorekeywords.py 在每個關鍵字之前添加MySQL注釋
ifnull2ifisnull.py 用“IF(ISNULL(A), B, A)”替換像“IFNULL(A, B)”的執行個體
lowercase.py 用小寫值替換每個關鍵字字元
modsecurityversioned.py 用注釋包圍完整的查詢
modsecurityzeroversioned.py 用當中帶有數字零的注釋包圍完整的查詢
multiplespaces.py 在SQL關鍵字周圍添加多個空格
nonrecursivereplacement.py 用representations替換預定義SQL關鍵字,适用于過濾器
overlongutf8.py 轉換給定的payload當中的所有字元
percentage.py 在每個字元之前添加一個百分号
randomcase.py 随機轉換每個關鍵字字元的大小寫
randomcomments.py 向SQL關鍵字中插入随機注釋
securesphere.py 添加經過特殊構造的字元串
sp_password.py 向payload末尾添加“sp_password” for automatic obfuscation from DBMS logs
space2comment.py 用“”替換空格符
space2dash.py 用破折号注釋符“--”其次是一個随機字元串和一個換行符替換空格符
space2hash.py 用磅注釋符“#”其次是一個随機字元串和一個換行符替換空格符
space2morehash.py 用磅注釋符“#”其次是一個随機字元串和一個換行符替換空格符
space2mssqlblank.py 用一組有效的備選字元集當中的随機空白符替換空格符
space2mssqlhash.py 用磅注釋符“#”其次是一個換行符替換空格符
space2mysqlblank.py 用一組有效的備選字元集當中的随機空白符替換空格符
space2mysqldash.py 用破折号注釋符“--”其次是一個換行符替換空格符
space2plus.py 用加号“+”替換空格符
space2randomblank.py 用一組有效的備選字元集當中的随機空白符替換空格符
unionalltounion.py 用“UNION SELECT”替換“UNION ALL SELECT”
unmagicquotes.py 用一個多位元組組合%bf%27和末尾通用注釋一起替換空格符寬位元組注入
varnish.py 添加一個HTTP頭“X-originating-IP”來繞過WAF
versionedkeywords.py 用MySQL注釋包圍每個非函數關鍵字
versionedmorekeywords.py 用MySQL注釋包圍每個關鍵字
xforwardedfor.py 添加一個僞造的HTTP頭“X-Forwarded-For”來繞過WAF
7、SQL注入練習
靶場環境搭建:sqli-labs-master 或者 DVWA
工具:Sqlmap、burpsuite、phpstudy_pro(建站)

以sqli-labs-master為例:
運作salmap 輸入參數-u和url進行檢測注入點:
檢測出了四種注入,并給出了注入playload
列出所有資料庫:
列出目前資料庫:
列出目前資料庫的表:
檢視uses表中的列名屬性:
擷取表字段中的資料:
8、Sqlmap與burpsuite的夢幻關聯
Burpsuite中的CO2插件的安裝:
對CO2進行配置(即sqlmap.py和使用的python路徑,路徑中不能有空格,否則會識别錯誤):
進行代理抓包并發送到CO2攻擊子產品:
點選run即可自動運作sqlmap:
在Options闆塊中可以根據自己的需要進行注入,可在detection中選擇攻擊等級,在Enumeration中勾選自己想要擷取的資訊,再次點選run即可:
如檢視目前使用者是否具有管理者權限:
利用burpsuite與sqlmap的關聯可以更為簡單的使用sqlmap,不再需要輸入繁瑣的指令,同時能直接将抓到的包為sqlmap所用。
9、sql注入的防禦
Sql注入的防禦我個人覺得主要在于權限、資料和語句審查三個方面。
(1)在權限上,我們可以進行分級管理,嚴格控制使用者的權限,避免越級行為;
(2)在資料上,我們可以提前将資料加密,這樣即使資料洩露,也仍能保證一定的安全;
(3)在語句審查上,我們可以對包含有一些特殊字元如#,+,--,”,and,等符号的sql語句進行審查及過濾,同時可進行參數化傳值,避免直接将變量寫入到sql語句中。
除此之外,我們還可以利用一些專門的sql安全參數,如sqlserver中的Parameters集合,它在資料庫中的功能是對資料進行類型檢查和長度驗證當程式員在程式設計時加入了Parameters集合,系統會自動過濾掉使用者輸入中的執行代碼,識别其為字元值。如果使用者輸入中含有惡意的代碼,資料庫在進行檢查時也能夠将其過濾掉。同時Parameters集合還能進行強制執行檢查。一旦檢查值超出範圍。系統就會出現異常報錯,同時将資訊發送系統管理者,友善管理者做出相應的防範措施。 或者對通路者的資料進行嚴格的多層驗證,隻有通過驗證的資料才能合法的通路系統。