首页
社区
课程
招聘
[原创]2020KCTF秋季赛第八题wp
发表于: 2020-12-6 22:12 6724

[原创]2020KCTF秋季赛第八题wp

2020-12-6 22:12
6724

去花:

inv_sbox

import re
patterns = [
    (rb"\x81\xFC\x00\x10\x00\x00\x7C\x05\xE9\x06\x00\x00\x00\x81\xC4\x04\x01\x00\x00\x40\x48",21),
    (rb"\x66\xb8\xeb\x05\x31\xc0\x74\xfa\xe8",9),
    (rb"\x33\xc0\x74\x01\xe9",5),
    (rb"\xeb\xff\xc0\x48",4),
    (rb"\x74\x03\x75\x01\xe8",5),
    (rb"\xe8\x01\x00\x00\x00\xe9\x80\x04\x24\x06\xc3",11),
    (rb"\xe8\x03\x00\x00\x00\xf8\x73\x07\x50\x8b\x44\x24\04\xff\xd0\x8b\x44\x24\x04\x83\xc4\x0c",22),
    (rb"\x8D\x45\xF8\xC7\x45\xF8\x00\x00\x00\x00\x6A\x00\x6A\x04\x50\x6A\x07\xFF\x15\x40\xA4\x57\x00\x50\xFF\x15\x20\xA9\x57\x00\x83\x7D\xF8\xFF\x0F\x84\xA1\x03\x00\x00",40),
    (rb"\xFF\x15\x3C\xA4\x57\x00\x8D\x8D\x2C\xFD\xFF\xFF\xC7\x85\x2C\xFD\xFF\xFF\x10\x00\x01\x00\x51\x50\xFF\x15\x38\xA4\x57\x00\x83\xBD\x30\xFD\xFF\xFF\x00\x0F\x85\xD0\x00\x00\x00\x83\xBD\x34\xFD\xFF\xFF\x00\x0F\x85\xC3\x00\x00\x00\x83\xBD\x38\xFD\xFF\xFF\x00\x0F\x85\xB6\x00\x00\x00\x83\xBD\x3C\xFD\xFF\xFF\x00\x0F\x85\xA9\x00\x00\x00",82)
]
 
functins_to_be_patched = [
    (0x402EE0,0x4033A0),
    (0x404010,0x404010+0x2000)
]
 
class Patcher:
    def __init__(self):
        with open('origin.exe','rb') as fp:
            self.file_data = list(fp.read())
 
    def va_to_offset(self,va):
        return va - 0x400000 + 0x400 - 0x1000
 
    def patch_all(self):
        for f in functins_to_be_patched:
            start_va = f[0]
            end_va = f[1]
            start_offset = self.va_to_offset(start_va)
            end_offset = self.va_to_offset(end_va)
 
            data = self.file_data[start_offset:end_offset]         
            opcode = bytes(data)
            for p in patterns:
                for m in re.finditer(p[0],opcode):
                    pos = m.start(0)
                    data[pos:pos+p[1]] = [0x90 for _ in range(p[1])]
                opcode = bytes(data)
 
            self.file_data[start_offset:end_offset] = data
    def output(self):
        with open('patched.exe','wb') as fp:
            fp.write(bytes(self.file_data))
 
 
if __name__ == "__main__":
    patcher = Patcher()
    patcher.patch_all()
    patcher.output()
