mirror of https://github.com/UMSKT/peacestone.git
mac key derivation
This commit is contained in:
parent
6604a71d07
commit
16a9a1054c
|
@ -36,6 +36,7 @@ image_start = ql.loader.images[0].base
|
||||||
image_end = ql.loader.images[0].end
|
image_end = ql.loader.images[0].end
|
||||||
image_size = image_end - image_start
|
image_size = image_end - image_start
|
||||||
pe = pefile.PE(data=ql.mem.read(image_start, image_size))
|
pe = pefile.PE(data=ql.mem.read(image_start, image_size))
|
||||||
|
scratch_base = ql.mem.map_anywhere(0x1000)
|
||||||
|
|
||||||
def mem_read_int(addr):
|
def mem_read_int(addr):
|
||||||
return ql.unpack(ql.mem.read(addr, 4))
|
return ql.unpack(ql.mem.read(addr, 4))
|
||||||
|
@ -52,7 +53,7 @@ def array_write_int(array, offset, val):
|
||||||
|
|
||||||
return arr_copy
|
return arr_copy
|
||||||
|
|
||||||
stub_frame = 0x010BE265
|
stub_frame = 0x120f989
|
||||||
|
|
||||||
num_obd = mem_read_int(sym_data_inv["?g_nNumObfuscatedBlockData@WARBIRD@@3KA"])
|
num_obd = mem_read_int(sym_data_inv["?g_nNumObfuscatedBlockData@WARBIRD@@3KA"])
|
||||||
obd_addr = sym_data_inv["?g_ObfuscatedBlockData@WARBIRD@@3PAU_OBFUSCATED_BLOCK_DATA@1@A"]
|
obd_addr = sym_data_inv["?g_ObfuscatedBlockData@WARBIRD@@3PAU_OBFUSCATED_BLOCK_DATA@1@A"]
|
||||||
|
@ -108,16 +109,43 @@ val1 = (obd[index][1] + obd[index][0]) % (1 << 32)
|
||||||
val2 = (obd[index][2] - obd[index][0]) % (1 << 32)
|
val2 = (obd[index][2] - obd[index][0]) % (1 << 32)
|
||||||
val3 = (obd[index][4] + obd[index][3]) % (1 << 32)
|
val3 = (obd[index][4] + obd[index][3]) % (1 << 32)
|
||||||
unk3 = obd[index][3]
|
unk3 = obd[index][3]
|
||||||
|
|
||||||
|
print(f"VAL1 {hex(val1)} VAL2 {hex(val2)} VAL3 {hex(val3)} UNK3 {hex(unk3)}")
|
||||||
|
|
||||||
data_size = unk3 & 0xfff
|
data_size = unk3 & 0xfff
|
||||||
xor_plus_binstart = image_start + xor_value
|
xor_plus_binstart = image_start + xor_value
|
||||||
val1_bytes = val1.to_bytes(4, "little")
|
|
||||||
val2_bytes = val2.to_bytes(4, "little")
|
|
||||||
enc_bytes = ql.mem.read(xor_plus_binstart, data_size + 1)
|
enc_bytes = ql.mem.read(xor_plus_binstart, data_size + 1)
|
||||||
dec_bytes = [0] * data_size
|
dec_bytes = [0] * data_size
|
||||||
chksum = 0xa5
|
chksum = 0xa5
|
||||||
|
|
||||||
if val2 & 0x1000000 == 0:
|
if val2 & 0x1000000 == 0:
|
||||||
raise Exception("USES MAC-DERIVED KEY")
|
print("DERIVING KEY FROM MAC")
|
||||||
|
mac_func = mem_read_int(sym_data_inv["?g_apMacFuncs@WARBIRD@@3PAP6AXAA_JPBE1ABU_CBCKey2@1@@ZA"] + (val2 >> 25) * 4)
|
||||||
|
|
||||||
|
for instr in md.disasm(ql.mem.read(mac_func, 0x100), mac_func):
|
||||||
|
if instr.mnemonic == "ret":
|
||||||
|
mac_end = instr.address
|
||||||
|
break
|
||||||
|
|
||||||
|
ql.mem.write(scratch_base, b"\x00\x01\x02\x03\x04\x05")
|
||||||
|
ql.mem.write(scratch_base + 0x10, ql.pack(xor_value))
|
||||||
|
ql.mem.write(scratch_base + 0x14, ql.pack(0))
|
||||||
|
ql.arch.stack_push(scratch_base)
|
||||||
|
ql.arch.stack_push(val1 + image_start + (val2 & 0xffff))
|
||||||
|
ql.arch.stack_push(val1 + image_start)
|
||||||
|
ql.arch.stack_push(0x10)
|
||||||
|
ql.arch.stack_push(0x69696969)
|
||||||
|
|
||||||
|
old_sp = ql.arch.regs.esp
|
||||||
|
ql.run(begin=mac_func, end=mac_end)
|
||||||
|
ql.arch.regs.esp = old_sp
|
||||||
|
|
||||||
|
key1 = ql.mem.read(0x10, 4)
|
||||||
|
key2 = ql.mem.read(0x14, 2)
|
||||||
|
else:
|
||||||
|
print("USING BLOCK VALUES AS KEY")
|
||||||
|
key1 = val1.to_bytes(4, "little")
|
||||||
|
key2 = (val2 & 0xFFFF).to_bytes(2, "little")
|
||||||
|
|
||||||
for i in range(data_size - 1, -1, -1):
|
for i in range(data_size - 1, -1, -1):
|
||||||
enc_byte = enc_bytes[i]
|
enc_byte = enc_bytes[i]
|
||||||
|
@ -128,30 +156,30 @@ for i in range(data_size - 1, -1, -1):
|
||||||
b = 0
|
b = 0
|
||||||
|
|
||||||
if i % 2 == 1:
|
if i % 2 == 1:
|
||||||
if (enc_byte ^ val1_bytes[3]) % 2 == 1:
|
if (enc_byte ^ key1[3]) % 2 == 1:
|
||||||
a = (enc_byte ^ val1_bytes[3] ^ val1_bytes[2] ^ 0x100) >> 1
|
a = (enc_byte ^ key1[3] ^ key1[2] ^ 0x100) >> 1
|
||||||
else:
|
else:
|
||||||
a = (enc_byte ^ val1_bytes[3]) >> 1
|
a = (enc_byte ^ key1[3]) >> 1
|
||||||
|
|
||||||
if (a ^ b) % 2 == 1:
|
if (a ^ b) % 2 == 1:
|
||||||
dec_byte = (a ^ b ^ val2_bytes[1] ^ 0x100) >> 1
|
dec_byte = (a ^ b ^ key2[1] ^ 0x100) >> 1
|
||||||
else:
|
else:
|
||||||
dec_byte = (a ^ b) >> 1
|
dec_byte = (a ^ b) >> 1
|
||||||
else:
|
else:
|
||||||
if (enc_byte ^ val1_bytes[1]) % 2 == 1:
|
if (enc_byte ^ key1[1]) % 2 == 1:
|
||||||
a = (enc_byte ^ val1_bytes[1] ^ val1_bytes[0] ^ 0x100) >> 1
|
a = (enc_byte ^ key1[1] ^ key1[0] ^ 0x100) >> 1
|
||||||
else:
|
else:
|
||||||
a = (enc_byte ^ val1_bytes[1]) >> 1
|
a = (enc_byte ^ key1[1]) >> 1
|
||||||
|
|
||||||
if (a ^ b) % 2 == 1:
|
if (a ^ b) % 2 == 1:
|
||||||
dec_byte = (a ^ b ^ val2_bytes[0] ^ 0x100) >> 1
|
dec_byte = (a ^ b ^ key2[0] ^ 0x100) >> 1
|
||||||
else:
|
else:
|
||||||
dec_byte = (a ^ b) >> 1
|
dec_byte = (a ^ b) >> 1
|
||||||
|
|
||||||
chksum ^= dec_byte
|
chksum ^= dec_byte
|
||||||
dec_bytes[i] = dec_byte
|
dec_bytes[i] = dec_byte
|
||||||
|
|
||||||
if chksum != val2_bytes[2]:
|
if chksum != (val2 >> 16) & 0xFF:
|
||||||
raise Exception("CHECKSUM FAILED!")
|
raise Exception("CHECKSUM FAILED!")
|
||||||
|
|
||||||
print(dec_bytes)
|
print(dec_bytes)
|
||||||
|
@ -187,11 +215,9 @@ while index < num_relocs:
|
||||||
offset = -xor_plus_binstart % (1 << 32)
|
offset = -xor_plus_binstart % (1 << 32)
|
||||||
elif ofmode == 2:
|
elif ofmode == 2:
|
||||||
offset = xor_plus_binstart
|
offset = xor_plus_binstart
|
||||||
elif ofmode == 3:
|
|
||||||
offset = 0
|
|
||||||
|
|
||||||
if ((private_relocs[index] >> 30) & 3) == 2:
|
if ((private_relocs[index] >> 30) & 3) == 2 and offset != 0:
|
||||||
print(hex(addr - xor_value), hex(offset))
|
print(f"RELOC @ OFFSET {hex(addr - xor_value)} +{hex(offset)}")
|
||||||
val = array_read_int(dec_bytes, addr - xor_value)
|
val = array_read_int(dec_bytes, addr - xor_value)
|
||||||
val = (val + offset) % (1 << 32)
|
val = (val + offset) % (1 << 32)
|
||||||
dec_bytes = array_write_int(dec_bytes, addr - xor_value, val)
|
dec_bytes = array_write_int(dec_bytes, addr - xor_value, val)
|
||||||
|
|
|
@ -41,7 +41,7 @@ ks = Ks(KS_ARCH_X86, KS_MODE_32)
|
||||||
md = Cs(CS_ARCH_X86, CS_MODE_32)
|
md = Cs(CS_ARCH_X86, CS_MODE_32)
|
||||||
md.detail = True
|
md.detail = True
|
||||||
md.skipdata = True
|
md.skipdata = True
|
||||||
ql = Qiling(["./rootfs/sppsvc.exe"], "./rootfs")
|
ql = Qiling(["./rootfs/sppsvc.exe"], "./rootfs", verbose=QL_VERBOSE.OFF)
|
||||||
image_start = ql.loader.images[0].base
|
image_start = ql.loader.images[0].base
|
||||||
image_end = ql.loader.images[0].end
|
image_end = ql.loader.images[0].end
|
||||||
image_size = image_end - image_start
|
image_size = image_end - image_start
|
||||||
|
@ -79,15 +79,17 @@ if __name__ == "__main__":
|
||||||
f = open("log.txt", "w")
|
f = open("log.txt", "w")
|
||||||
|
|
||||||
for match in re.finditer(STUB_RET4_REGEX, pe_data):
|
for match in re.finditer(STUB_RET4_REGEX, pe_data):
|
||||||
|
print(hex(match.start()))
|
||||||
|
|
||||||
match_addr = image_start + match.start()
|
match_addr = image_start + match.start()
|
||||||
stub_code = ql.mem.read(match_addr - 0x1000, 0x1000)
|
stub_code = ql.mem.read(match_addr - 0x50, 0x50)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
stub_start_offset = list(re.finditer(PUSH_REGEX, stub_code))[0].start()
|
stub_start_offset = list(re.finditer(PUSH_REGEX, stub_code))[0].start()
|
||||||
except:
|
except:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
stub_start_addr = match_addr - 0x1000 + stub_start_offset
|
stub_start_addr = match_addr - 0x50 + stub_start_offset
|
||||||
instrs = list(md.disasm(ql.mem.read(stub_start_addr, 0x47), stub_start_addr))
|
instrs = list(md.disasm(ql.mem.read(stub_start_addr, 0x47), stub_start_addr))
|
||||||
ret = 0
|
ret = 0
|
||||||
|
|
||||||
|
@ -170,7 +172,13 @@ if __name__ == "__main__":
|
||||||
else:
|
else:
|
||||||
handler_name = hex(handler_addr)
|
handler_name = hex(handler_addr)
|
||||||
|
|
||||||
f.write(f"J R4 S {hex(jmp_insert_addr)} H {handler_name} N {hex(next_addr)}\n")
|
if next_addr in sym_data:
|
||||||
|
next_name = f"{hex(next_addr)} {sym_data[next_addr]}"
|
||||||
|
else:
|
||||||
|
next_name = hex(next_addr)
|
||||||
|
|
||||||
|
f.write(f"J R4 S {hex(jmp_insert_addr)} H {handler_name} N {next_name}\n")
|
||||||
|
|
||||||
# input()
|
# input()
|
||||||
print()
|
print()
|
||||||
|
# input()
|
Loading…
Reference in New Issue