QGB-REVER


强国杯-Rever-OBF

0x0 前言

12点发题到晚上9点结束,没做出来,硬是动调刚汇编看出来是xtea魔改

而且也得到了正确的key和delta,就是解密不出来,最终通过Retard师傅告诉我是魔改轮数为8,而且发现ida7.6 f5不了,但是7.7可以,泪目,吃一堑长一智。这里就分享一下7.6动调硬刚汇编。

0x1 ida7.6动调

1

在strlen的下一句下断,然后在右边的rdx寄存器进入内存,可以看见已经读取了我们输入的flag(flag这里我是直接拿做出来的输进去了,之前都是12345678)

然后再往下可以发现有一条字符串

2

这里我做了注释可以看见,其实就是把输入的附近当作临时存储计算出来的变量,可以看见先提取了前4位v0 下面v1就是后4位。左移和右移分别有一个地方存储。

3

因为xtea第一轮sum是0,这个地方应该注释sum,这是刚加第一轮的delta,可以发现就是字符串的最后4位。

4

左4

5

右5

6

xor

7

右移B == >11

这里&3取key我就没截图了。但是通过这些完全可以判断出是xtea了

key就是前16个字符串,在后面跟就可以找到,密文也在后面有对比。

Retard师傅告诉我还有密文异或下标和魔改了轮数为8,我才知道,因为动调最终对比中我就没发现。

0x2解密

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

/* take 64 bits of data in v[0] and v[1] and 128 bits of key[0] - key[3] */


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

void decipher(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 = 0x66786a6b, 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()
{
    uint32_t v[2] = { 0xf0cbf4f8,0x2f88f98a };
    uint32_t v1[2] = { 0x7e8e641c,0x5876f55c };
    uint32_t v2[2] = { 0x42dab16,0x1fce5989 };
    uint32_t v3[2] = { 0xee42bbc,0x19629a1d };
    uint32_t const k[4] = { 0x79776968, 0x66686472, 0x73687369, 0x64756b64 };
    unsigned int r = 8;//num_rounds建议取值为32
    // v为要加密的数据是两个32位无符号整数
    // k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位
    decipher(r, v, k);
    printf("解密后的数据:%x %x\n", v[0], v[1]);
    decipher(r, v1, k);
    printf("解密后的数据:%x %x\n", v1[0], v1[1]);
    decipher(r, v2, k);
    printf("解密后的数据:%x %x\n", v2[0], v2[1]);
    decipher(r, v3, k);
    printf("解密后的数据:%x %x\n", v3[0], v3[1]);
    return 0;
}

解密出来为小端序,然后我这里没有密文异或下标是因为我是直接动调dump的密文

0x3总结

Retard师傅告诉了我还差密文异或下标和轮数8,最终倒在了轮数8上。

在这里感谢一下Retard师傅的指点!!!


文章作者: Blue
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Blue !
评论
  目录