Home » Posts tagged "injection"

相對路徑的攻擊方式 (Relative Path Overwite,RPO)

在「Large-scale analysis of style injection by relative path overwrite」這邊看到的,記得這個方式不是新方法,不過還是有人會中...

這種攻擊是組合技,基礎是引用 css 或是 js 時使用相對路徑 (像是 static/style.css 這樣的引用法),再加上 https://www.example.com/a.php 這樣的頁面通常也可以吃 https://www.example.com/a.php/,甚至是後面再加東西... 在某些情境下組不出來,但精心策劃後就有機會在頁面上弄出奇怪的 xss 或是其他攻擊了。而論文內列出了常見的的組合:

然後拿 Alexa 的排名來看,其實還是有些站台可以打:

防禦的方式也不算太難,absolute path 是個還不錯的方式:

One option is to use only absolute URLs, taking away the relative path expansion.

base tag 也是個方式 (不過在 IE 上還是有問題):

Alternatively you can specify a base tag, though Internet Explorer did not appear to implement the tag correctly (i.e., was still vulnerable) at the time of the evaluation.

另外作者也提到了 document type 的方式 (看起來是建議用 html5 的 <!DOCTYPE html>),然後 IE 另外做些處理避免失效:

One of the best mitigations is to avoid exploitation by declaring a modern document type that causes rendering in standards compliant mode. This defeats the attack in all browsers apart from IE. For IE it is also necessary to prevent the page being loaded in a frame by using X-Frame-Options , using X-Content-Type-Options to disable ‘content type sniffing,’ and X-UA-Compatible to turn off IE’s compatibility view.

不過大型站台本來就因為業務需求,會把 asset domain 切開 (然後透過 CDN 加速),而且會設計系統讓 programmer 很容易使用這樣的架構,反而因此比較不會用到 relative path,中這個攻擊的機會就低多了...

Google 對 GitHub 先前遭受 GFW 的 DDoS 攻擊的分析

Google Online Security 分析了前陣子 GitHub 被 DDoS 攻擊的行為:「A Javascript-based DDoS Attack as seen by Safe Browsing」。

透過 GoogleSafe Browsing,針對 baidu.com 這個網域的 injection 情況分析:

可以看得出來分成多個不同階段攻擊。其中 AWSCloudFront 承受了不小的壓力,不過畢竟是商用水準的 CDN,沒那麼容易垮掉。後來則是攻擊 GitHub 造成影響而上了新聞。

最終還是繼續推廣 TLS,可以避免中間被 injection 攻擊:

Had the entire web already moved to encrypted traffic via TLS, such an injection attack would not have been possible.

XSScrapy:自動化 XSS 攻擊

也是不知道在哪邊看到的,反正容易安裝就裝起來玩玩看:「XSScrapy: fast, thorough XSS vulnerability spider」。XSScrapy 是一套自動化攻擊軟體,是目前這類測試軟體裡用起來最簡單的版本。

直接 clone 下來就可以執行了,如果有遇到 dependency 的問題,可以透過 pip 安裝:

pip install -r requirements.txt

執行的方法就這樣:

./xsscrapy.py -u http://example.com

上面這個方法是在訪客模式下慢慢跑,你也可以給他一組帳號密碼讓他填 form,他會試著登入後不斷打下去:

./xsscrapy.py -u http://example.com/login_page -l loginname -p pa$$word

也可以用 HTTP Basic Authentication:

./xsscrapy.py -u http://example.com/login_page -l loginname -p pa$$word --basic

然後發現的問題會寫到 XSS-vulnerable.txt 裡面:

XSS vulnerabilities are reported in XSS-vulnerable.txt

用法就這樣而已... XD

Filter Input & Escape Output...

維基百科上有一篇「Secure input and output handling」說明要怎麼處理 input 與 output (對資安方面的說明)。標題的 Filter Input 與 Escape Output 是 Gasol 之前提到後才知道的名詞,以前只知道要 validate & escape,沒想過一個比較好記的念法...

這邊都以 PHP 為主,其他程式語言也應該會有對應的方式...

Input 有很多管道,有可能是使用者或是 3rd party 廠商透過 Form 傳進來的資料 (在 PHP 裡可能是 $_GET 或是 $_POST),也有可能是 cookie 的資料 (因為使用者可以修改,所以視為不安全的資料)。從檔案讀資料進來 (可能是普通的文字檔,或是 XML,也可能是圖片) 也算是 input。

