如果你是一名開發人員,平時可能在本地會運行一些數據庫服務,比如Redis,、Memcached、Elasticsearch之流。相信很多產品都會依賴這一類的服務。
但是你可能不知道,這些本地運行的服務能跟你在外網訪問的網站進行通信,黑客也許能借此從你本地服務中竊取數據。
攻擊如何生效的
雖然筆者下面要講的并不是新的東西,但攻擊利用方法其實還是比較新穎的,因為以前很少有人把這些攻擊組合在一起。在這里,我將結合兩種不同技術進行測試,即“跨協議腳本”+“DNS重新綁定”。
跨協議腳本(cross protocol scripting)
第一種技術我們稱之為“跨協議腳本”,有人在2001年曾經放出過這種攻擊的細節。簡單解釋下攻擊原理,那就是Redis、Memcached都存在一個簡單的命令行協議,它會忽略無效的命令內容。這意味著,你的瀏覽器如果發送下面的HTTP請求到你本地的redis(localhost:6379),redis就會執行相應的SET命令。
POST / HTTP/1.1
Host: localhost:6379
SET abc 123
QUIT
惡意站點可以通過下面的form表單,借助你的手給你本地的redis發送惡意請求:
而Elasticsearch協議則完全是基于HTTP,所以在通信時沒有什么特別的技巧和需要注意的地方。
但是我們在執行上面的測試命令時,實際上是不能直接收到結果的。這是因為瀏覽器的同源策略,會在你發送請求給另一個域時,能進行限制讓你無法取得返回的數據。那么,現在我們就需要用到上面講的另外一門技術了。
DNS重綁定(DNS Rebinding)
簡單解釋下,DNS重綁定的攻擊原理就是字面的意思,我們采用某種手段重新更新一下DNS A記錄,綁定為別的地址。
為了繞過同源策略的保護,我們可以使用DNS重綁定技術,這種攻擊需要一臺跟你相對TTL值很低的服務器作為域名站點。一旦你瀏覽器訪問了惡意網站,站點上的惡意代碼會在特定的時刻,突然將站點DNS記錄更改到另外一個的IP地址,比如你私有的IP地址(127.0.0.1),該惡意站點就能借此竊取你本地服務里面的數據。當然,這前提是在它訪問你本地的服務時,能夠通過相應的認證授權。
POC代碼
我在extractdata.club網站上插入了攻擊的POC代碼,它會主動嘗試連接你本地默認端口的Redis, Memcached和Elasticsearch服務。
大約一分鐘后,這個網站會返回類似于下面的頁面。
這里的POC只會接收服務的版本信息,并不會去漫游你整個數據庫,咱們的POC代碼在這里。
修復方案
很遺憾其實沒有特別好的辦法來解決這個問題,但是我們可以試著為本地運行的服務設置密碼。筆者還想出了一個辦法,那就是對于Redis和Memcached這兩種服務,只要檢測到連接是通過HTTP請求發送來的,就可以立即阻止并退出。
對于瀏覽器方面來講,廠商可以在瀏覽器里面實現“DNS阻塞(DNS pinning)”。簡單來說就是,一旦某個網站被加載完成,瀏覽器就需要忽略其DNS的變化。
瀏覽器廠商也可以把Redis和Memcached端口加入它們阻塞的端口列表中,現在已經在列表中的常見協議有SMTP和IRC。當然,這辦法是治標不治本,如果出現了新的服務還是會出現漏洞的。
后記
Chromium開發人員正在致力于移除對HTTP/0.9的支持,這樣瀏覽器就不能從Redisand和Memcached讀取數據了。然而,即使這樣是這樣做,黑客仍然可以進行遠程命令執行。
對某些開發者來講,本地使用的測試數據庫里可能不會有太多有價值的東西。但黑客一旦擁有了讀寫權限,可能會對開發者的電腦進行遠程代碼執行操作。比如,黑客可以用惡意的payload覆蓋疑似Ruby marshalled或者Python pickled數據,這樣開發者的電腦就可能會淪陷。
結論
這個POC證明了計算機安全是很難得到絕對的保證的。有的時候,軟件單獨工作的時候看起來會很安全,但它們在交互時就可能就會產生一定的漏洞。
相關閱讀
跨協議腳本
DNS重綁定
在Rails使用DNS重綁定