import re
patterns = [
    (rb"\x81\xFC\x00\x10\x00\x00\x7C\x05\xE9\x06\x00\x00\x00\x81\xC4\x04\x01\x00\x00\x40\x48",21),
    (rb"\x66\xb8\xeb\x05\x31\xc0\x74\xfa\xe8",9),
    (rb"\x33\xc0\x74\x01\xe9",5),
    (rb"\xeb\xff\xc0\x48",4),
    (rb"\x74\x03\x75\x01\xe8",5),
    (rb"\xe8\x01\x00\x00\x00\xe9\x80\x04\x24\x06\xc3",11),
    (rb"\xe8\x03\x00\x00\x00\xf8\x73\x07\x50\x8b\x44\x24\04\xff\xd0\x8b\x44\x24\x04\x83\xc4\x0c",22),
    (rb"\x8D\x45\xF8\xC7\x45\xF8\x00\x00\x00\x00\x6A\x00\x6A\x04\x50\x6A\x07\xFF\x15\x40\xA4\x57\x00\x50\xFF\x15\x20\xA9\x57\x00\x83\x7D\xF8\xFF\x0F\x84\xA1\x03\x00\x00",40),
    (rb"\xFF\x15\x3C\xA4\x57\x00\x8D\x8D\x2C\xFD\xFF\xFF\xC7\x85\x2C\xFD\xFF\xFF\x10\x00\x01\x00\x51\x50\xFF\x15\x38\xA4\x57\x00\x83\xBD\x30\xFD\xFF\xFF\x00\x0F\x85\xD0\x00\x00\x00\x83\xBD\x34\xFD\xFF\xFF\x00\x0F\x85\xC3\x00\x00\x00\x83\xBD\x38\xFD\xFF\xFF\x00\x0F\x85\xB6\x00\x00\x00\x83\xBD\x3C\xFD\xFF\xFF\x00\x0F\x85\xA9\x00\x00\x00",82)
]
 
functins_to_be_patched = [
    (0x402EE0,0x4033A0),
    (0x404010,0x404010+0x2000)
]
 
class Patcher:
    def __init__(self):
        with open('origin.exe','rb') as fp:
            self.file_data = list(fp.read())
 
    def va_to_offset(self,va):
        return va - 0x400000 + 0x400 - 0x1000
 
    def patch_all(self):
        for f in functins_to_be_patched:
            start_va = f[0]
            end_va = f[1]
            start_offset = self.va_to_offset(start_va)
            end_offset = self.va_to_offset(end_va)
 
            data = self.file_data[start_offset:end_offset]         
            opcode = bytes(data)
            for p in patterns:
                for m in re.finditer(p[0],opcode):
                    pos = m.start(0)
                    data[pos:pos+p[1]] = [0x90 for _ in range(p[1])]
                opcode = bytes(data)
 
            self.file_data[start_offset:end_offset] = data
    def output(self):
        with open('patched.exe','wb') as fp:
            fp.write(bytes(self.file_data))
 
 
if __name__ == "__main__":
    patcher = Patcher()
    patcher.patch_all()
    patcher.output()
