搜尋此網誌

2014年1月10日 星期五

[工具介紹] Apache 模組 mod_security - 以阻擋造訪路徑攻擊為例

前一篇文章中,我提到網站應用程式的安全問題,光靠定期更新並不能有效加以解決。透過 Secure SDLC 與 Secure Coding 的施作,才能有效提昇系統的整體安全性。而在前兩篇文章中,我提到了這幾天遠通電信網站被發現的一個安全漏洞 - 造訪路徑攻擊,也提到了一些防護手法。
但是回到現實面,我們知道很多時候該做的事情就是沒辦法進行,所以文章中提到的防護手法不一定能夠順利實施。原因有很多,不過歸到底通常都出在人身上。正所謂樹多有枯枝,人多有白痴。那怕只是一個程式設計師的一時鬼遮眼,都有可能讓系統產生莫大的安全漏洞。針對這種狀況,通常建議的作法就是採用 Virtual Patching,白話一點來說就是導入 WAF (Web Application Firewall)。不過再次回到現實面的現實面,導入 WAF 的金錢成本相當高,通常沒有準備七位數是沒有廠商會理你的。
好消息是沒錢也有沒錢的作法,其中 Apache 的 mod_security 模組正是一個免費的好用工具。在這次的文章中,我將示範如何利用 mod_security 來阻擋造訪路徑攻擊,環境為 CentOS 6。在進行前必須提醒讀者,因為示範過程將會改變網站的存取行為,因此請不要直接在正式的環境模擬
為了完成這次的範例,我先在網站上放置了一個 PHP 程式 – get_file_content.php,其內容為
<?php
  $content = file_get_contents($_GET['path']);
  echo nl2br($content);
