ISCC RE方向复现
1845017719556138 发表于 江西 CTF 191浏览 · 2024-11-12 01:17

最近闲来无事,想着把ISCC的RE复现一下,先复现第一周的。

iscc-week1-re1

查壳

64位未加壳,直接丢进ida里面。

进入到主函数里面

加密逻辑就是将flag与v3的差值作为相应字符数组的索引,即大写字母对应v16,小写对应v10,数字对应v4.

进入check2函数,发现了加密后的字符串flag

进行爆破,得到flag:ISCC{b}o}ffogj|zN\mvOs``MV}

EXP:

#include <iostream>
int main()
{
    char v16[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    char v10[] = "abcdefghijklmnopqrstuvwxyz";
    char v4[] = "0123456789+/-=!#&*()?;:*^%";
    char v3[] = "DABBZXQESVFRWNGTHYJUMKIOLPC";
    char flag[] = "00000000000000000000000000";
    int n = 0;
    char enc[] = "FSBBhKsqqQgdQc1mGDjhCoXRBG6";
    char flagg[28] = "";
    for (int i = 0; i < 27; i++) {
        for (;;) {
            if (flag[i] - v3[i] > 0) {
                n = flag[i] - v3[i];
                if (n > 25) {
                    if (n > 51) {
                        flagg[i] = *(v4 + n - 52);
                    }
                    else {
                        flagg[i] = *(v10 + n - 26);
                    }
                }
                else {
                    flagg[i] = *(v16 + n);
                }
            }
            if (flagg[i] == enc[i])break;
            else flag[i]++;
        }
        printf("%c", flag[i]);
    }
}
//ISCC{b}o}ffogj|zN\mvOs``MV}

iscc-week1-re2

查壳

64位文件,加了upx壳,脱壳后进入主函数

明面上flag进行了两次加密

点进mix里面看一下

发现其实并没有进行加密,于是跟进Encryption


发现了一部分加密代码,跟进new。

同样也是加密代码,至此,找出了所有的加密代码,根据加密逻辑写出解密代码.

EXP:

#include <iostream>
int main()
{
    char flag[28] = { 0x3A, 0xE4, 0x73, 0xA1, 0xB6, 0x96, 0xE4, 0x36 ,0x2B, 0xD3, 0xFC, 0x0A, 0x52, 0xBC, 0xA4, 0x92 ,0xD2, 0x4D, 0x5C, 0xDA, 0x8D, 0xB5, 0x18, 0xE0 , 0xF0, 0x34 };
    char key[5] = "ISCC";
    int v4 = 0;
    char a2[] = "So--this-is-the-right-flag";
    for (int i = 0;; i++) {
        if (i >= 26)break;
        flag[i] -= 10;
    }
    for (int i = 0; i<=24; i++) {
        flag[i] += flag[i + 1];
    }
    for (int i = 0; i < 25; i++) {
        flag[i] ^= key[2];
    }
    for (int i = 0; i < 26; i+=2) {
        flag[i] ^= key[i % 4];
    }for (int i = 0; i < 13; i++) {
        v4 = flag[i];
        flag[i] = flag[25 - i];
        flag[25 - i] = v4;
    }
    for (int i = 0;; i++) {
        if (i >= 13) break;
        int v4 = flag[i];
        flag[i] = flag[25 - i];
        flag[25 - i] = v4;
    }
    for (int i = 0; i < 26; i++) {
        flag[i] += key[i % 4];
        printf("%c", flag[i]);
    }
}
//ISCC{xIQ)K5N9beVJ)eSmM'Bc}

iscc-week1-re3

查壳,32位无壳

丢进ida里面

可知,flag长度为24,进行分析后发现,进行了三次加密,分别是加减,异或,标准xxtea,其中异或的密钥生成来自于伪随机数,写脚本解出,得到key=“674094872038771148666737”

EXP:

#include <stdio.h>
#include <stdint.h>  
#define DELTA 0x9e3779b9
#define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z)))  
void btea(uint32_t* v, int n, uint32_t const key[4])
{
    uint32_t y, z, sum;
    unsigned p, rounds, e;
    //加密
    if (n > 1)
    {
        rounds = 6 + 52 / n;
        sum = 0;
        z = v[n - 1];
        do
        {
            sum += DELTA;
            e = (sum >> 2) & 3;
            for (p = 0; p < n - 1; p++)
            {
                y = v[p + 1];
                z = v[p] += MX;
            }
            y = v[0];
            z = v[n - 1] += MX;
        } while (--rounds);
    }
    //解密
    else if (n < -1)
    {
        n = -n;
        rounds = 6 + 52 / n;
        sum = rounds * DELTA;
        y = v[0];
        do
        {
            e = (sum >> 2) & 3;
            for (p = n - 1; p > 0; p--)
            {
                z = v[p - 1];
                y = v[p] -= MX;
            }
            z = v[n - 1];
            y = v[0] -= MX;
            sum -= DELTA;
        } while (--rounds);
    }
}
int main() {
    unsigned int Buf2[6];
    Buf2[0] = 0x3881C7CA;
    Buf2[1] = 0x5AEA661A;
    Buf2[2] = 0xC0E1397D;
    Buf2[3] = 0x3C415BB1;
    Buf2[4] = 0xDC546CB9;
    Buf2[5] = 0x5DC6BE6;
    unsigned int key[] = { 0x12345678,0x9ABCDEF0,0x0FEDCBA98,0x76543210 };
    btea(Buf2, -6, key);
    unsigned char* p = (unsigned char*)Buf2;
    unsigned char flag[24] = { 0 };
    for (int i = 0; i < 24; i++)
    {
        flag[i] = p[i];
    }
    char encbuf[] = "674094872038771148666737";
    for (int i = 0; i < 24; i++)
    {
        flag[i] = (encbuf[i] - '0') ^ flag[i];
    }
    for (int i = 0; i < 24; i++)
    {
        if (i % 2)
        {
            flag[i] -= 2;
        }
        else {
            flag[i] += 3;
        }
    }
    printf("%s", flag);
}//ISCC{9YloUOEypr7MK6UCpF}

得到flag:ISCC{9YloUOEypr7MK6UCpF}

iscc-week1-re4

查壳,32位无壳


丢进ida里面

进行动调及分析可知,v9的后半段储存的是奇数位的密文,前半段位偶数位的密文。

进入奇数位加密函数

可知,奇数位进行的是交换顺序的加密,即将key[i]作为索引,将明文v2[i]赋值给v7[key[i]]达到改变顺序的结果。

偶数位加密在dll文件的encode函数中

显然,对传入的偶数位字符串进行了异或加密,密钥为"ISCC"

写出解密脚本

EXP:

#include <stdio.h>
#include <stdint.h>  
int main() {
    int v9[24] = {};
    v9[0] = 0;
    v9[1] = 16;
    v9[2] = 0x38;
    v9[3] = 19;
    v9[4] = 10;
    v9[5] = 61;
    v9[6] = 0x74;
    v9[7] = 0x2B;
    v9[8] = 3;
    v9[9] = 0;
    v9[10] = 0x14;
    v9[11] = 3;
    v9[12] = 0x43;
    v9[13] = 0x59;
    v9[14] = 0x53;
    v9[15] = 0x44;
    v9[16] = 0x46;
    v9[17] = 0x54;
    v9[18] = 0x40;
    v9[19] = 0x67;
    v9[20] = 0x4B;
    v9[21] = 0x7D;
    v9[22] = 0x75;
    v9[23] = 0x62;
    int key[12] = {};
    key[0] = 2;
    key[1] = 0;
    key[2] = 3;
    key[3] = 1;
    key[4] = 6;
    key[5] = 4;
    key[6] = 7;
    key[7] = 5;
    key[8] = 10;
    key[9] = 8;
    key[10] = 11;
    key[11] = 9;
    char flag[25];
    char v4[5] = "ISCC";
    for (int i = 0; i < 12; i++) {   
        flag[i * 2] = v9[i] ^ v4[i & 3];
        flag[i * 2 + 1] = v9[key[i] + 12];
        printf("%c%c", flag[i * 2], flag[i * 2 + 1]);
    }    
}//ISCC{DPYC@nF7ghTJuSKWb@}

得到flag:ISCC{DPYC@nF7ghTJuSKWb@}

0 条评论
某人
表情
可输入 255