不安全的引用物件 (Insecure Direct Object Reference)是個非常常見的資安漏洞,在 OWASP公布的十大網站應用程式安全漏洞中高居第四名。通常發生在網站應用程式上沒有針對輸入的參數做好檢查,就把參數丟入 include 或 readfile 等函數當中引用,使得攻擊者可以藉此存取任意文件的原始碼。
今天這個案例就發生在 PHP 的官方網站 (http://www.php.net/),消息來源是知名的 0-Day 黑市 1337day,發佈的日期是 2014/4/4 ,原始的內容是這樣的:
可以看到這個弱點是不公開的,想要知道內容的話要支付 82 美元相當於新台幣 3500 元呢!在強烈的好奇心屈使之下,自己打開工具來找看看:
透過簡單的分析和一點點運氣,找到了 「http://www.php.net/cached.php」 這隻程式,發現它傳入了「t」和「f」這兩個參數。「t」直覺上就是個 rand 數值,而「f」應該就是檔案位置了。這時候對 f 參數小小修改一下,神奇的事情發生了:
index.php 的原始碼被完整的讀出來,當然也要來看一下 cached.php 是怎麼寫的:
可以看到此處並未對 $_GET[“f”] 進行檢查,所以修改了 $_GET[“f”] 後,與 $abs 組合完,最後就直接丟入 readfile 讀取檔案。比較值得研究的是這邊使用了 realpath 與 strncmp 來比較 f 及 DOCUMENT_ROOT,確保 $abs 只能在網站目錄之下,所以無法使用 ../../ (Path Traversal) 的方式跳脫目錄進行更進一步的滲透。
最後我們將此發現回報給 security@php.net ,得到的回應是他們是「故意的 (intentional)」。且後來也知道 PHP 官網是開放原始碼(Open Source)的,可以到 http://git.php.net/?p=web/php.git;a=tree下載整個官網的原始碼。
雖然在這個案例中並沒有造成實質上的危害,沒有帳號、密碼、系統設定等機敏資料,但若把此種寫法用在其他地方,則可能造成很大的資安風險。就連 PHP 官方網站都有這樣的失誤,身為開發人員的你們更不可不慎!