static uint8_t inv_s_box[256] = {
    0xbb, 0xda, 0x21, 0x9c, 0xca, 0x9b, 0x31, 0x71, 0x51, 0x33, 0xb5, 0xc2, 0x8e, 0xa6, 0xeb, 0x99,
    0x1e, 0xea, 0xb1, 0x48, 0xb4, 0x89, 0x29, 0x18, 0xd4, 0x2a, 0x1a, 0x76, 0x4f, 0xaa, 0x9d, 0xdf,
    0x3e, 0x73, 0xcc, 0xd2, 0x58, 0x3d, 0xa8, 0x5, 0xa1, 0xc9, 0x6e, 0x40, 0x3f, 0x10, 0x17, 0x87 ,
    0x23, 0xbe, 0x26, 0x4d, 0xf5, 0x5e, 0xb, 0x98, 0xde, 0xee, 0xc4, 0x14, 0xb7, 0x6b, 0xa4, 0x36 ,
    0x5d, 0x42, 0xe6, 0x8f, 0xa2, 0x41, 0xb9, 0x80, 0x3c, 0x49, 0x57, 0x9a, 0x83, 0x34, 0xf7, 0x28,
    0x1d, 0xe2, 0xb0, 0x7b, 0x67, 0x19, 0x7e, 0x2e, 0x39, 0x30, 0xc1, 0x16, 0x7f, 0x95, 0x45, 0x63,
    0xba, 0xe7, 0xe5, 0x0, 0x78, 0xae, 0x96, 0x1c, 0x3a, 0x4b, 0x56, 0xe, 0x72, 0xa9, 0xb8, 0xed,
    0x82, 0x2b, 0xf0, 0x7, 0x68, 0x50, 0xe4, 0x5b, 0x32, 0x5c, 0xd0, 0xe3, 0x1, 0xc6, 0x2, 0x4,
    0xab, 0xcd, 0x88, 0x24, 0x85, 0x44, 0x4e, 0x12, 0xa5, 0x81, 0x3, 0xc, 0x8d, 0x27, 0xad, 0x9,
    0xfb, 0xd, 0x7d, 0x3b, 0xcf, 0x94, 0x61, 0x6, 0xf9, 0xdb, 0xdd, 0xfa, 0xe0, 0xc3, 0xd9, 0x91,
    0xf, 0xe8, 0x75, 0x93, 0xc0, 0xc8, 0xf3, 0x6d, 0x5a, 0xf2, 0xd1, 0x4a, 0xd7, 0x65, 0x22, 0xd8,
    0x6a, 0xe9, 0x15, 0xf8, 0xc7, 0xbd, 0xd5, 0x8c, 0xb2, 0x70, 0x55, 0xf4, 0xd3, 0x47, 0x86, 0x53,
    0x9f, 0x13, 0x7c, 0xb3, 0x66, 0xaf, 0x69, 0xdc, 0xff, 0x90, 0x46, 0x4c, 0x54, 0xec, 0x97, 0xa3,
    0xbf, 0x62, 0x7a, 0xa, 0x37, 0xfd, 0x20, 0x25, 0x43, 0x52, 0xbc, 0x1b, 0x9e, 0x11, 0xd6, 0x6c,
    0x84, 0x35, 0x5f, 0xe1, 0x92, 0x1f, 0x74, 0xac, 0xef, 0xf6, 0x2f, 0xcb, 0x60, 0x2c, 0x64, 0x8b,
    0x6f, 0x59, 0x77, 0x38, 0x2d, 0xc5, 0x79, 0xf1, 0xce, 0xfc, 0xa0, 0xb6, 0xfe, 0x8a, 0xa7, 0x8
};
static uint8_t inv_s_box[256] = {
    0xbb, 0xda, 0x21, 0x9c, 0xca, 0x9b, 0x31, 0x71, 0x51, 0x33, 0xb5, 0xc2, 0x8e, 0xa6, 0xeb, 0x99,
    0x1e, 0xea, 0xb1, 0x48, 0xb4, 0x89, 0x29, 0x18, 0xd4, 0x2a, 0x1a, 0x76, 0x4f, 0xaa, 0x9d, 0xdf,
    0x3e, 0x73, 0xcc, 0xd2, 0x58, 0x3d, 0xa8, 0x5, 0xa1, 0xc9, 0x6e, 0x40, 0x3f, 0x10, 0x17, 0x87 ,
    0x23, 0xbe, 0x26, 0x4d, 0xf5, 0x5e, 0xb, 0x98, 0xde, 0xee, 0xc4, 0x14, 0xb7, 0x6b, 0xa4, 0x36 ,
    0x5d, 0x42, 0xe6, 0x8f, 0xa2, 0x41, 0xb9, 0x80, 0x3c, 0x49, 0x57, 0x9a, 0x83, 0x34, 0xf7, 0x28,
    0x1d, 0xe2, 0xb0, 0x7b, 0x67, 0x19, 0x7e, 0x2e, 0x39, 0x30, 0xc1, 0x16, 0x7f, 0x95, 0x45, 0x63,
    0xba, 0xe7, 0xe5, 0x0, 0x78, 0xae, 0x96, 0x1c, 0x3a, 0x4b, 0x56, 0xe, 0x72, 0xa9, 0xb8, 0xed,
    0x82, 0x2b, 0xf0, 0x7, 0x68, 0x50, 0xe4, 0x5b, 0x32, 0x5c, 0xd0, 0xe3, 0x1, 0xc6, 0x2, 0x4,
    0xab, 0xcd, 0x88, 0x24, 0x85, 0x44, 0x4e, 0x12, 0xa5, 0x81, 0x3, 0xc, 0x8d, 0x27, 0xad, 0x9,
    0xfb, 0xd, 0x7d, 0x3b, 0xcf, 0x94, 0x61, 0x6, 0xf9, 0xdb, 0xdd, 0xfa, 0xe0, 0xc3, 0xd9, 0x91,
    0xf, 0xe8, 0x75, 0x93, 0xc0, 0xc8, 0xf3, 0x6d, 0x5a, 0xf2, 0xd1, 0x4a, 0xd7, 0x65, 0x22, 0xd8,
    0x6a, 0xe9, 0x15, 0xf8, 0xc7, 0xbd, 0xd5, 0x8c, 0xb2, 0x70, 0x55, 0xf4, 0xd3, 0x47, 0x86, 0x53,
    0x9f, 0x13, 0x7c, 0xb3, 0x66, 0xaf, 0x69, 0xdc, 0xff, 0x90, 0x46, 0x4c, 0x54, 0xec, 0x97, 0xa3,
    0xbf, 0x62, 0x7a, 0xa, 0x37, 0xfd, 0x20, 0x25, 0x43, 0x52, 0xbc, 0x1b, 0x9e, 0x11, 0xd6, 0x6c,
    0x84, 0x35, 0x5f, 0xe1, 0x92, 0x1f, 0x74, 0xac, 0xef, 0xf6, 0x2f, 0xcb, 0x60, 0x2c, 0x64, 0x8b,
    0x6f, 0x59, 0x77, 0x38, 0x2d, 0xc5, 0x79, 0xf1, 0xce, 0xfc, 0xa0, 0xb6, 0xfe, 0x8a, 0xa7, 0x8
};
import struct
from Crypto.Cipher import AES
from hashlib import sha256
u32 = lambda s:struct.unpack('<I',s)[0]
p32 = lambda x:struct.pack("<I",x)
def get_opcode():
    with open('opcode.bin','rb') as fp:
        data = fp.read()
    opcode = data[6160:6160+0x111F71]
    assert(opcode[0] == 0x69)
    return opcode
 
 
