sql注入簡介

00x 什麼是sql注入
sql注入是一種將sql代碼插入或添加到應用(用戶)的輸入參數中,
之後再將這些數據傳遞給後臺的sql服務器加以解析並執行的攻擊。
01x sql注入產生的過程
如果開發人員無法確保在從Web表單、cookie、輸入參數等收到的
值傳遞給sql查詢之前已經對其進行驗證,通常就會出現sql注入漏洞。
02x sql注入分類:
按照注入點類型分類分爲:數字型、字符型 、搜索型
數字型注入:
即傳入sql服務器解析的參數是數字型(在sql表中字段的類型是數字型)
表結構如下:
《》
執行 sql查詢的語句
《》
類似url:
http://127.0.0.1/index.php?user_id=1
構造參數執行過程
《》
由數字型sql執行語句知道構造注入參數時只需 使用空格就可以插入新的sql函數,
從而影響原sql語句的執行結果(以上爲例即1+payload)。
字符型注入 :
即傳入sql服務器解析的參數不是數字型(在sql表中字段的類型不是數字型如:字符、時間等)
表結構如下:
《》
執行sql查詢的語句如下:
《》
類似url:
http://127.0.0.1/index.php?admin=admin
構造參數如下:
《》
由字符型sql執行語句知道構造sql注入參數時,需要先將上一個參數進行前後閉合,中間的參數即爲攻擊者想要執行的sql語句
(以上爲例即admin’+payload+and ‘1’=‘1)
搜索型注入 :
其實傳入的參數也是字符型,只不過執行的sql查詢的語句不同,可以當作是字符型的特殊類型。
執行SQL查詢的語句:
《》
類似url
http://127.0.0.1/index.php?search=o
構造參數如下:
《》
原理和字符型一樣前後閉合。
按照提交方式分類分爲:GET型、POST型、Cookie型、HTTP頭部注入
http協議簡介
HTTP協議(HyperText Transfer Protocol,超文本傳輸協議)是因特網上應用最爲廣泛的一種網絡傳輸協議,
所有的WWW文件都必須遵守這個標準。HTTP是一個基於TCP/IP通信協議來傳遞數據(HTML 文件, 圖片文件, 查詢結果等)。
http請求方法
序號 方法 描述
1 GET 請求指定的頁面信息,並返回實體主體。
2 HEAD 類似於 GET 請求,只不過返回的響應中沒有具體的內容,用於獲取報頭
3 POST 向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據被包含在請求體中。POST 請求可能會導致新的資源的建立和/或已有資源的修改。
4 PUT 從客戶端向服務器傳送的數據取代指定的文檔的內容。
5 DELETE 請求服務器刪除指定的頁面。
6 CONNECT HTTP/1.1 協議中預留給能夠將連接改爲管道方式的代理服務器。
7 OPTIONS 允許客戶端查看服務器的性能。
8 TRACE 回顯服務器收到的請求,主要用於測試或診斷。
9 PATCH 是對 PUT 方法的補充,用來對已知資源進行局部更新 。
get型注入注入點存在get請求的某個參數中;post型注入注入點存在post數據中;
cookie型注入注入點存在cookie參數中;http頭部注入注入點存在http請求頭部的某個字段中
《》《》

