香山杯

# 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 即可

image-20231015192950112

# 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('}')