WordPress插件漏洞影響超過100萬個網站
前言
作為我們Sucuri防火墻(WAF)漏洞研究項目的一部分,為了查找存在的安全問題,我們已經審計了多個開源項目。當審計WordPress的“NextGEN”相冊插件時,我們發現了一個嚴重的SQL注入漏洞。該漏洞允許一個未經授權的用戶從受害人網站的數據庫中偷取數據,包括用戶的敏感信息。目前,有超過100萬個WordPress網站安裝了這個易被攻擊的插件。
你處在危險中嗎?
攻擊者利用該漏洞需要至少兩個條件:
- 在你的網站中是否使用了“NextGEN Basic TagCloud Gallery”?
- 你是否允許你網站的用戶提交要審閱的文章(投稿人)?
如果你的網站符合這兩種情況之一,那你已經處在危險之中了。
漏洞原因是NextGEN相冊允許用戶在WordPress執行一條SQL查詢時輸入未經過濾的數據,本質上就是將用戶輸入直接添加到了一條SQL查詢中。使用該攻擊方法,一個攻擊者可以偷取到密碼的HASH、和WordPress其它配置的秘密信息。
技術細節
永遠不要相信輸入數據---這是一條金科玉律。如果遵守這條規律,那將會很安全。在很多情況下,我們必須問自己幾個簡單的問題:
- 這條輸入數據足夠安全嗎?
- 對它進行過濾了嗎?
- 我們遵循任何具體框架的規則和最佳實踐了嗎?
WordPress使用了PHP的vsprintf函數,用于在$wpdb->prepare()函數中提前準備好SQL statement,這意味著SQL語句使用格式化字符串和輸入值作為參數。這使我們得出結論:將用戶的輸入提供給格式化字符串從來不是一個好主意,因為它可能沒有對字符串進行過濾,可能會包含有效的sprintf/printf指令。
這就是為什么這個方法,get_term_ids_for_tags()引起了我們的注意:
上面的代碼可以在下面的路徑中發現:
nextgen-gallery/products/photocrati_nextgen/modules/nextgen_gallery_display/package.module.nextgen_gallery_display.php
在這個源代碼中,我們注意到“$container_ids”字符串是由tag輸入創建的,并且它的值并沒有經過適當的過濾。對于SQL注入,它是安全的,但是,它不能阻止任意格式化字符串指令/輸入的插入,在WordPress數據庫的$wpdb->prepare()方法下會引起問題。
$wpdb->prepare和sprintf
在prepare()方法的代碼中,我們注意到原始SQL代碼在執行前發生了一些變化,具體變化是:如果在語句中發現%s,會被替換成‘%s’。同樣,我們看到在發生變化之后,它會被傳遞給vsprintf函數,這意味著我們注入的任何有效的格式化字符串將有可能被處理。從PHP的sprintf函數文檔中我們知道可能會發生參數交換,當沒有適當過濾的輸入數據添加到格式化字符串時,有可能導致類似于下面的一些問題:
1.惡意用戶將下面的輸入注入到格式化字符串/查詢中:
2.生成的查詢有可能類似于這樣:
3.當傳遞給prepare()方法時,有可能會被修改為:
(%s將會變成‘%s’)。
4.于是,當由此產生的格式化字符串傳遞給vsprintf函數后,產生的SQL查詢語句具有以下格式:
如上所示,這意味著我們保留了一個額外的‘符號,這打破了我們字符串的單引號序列,并會將我們生成的[any_text2]字符串變成SQL查詢的一部分。
利用方案
在插件的源代碼中,我們發現有兩個地方的函數會創建“$container_ids”字符串,分別是:
- 當使用標簽庫的短碼時。它需要一個特權認證用戶來執行這個攻擊。
- 當從一個“NextGEN Basic TagCloud”相冊訪問標簽時,惡意訪問者可以通過稍微修改相冊的URL(網站中存在的相冊),去發起攻擊。
有了這些知識,一個未經授權的攻擊者可以向SQL查詢中添加額外的sprintf/printf指令,并利用$wpdb->prepare()的行為向執行的語句中添加攻擊者控制的代碼。
最終的攻擊載荷(使用了TagCloud方法)類似于下面這樣:
(http://target.url/2017/01/17/new-one/nggallery/tags/test%1$%s)) or 1=1#)
或者
(http://target.url/2017/01/17/new-one/nggallery/tags/test%1$%s)) or 1=2#)
結論
這是一個嚴重漏洞,如果你使用了該插件的一個有漏洞的版本,請盡可能快的對它進行升級。
參考鏈接
來自: http://netsecurity.51cto.com/art/201703/534332.htm