WMctf2021复现

re1

1.ida分析

程序加了扰乱堆栈的花指令去除即可。

花指令:

 

 改跳转逻辑即可,去除后。

 

 

2.程序执行流程

首先程序验证了输入长度在[0xC,0x2D]之中,并且格式为WMCTF{xxxxxxxxx}。

 

 然后取出{}内的字符串的前4个按一定规则生成一个表,然后再读取后16个字符。

 

 程序会对读取到的不同特殊字符执行不同的操作,特殊字符为_@#?!&-$+

通过调试和阅读代码可以得到每个字符对应的操作。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 然后验证前4个字符是否为'Hah4',最后把读取的16个字符和一个特殊的密钥进行xtea加密,最后验证加密后的数据。

 

 

3.解决方法

首先求出前4个字符的内容。

from z3 import *

s=Solver()
key=[BitVec('x%d'%i,32) for i in range(4)]
s.add(key[0]+key[1]==0x11ab7a7a)
s.add(key[1]-key[2]==0x1cd4f222)
s.add(key[2]+key[3]==0xc940f021)
s.add(key[0]+key[2]-key[3]==0x7c7d68d1)

if s.check()==sat:
    m=s.model()
    m=[hex(m[key[i]].as_long()) for i in range(4)]
    print(m)
#include <stdio.h>
#include<stdlib.h>
#include<stdint.h>

unsigned int box[256];
char res[5];
int number[] = { 0x100,0x100,0xf,0x1c };
unsigned enc[] = { 2750330814,1841087164,1357369498,2019106695 };

void gen_box() {
    unsigned int j; // [rsp+4h] [rbp-Ch]
    unsigned int i; // [rsp+8h] [rbp-8h]
    unsigned int v3; // [rsp+Ch] [rbp-4h]

    for (i = 0; i < 0x100; ++i)
    {
        v3 = i;
        for (j = 0; j < 8; ++j)
        {
            if ((v3 & 1) != 0)
                v3 = (v3 >> 1) ^ 0x8320EDB8;
            else
                v3 >>= 1;
        }
        box[i] = v3;
        
    }
    
}

unsigned int fun1(unsigned int a1, unsigned char a2[256], unsigned int a3) {
    unsigned int v4; // [rsp+4h] [rbp-1Ch]
    unsigned int v5; // [rsp+8h] [rbp-18h]

    v5 = 0;
    v4 = a1;
    while (v5 < a3)
        v4 = (v4 >> 8) ^ box[(unsigned char)(a2[v5++] ^ v4)];
    return a1 ^ v4;
}

unsigned int bp(int up, int number, unsigned int pre, unsigned int next) {
    for (int i = 0; i < 127; i++) {
        unsigned char block[256];
        for (int j = 0; j < number;  j++) {
            block[j] = i + j + up;
        }

        if (fun1(pre, block, number) == next)
            return i;
    }
}

int main() {
    gen_box();
    for (int i = 0; i < 4; i++) {
        if (i == 0)
            res[i] = bp(i, number[i], -2, enc[i]);
        else
        {
            res[i] = bp(i, number[i], enc[i - 1], enc[i]);
        }
    }
    puts(res);
}

最后求出为'Hah4'

然后xtea输入的内容,一开始使用的密钥为k[4] = { 0x78591fad,0x6dbcc2bc,0xa3eeb7be,0x50e7de9a },但是发现怎么也解不出,才测*(_98+0x111)这个地方的值是会变的,爆破这个值。


#include <stdio.h>
#include<stdlib.h>
#include<stdint.h>

void decrypt(uint32_t v[2], uint32_t const key[4]) {
    unsigned int i;
    uint32_t v0 = v[0], v1 = v[1], delta = 0x9981abcd, sum = delta * 0x20;
    for (i = 0; i < 0x20; 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 check(unsigned a) {
    for (int i = 0; i < 4; i++)
    {
        if (((char*)&a)[i] < 32 || ((char*)&a)[i] > 127)
            return 0;
    }

    return 1;
}

int main() {
    int i,j = 0;
    unsigned int v78 = 0x50e7d09a, v80 = 0xa3eeb7be, v7c = 0x6dbcc2bc, v74,v92 = 0x78591f87;
    v78 = v78 & 0xffff00ff;
    v74 = v92 & 0xffffff00;
    v78 |= 0xdead & 0xff00;
    v74 = v92 & 0xffffff00 | 0xdead;
    //printf("%x,%x,%x,%x\n", v74, v7c, v80, v78);
    unsigned int k[4] = { 0x78591fad,0x6dbcc2bc,0xa3eeb7be,0x50e7de9a };
    //unsigned int k[4] = { 0xa3eeb7be ,0x50e7de9a ,0x6dbcc2bc,0x78591fad };
    for (i = 0; i < 0xff; i++) {
        for (j = 0; j < 0xff; j++) {
            uint32_t v[2] = { 0x1989fb2b,0x83f5a243 };
            //uint32_t v[2] = { 0x556E2853,0x4393DF16 };
            k[0] &= 0xffffff00;
            k[0] |= i;
            k[3] &= 0xffff00ff;
            k[3] |= j<<8;

            decrypt(v, k);

            if (check(v[0]) && check(v[1])) {
                for (int t = 0; t < 8; t++) {
                    printf("%c", ((char*)v)[t]);
                }
                printf("%x,%x", i, j);
                putchar(10);
            }
        }
    }
    
}

 

 根据结果的语义得出值为0xad,0xb7。用来解另一个数据,最后得到_D0_yOu_L1kE_It!

最后再根据那些特殊字符的对应操作来推理出后面的内容。

最后为


WMCTF{Hah4_D0_yOu_L1kE_It!@FFFE#0F20-11B7}

 

posted @ 2021-09-04 16:34  mio_yy  阅读(266)  评论(0编辑  收藏  举报