Socket = socket descriptor
Buffer = memory location for our second stage payload
BufferSize = memory space allocation for our second stage payload
Flags = Socket flags…can be set to Null
These are the parameters will need to be pushed to the stack (don't forget reverse order).
Before I populated the parameters, I grabbed the address of recv() which can be done by going in to the .text entry point and if we scroll down, we will find the functions.
Address 0x00401953 has the recv() but if you double click it...it shows the actual address which is 0x0040252C
I set a breakpoint at address 0x0040252C.
Once we hit our breakpoint, if you look at the stack, we can see the parameters that are currently loaded in the stack.
Note that at this point...both EAX and EBX registers have the socket descriptor value of 0x00000050. This is because of the instructions at these addresses: 0x0040194A and 0x00401950
0x0040194A - MOV EAX, DWORD PTR SS: [EBP-420]
This is a pointer to [EBP-420] so whatever the value loaded in [EBP-420] gets mov into EAX
We can see that EBP currently points to address 0x00EEFF88 so subtracting 420 should get us to the address that holds the socket descriptor.
As expected, if we jump to address 0x00EEFB68...we can see the value 0x00000050 loaded in.
Now, address 0x00401950 has the following instructions..
0x00401950 - MOV DWORD PTR SS:[ESP], EAX
This basically just loads the socket descriptor value stored in EAX, to the the [ESP] pointer. We can verify this by following ESP in the stack which currently points to address 0x011CF9E0
Next, we will load the value of socket descriptor to EAX. ASLR is enabled we will to do some math and ee will use ESP's address as a reference point.
We know that EBP register holds the socket descriptor located at address 0x00EEFB68. This means that we will need to do following:
0x00EEFB68 (EBP) - 0x00EEF9E0 (ESP) = 188 (in hex)
Great..so we will need to add 188 to ESP. We will do this by pushing ESP into stack, and pop it to EAX then add 188 to EAX. If our calculation is correct, we should have the socket descriptor address (0x00EEFB68) loaded to EAX.
We run the following instuctions:
ADD AX, 188
And we can see that address 00EEFB68 is now loaded in EAX which contains the socket descriptor value of 0x00000050 as shown in the stack.
Great...now we have the socket descriptor easily accessible!
Socket descriptor = 0x00000050
Buffer location = beginning of our C's (NOTE: this was adjusted to address 0x00EEF97C)
Buffer size = 400 (1024 in dec)
Flags = 0
Calling the RECV()
As you can see the recv() address contains null bytes which we will need to be removed. I learned something new from https://purpl3f0xsec.tech/2019/09/04/Vulnserver-KSTET-Socket-Reuse.html as to how to remove these null bytes.
We simply use an arbitrary address such as removing the null bytes and adding 90 for the lowest byte: 0x40252C90 instead of 0x0040252C
So we move this arbitrary address to EAX:
MOV EAX, 40252C90
Then we shift to right by 8 bits which removes the last 8 bits (0x90) and adds 00 to the first 8 bits
SHR EAX, 8
Finally, we simply CALL EAX
Here just right before we execute CALL EAX, we can see that it currently points to the recv() address
That is the entire first stage...and we update our POC as shown below