?>
這個程式的功能很簡單,就是讓使用者透過 path 變數指定某個檔案名稱,然後程式就會將檔案內容完整顯示出來。所以當我們呼叫 get_file_content.php?path=../../../../../../etc/passwd 時,應該會看到這個熟悉的畫面
image
接下來,就讓我們一步步完成今天的範例吧。
  • 安裝 EPEL Repository
    EPEL 提供了 mod_security 的 RPM 套件,可以大幅簡化安裝與日後更新的動作,所以我選擇透過 EPEL 來安裝 mod_security。請先在 https://fedoraproject.org/wiki/EPEL 下載並安裝適合的版本。
  • 安裝 mod_security
    指令是
    yum -y install mod_security
  • 新增造訪路徑攻擊字串的規則
    mod_security 的規則設定檔放在目錄 /etc/httpd/modsecurity.d/activated_rules 內,檔案名稱必須以 .conf 結尾。請在這個目錄產生一個稱為 testing.conf 的檔案,並在檔案內加入下列內容
    SecRule REQUEST_URI "../" "phase:1,t:urlDecode,log,deny,status:503,id:1000"
  • 重新讀取 apache 設定檔
    指令是
    service httpd reload
  • 重新載入網址
    此時畫面應該會出現錯誤訊息 (Code=503)
    image
  • 查看阻擋記錄
    我們可以在日誌檔 /var/log/httpd/modsec_audit.log 看到類似下列的訊息
    --48927b7c-A--
    [10/Jan/2014:01:24:19 +0800] Us7bQ8CoAHcAAEwAH-AAAAAB 192.168.10.11 51517 192.168.10.10 80
    --48927b7c-B--
    GET /get_file_content.php?path=../../../../../../etc/passwd HTTP/1.1
    Host: 192.168.10.10
    Connection: keep-alive
    Cache-Control: max-age=0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36 OPR/18.0.1284.68
    Accept-Encoding: gzip,deflate,sdch
    Accept-Language: zh-TW,zh;q=0.8,en-US;q=0.6,en;q=0.4
    
    --48927b7c-F--
    HTTP/1.1 503 Service Temporarily Unavailable
    Content-Length: 402
    Connection: close
    Content-Type: text/html; charset=iso-8859-1
    
    --48927b7c-E--
    
    --48927b7c-H--
    Message: Access denied with code 503 (phase 1). Pattern match "../" at REQUEST_URI. [file "/etc/httpd/modsecurity.d/activated_rules/testing.conf"] [line "1"] [id "1000"]
    Action: Intercepted (phase 1)
    Stopwatch: 1389288259978368 472 (- - -)
    Stopwatch2: 1389288259978368 472; combined=48, p1=43, p2=0, p3=0, p4=0, p5=5, sr=0, sw=0, l=0, gc=0
    Response-Body-Transformed: Dechunked
    Producer: ModSecurity for Apache/2.7.3 (http://www.modsecurity.org/).
    Server: Apache/2.2.15 (CentOS)
    Engine-Mode: "ENABLED"
    
    --48927b7c-Z--
  • 下載 OWASP 規則
    透過一個簡單的規則,我們就可以避免造訪路徑攻擊。儘管如此,這個規則其實功能有限,因為它只檢查了 Request 字串,萬一是透過 POST (也就是 Content Body) 傳遞攻擊字串,那可就一點也派不上用場了。
    撰寫規則這種事,最好還是讓給專業的來。目前 mod_security 提供兩組規則,其中一組要錢,另外一組由 OWASP 所維護的規則則免費使用。在此我們選用 OWASP 的免費規則,指令如下
    cd /etc/httpd/modsecurity.d
    rm –f activated_rules/testing.conf
    wget https://github.com/SpiderLabs/owasp-modsecurity-crs/tarball/master -O owasp-modsecurity-crs.master.tgz
    tar xvfz owasp-modsecurity-crs.master.tgz
  • 安裝所需規則
    我們下載的檔案內包含許多規則,一般而言,我們不會啟用全部的規則。在此範例中,我們僅會啟用示範所需的規則。指令如下
    cd activated_rules/
    cp ../SpiderLabs-owasp-modsecurity-crs-f4d33c4/modsecurity_crs_10_setup.conf.example modsecurity_crs_10_setup.conf
    ln –s ../SpiderLabs-owasp-modsecurity-crs-f4d33c4/base_rules/modsecurity_crs_42_tight_security.conf modsecurity_crs_42_tight_security.conf
  • 重新讀取 apache 設定檔
    指令是
    service httpd reload
  • 重新載入網址
    此時畫面應該會出現錯誤訊息 (Code=403)
    image
    雖然錯誤訊息有所不同,但是一樣達到阻擋造訪路徑攻擊的目的。
  • 新增其他規則
    等等,萬一駭客輸入的攻擊字串不包含 ../,而是直接輸入 /etc/passwd 呢?令人驚訝的是,呼叫 get_file_content.php?path=/etc/passwd 依舊會直接顯示出檔案內容。因為 /etc/passwd 實在太過重要,所以 OWASP 提供了其他的規則以避免這類攻擊字串,指令如下
    ln –s ../SpiderLabs-owasp-modsecurity-crs-f4d33c4/base_rules/modsecurity_40_generic_attacks.data modsecurity_40_generic_attacks.data
    ln –s ../SpiderLabs-owasp-modsecurity-crs-f4d33c4/base_rules/modsecurity_crs_40_generic_attacks.conf modsecurity_crs_40_generic_attacks.conf
  • 再次重新讀取 apache 設定檔
    指令是
    service httpd reload
  • 再次測試
    此時呼叫 get_file_content.php?path=/etc/passwd 應該也會看到錯誤訊息了
    image
透過 mod_security 與 OWASP 提供的規則,我們就可以輕鬆避免遭受造訪路徑的攻擊。好啦,輕鬆兩字是騙人的,儘管 mod_security 解決了金錢成本的問題,但是導入 WAF 時所可能遭遇的其他問題,還是需要好好處理才能真正發揮 mod_security 的效用

About