def get_bit(v,n):
    return 1 if (v>>n)&1 else 0
 
def get_ops():
    opcode = get_opcode()
    pc = 0
    vals_a = [0x6978,0x4b5a,0x2d3c,0xf1e,0xcdef,0x89ab,0x4567,0]
    vals_b = [0x23,0x01,0x67,0x45,0xAB,0x89,0xEF,0xCD,0x1e,0x0f,0x3c,0x2d,0x5a,0x4b,0x78,0x69]
    operations = []
 
    cnt = 0
    while pc < 0x111F71:
        andval = u32(opcode[pc:pc+4])
        k3 = get_bit(andval,7) + 2*get_bit(andval,16)
        idx = get_bit(andval,8) + get_bit(andval,19)*2 + get_bit(andval,27)*4
 
        a = opcode[pc+4]
        b = opcode[pc+k3+5]
        c = opcode[pc+k3+6]
        idxb = a ^^ vals_b[2*idx+1]
        idxa = idxb >> 4
        idxb = idxb & 0xf
        op = vals_b[2*idx]^^b
        shval = c
 
        operations.append((op,idxa,idxb,andval,shval))
 
        pc = pc + k3 + 7
 
        vals_a[7] = b + (a<<8)
        vals_b[0] = vals_a[6]&0xff
        vals_b[1] = (vals_a[6]>>8)&0xff
        vals_b[2] = vals_a[5]&0xff
        vals_b[3] = (vals_a[5]>>8)&0xff
        vals_b[4] = vals_a[4]&0xff
        vals_b[5] = (vals_a[4]>>8)&0xff
        vals_b[6] = vals_a[3]&0xff
        vals_b[7] = (vals_a[3]>>8)&0xff
        vals_b[8] = vals_a[2]&0xff
        vals_b[9] = (vals_a[2]>>8)&0xff
        vals_b[10] = vals_a[1]&0xff
        vals_b[11] = (vals_a[1]>>8)&0xff
        vals_b[12] = vals_a[0]&0xff
        vals_b[13] = (vals_a[0]>>8)&0xff
 
 
        vals_a[7] = b + (a<<8)
        vals_a[6] = vals_a[5]
        vals_a[5] = vals_a[4]
        vals_a[4] = vals_a[3]
        vals_a[3] = vals_a[2]
        vals_a[2] = vals_a[1]
        vals_a[1] = vals_a[0]
        vals_a[0] = vals_a[7]
 
        vals_b[14] = vals_a[7]&0xff
        vals_b[15] = (vals_a[7]>>8)&0xff
    return operations
