首页
论坛
课程
招聘
[原创]第二题 迷失丛林WP
2021-11-17 11:39 9933

[原创]第二题 迷失丛林WP

2021-11-17 11:39
9933

验证逻辑

序列号长度为0x20, 经函数0x004014A0转换为0x10字节数组,调用验证函数0x00401580完成验证,验证包含3个步骤:


膨胀 0x004015CC - 0x004016B6

  1. 将序列号前8字节放入数组,与已初始化数据组成0x100大小的原始数据,记为g_box

  2. 按特定算法将数组中1个字节膨胀到0x100字节

  3. 检验特定位个数是否满足要求

枚举算法如下:

sbox = bytes.fromhex("""00 00 00 00 00 00 00 00 A2 9B F4 DF AC 7C A1 C6
16 D0 0F DD DC 73 C5 6B D1 96 47 C2 26 67 4E 41
82 20 56 9A 6E 33 92 88 29 B5 B4 71 A9 CE C3 34
50 59 BF 2D 57 22 A6 30 04 B2 CD 36 D5 68 4D 5B
45 9E 85 CF 9D CC 61 78 32 76 31 E3 80 AD 39 4F 
FA 72 83 4C 86 60 B7 D7 63 0C 44 35 B3 7B 19 D4 
69 08 0B 1F 3D 11 79 D3 EE 93 42 DE 23 3B 5D 8D 
A5 77 5F 58 DB 97 F6 7A 18 52 15 74 25 62 2C 05 
E8 0D 98 2A 43 E2 EF 48 87 49 1C CA 2B A7 8A 09 
81 E7 53 AA FF 6F 8E 91 F1 F0 A4 46 3A 7D 54 EB 
2F C1 C0 0E BD E1 6C 64 BE E4 02 3C 5A A8 9F 37 
AF A0 13 ED 1B EC 8B 3E 7E 27 99 75 AB FE D9 3F 
F3 EA 70 F7 95 BA 1D 40 B0 F9 E5 F8 06 BC B6 03 
C9 10 9C 2E 89 5C 7F B1 1A D6 90 AE DA E6 5E B9 
84 E9 55 BB C7 0A E0 66 F2 D8 CB 00 12 B8 17 94 
6A 4A 01 24 14 51 07 65 21 C8 38 FD 8F C4 F5 FC """
)


def emu(skey):
    box = list(sbox)
    for i in range(0, 8):
        box[i] = skey[i]
   
    ncount = [0, 2, 4, 8, 0x10, 0x20, 0x40, 0x80]
    osub = []
    sub = []
    for idx in range(0, len(box)):
        bidx = 0
        sub.clear()
        sub.append(box[idx])
        sub.append((idx + 1) % 0x100)
        isub = 0
        for icount in range(1, len(ncount)):
            bcount = ncount[icount]
            for c in range(0, bcount):
                inext = sub[isub]
                sub.append(box[inext])
                sub.append((inext + 1) % 0x100)
                isub = isub + 1
        osub.append(sub[:])
        # #DEBUG
        # s = ""
        # for i in range(0, len(sub)):
        #     s = s + hex(sub[i]) + " "
        #     if((i + 1) % 16 == 0):
        #         print(s + "\n")
        #         s = ""
        # print(s + "\n")

        # # #检查
        # f = open("C:\\Users\\Administrator\\OneDrive\\Projects\\CTF\\Kanxue\\cm01\\sub_1", "rb")
        # #file = open("C:\Users\Administrator\OneDrive\Projects\CTF\Kanxue\cm01\\sub1","rb")
        # i = 0
        # for b in sub:
        #     c = f.read(1)[0]
        #     if b != c:
        #         print("ERROR: check failed at :" + str(i) + hex(b) + "!=" + hex(c) + "\n")
        #     i = i + 1
       
   
    blocks = []
    for sub in osub:
        block = [0] * 0x100
        for i in range(0xfe, 0x1fe):
            block[sub[i]] = block[sub[i]] + 1
        blocks.append(block[:])
   
    # #检查
    # f = open('C:\\Users\\96351\\OneDrive\\Projects\\CTF\\Kanxue\\cm01\\blocks', "rb")
    # #file = open("C:\Users\96351\OneDrive\Projects\CTF\Kanxue\cm01\blocks","rb")
    # for block in blocks:
    #     for b in block:
    #         c = f.read(1)[0]
    #         if b != c:
    #             print("check failed");


    b00 = 0
    b0E = 0
    b28 = 0
    b4F = 0
    for block in blocks:
        if block[0x00] != 0 :
            b00 = b00 + 1
        if block[0x0E] != 0 :
            b0E = b0E + 1
        if block[0x28] != 0 :
            b28 = b28 + 1
        if block[0x4F] != 0 :
            b4F = b4F + 1

    #print(hex(b00), hex(b0E), hex(b28), hex(b4F))
    if b00 == 0xa9 and b0E == 0xac and b28 == 0xa7:
        print("***FOUND***\n", hex(b00), hex(b0E), hex(b28), hex(b4F))
        seri = ""
        for i in range(0, 8):
            v = ((box[i] & 0xf) << 4) | ((box[i] >> 4) & 0xf)
            seri += hex(v) + " "        
        print(seri)



#skey = [0x1E, 0x28, 0x4B, 0x6D, 0x8C, 0xA3, 0xD2, 0xFB]
skey = [0x4B, 0x6D, 0x28, 0x8C, 0xFB, 0xD2, 0x1E, 0xA3]
def enum_key(position):
    if position == len(skey) - 1:
        # for k in skey:
        #     print(hex(k))
        emu(skey)
    else:
        for index in range(position, len(skey)):
            skey[index], skey[position] = skey[position], skey[index]
            enum_key(position+1)
            skey[index], skey[position] = skey[position], skey[index]


enum_key(0)  
#SERI: 0xb4 0xd6 0x82 0xc8 0xbf 0x2d 0xe1 0x3a


替换 004016BC - 00401724

对g_box数组做自替换,结束后的g_box数组前8字节作为密文(记为cipher),序列号后8字节作为密钥(记为key)进行解密


解密 00401726 - 004017A2

枚举算法如下:

//IDC
static search(cipher, plain)
{
    auto sbox = 0x00404000;
    auto s = 0;
    do
    {
        auto b = cipher;
        auto i;
        for(i=0; i<8; i++)
        {
          if(s & (1<<i))
          {
            ++b;
            if(b >= 0x100)
              break;
          }
            else
            {
              b = byte(sbox + b);
            }
        }
        
        if(b == plain)
        {
            return s;
        }
        
        ++s;
    }while(s < 0x100);
    return -1;
}

//ENTRY
static main()
{
    auto i = 0;
    do
    {
        auto plain = byte(0x0040412C + i);
        if(i == 0 || i == 7)
            plain = plain + 1;
        auto cipher = byte(0x00414420 + i);
        msg("\n%x, %x, ", plain, cipher);
        auto s = search(cipher, plain);
        msg("%02x ", s);
    }while(++i < 8);

}

算得最终序列号为:“B4D682C8BF2DE13AD9B6AEF24A80CB22”


[2022夏季班]《安卓高级研修班(网课)》月薪三万班招生中~

收藏
点赞1
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回