*CTF 2022 Re

最近没怎么打比赛,来打*CTF的时候,比赛快结束了,因此只做了一题。

NaCI

代码调用逻辑非常乱,一大堆代码块,用jmp rdi这种指令动态串联起来,导致IDA基本无法正确反编译。唯一的思路就是从输入点一路追踪数据流向,一路审查汇编,捋清逻辑。
跳过前面数据初始化等一堆乱七八糟的东西,最终追踪下来,对输入数据的操作主要分为两部分。
第一部分操作如下,

主要操作抽离出表达式为

a0 = input[i+0]
a1 = input[i+1]
t = ( __ROL__(a0, 1) & __ROL__(a0, 1) ) ^ __ROL__(a0, 2) ^ a1 ^ tb[i]
a1 = a0 
a0 = t

第二部分是一个改了Delta的标准XTEA,每次加密的轮数分别是2,4,8,16。

由此脚本如下。

#include <stdio.h>
#include <stdint.h>
#include "defs.h" //ida的一个头文件


void XTeaDecipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {
    unsigned int i;
    uint32_t v0 = v[0], v1 = v[1], delta = 0X10325476, sum = delta * num_rounds;
    for (i = 0; i < num_rounds; i++) {
        v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);
        sum -= delta;
        v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
    }
    v[0] = v0; v[1] = v1;
}


int main()
{
    unsigned char table[] =
    {
      0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0F, 0x0E,
      0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x1B, 0xE8, 0x3F, 0xCD,
      0x77, 0x54, 0xC4, 0xD7, 0x36, 0x92, 0x3E, 0x9F, 0x87, 0xF1,
      0x07, 0x01, 0x81, 0xCB, 0x93, 0xF9, 0x6C, 0x16, 0x74, 0xBF,
      0x27, 0x84, 0x19, 0xDA, 0xFF, 0xAB, 0x05, 0x1A, 0xE4, 0xE5,
      0x07, 0x93, 0x45, 0x0E, 0x8B, 0xCB, 0xF5, 0xF7, 0x6D, 0x30,
      0x97, 0x01, 0x30, 0xAD, 0x56, 0xB0, 0x86, 0xAA, 0xBA, 0x63,
      0x92, 0x44, 0x1B, 0x40, 0xA4, 0x3F, 0x17, 0xF9, 0x41, 0x1E,
      0x7D, 0x1E, 0xCB, 0xC6, 0x7A, 0x0D, 0xEB, 0x18, 0x00, 0x48,
      0xEC, 0xD4, 0x2B, 0xF9, 0x86, 0xB4, 0xF3, 0xF9, 0x37, 0x87,
      0x25, 0x3D, 0x5E, 0x76, 0x37, 0x35, 0x3D, 0xDB, 0x2B, 0x55,
      0x44, 0xEE, 0x4C, 0xC9, 0xD0, 0x11, 0xCB, 0x5B, 0x60, 0x9B,
      0xB3, 0x98, 0x3B, 0x90, 0xA3, 0xEE, 0xC2, 0x24, 0xA2, 0x10,
      0x6E, 0x89, 0xC0, 0xF0, 0x47, 0x22, 0xAA, 0x5C, 0x4E, 0xB8,
      0xF0, 0x04, 0x2C, 0x8D, 0x2C, 0x84, 0xC7, 0x3B, 0x06, 0xD6,
      0x50, 0x1A, 0x7C, 0x91, 0xA1, 0x49, 0x0C, 0xB5, 0x1C, 0x7E,
      0x26, 0xB8, 0x27, 0xFC, 0xBC, 0xDF, 0xDD, 0x5F, 0x04, 0xC4,
      0x0F, 0xDE, 0x07, 0x09, 0xB3, 0xB2
    };
    uint32_t* tb = (uint32_t*)table;
    uint32_t key[] = { 0x3020100, 0x7060504, 0x0B0A0908, 0x0F0E0D0C };
    uint32_t enc[] = {
        0xFDF5C266, 0x7A328286,
        0xCE944004, 0x5DE08ADC,
        0xA6E4BD0A, 0x16CAADDC,
        0x13CD6F0C, 0x1A75D936,
        0
    };

    XTeaDecipher(2, enc, key);
    XTeaDecipher(4, enc + 2, key);
    XTeaDecipher(8, enc + 4, key);
    XTeaDecipher(16, enc + 6, key);

    
    for (size_t n = 0; n < 4; n++)
    {
        uint32_t* data = enc + n * 2;
        auto tmp = data[0];
        data[0] = data[1];
        data[1] = tmp;

        for (int i = 43; i >= 0; i--)
        {
            uint32_t last_a0 = data[1];
            uint32_t last_a1 = (__ROL4__(data[1], 1) & __ROL4__(data[1], 8)) ^ __ROL4__(data[1], 2) ^ data[0] ^ tb[i];
            data[0] = last_a0;
            data[1] = last_a1;
        }

        uint8_t* e1 = (uint8_t*)data;
        uint8_t* e2 = e1 + 4;

        uint8_t t = 0;

        t = e1[0];
        e1[0] = e1[3];
        e1[3] = t;

        t = e1[1];
        e1[1] = e1[2];
        e1[2] = t;

        t = e2[0];
        e2[0] = e2[3];
        e2[3] = t;

        t = e2[1];
        e2[1] = e2[2];
        e2[2] = t;

    }

    printf("*CTF{%s}\n", enc); //*CTF{mM7pJIobsCTQPO6R0g-L8kFExhYuivBN}

	return 0;
}
posted @ 2022-04-18 11:38  辰星-cxing  阅读(95)  评论(0编辑  收藏  举报