Web應用程序攻防實戰
原創【51CTO.com獨家翻譯】想親自擊敗黑客嗎?OK,沒問題,首先你要了解黑客是如何查找安全漏洞的,其次就是要了解黑客是如何利用Web應用程序漏洞的,最后就是了解他們是如何組織進攻的。本文將以一個漏洞百出的程序Jarlsberg為例,為大家講解Web應用程序的攻防手段,全面解剖黑客的行徑和應對辦法。Jarlsberg是用Python編寫的,因此略懂Python會幫助理解本文,但即使不懂也無所謂,因為漏洞和修復漏洞的方法基本上是與語言無關的。另外我們會涉及到黑盒黑客和白盒黑客,所謂黑盒黑客就是通過操縱輸入字段或URL參數,觀察Web應用程序的響應和變化,嘗試找出讓它出錯的一種攻擊手段,這里我們通常會查看HTTP/HTTPS請求和響應,推薦兩款很棒的輔助工具Burp和WebScarab;所謂白盒黑客就是分析Web應用程序源代碼,嘗試找出bug并進行攻擊的手段。
你完全可以根據本文介紹的內容搭建一個滲透測試環境,自己做做練習,以提升自己的技能,當然最重要的是通過學習達到舉一反三,以后自己也能發現和修復漏洞,Jarlsberg的下載地址是http://jarlsberg.appspot.com/jarlsberg-code.zip,你也可以直接訪問http://jarlsberg.appspot.com/start,AppEngine會自動為你創建一個新的Jarlsberg實例,每個實例都運行在獨立的沙盒中,用唯一的ID進行標識,你可以隨意展開攻擊,你也可以將你唯一的URL分享給其它人進行攻擊研究。
如果想在本地運行Jarlsberg,需要先安裝Python 2.5,其它版本可能不行,執行Jarlsberg安裝的命令如下:
|
用localhost:8008替換所有文件中的jarlsberg.appspot.com,并用分配給你的唯一ID替換默認ID 123。
如果是直接在AppEngine上創建的Jarlsberg實例,它有諸多限制,如不能訪問和干擾其它Jarlsberg實例,資源使用也是有限制的,如果你搗鼓得Jarlsberg實例無法運行時,可以通過下面的URL進行重置,不過要注意的是所有歷史數據都將被清除掉。
http://jarlsberg.appspot.com/resetbutton/123 |
注意用你自己的ID替換這里的123。
Jarlsberg各個源文件介紹:
◆jarlsberg.py是Jarlsberg Web服務器
◆jdata.py在數據庫中存儲默認數據,有一個管理員賬號和兩個默認用戶
◆jtl.py是Jarlsberg模板語言
◆jsanitize.py是Jarlsberg保護自身HTML免受攻擊的模塊
◆resources/...目錄下存放了所有模板,圖片和CSS等文件
跨站腳本(XSS)
跨站腳本(XSS)指的是黑客通過網站漏洞在不受自己控制的網站內容(通常是HTML或JavaScript)中植入代碼,當受害者瀏覽這樣的網頁時,植入的代碼就會在受害者瀏覽器中執行,這樣就可以順理成章地竊取受害者與網站請求相關的個人信息。
在一個反射式XSS攻擊中,攻擊通常是嵌入在請求URL中,受害者瀏覽黑客構造的惡意URL時就被攻擊了。在存儲式XSS攻擊中,攻擊者將攻擊代碼保存在應用程序內,受害者瀏覽到這樣的網頁時就觸發攻擊代碼的執行。
假設http://www.google.com/search?q=flowers這個URL返回的頁面包含以下HTML片段:
|
查詢參數q的值被嵌入到Google返回的頁面中,如果www.google.com不做任何驗證或忽略q,攻擊者就可以構造一個類似下面這樣的鏈接進行攻擊嘗試:
http://www.google.com/search?q=flowers+%3Cscript%3Eevil_script()%3C/script%3E |
接下來就是欺騙受害者點擊這個鏈接,當受害者點擊這個鏈接后,他的瀏覽器就會解析下面的代碼:
|
瀏覽器就會執行evil_script(),于是受害者的瀏覽器狀態和所有該域名對應的cookies都全部暴露出來了。
有時即使受害者不直接地點擊惡意鏈接也會遭受攻擊,例如,假設攻擊者擁有www.evil.example.com域名,在頁面中用
XSS挑戰
一般說來,當其他用戶瀏覽一個網頁時,你可以讓一段JavaScript代碼在這個網頁上執行,就說明它有XSS漏洞,一個簡單有效的JavaScript函數是alert(),它會彈出一個窗口。
你可能認為插入一個alert消息不會有任何危險,但如果你能夠插入alert(1),那么插入其它惡意代碼,如eval(String.fromCharCode(...))也就沒有問題了。
我們的挑戰是發現Jarlsberg中的XSS漏洞,在哪些地方去找這個漏洞呢?一個是URL,另一個是存儲的數據。因為XSS漏洞通常包含在那些不能正確處理非受信用戶數據的應用程序中,發現XSS漏洞的方法通常是在輸入字段中輸入任意文字,再看響應的HTML代碼變化。我們先來做一個簡單的嘗試。
文件上傳XSS
任務:你能上傳一個文件,讓你在jarlsberg.appspot.com域名上執行任意腳本嗎?
暗示:你可以上傳一個包含腳本的HTML文件。
攻擊:上傳一個.html文件,包含以下腳本
|
修復:在一個獨立的域名上托管內容,這樣腳本就不能訪問你域名上的任何內容了,也就是說,我們應該用username.usercontent.example.com或username.example-usercontent.com這樣的域名代替example.com/username托管用戶的內容,另外還要注意不要讓用戶可以注冊注入wwww等容易引起釣魚攻擊的用戶名。
反射式XSS
有趣的是,有些瀏覽器內置了防反射式XSS攻擊,如IE和Chrome,另外也有一些瀏覽器擴展,如NoScript也能提供這樣的保護,為了解決這個問題,Jarlsberg特意在每個HTTP響應頭中加入了X-XSS-Protection: 0,讓IE可以識別,如果是Chrome,你可以通過disable-xss-auditor啟動參數禁用反射式XSS保護。
如果你使用的是Firefox,并安裝了NoScript擴展,請將jarlsberg.appspot.com列入允許列表,如果還不行,最好換個其它瀏覽器。
也許你認為既然瀏覽器有了保護能力,為什么還需要擔心這種攻擊呢?其實瀏覽器并不能完全準確地實施保護,因為它不了解你的應用程序,聰明的黑客是可以繞過這層保護機制的,真正的保護是從應用程序源頭杜絕XSS漏洞。
任務:找出一個反射式漏洞,我們希望通過點擊一個URL執行一個腳本。
提示1:這個URL是什么呢?
http://jarlsberg.appspot.com/123/invalid |
提示2:在URL中最危險的字符是<和>,嘗試輸入下面的URL:
以上的URL是通過不同語言風格構造的<和>,直接在瀏覽器地址欄輸入<和>是一樣的,瀏覽器會自動編碼,然后查看返回的HTML代碼,研究服務器對這些URL的響應。
攻擊:創建下面這樣一個URL,讓受害者點擊它
http://jarlsberg.appspot.com/123/> |
修復:你需要繞過顯示在錯誤信息中的用戶輸入,錯誤信息是使用error.jtl顯示的,但沒有繞過模板,提供消息的模板部分是{{message}},添加:text繞過用戶輸入。
|
杜絕這個漏洞的最好辦法是避免所有默認的輸出,僅顯示原始HTML。#p#
存儲式XSS
任務:現在我們來尋找一個存儲式XSS,我們想做的是在Jarlsberg內部放置一小段代碼,其它人訪問時就執行它。
提示1:放置下面這段代碼看看效果
|
將腳本嵌入到文檔有很多方式。
提示2:黑客不會限制他們自己驗證HTML語法,試試一些無效的網頁,看看會返回什么,你可能需要試驗一下,以便找到下手的地方。
攻擊:嵌入下面任意一種代碼片段
| alert(1)hello
修復:在jsanitize.py文件_SanitizeTag部分中,將onmouseover添加到disallowed_attributes列表中,可以預防片段1的攻擊。
但這種修復方法不徹底,因為檢查不允許的屬性時是區分大小寫的,而HTML則不區分大小寫,正確的做法是:
1、將輸入解析為一個中間DOM結構,然后以良好的格式輸出;
2、為允許的標記和屬性使用嚴謹的白名單;
3、對允許的URL和CSS屬性采用嚴格的凈化處理。
在條件允許的情況下,最好使用一個HTML凈化器。
通過HTML屬性進行存儲式XSS
任務:你也可以在HTML屬性上注入值來實施XSS,如通過設置配置文件中的顏色值植入一段腳本。
提示1:顏色是使用style='color:color'渲染的,試試在顏色名中包含一個單引號字符的效果。
提示2:你可以插入一個HTML屬性執行一個腳本。
攻擊:使用的下面的代碼設置顏色
red' onload='alert(1)' onmouseover='alert(2) |
當你鼠標移到它上面時就觸發了攻擊。
修復:我們需要一個正確的文字轉義程序,有效地規避單引號和雙引號,將下面的函數增加到jtl.py,用它替代cgi.escape。
def _EscapeTextToHtml(var): """Escape HTML metacharacters. This function escapes characters that are dangerous to insert into HTML. It prevents XSS via quotes or script injected in attribute values. It is safer than cgi.escape, which escapes only <, >, & by default. cgi.escape can be told to escape double quotes, but it will never escape single quotes. """ meta_chars = { '"': '"', '\'': ''', # Not ' '&': '&', '<': '<',< '>': '>', } escaped_var = "" for i in var: if i in meta_chars: escaped_var = escaped_var + meta_chars[i] else: escaped_var = escaped_var + i return escaped_var |
但這種修復方法仍然不完美,顏色值仍然存在漏洞。
提示1:有些瀏覽器允許你在樣式表中包含腳本。
提示2:最容易遭到利用的瀏覽器是IE,因為它支持動態CSS屬性(也叫做CSS表達式)。
攻擊方法:使用下面的代碼替換顏色值
expression(alert(1)) |
雖然其它瀏覽器不支持動態CSS屬性,但一樣存在其它危險的CSS屬性,如Mozilla的-moz-binding。
修復辦法:我們需要將顏色值凈化為一個真正的顏色值,最好的辦法是增加一個新的輸出凈化格式給jtl,例如,我們可能會書寫{{foo:color}}確保foo被安全地用作一個顏色,下面這個函數可以用來凈化。
|
你可以為字體大小,字體,URL等做類似的凈化,它對輸入驗證也很有幫助,如果有人輸入了一個無效值,你可以立即提醒或是拒絕他,但光做輸入驗證還不夠,如果你的驗證代碼本身也有漏洞,或是瀏覽器暴出新的攻擊向量,你不得不返回重新清洗之前全部輸入的值,或是增加輸出驗證。#p#
通過Ajax進行存儲式XSS
任務:使用Jarlsberg Ajax代碼中的bug找出一個XSS攻擊點,當你點擊頁面刷新鏈接時觸發攻擊。
提示1:在http://jarlsberg.appspot.com/123/feed.jtl上運行curl查看結果,或者在瀏覽器中輸入這個URL,查看返回結果的HTML源代碼,你會看到每個用戶的第一個微博包含在響應包中,然后整個響應包在客戶端接受評估,最后將微博內容插入到文檔中,你能夠在微博內容中加入點什么使其與預期的結果有所不同嗎?
提示2:在你的微博內容中添加一個雙引號試試。
利用方法:將下面的代碼插入到你的微博內容中。
|
JSON看起來應該象
_feed(({..., "Mallory": "snippet", ...})) |
代替后看起來象
|
注意,每個下劃線部分都是一個獨立的表達式,這個攻擊是不可見的,因為使用了
修復辦法:首先,在服務器端,原文在JSON響應中呈現時轉義就不正確,雖然模板聲明了{{snippet.0:html}},但仍然不夠,原文將被插入到DOM節點的內部HTML中,因此HTML必須進行凈化,但凈化后的原文將被插入到JavaScript中,單引號和雙引號將被轉義,給jtl增加{{...:js}}支持是不夠的,我們也需要支持{{...:html:js}}。
如果要轉義單引號和雙引號,分別使用\x27和\x22,用和"替代它們是不正確的,因為JavaScript是不能識別和"的。
其次,在瀏覽器中,Jarlsberg使用JavaScript的eval轉換JSON,通常情況下,使用eval非常危險,我們應該使用JSON解析器確保字符串不包括任何不安全的內容,json.org就提供了JSON解析器下載。
通過Ajax實施反射式XSS
任務:使用Jarlsberg的Ajax功能,找出一個URL,點擊它就執行一個腳本。
提示1:Jarlsberg刷新用戶的微博頁面時,使用了:
http://jarlsberg.appspot.com/123/feed.jtl?uid=value |
結果是腳本
_feed((["user", "snippet1", ... ])) |
提示2:這里使用了不同的漏洞,但和前面的反射式XSS利用方法是類似的。
攻擊方法:創建類似下面這樣的URL,誘使受害者點擊它
|
它們被翻譯為
_feed(([""])) |
這個bug讓Jarlsberg返回了所有文件類型為text/html的jtl文件。
修復辦法:需要確保JSON內容不會當作HTML解析,需要修改{{...:js}},用JavaScript轉移字符\x3c和\x3e進行替換,在JavaScript中用\x3c和\x3e分別替換<和>總是安全的,注意,用HTML轉移字符<和>也是不正確的。
同時,你還應該設置響應的內容類型,這里我們使用application/javascript。
此外,Jarlsberg也未設置內容編碼,瀏覽器會嘗試根據文檔內容進行猜測,攻擊者也可以利用這個漏洞欺騙瀏覽器,如攻擊者使用UTF-7編碼欺騙瀏覽器,于是就可以嵌入+ADw-script+AD4-腳本標記,在UTF-7中,+ADw-和+AD4-分別代表<和>,因此不僅要設置正確的內容類型,編碼也要設置,設置方法和HTML類似,如:
Content-Type: text/html; charset=utf-8 |
雖然沒有一種萬能的方法來防御XSS漏洞,但仍然有一些重要的原則應該遵守。
1、首先確保你弄明白了問題;
2、盡可能通過模板功能凈化,盡量不要直接在代碼中使用轉義字符進行凈化;
3、實施XSS相關的測試;
4、不要試圖自己寫模板庫。 #p#
客戶端狀態操縱
用戶與Web應用程序交互是通過瀏覽器進行的,點擊一個按鈕或是提交一個表單,瀏覽器都會將請求發送給Web服務器,因為瀏覽器很容易被黑客控制,因此Web服務器不應該相信任何瀏覽器發來的數據。
寫一個Web應用程序也不相信任何數據似乎不太可能,也沒那個必要,如用戶提交一個表單表示他想購買的商品列表,這時信任它也無妨,但如果提交的表單也包含價格信息,那就應該謹慎了。
特權提升
任務:將你的帳戶升級成管理員
提示:一般用戶和管理員都使用editprofile.jtl編輯自己的配置信息,如果你不是管理員,這個頁面看起來會有所不同。
攻擊方法:使用下面任意一個URL都可以將你的普通帳戶轉換成管理員
|
第二個URL可以通過替換username將任何一個普通用戶升級成管理員。
由于Cookie的問題,你可能看到帳戶狀態不是立即顯示為管理員,只要你注銷重新登錄就可以了。
修復辦法:這里的bug是服務器端代碼缺少身份驗證引起的,正確的做法是在服務器端檢查授權。
Cookie操縱
因為HTTP協議是無狀態的,Web無法知道某兩個請求來自同一個用戶,就是在這種背景下,Cookie誕生了,當一個網站在HTTP響應中引入Cookie后,瀏覽器在下一次請求時就會自動發送Cookie,網站可以使用Cookie保存會話狀態,Jarlsberg使用Cookie記住登錄用戶的身份,因為Cookie是保存在客戶端的,因此很容易受到操縱,Jarlsberg為了保護Cookie專門增加了一個散列,遺憾的是,實施攻擊不一定需要破壞散列。
任務:讓Jarlsberg為你生成其它用戶的Cookie。
提示:Jarlsberg的Cookie格式如下
hash|username|admin|author |
當你登錄時Jarlsberg為你生成一個Cookie。
攻擊方法:使用“foo|admin|author”作為用戶名創建一個新用戶,然后用它登錄,Jarlsberg產生“hash|foo|admin|author||author”Cookie,于是foo成為管理員,因此這也算是一種特權提升攻擊。
修復辦法:由于系統對用戶名沒有任何字符限制才導致攻擊可以得逞,因此在構造Cookie時要對用戶名進行轉義,如果與預期的模式不能匹配,就拒絕為其產生Cookie。
跨站請求偽造(XSRF)
前面我們曾提到,如果用戶提交的表單僅僅表示他希望購買的商鋪列表,那信任這些數據也無妨,只要確保是這個用戶提交的數據即可,如果你的網站有XSS漏洞,即使你已經實施了XSS保護,但還有另一種攻擊需要保護,那就是跨站請求偽造。
瀏覽器向網站發送請求時,它也會將該網站的Cookie一并發送,Web服務器不會區分請求是否有用戶行為(如用戶點擊提交按鈕,或是頁面中嵌入的一個圖片),因此,當網站接收到一個請求要執行一些動作時(如刪除郵件,修改聯系人信息等),Web服務器不知道這些行為是否是用戶真正的本意,即使請求中包含了Cookie也證明不了,攻擊者可以利用這個漏洞欺騙服務器,執行非用戶本意想要執行的動作。
例如,假設Blogger有XSRF漏洞,在頁面上有一個刪除按鈕,其對于的URL是:
http://www.blogger.com/deleteblog.do?blogId=BLOGID |
攻擊者Bob在他自己的網頁http://www.evil.example.com中嵌入下面的HTML代碼:
|
如果受害者Alice登錄到www.blogger.com,當她瀏覽上面的頁面時,會發生:
◆她的瀏覽器從http://www.evil.example.com載入頁面,之后瀏覽器嘗試載入頁面中嵌入的所有對象,包括這里的img對象;
◆瀏覽器向產生一個請求,載入圖片,由于Alice已經登錄到Blogger,她就有一個Blogger Cookie,瀏覽器也會在請求中發送該Cookie;
◆Blogger驗證Cookie是一個有效的會話Cookie,然后驗證alice's-blog-id對應的博客是否屬于Alice,如果是就刪除該博客;
◆Alice不知道是什么原因造成自己的博客就沒有了。
在這個攻擊示例中,因為每個用戶有他們自己的博客id,攻擊目標是單個用戶,但在很多時候,類似這樣的攻擊可以針對批量用戶,批量數據。
XSRF挑戰
這里的目標是找到一個方法代表登錄Jarlsberg的用戶執行賬號修改行為,但真正的用戶并不知情,假設你可以正常訪問一個網頁。
任務:找到一個方法讓某個人刪除他們的Jarlsberg微博內容。
提示:刪除一個微博內容用到的URL是什么?
攻擊方法:誘使用戶訪問產生下列請求的頁面
http://jarlsberg.appspot.com/123/deletesnippet?index=0 |
為了達到更好的迷惑性,我們將Jarlsberg圖標加在這個URL上。
修復辦法:我們首先應該修改/deletesnippet通過POST請求工作,因為這是一個狀態改變行為,按照HTML形式,將method='get'修改為method='post'。在服務器端,GET和POST請求除了調用不同的處理程序外,它們都一樣,例如,Jarlsberg使用Python的BaseHTTPServer為GET請求調用do_GET,為POST請求調用do_POST。
但僅僅修改為POST并是完美的修復方法,只能說使用POST是正確的做法,因為GET請求是可以重新發出的,而POST請求是不能重新發出的,我們需要傳遞一個唯一的,不可預知的認證令牌action_token給用戶,可以使用用戶Cookie和當前時間戳的哈希值,在所有改變狀態的HTTP請求中作為一個附加HTTP參數包含這個令牌,使用時間戳的目的是可以讓過期的令牌失效,即使它被泄露出去,因時效性問題,引起的影響也會很小。
在處理一個請求時,Jarlsberg應該重新生成令牌,與請求提供的令牌進行比較,如果相同就執行行為,否則就拒絕它,生成和驗證令牌的函數如下:
|
很遺憾,這個函數仍然有問題。
因為令牌中包含時間,我們必須防止它永久有效,如果攻擊者獲得一個令牌的拷貝,他可以在24小時內反復使用它就麻煩了,令牌的過期時間應盡可能設得短一點,即使請求被攻擊者攔截,也只能攻擊一次,攻擊者不能反復利用這個請求,令牌應該和特定的狀態改變行為聯系起來,如一個頁面的URL,對于非常長的行為,如編輯一個微博,頁面上的腳本可以查詢服務器更新令牌。
XSRF漏洞的存在讓攻擊者可以輕易構造一系列請求,為了阻止這種攻擊,需要引入一些不可預知的值,讓攻擊者不是那么容易構造偽造的請求,有些應用程序框架內置了XSRF保護,它們會在每個響應中包含一個唯一的令牌,并且會驗證每個POST請求。#p#
跨站腳本置入(XSSI)
瀏覽器可以阻止一個域名下的網頁讀取另一個域名下的網頁,但它不能阻止一個域名下的網頁引用另一個域名下的資源,特別是它們允許引用另一個域名下的圖片,執行另一個域名下的腳步,引用的腳本無自己的安全上下文,它完全依賴引用它的頁面的安全上下文,例如,如果www.evil.example.com包含了一個托管在www.google.com上的腳本,這個腳本就運行在evil上下文而不是google上下文中,因此這個腳本中包含的任何用戶數據都可能被泄露。
XSSI挑戰
任務:使用XSSI找到一個閱讀他人私有微博的方法。
在另一個網站上創建一個網頁,在這個網頁中插入一些代碼,使其可以訪問你的私有微博內容。
提示1:將下面的代碼添加到你的HTML頁面,你可以從另一個域名運行腳本
> |
當feed.jtl中的腳本被執行時,它運行在攻擊者頁面的上下文中。
修復辦法:首先使用XSRF令牌確保包含機密數據的JSON結果只會返回給你自己的頁面,其次,你的JSON響應頁面應該只支持POST請求,防止通過腳本標記載入腳本,第三,要確保腳本是不可執行的,標準的做法是增加一些不可執行的前綴,如])}while(1);,相同域名下的腳本可以讀取響應的內容,自動卸掉前綴,但運行在另一個域名的腳本就不能讀取響應的內容。
路徑遍歷
一般來說,一個Web應用程序包含很多靜態文件,如圖片,CSS,JS文件等,正常情況下有些文件的訪問是要經過驗證的,但如果不小心,可能導致攻擊者越權遍歷整個網站的目錄,例如,在Windows和Linux下,..代表父目錄,如果你能在訪問路徑中注入../,那就意味著你可以訪問到父目錄中的文件。
如果攻擊者知道你的文件系統結構,那么他們可以構造一個URL遍歷網站目錄以外的目錄,甚至是/etc,例如,如果Picasa有路徑遍歷漏洞,Picasa使用Unix類系統,那么下面的URL將可以竊取到系統密碼文件:
http://www.picasa.com/../../../../../../../etc/passwd |
通過路徑遍歷暴露信息
任務:找到一個方法從Jarlsberg服務器讀取secret.txt。
這種攻擊在許多情況下不是必需的,人們安裝程序時往往不會修改默認位置,因此攻擊者首先會嘗試默認路徑遍歷。
提示1:這不是一個黑盒攻擊,因為你需要知道secret.txt文件是否存在,它位于哪里,以及Jarlsberg將它的資源文件存儲在哪里,你不需要查看任何源代碼。
提示2:服務器如何知道哪個URL表示資源文件,你可以使用curl或Web代理構造一個請求URL。
攻擊方法:通過下面的URL竊取secret.txt
http://jarlsberg.appspot.com/123/../secret.txt |
有些瀏覽器,如Firefox和Chrome,優化了URL中的../輸出,但這不能提供任何安全保障,因為攻擊者可以使用類似curl、Web代理或是沒做這種優化的瀏覽器等工具。
修復辦法:我們需要阻止訪問資源目錄以外位置的文件,驗證文件路徑的辦法有點麻煩,因為有很多種隱藏../或~等路徑元素的辦法,最佳的保護辦法是只服務特定的資源文件,可以將其硬編碼進你的應用程序,只接收訪問這些文件的請求,如果非要做文件路徑驗證,那也只能對最終路徑進行驗證,而不是對URL進行驗證,因為URL中的字符是可以轉義的。
通過路徑遍歷進行數據篡改
任務:找到一個辦法替換掉處于運行中的Jarlsberg服務器上的secret.txt。
提示:如果我以用戶brie登錄并上傳一個文件,服務器會將它存放在哪里?你可以欺騙服務器將上傳文件替換掉../secret.txt嗎?
攻擊方法:創建一個新用戶..,上傳你的secret.txt,你也可以創建一個名叫brie/../..的用戶來達到同樣的目的。
修復辦法:需要對用戶名進行危險字符轉義,我們應該限制用戶名允許的字符,另外還需要轉換大小寫,因為Windows下的文件名是不區分大小寫的,而Jarlsberg要區分。
拒絕服務(DoS)
拒絕服務攻擊就是讓服務器超負荷處理偽造的請求,使其無法為正常的請求提供服務,保護應用程序防止這種攻擊超出了本文的范圍,對Jarlsberg的DoS攻擊將會轉化為對App Engine的攻擊。下面的任務是找出Jarlsberg中可以用來執行DoS攻擊的bug。
DoS – 服務器停機攻擊
最簡單的攻擊辦法就是讓服務器停機。
任務:找出讓服務器停機的辦法。
提示:管理員可以關閉服務器,管理頁面是manage.jtl。
攻擊方法:向http://jarlsberg.appspot.com/123/quitserver發送一個請求。
修復辦法:只允許管理員訪問/quitserver。
|
DoS – 服務器超負荷攻擊
任務:找到一個讓服務器處理一個請求就超負荷工作的方法。
提示:可以上傳一個模板來實現,每個頁面都包含menubar.jtl模板。
攻擊方法:創建menubar.jtl文件,包含
[[include:menubar.jtl]]DoS[[/include:menubar.jtl]] |
使用路徑遍歷攻擊將其上傳到resources目錄。
修復辦法:和前面一樣,實現路徑遍歷保護。
代碼執行
如果攻擊者能遠程在你服務器上執行任意代碼,那表示你玩完了,遺憾的是目前也沒有一個萬能的方法來預防遠程代碼執行,因此只有靠程序本身進行驗證。
攻擊方法:通過修改jtl.py,置入惡意代碼,然后上傳替換掉原來的jtl.py,通過http://jarlsberg.appspot.com/123/quitserver讓服務器關機,等它重啟后,置入的惡意代碼就開始工作了。
Jarlsberg也有這個漏洞,因為Jarlsberg目錄允許寫入文件,這違背了最小權限原則。
修復辦法:修復前面兩個漏洞即可。
配置漏洞
黑客們都非常熟悉常用應用系統的默認設置,如按照目錄,默認管理員用戶和密碼等,如果配置不當,也相當于暴露了系統的漏洞。我們常見的如調試選項默認被開啟,默認的狀態頁,堆棧轉儲跟蹤等都屬于配置漏洞。
信息泄露
比如通過http://jarlsberg.appspot.com/123/dump.jtl就可以暴露出Jarlsberg的數據庫內容,唯一的辦法就是刪除/dump.jtl,如果非要開啟調試功能,那最好只允許管理員訪問,同時開啟IP地址訪問限制。
通過暴庫,我們可以獲得系統用戶名和密碼,因此密碼最好使用哈希值保存。
雖然我們可以刪除原始的dump.jtl,但Jarlsberg有文件上傳漏洞,因此攻擊者可以構造自己的dump.jtl,我們只能限制用戶上傳,或是用戶上傳的文件不能和Web應用程序位于同一位置,另外也可以限制上傳的文件類型。
總結
Web應用程序的安全涉及的內容很多,從代碼到配置都必須引起重視,可能一個小小的失誤就會導致整個服務器被攻擊者控制,安全從來就是相對的,攻防技術是不斷發展和變化的,加強學習和實戰是提高的唯一辦法。
【51CTO.COM 獨家翻譯,轉載請注明出處及作者!】
【編輯推薦】