按照執行效果來分類分爲:基於布爾的盲注 、基於時間的盲注、
基於報錯的注入、聯合查詢注入、堆查詢注入、寬字節注入
基於布爾的盲注
可以根據嵌入的sql真假條件返回的頁面結果判斷是否存在sql注入
基於時間的盲注
不能根據頁面返回結果判斷是否存在sql注入,可以根據嵌入的sql
時間延遲語句判斷頁面響應時間從而進一步判斷是否存在sql注入。
時間函數
a)mysql數據庫:
5.0.12及以後版本sleep()函數;5.0.12以前版本benchmark()函數。
1)區別:benchmark()函數向查詢中引入了一個可變但非常顯著的延遲,而
sleep()函數則強制產生一個固定延遲。
2)通用mysql二分搜索推斷漏洞
’ union select if(ascii(substring(…),i,1))>k,sleep(1),1)#
’ union select if(ascii(substring(…),i,1))>k,benchmark(100000000,rand()),1)#
其中i是由子查詢(…)返回的第i個字節,k是當前二分搜索的中間值。
3)通用的mysql逐位推斷漏洞
’ union select if(ascii(substring(…),i,1))&2j=2j,sleep(1),1)#
’ union select if(ascii(substring(…),i,1))&2j=2j,benchmark(100000000,rand()),1)#
其中i是由子查詢(…)返回的第i個字節,j是我們關心的位
b)PostgreSQL數據庫
8.1及8.1以下版本sleep()函數;8.2及8.2以上版本使用pg_sleep()函數
1)二分搜索法漏洞推斷
使用堆疊查詢和用戶自定義pause()函數的注入字符串:
’ ; select case when (ASCII(SUBSTR(…,i,1))>k) THEN pg_sleep(1) END;SELECT NULL,…NULL;–
’ || (select case when (ASCII(SUBSTR(…,i,1))>k) THEN PAUSE(1) ELSE 1 END);–
其中,i是子查詢(…)返回的第i個字節,而當k是當前二分搜索的中間值。
2)通用的PostgreSQL逐位方法漏洞推斷
’ ; select case when (ASCII(SUBSTR(…,i,1))&2j=2j) THEN pg_sleep(1) END;SELECT NULL,…NULL;
’ || (select case when (ASCII(SUBSTR(…,i,1))&2j=2j) THEN PAUSE(1) ELSE 1 END);–
其中i是由子查詢(…)返回的第i個字節,j是我們關心的位
c) SQL Server數據庫
waitfor關鍵字,用法:waitfor delay ‘00:00:15"
1) 通用SQL Server二分搜索推斷
’ ; IF ASCII(SUBSTRING((…),i,1))>k waitfor delay ‘00:00:05’; –
其中,i是子查詢(…)返回的第i個字節,而當k是當前二分搜索的中間值。
2) 通用SQL Server逐位推斷
’ ; IF ASCII(SUBSTRING((…),i,1))&2j=2j waitfor delay ‘00:00:05’; –
其中i是由子查詢(…)返回的第i個字節,j是我們關心的位
d) Oracle數據庫
Oracle數據庫使用DBMS_LOCK包,這個包提供了sleep()函數和其他函數,其調用如下:
BEGIN DBMS_LOCK>SLEEP(n); END;
該方法存在很多約束。1、不能將它嵌入子查詢中;2、默認情況下除了數據庫管理員外,其他用戶均無法使用DBMS_LOCK包
如果注入點位於PL/SQL塊中,可使用如下代碼來產生延遲:
if (bitand(ascii(substr(…),i,1)),2j)=2j) then dbms_lock,sleep(5);end if;
其中i是由子查詢(…)返回的第i個字節,j是我們關心的位
基於報錯的注入
頁面會返回錯誤信息或者直接返回sql語句
可以使用如下代碼:
a、’
b、and 1=1/and 1=2
聯合查詢注入
可以使用union
堆查詢注入
可以同時執行多條語句
寬字節注入
04x sql注入防禦
1)使用參數化語句
大多數編程語言和數據庫訪問API可以使用佔位符或綁定變量來向SQL查詢提供參數(而非直接對用戶輸入進行操作)。
優勢:數據庫可以根據提供的預備語句來優化查詢,從而提高後續查詢的性能。
缺點:如果正在調用的數據庫功能在存儲過程或函數的實現中使用了動態SQL,那麼仍然可能出現SQL注入漏洞 。
2)輸入驗證
輸入驗證是指測試應用程序接收到的輸入,以保證其符合應用程序中標準定義的過程。它可以簡單到將參數限制成某
中類型,也可以複雜到使用正則表達式或業務邏輯來驗證輸入。分爲白名單驗證(包含驗證或正驗證)和黑名單驗證(排除
驗證或負驗證)
3)編碼輸出
確保對包含用戶可控輸入的查詢進行正確編碼以防止使用單引號或其他字符來修改查詢。
如果正在使用LIKE子句,請確保對LIKE中的通配符恰當的編碼。
4)規範化
將輸入解碼或變爲規範格式後才能執行輸入驗證過濾器和輸出編碼。
儘可能使用白名單輸入驗證並拒絕非規範化格式的輸入
5)通過設計避免sql注入
使用存儲過程以便數據庫層擁有較細粒度的許可。
可以使用數據訪問抽象層來對整個應用施加安全的數據訪問
設計時,請考慮對敏感信息進行附加控制
05x sql防禦繞過
Web應用通常會使用輸入過濾器來防禦包括sql注入在內的常見攻擊。
1)使用大小寫變種
2)使用sql註釋
3)使用URL編碼
4)使用動態查詢執行
SQL Server 使用EXEC函數:
EXEC(‘SELECT password from tblUsers’)
Orcale 使用EXECUTE IMMEDIATE命令
DECLARE pw VARCHAR2(1000);
BEGIN
EXECUTE IMMEDIATE ‘SELECT password from tblUsers’ INTO pw;
DBMS_OUTPUT.PUT_LINE(pw);
END;
5) 使用拼接
Orcale:‘SEL’||‘ECT’
MS-SQL:‘SEL’+‘ECT’
MySQL:‘SEL’ ‘ECT’
6) char函數(Orcale爲CHR)構造單獨的字符
如select=CHAR(83)+CHAR(69)+CHAR(76)+CHAR(69)+CHAR(67)+CHAR(84)
其他函數如Orcale中的REVERSE、TRANSLATE、REPLACE和SUBSTR函數
7) 使用空字節(如tab)
8)嵌套剝離後的表達式
有些過濾器會先從用戶輸入中剝離特定的字符或表達式,然後再按照常用的方式處理剩下的數據。
如果被剝離的表達式中包含兩個或多個字符,就不會遞歸應用過濾器。如selselectect
9) 利用截斷
10)寬字節注入

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章