收获

  • 对于加密算法的逆向,根据密文恢复明文

(2023年5月1日-2023年5月25日)【ISCC 2023】JustDoIt


思路

用 32 位 IDA 打开,shift + F12 查看与 flag 有关信息,跟进过去

ISCC2023-JustDoIt1.png

结合运行程序的输出可知:
sub_4865AD()printf() 函数
sub_484D2F()scanf() 函数
其中,v5 为明文,v8 为密文

分析可知加密逻辑在 sub_487C91() 中,sub_487C91() 执行 sub_499080()

ISCC2023-JustDoIt2.png

逻辑比较清晰了,都是一些常规运算,逆过来写一个解密函数即可

加密逻辑:
① 先将 flag 的每个元素减 60
② 然后将字符串的顺序往后顺延一位
③ 通过 for 循环把每一位字符加上其数组索引
④ 再通过一个 for 循环进行除、取余、异或等操作处理字符串

按照逻辑,编写脚本解密即可


脚本

#include <iostream>  
  
using namespace std;  
  
  
int main(){  
    int v8[16];  
    v8[0] = 23;  
    v8[1] = 68;  
    v8[2] = 68;  
    v8[3] = 15;  
    v8[4] = 94;  
    v8[5] = 10;  
    v8[6] = 8;  
    v8[7] = 10;  
    v8[8] = 6;  
    v8[9] = 95;  
    v8[10] = 8;  
    v8[11] = 24;  
    v8[12] = 87;  
    v8[13] = 3;  
    v8[14] = 26;  
  
    v8[15] = 'i';    // 注意最后一位
  
    char key[] = {'I', 'S', 'C', 'C'};  
  
  
    for (int m = 1; m < 16; ++m )  
    {  
        v8[m] ^= *key;  
        v8[m] -= key[m % 4] % 5;  
        v8[m] = v8[m] + key[2] % 6 + key[3] / 6;  
        v8[m] -= key[1] / 7 + *key % 7;  
    }  
  
    for (int k = 1; k < 16; ++k )  
        v8[k] -= k;  
  
    int tmp = v8[16 - 1];  
    for (int j = 14; j >= 0; --j )  
        v8[j + 1] = v8[j];  
    v8[0] = tmp;  
  
    for (int i = 0; i < 16; ++i )  
        v8[i] += 60;  
  
    for (int l = 0; l < 16; ++l) {  
        printf("%c", v8[l]);  
    }  
    return 0;  
}

结果

ISCC{Just~Do~It}

ISCC2023-JustDoIt3.png