香山杯
# PREFACE:比较简单的比赛,ak 了 re,ai 题没看明白后续研究一下
# RE-URL 从哪儿来
提取资源区并解密:
with open('./decE_OU101', 'wb') as file1: | |
with open('./E_OU101', 'rb') as file: | |
a = file.read() | |
for i in a: | |
if (i != 120 and i != 0): | |
file1.write(bytes([i ^ 0x78])) | |
else: | |
file1.write(bytes([i])) |
动调拿 flag 即可
# hello_py
python 安卓,提取后 hello_py\assets\chaquopy
这个路径下解压 app.imy 得到加密文件,xxtea,解密即可
from ctypes import * | |
class XXTEACipher: | |
k = [c_uint32(0)]*4 | |
def __init__(self, key): | |
if len(key)!=16: | |
raise ValueError("Length of key must be 16 bytes long.") | |
if type(key) != bytes: | |
raise TypeError("Key must be a bytes object.") | |
for i in range(4): | |
tmp = c_uint32(0) | |
for j in range(4): | |
tmp.value = tmp.value << 8 | |
tmp.value = tmp.value + key[4 * i + (3 - j)] | |
self.k[i] = tmp | |
def encrypt(self, plain): | |
""" | |
:param | |
plain: byte string | |
The plaintext that will be encrypted. | |
It must to be a multiple of 4 bytes long. | |
:return: bytes string | |
The encrypted bytes. | |
""" | |
length = len(plain) | |
if length % 4 != 0: | |
raise ValueError("Length of plain must be a multiple of 4.") | |
if type(plain) != bytes: | |
raise TypeError("Plain must be a bytes object.") | |
n = length // 4 | |
v = [c_uint32()]*n | |
for i in range(n): | |
tmp = c_uint32(0) | |
for j in range(4): | |
tmp.value = tmp.value << 8 | |
tmp.value = tmp.value + plain[4 * i + (3 - j)] | |
v[i] = tmp | |
q = 6 + 52 // n | |
z = c_uint32(v[n-1].value) | |
y = c_uint32(v[0].value) | |
sum_delta = c_uint32(0) | |
delta = c_uint32(0x9e3779b9) | |
for i in range(q)[::-1]: | |
sum_delta.value += delta.value | |
for p in range(n-1): | |
e = (sum_delta.value >> 2) & 3 | |
y.value = v[p+1].value | |
v[p].value += ((z.value >> 5 ^ y.value << 2) + (y.value >> 3 ^ z.value<<4)) ^ ((sum_delta.value ^ y.value) + (self.k[(p&3)^e].value ^ z.value)) | |
z.value = v[p].value | |
y.value = v[0].value | |
v[n-1].value += ((z.value >> 5 ^ y.value << 2) + (y.value >> 3 ^ z.value<<4)) ^ ((sum_delta.value ^ y.value) + (self.k[((n-1)&3)^e].value ^ z.value)) | |
z.value = v[n-1].value | |
print("0x%08x, 0x%8x"%(v[0].value, v[1].value)) | |
cipher = b"" | |
for i in range(n): | |
for j in range(4): | |
cipher+=bytes([v[i].value&0xff]) | |
v[i].value = v[i].value >> 8 | |
return cipher | |
def decrypt(self, cipher): | |
""" | |
:param | |
plain: byte string | |
The plaintext that will be encrypted. | |
It must to be a multiple of 4 bytes long. | |
:return: bytes string | |
The encrypted bytes. | |
""" | |
length = len(cipher) | |
if length % 4 != 0: | |
raise ValueError("Length of cipher must be a multiple of 4.") | |
if type(cipher) != bytes: | |
raise TypeError("Cipher must be a bytes object.") | |
n = length // 4 | |
v = [c_uint32()]*n | |
for i in range(n): | |
tmp = c_uint32(0) | |
for j in range(4): | |
tmp.value = tmp.value << 8 | |
tmp.value = tmp.value + cipher[4 * i + (3 - j)] | |
v[i] = tmp | |
q = 6 + 52 // n | |
z = c_uint32(0) | |
y = c_uint32(v[0].value) | |
delta = c_uint32(0x9e3779b9) | |
sum_delta = c_uint32(q * delta.value) | |
print("0x%08x, 0x%8x"%(v[0].value, v[1].value)) | |
for i in range(q)[::-1]: | |
e = (sum_delta.value >> 2) & 3 | |
for p in range(1, n)[::-1]: | |
z.value = v[p-1].value | |
v[p].value -= ((z.value >> 5 ^ y.value << 2) + (y.value >> 3 ^ z.value<<4)) ^ ((sum_delta.value ^ y.value) + (self.k[(p&3)^e].value ^ z.value)) | |
y.value = v[p].value | |
z.value = v[n-1].value | |
v[0].value -= ((z.value >> 5 ^ y.value << 2) + (y.value >> 3 ^ z.value<<4)) ^ ((sum_delta.value ^ y.value) + (self.k[(0&3)^e].value ^ z.value)) | |
y.value = v[0].value | |
sum_delta.value -= delta.value | |
print("0x%08x, 0x%8x"%(v[0].value, v[1].value)) | |
plain = b"" | |
for i in range(n): | |
for j in range(4): | |
plain+=bytes([v[i].value&0xff]) | |
v[i].value = v[i].value >> 8 | |
return plain | |
def new(key): | |
""" | |
:param | |
key: byte string | |
key: byte string | |
The secret key to use in the symmetric cipher. | |
It must to be 16 bytes long. | |
:return: A XXTEACipher object. | |
""" | |
return XXTEACipher(key) | |
if __name__ == "__main__": | |
import struct | |
key = [12345678 ,12398712 ,91283904 ,12378192 ] | |
key = struct.pack("<IIII", *key) | |
xxtea = XXTEACipher(key) | |
cipher =[689085350 ,626885696 ,1894439255 ,1204672445 ,1869189675 ,475967424 ,1932042439 ,1280104741 ,2808893494 ] | |
cipher = struct.pack("<IIIIIIIII", *cipher) | |
plain = xxtea.decrypt(cipher) | |
print(plain) |
# nesting
虚拟机,模拟了很多 opcode
先批量 hook 一下,然后发现是类似流密钥的操作,,总归对于 flag 仅有 xor
单独 hook 得到 xor 的 key,一位一位 check 的,动调一位一位 xor 解密输入即可
# print(hex(get_reg_value('eax')) + ' | ' + hex(get_reg_value('ecx'))) | |
# print(hex(idc.get_wide_dword(get_reg_value("rbp") - 2)) + ' ==? ' + hex(get_reg_value('ax'))) | |
# print('ax = ' + hex(get_reg_value('ax'))) | |
# if (hex(get_reg_value('ax')) != '0x0'): | |
# print('ax = ' + hex(get_reg_value('ax'))) | |
# print(hex(get_reg_value('ax')) + ' ^ ' + hex(idc.get_wide_word(get_reg_value("rbp") - 2))) | |
# if (hex(idc.get_wide_word(get_reg_value("rbp") - 2)) != '0x2a'): | |
# print(hex(get_reg_value('ax')) + ' ^ ' + hex(idc.get_wide_word(get_reg_value("rbp") - 2))) | |
# flag{2c7c093b-f648-11ed-1111-11111111111} | |
print('flag{',end='') | |
print(chr(0x4 ^ 0x36),end='') | |
print(chr(0x5 ^ 0x66),end='') | |
print(chr(0x39 ^ 0xe),end='') | |
list = [0xe, 0x5d, 0x53, 0xc9, 0x4e, 0x46, 0xa, 0x13, 0x1, 0x3, 0x38, 0xa0, | |
0xbb, 0xc7, 0x44, 0xfa, 0xbc, 0x3, 0x44, 0x2c, 0x9a, 0x6d, 0x98, 0x35, | |
0x4f, 0x4a, 0x10,0xc4, 0x17, 0x9, 0x61, 0x06, 0xe1, 0x8d] | |
print(chr(0x5d ^ 0x3e),end='') | |
print(chr(0x53 ^ 0x63),end='') | |
print(chr(0xc9 ^ 0xf0),end='') | |
print(chr(0x4e ^ 0x7d),end='') | |
print(chr(0x46 ^ 0x24),end='') | |
print(chr(0xa ^ 0x27),end='') | |
print(chr(0x13 ^ 0x75),end='') | |
print(chr(1 ^ 0x37),end='') | |
print(chr(0x3 ^ 0x37),end='') | |
print(chr(0x38 ^ 0),end='') | |
# print(chr(0x21 ^ 0xa0),end='') | |
print('-11',end='') | |
print(chr(0x44 ^ 0x21),end='') | |
print(chr(0xfa ^ 0x9e),end='') | |
print('-',end='') | |
print(chr(3 ^ 0x62),end='') | |
print(chr(0x44 ^ 0x73),end='') | |
print(chr(0x1d ^ 0x2c),end='') | |
print(chr(0x9a ^ 0xac),end='') | |
print('-',end='') | |
print(chr(0x98 ^ 0xaf),end='') | |
print(chr(0x35 ^ 5),end='') | |
print(chr(0x7e ^ 0x4f),end='') | |
print(chr(0x2b ^ 0x4a),end='') | |
# print('-',end='') | |
print(chr( 0x10 ^ 0x72),end='') | |
print(chr(0xc4^ 0xfc),end='') | |
print(chr( 0x17^ 0x74),end='') | |
print(chr( 0x9^ 0x68),end='') | |
print(chr( 0x61^ 0x0),end='') | |
print(chr(0x06^ 0x67),end='') | |
print(chr( 0xe1^ 0x87 ),end='') | |
print(chr(0x8d^ 0xe8),end='') | |
print('}') |