def vm_calc(v,operations):
    data = [0]*16
    # data[15] = 0xD55D8CDD
    data[15] = v
    # wanted = 0xEE95C1D4
 
    for ops in operations:
 
        op,idxa,idxb,andval,shval = ops
        if op&0x40:
            data[idxa] &= andval
            data[idxa] &= 0xffffffff
        elif op&0x20:
            # print(hex(shval))
            data[idxa] >>= shval
            data[idxa] &= 0xffffffff
        elif op&0x10:
            # print(hex(shval))
            data[idxa] <<= shval
            data[idxa] &= 0xffffffff
        elif op&8:
            data[idxa] ^^= data[idxb]
        elif op&4:
            # print(cnt)
            data[idxa] = data[idxb]
            data[idxa] &= 0xffffffff
        elif op&2:
            data[idxa] += data[idxb]
            data[idxa] &= 0xffffffff
 
    return data[14]
 
def bits_to_val(v):
    res = 0
    for b in v[::-1]:
        res <<= 1
        res += b
    return res
 
def val_to_bits(val):
    return [(val>>(31-i))&1 for i in range(32)]
 
def recover_matrix():
    ops = get_ops()
    res = [[0 for i in range(32)] for j in range(32)]
    for i in range(32):
        v = [0 for _ in range(32)]
        v[i] = 1
        x = bits_to_val(v)
        o = vm_calc(x,ops)
        bits = val_to_bits(o)
        for j in range(32):
            res[j][i] = bits[j]
    return res
 
def solve_part3(wanted):
    assert(len(wanted)==16)
    res = []
    for n in wanted:
        res.append(n)
        res.append((n+0x7f)&0xff)
    return bytes(res)
 
def solve_part1(wanted):
    res = []
    A = recover_matrix()
    A = Matrix(GF(2),A)
    _A = A.inverse()
    for i in range(8):
        y = u32(wanted[4*i:4*i+4])
        bits = val_to_bits(y)
        y = vector(GF(2),bits)
        x = _A*y
        x = [int(b) for b in x]
        # print(x)
        x = bits_to_val(x)
 
        res.append(x)
    res = b''.join([p32(x) for x in res])
    return res.hex()
 
def solve_part2(wanted):
    iv = b'\x00'*16
    key = sha256(b"1_L0V3_BXS_F0REVER!").digest()
    ci = AES.new(key,AES.MODE_CBC,iv=iv)
    res = ci.decrypt(wanted)
    return res
wanted = bytes.fromhex("1f 93 c5 33 27 f9 2a d7 91 98 af 2e f5 97 ca 4a")
wanted = solve_part3(wanted)
# wanted = bytes.fromhex("60 DF E9 68 4A C9 73 F2 59 D8 AF 2E 52 D1 93 12 E7 66 C7 46 55 D4 3F BE 80 FF 5F DE E4 63 8A 09")
 
wanted = solve_part2(wanted)
# wanted = bytes.fromhex("D4 C1 95 EE 99 43 3A 33 DF 55 A4 E2 F1 FC D6 A3 31 CD 01 AB 9F 50 D4 2E 2D 94 B7 52 11 18 E2 6E")
flag = solve_part1(wanted)
 
print(flag)
import struct
from Crypto.Cipher import AES
from hashlib import sha256
u32 = lambda s:struct.unpack('<I',s)[0]
p32 = lambda x:struct.pack("<I",x)
def get_opcode():
    with open('opcode.bin','rb') as fp:
        data = fp.read()
    opcode = data[6160:6160+0x111F71]
    assert(opcode[0] == 0x69)
    return opcode
 
 
def get_bit(v,n):
    return 1 if (v>>n)&1 else 0
 
