def formbook_patch_encrypted_bytecode(): text_segm = ida_segment.get_segm_by_name('.text') if not text_segm: return idaapi.BADADDR seg_start = text_segm.startEA seg_end = text_segm.endEA fb_decrypt = FormBookDecryption() rc4_key = "faddefad156c45629c95d5f429363b0653ad5c1d".decode('hex') # same as rc4_final from formbook_decrypt_hashes_and_strings() for i in [(0x40, 0x48), (0x41, 0x49), (0x42, 0x4a), (0x43, 0x4b), (0x44, 0x4c)]: egg_pattern = ''.join('{:02x} '.format(x) for x in [i[0], 0x90, 0x90, 0x90, i[1]]) encrypted_start = idaapi.find_binary(seg_start, seg_end, egg_pattern, 16, idaapi.SEARCH_DOWN) if encrypted_start != idaapi.BADADDR: encrypted_end = idaapi.find_binary(encrypted_start + 5, seg_end, "90 90 90 90", 16, idaapi.SEARCH_DOWN) if encrypted_end != idaapi.BADADDR: encrypted_start += 5 patch_length = encrypted_end - encrypted_start if idaapi.visit_patched_bytes(encrypted_start, encrypted_end, callback_on_patched_bytes) == 0: encrypted_buff = idaapi.get_bytes(encrypted_start, patch_length) decrypted_buff = fb_decrypt.decrypt_func2(encrypted_buff, rc4_key) print('Patching encrypted bytecode at 0x{:x} ({:d} bytes)'.format(encrypted_start, patch_length)) idaapi.patch_many_bytes(encrypted_start, decrypted_buff) else: print('Encrypted bytecode at 0x{:x} ({:d} bytes) is already patched'.format(encrypted_start, patch_length))
def decrypt_c2c_uri(self): import json import r2pipe import validators sys.path.append(os.path.abspath('external/tildedennis/formbook/')) from formbook_decryption import FormBookDecryption fb_decrypt = FormBookDecryption() encbuf6_addr = '0x{0:08X}'.format(self.enc_buffers[2]['addr'] + 7) encbuf7_addr = '0x{0:08X}'.format(self.enc_buffers[5]['addr'] + 7) encbuf8_addr = '0x{0:08X}'.format(self.enc_buffers[0]['addr'] + 7) encbuf9_addr = '0x{0:08X}'.format(self.enc_buffers[3]['addr'] + 7) self.r2.cmd('s %s' % encbuf6_addr) encbuf6_s0 = self.r2.cmd( 'p8 %s' % str(self.enc_buffers[2]['size'] * 2)).decode("hex") self.r2.cmd('s %s' % encbuf7_addr) encbuf7_s0 = self.r2.cmd( 'p8 %s' % str(self.enc_buffers[5]['size'] * 2)).decode("hex") self.r2.cmd('s %s' % encbuf8_addr) encbuf8_s0 = self.r2.cmd( 'p8 %s' % str(self.enc_buffers[0]['size'] * 2)).decode("hex") self.r2.cmd('s %s' % encbuf9_addr) encbuf9_s0 = self.r2.cmd( 'p8 %s' % str(self.enc_buffers[3]['size'] * 2)).decode("hex") rc4_key_two = fb_decrypt.decrypt_func1(encbuf6_s0, self.enc_buffers[2]['size']) rc4_key_one = fb_decrypt.decrypt_func1(encbuf7_s0, self.enc_buffers[5]['size']) encbuf8_s1 = fb_decrypt.decrypt_func1(encbuf8_s0, self.enc_buffers[0]['size']) encbuf9_s1 = fb_decrypt.decrypt_func1(encbuf9_s0, self.enc_buffers[3]['size']) rc4_key = FormBook.sha1(encbuf9_s1) encbuf8_s2 = fb_decrypt.decrypt_func2(encbuf8_s1, rc4_key) self.r2.cmd('s 0x%08x' % json.loads( self.r2.cmd("axtj %s" % '0x{0:08X}'.format( self.enc_buffers[0]['addr'])))[0]['from']) while json.loads(self.r2.cmd('pdj 1'))[0]['type'] != 'push': self.r2.cmd('so 1') c2_size = json.loads(self.r2.cmd('pdj 1'))[0]['val'] found = False for i, c in enumerate(encbuf8_s2): encrypted_c2c_uri = encbuf8_s2[i:i + c2_size] encrypted_c2c_uri = fb_decrypt.decrypt_func2( encrypted_c2c_uri, rc4_key_two) c2c_uri = fb_decrypt.decrypt_func2(encrypted_c2c_uri, rc4_key_one) if validators.url('http://' + '{:s}'.format(c2c_uri).replace('\x00', '')): print '[+] C&C URI found: hxxp://{:s}'.format(c2c_uri)
def formbook_decrypt_hashes_and_strings(): fb_decrypt = FormBookDecryption() # PE base address: 0x00400000 encbuf1_addr = 0x0041AF4C # fake prologue encbuf2_addr = 0x0041B160 # fake prologue encbuf3_addr = 0x0041AAA4 # fake prologue encbuf4_addr = 0x00419A83 # fake prologue # decrypt_func1 input length buffer is unknown # but is always >= output length encbuf1_s0 = idaapi.get_bytes(encbuf1_addr, 0x139 * 2) encbuf2_s0 = idaapi.get_bytes(encbuf2_addr, 0x35C * 2) encbuf3_s0 = idaapi.get_bytes(encbuf3_addr, 0x14 * 2) encbuf4_s0 = idaapi.get_bytes(encbuf4_addr, 0x9d3 * 2) encbuf1_s1 = fb_decrypt.decrypt_func1(encbuf1_s0, 0x139) encbuf2_s1 = fb_decrypt.decrypt_func1(encbuf2_s0, 0x35c) encbuf3_s1 = fb_decrypt.decrypt_func1(encbuf3_s0, 0x14) encrypted_strings = fb_decrypt.decrypt_func1(encbuf4_s0, 0x9d3) rc4_key_one = formbook_compute_sha1(encbuf1_s1) rc4_key_two = formbook_compute_sha1(encbuf3_s1) encbuf2_s2 = fb_decrypt.decrypt_func2(encbuf2_s1, rc4_key_one) encrypted_hashes_array = fb_decrypt.decrypt_func2(encbuf2_s2, rc4_key_two) rc4_key_pre_final = formbook_compute_sha1(encrypted_hashes_array) rc4_key_final = fb_decrypt.decrypt_func2(encbuf3_s1, rc4_key_pre_final) formbook_decrypt_hashes(fb_decrypt, rc4_key_final, encrypted_hashes_array) formbook_decrypt_strings(fb_decrypt, rc4_key_final, encrypted_strings)
def formbook_decrypt_c2c_uri(): fb_decrypt = FormBookDecryption() encbuf6_addr = 0x0041AAA4 # fake prologue encbuf7_addr = 0x0041AE45 # fake prologue encbuf8_addr = 0x0041AF4C # fake prologue encbuf9_addr = 0x00419A83 # fake prologue encbuf7_s0 = idaapi.get_bytes(encbuf7_addr, 0x14 * 2) encbuf6_s0 = idaapi.get_bytes(encbuf6_addr, 0x14 * 2) encbuf8_s0 = idaapi.get_bytes(encbuf8_addr, 0x139 * 2) encbuf9_s0 = idaapi.get_bytes(encbuf9_addr, 0x9d3 * 2) rc4_key_two = fb_decrypt.decrypt_func1(encbuf6_s0, 0x14) rc4_key_one = fb_decrypt.decrypt_func1(encbuf7_s0, 0x14) encbuf8_s1 = fb_decrypt.decrypt_func1(encbuf8_s0, 0x139) encbuf9_s1 = fb_decrypt.decrypt_func1(encbuf9_s0, 0x9d3) rc4_key = formbook_compute_sha1(encbuf9_s1) encbuf8_s2 = fb_decrypt.decrypt_func2(encbuf8_s1, rc4_key) encrypted_c2c_uri = encbuf8_s2[220:220+44] # 44 is the length of the C&C URI encrypted_c2c_uri = fb_decrypt.decrypt_func2(encrypted_c2c_uri, rc4_key_two) c2c_uri = fb_decrypt.decrypt_func2(encrypted_c2c_uri, rc4_key_one) print('C&C URI: {:s}'.format(c2c_uri))
def formbook_decrypt_image_name(): fb_decrypt = FormBookDecryption() encbuf5_addr = 0x41AACE # fake prologue encbuf5_s0 = idaapi.get_bytes(encbuf5_addr, 0x222 * 2) encbuf5_s1 = fb_decrypt.decrypt_func1(encbuf5_s0, 0x222) buff_dbg = '\x00\x00\x01\x01\x00\x00\x01\x00\x01\x00\x01\x00\x00\x00\x00\x00' rc4_key = formbook_compute_sha1(buff_dbg) print('Encrypted image name decryption:') j = 0 enc_str_len = 13 # each encrypted string is 13 bytes long f = open('decrypted_image_name.txt', 'w') for i in range(0, len(encbuf5_s1), enc_str_len): enc_img_name = encbuf5_s1[i:i+enc_str_len] if j < 2: # the 2 first strings are obfuscated with an additional routine enc_img_name = formbook_string_byte_substraction(enc_img_name, j) dec_image_name = str(fb_decrypt.decrypt_func2(enc_img_name, rc4_key)) line = '{:d} {:s}'.format(j, dec_image_name) print(line) print(line, file=f) j += 1 f.close()
def formbook_decrypt(self, key1, key2, config, config_size, strings_data, strings_size, url_size, hashs_data, hashs_size): fb_decrypt = FormBookDecryption() p_data = OrderedDict() rc4_key_one = fb_decrypt.decrypt_func1(key1, 0x14) rc4_key_two = fb_decrypt.decrypt_func1(key2, 0x14) encbuf2_s1 = fb_decrypt.decrypt_func1(hashs_data, hashs_size) encbuf8_s1 = fb_decrypt.decrypt_func1(config, config_size) encbuf9_s1 = fb_decrypt.decrypt_func1(strings_data, strings_size) rc4_key_1 = self.formbook_compute_sha1(encbuf8_s1) rc4_key_2 = self.formbook_compute_sha1(encbuf9_s1) rc4_key_3 = self.formbook_compute_sha1(rc4_key_two) encbuf2_s2 = fb_decrypt.decrypt_func2(encbuf2_s1, rc4_key_1) encbuf8_s2 = fb_decrypt.decrypt_func2(encbuf8_s1, rc4_key_2) n = 1 for i in xrange(config_size): encrypted_c2c_uri = encbuf8_s2[i:i + url_size] encrypted_c2c_uri = fb_decrypt.decrypt_func2(encrypted_c2c_uri, rc4_key_two) c2c_uri = fb_decrypt.decrypt_func2(encrypted_c2c_uri, rc4_key_one) if "www." in c2c_uri: p_data["C&C URI " + str(n)] = c2c_uri n += 1 encrypted_hashes_array = fb_decrypt.decrypt_func2(encbuf2_s2, rc4_key_3) rc4_key_pre_final = self.formbook_compute_sha1(encrypted_hashes_array) rc4_key_final = fb_decrypt.decrypt_func2(rc4_key_two, rc4_key_pre_final) p_data = self.formbook_decrypt_strings(fb_decrypt, p_data, rc4_key_final, encbuf9_s1) return p_data