Output 也有很多管道,像是 HTML、JSON,或是組 SQL statement 時使用變數。

Filter Input

在處理 input data 時,一般常常忘記的是「先強制轉成 Non-null UTF-8 string」(現在一般都是用 UTF-8,所以這邊就只講 UTF-8)。

這是因為很多 PHP function 對非 Non-null UTF-8 string 有非定義行為 (undefined behavior,不保證效果與輸出結果的正確性),加上一般常見的產品需求可以用 Non-null UTF-8 string 滿足,所以在 PHP 內拿到資料時可以先 filter 過。

Update:下面說的步驟錯了,請參考「關於 Non-null string 的處理...」這篇的說明。

有兩個步驟要做,第一個是確保他是 Non-null,直接把 \0 以及以後的東西幹掉:

$str_out = preg_replace('/\0.*/g', '', $str_in);
$str = preg_replace('/\0.*/g', '', $str); // 直接取代原來字串

第二個是確保他是 UTF-8 string。這點可以直接用 iconv() 轉,而不用自己寫 regex 處理了:

$str_out = iconv('UTF-8', 'UTF-8', $str_in);
$str = iconv('UTF-8', 'UTF-8', $str);

iconv() 從 UTF-8 轉到 UTF-8 是一個特別的用法,我是在 Cal Henderson 的「Building Scalable Web Sites: Building, Scaling, and Optimizing the Next Generation of Web Applications」上看到的 (有中譯版)。

如果傳進來的值本來就假設是整數,那麼就用 intval() 轉一次。如果假設是非負整數 (包含 0),那麼就用 abs()intval()。如果是文字類的 (像是 e-mail),可以再用其他的 regex 檢查。

一般來說,白名單會比黑名單好。不過這也是一般性,很多時候還是很囧的...

Escape Output

Escape 指的是 Escape character (轉義字元)。不同的情況下會有不同的 escape character,所以保護的方式也不一樣。

以 HTML 來說,想要顯示小於符號 <,實際上要用 &lt; 表示。而在 PHP 裡面常用的 htmlspecialchars() 定義了「只 escape 五個符號」,剛好可以拿來用:

<div><?= htmlspecialchars($str) ?></div>

也有人推薦 htmlentities(),不過因為轉的比較多 (所以要考慮的行為比較多),我比較不喜歡...

對於 XML,在 XML 的規範裡規定一定要把 <& 換成 &lt;&amp; (Character Data and Markup),但 > 則可以 (非必要) 換成 &gt;。也允許把雙引號 " 換成 &quot;,以及單引號 ' 換成 &apos;

所以 XML 剛好可以直接用 htmlspecialchars() (確認完全符合 spec 要求),反過來 htmlentities() 就不保證了。

再來是 MySQL 的 escape 與 charset 有關,所以要用 mysql_real_escape_string() 或是 PDO::quote(),但更好的方法應該是使用 prepare & execute (binding variables)...

而 shell 的 escape 則應該用 escapeshellarg() 再帶入 string 裡。

每一種 output 所需要的 escape function 不同,都不能直接拿 addslashes() 來用... (這個 function 的設計就很 PHP...)

純粹 JSON 的話,用 json_encode() 就可以幫你處理好。問題是在 HTML + JSON 時會讓你處理到抱頭痛哭... 這就是另外的故事了 +_+

結論?

Filter Input + Escape Output 只是最基本的一步,不過在大多數的狀況下,這個方法就可以擋下不少問題了,算是很實用的 policy...

請僅快確認這次 RoR 所提供的安全性公告

下午遇到布丁大長輩的時候他還很開心說「我用 2.3 沒問題的啊~」XDDD

今天 Ruby on Rails 官方對 Active Record 發出安全性通報以及更新 (類別為 SQL Injection):「[ANN] Rails 3.2.10, 3.1.9, and 3.0.18 have been released!」。

請不要只看標題,這次的安全性問題包括所有版本,而非 3.x 而已。這次的安全性問題太過歡樂,所以除了在支援的版本以外 (3.1 與 3.2),這次的安全性問題還是提供了 2.3 與 3.0 的 patch 讓人下載,並提供當無法使用 patch 時的 workaround:「SQL Injection Vulnerability in Ruby on Rails (CVE-2012-5664)」。

Archives