【CTF】Reverse Writeup 魔改tea,smc加密与验证 2022hws 逆向学习
浏览 195 | 评论 1 | 字数 3587
Xunflash
2022年08月10日
  • re1

    直接关键词捕捉Tea 那就是tea加密吧

    image-20220729163312015

    点进tea那个函数里面稍微美化下,可以发现其实是魔改过的xxtea,跑12轮,分了8组。那就直接开逆

    image-20220729163344218

    改一下现成的脚本

    #include<stdio.h>
    #include"defs.h"
    #include <stdint.h>  
    
    unsigned int enc_2[8] = {
       0x10BD3B47, 0x6155E0F9, 0x6AF7EBC5, 0x8D23435F, 0x1A091605, 0xD43D40EF, 0xB4B16A67, 0x6B3578A9
    };
    unsigned int data[8] = {
        0xD58F4C91, 0x9A751121, 0xD1F7D6AC, 0x63575833, 0x2A313023, 0xF9750867, 0xB2A9EDA5, 0xD6A7CD37
    };
    unsigned int data1[8] = {
        0x5DFAFC16, 0x3E3D5252, 0x03623808, 0x6B884FEA, 0xE99A75EB, 0xB741A335, 0x0C77D248, 0xE4908612
    };
    
    uint32_t DeryptoLoop(unsigned int num1, unsigned int num2, uint32_t sum, uint32_t index)
    {
        unsigned int key[4] = { 0x1234,0x2345,0x4567,0x6789 };
        //unsigned int key[4] = { 4,3,2,2 };
        uint32_t tmp1 = ((num1 >> 3) ^ 16 * num2) + (4 * num1 ^ (num2 >> 5));
        uint32_t tmp2 = (key[(sum >> 2) & 3  ^ index] ^ num2) + (num1 ^ sum);
        return tmp1 ^ tmp2;
    
    }
    
    void decrypt2(unsigned dec_2[8])
    {
        unsigned int state[8];
        unsigned int DELTA = 0x6a99b4ac;
        unsigned int key[4] = { 0x1234,0x2345,0x4567,0x6789 };
        int round = 0;
        for (int i = 0; i < 8; i++)
        {
            state[i] = enc_2[i];
        }
        int tmpd = DELTA;
        do {
            state[7] -= DeryptoLoop(state[0], state[6], tmpd, 3);
            state[6] -= DeryptoLoop(state[7], state[5], tmpd, 2);
            state[5] -= DeryptoLoop(state[6], state[4], tmpd, 1);
            state[4] -= DeryptoLoop(state[5], state[3], tmpd, 0);
            state[3] -= DeryptoLoop(state[4], state[2], tmpd, 3);
            state[2] -= DeryptoLoop(state[3], state[1], tmpd, 2);
            state[1] -= DeryptoLoop(state[2], state[0], tmpd, 1);
            state[0] -= DeryptoLoop(state[1], state[7], tmpd, 0);
            tmpd += 0x61C88647;
            round += 1;
        } while (round < 12);
        for (int i = 0; i < 8; i++)
        {
            dec_2[i] = state[i];
        }
    }
    
    int main(){
        unsigned int dec_2[8];
        decrypt2(dec_2);
        for (int i = 0; i < 8; i++)
        {
           for (int j = 0; j < 4; j++)
            {
                printf("%c", (dec_2[i] >> (j * 8)) & 0xFF);
            }  
        }
        //puts(dec_2);
        //0x33323130, 0x37363534, 0x31303938, 0x35343332, 0x39383736, 0x33323130, 0x37363534, 0x31303938
        return 0;
    }

    其中有几个要注意的地方,首先就是初始的delta需要动调一下,先动调跑到最后一轮拿到delta然后再拿来解密。然后就是key是异或0123位这样

    最后得到flag:7f943921724d63dc0ac9c6febf99fa88

    re2

    ida打开可以发现有个TlsCallback_0,main里面有一些怪东西,动调可以发现把输入的东西读入到了byte_41B2EC

    image-20220801192325157

    然后看TlsCallback_0,经典smc异或,然后新线程执行。动调之后可以看代码,那么直接断在这里

    image-20220801192612914

    然后看401040的东西,上面一坨拿代码段的字节加起来然后取一个byte,然后用这个和输入进行异或(这个代码段还加了几个花指令,我直接被骗,patch之后发现后面跑不出来.....),下面一堆不用看,直接看最下面

    image-20220801192840923

    v6是上面一堆操作得到的,和输入没有关系,然后异或,最后进行验证

    这个验证循环也比较有意思,他把密文直接放在代码段里面了,可以看到k+4199175,这个地址在代码段里面,过去把密文复制了就行

    image-20220801193353098

    我最终选择的方式是直接改内存,因为这一堆异或,都是可逆的。先直接把最上面的sleep上的dword改了,再改一下数组长度和输入,直接把输入的改成密文即可

    image-20220801193739782

    断在这里

    image-20220801193814194

    点进v7即可看到flag

    image-20220801193841251

    本文作者:Xunflash
    本文链接:https://xunflash.top/index.php/archives/2022hws.html
    最后修改时间:2022-08-10 14:24:43
    本站未注明转载的文章均为原创,并采用 CC BY-NC-SA 4.0 授权协议,转载请注明来源,谢谢!
    评论
    114514
    textsms
    支持 Markdown 语法
    email
    link
    评论列表
    已有 1 条评论
    2022-09-06 09:34
    虽然看不懂,还是支持一下~~
    鸟叔从十年之约而来,欢迎回访~~