作者:fenix@知道創宇404實驗室
時間:2021年6月10日
前言
群暉科技(Synology)自始便專注于打造高效能、可靠、功能豐富且綠色環保 NAS 服務器,是全球少數幾家以單純的提供網絡存儲解決方案獲得世界認同的華人企業【1】。
2021 年 5 月 27 日,HITB 2021(阿姆斯特丹)會議上分享了 Synology NAS 的多個漏洞【2】,Synology Calendar、Media Server、Audio Station 等套件中的漏洞可通過 Web 服務入口遠程利用。Audio Station 套件的漏洞成因為 audiotransfer.cgi 存在緩沖區溢出,遠程攻擊者可構造特殊數據包,然后利用該漏洞以 root 權限在目標設備執行任意命令。
Synology 在產品安全性上還是很負責的,對于安全漏洞提供最高達 10000$ 的賞金,近幾年公開的漏洞中嚴重并且有詳情的也不多,比如之前的《CVE-2017-11151 - Synology Photo Station Unauthenticated Remote Code Execution》 【3】。
Audio Station 這個漏洞品相著實有點好,經驗證發現無需認證即可利用,雖然開了 ASLR 也不需要爆破,一個請求即可實現穩定 RCE。
寫篇文章記錄一下, 等年紀大了,還能回頭看看 :)
環境搭建
Synology DS3615xs / DSM 5.2-5592 / Audio Station 5.4-2860
安裝好黑群暉后,在應用商店安裝 Audio Station 套件即可,DSM 5.2 的最新版 Audio Station 也存在漏洞。

漏洞分析
漏洞觸發流程如下(圖片來自會議 PPT):

PoC 很容易構造,棧上沒有指針需要恢復,一路暢通無阻,直接可控 PC。

調試及 EXP 構造
X86 架構,只開了 NX 保護,ASLR 為半隨機,Payload 中不能包含 '\x00'、'/'。

本程序有 popen() 的符號 ,不需要 return-to-libc。

接下來進入調試環節,我們知道 Web 服務器收到客戶端的請求后通過環境變量和標準輸入(Stdin)將數據傳遞給 CGI 程序, CGI 程序執行后通過標準輸出(stdout)返回結果。因此調試的時候就有兩種方法,1:gdb attach 到 Web 服務程序,然后 set follow-fork-mode child;2:設置好環境變量,直接運行 CGI。為了避免 Web 服務程序帶來的干擾,如對特殊字符編碼解碼處理,我們先通過手動設置環境變量的方式來調試:

可以看到,已經劫持執行流到 popen 了,現在思考一下參數傳遞的問題。 popen 的函數原型如下:
FILE *popen(const char *command, const char *type);
The popen() function opens a process by creating a pipe, forking,
and invoking the shell. Since a pipe is by definition
unidirectional, the type argument may specify only reading or
writing, not both; the resulting stream is correspondingly read-
only or write-only.
The command argument is a pointer to a null-terminated string
containing a shell command line. This command is passed to
/bin/sh using the -c flag; interpretation, if any, is performed
by the shell.
The type argument is a pointer to a null-terminated string which
must contain either the letter 'r' for reading or the letter 'w'
for writing.
第二個參數很好處理:
In [7]: open('./audiotransfer.cgi', 'rb').read().index(b'r\x00')
Out[7]: 2249
第一個參數是命令字符串的地址,可以將其放到棧上,前面加一些 ';' 作為命令滑板,然后 Payload 給一個大概的棧地址即可。此外,CGI 程序崩潰對 Web 服務沒啥影響,可以爆破。
到這里就結束了嗎?還有一個驚喜。
請求的 User-Agent 存到了堆上,由于 ASLR 為 1,通過 brk()分配的內存空間不會隨機化,因此這是一個固定地址。

將命令字符串放到 User-Agent,調整 Payload,成功獲取到 root shell。

然后就是 gdb attach 到 Web 服務程序進行實際漏洞利用調試了,可使用以下代碼替換 audiotransfer.cgi ,方便確認 Payload 是否被修改,以及通過 /proc/$pid/stat 得到父進程的 pid。
#include<stdio.h>
#include<stdlib.h>
int main() {
printf("%s", getenv("REQUEST_URI"));
printf("%s", getenv("HTTP_USER_AGENT"));
sleep(1000000);
}

影響范圍
通過 ZoomEye 網絡空間搜索引擎對關鍵字 app:"Synology NAS storage-misc httpd" 進行搜索,共發現 10154041 條 Synology NAS 的 IP 歷史記錄,主要分布在中國、德國【4】。安裝了Audio Station 套件且版本 < 6.5.4-3367 的會受到該漏洞影響。

從 ZoomEye 隨機抽取 10000 的目標進行漏洞檢測,成功率為 127/10000。

致謝
Synology 官方沒有發布該漏洞的安全公告,之前的文章引用了錯誤的鏈接及影響版本,實際影響版本為 < 6.5.4-3367(修復版本),感謝 swing 師傅指正 :)
相關鏈接
【1】: Synology 官網
【2】: A Journey into Synology NAS
【3】: Synology Photo Station Unauthenticated Remote Code Execution
https://www.seebug.org/vuldb/ssvid-96331
【4】: ZoomEye 網絡空間搜索引擎
https://www.zoomeye.org/searchResult?q=app%3A%22Synology%20NAS%20storage-misc%20httpd%22
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1604/
暫無評論