def get_ops():
    opcode = get_opcode()
    pc = 0
    vals_a = [0x6978,0x4b5a,0x2d3c,0xf1e,0xcdef,0x89ab,0x4567,0]
    vals_b = [0x23,0x01,0x67,0x45,0xAB,0x89,0xEF,0xCD,0x1e,0x0f,0x3c,0x2d,0x5a,0x4b,0x78,0x69]
    operations = []
 
    cnt = 0
    while pc < 0x111F71:
        andval = u32(opcode[pc:pc+4])
        k3 = get_bit(andval,7) + 2*get_bit(andval,16)
        idx = get_bit(andval,8) + get_bit(andval,19)*2 + get_bit(andval,27)*4
 
        a = opcode[pc+4]
        b = opcode[pc+k3+5]
        c = opcode[pc+k3+6]
        idxb = a ^^ vals_b[2*idx+1]
        idxa = idxb >> 4
        idxb = idxb & 0xf
        op = vals_b[2*idx]^^b
        shval = c
 
        operations.append((op,idxa,idxb,andval,shval))
 
        pc = pc + k3 + 7
 
        vals_a[7] = b + (a<<8)
        vals_b[0] = vals_a[6]&0xff
        vals_b[1] = (vals_a[6]>>8)&0xff
        vals_b[2] = vals_a[5]&0xff
        vals_b[3] = (vals_a[5]>>8)&0xff
        vals_b[4] = vals_a[4]&0xff
        vals_b[5] = (vals_a[4]>>8)&0xff
        vals_b[6] = vals_a[3]&0xff
        vals_b[7] = (vals_a[3]>>8)&0xff
        vals_b[8] = vals_a[2]&0xff
        vals_b[9] = (vals_a[2]>>8)&0xff
        vals_b[10] = vals_a[1]&0xff
        vals_b[11] = (vals_a[1]>>8)&0xff
        vals_b[12] = vals_a[0]&0xff
        vals_b[13] = (vals_a[0]>>8)&0xff
 
 
        vals_a[7] = b + (a<<8)
        vals_a[6] = vals_a[5]
        vals_a[5] = vals_a[4]
        vals_a[4] = vals_a[3]
        vals_a[3] = vals_a[2]
        vals_a[2] = vals_a[1]
        vals_a[1] = vals_a[0]
        vals_a[0] = vals_a[7]
 
        vals_b[14] = vals_a[7]&0xff
        vals_b[15] = (vals_a[7]>>8)&0xff
    return operations
def vm_calc(v,operations):
    data = [0]*16
    # data[15] = 0xD55D8CDD
    data[15] = v
    # wanted = 0xEE95C1D4
 
    for ops in operations:
 
        op,idxa,idxb,andval,shval = ops
        if op&0x40:
            data[idxa] &= andval
            data[idxa] &= 0xffffffff
        elif op&0x20:
            # print(hex(shval))
            data[idxa] >>= shval
            data[idxa] &= 0xffffffff
        elif op&0x10:
            # print(hex(shval))
            data[idxa] <<= shval
            data[idxa] &= 0xffffffff
        elif op&8:
            data[idxa] ^^= data[idxb]
        elif op&4:
            # print(cnt)
            data[idxa] = data[idxb]
            data[idxa] &= 0xffffffff
        elif op&2:
            data[idxa] += data[idxb]
            data[idxa] &= 0xffffffff
 
    return data[14]
 
def bits_to_val(v):
    res = 0
    for b in v[::-1]:
        res <<= 1
        res += b
    return res
 
def val_to_bits(val):
    return [(val>>(31-i))&1 for i in range(32)]
 
def recover_matrix():
    ops = get_ops()
    res = [[0 for i in range(32)] for j in range(32)]
    for i in range(32):
        v = [0 for _ in range(32)]
        v[i] = 1
        x = bits_to_val(v)
        o = vm_calc(x,ops)
        bits = val_to_bits(o)
        for j in range(32):
            res[j][i] = bits[j]
    return res
 
def solve_part3(wanted):
    assert(len(wanted)==16)
    res = []
    for n in wanted:

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2020-12-7 10:40 被afa9040e编辑 ,原因:
收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//