# 思路
这个程序是一个 32 位的程序,并且是带了 asp 的壳,我还不会手动去壳,所以就用工具把壳去掉了,下面看到主函数
在点进去第一个函数之后就很明显,这是个 RC4 算法的题,而且不难看出,这个 dword_492040 [i] 就是 S 表,在这我将它的名字改位 S [i]
在看第二个函数,也很明显,这个 v1 应该就是密钥了,用 v1 来填充 k 表,但是这里的填充规则是有些改动的,我们需要知道 sub_41A038 的值才能进行计算,我们先不管这个
要注意的是,v1 密钥 “123456” 是字符串的形式,但我们填表是要用十进制的形式的,将 “123456” 转化为十进制之后是这样的
第三个函数是对 S 表的初始置换
第四个函数是计算新 K 表也就是密钥流,用来与明文进行异或运算的,这个 dword_492940 数组就是新 K 表
现在我们退出去,第一行有一个 v3,这个就是我们刚才需要知道的一个值,那它等于多少呢?根据逻辑关系,v3 的值是四个函数下面的 for 循环的限制条件(v3 也是明文的长度),也就是最后一步,即异或运算的循环次数,这个循环次数取决于 v2 数组的长度,而 v2 的长度是 42,所以 v3=42
在最后的 for 循环中,密文也就是 v2,等于 K 表的低位与明文进行异或然后再加 71,那么我们的脚本写出来就是把密文减 71 再与 K 表异或就是我们的明文了
# 脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
| #include<iostream> #include<stdint.h> using namespace std; int s[256]; char t[256]; int k[50]; void swap(int* a, int* b) { uint8_t tmp; tmp = *a; *a = *b; *b = tmp; } void Rc4_Init(uint8_t* key, uint32_t klen) { int i, j; for (i = 0; i < 256; i++) { s[i] = i; t[i] = key[i % klen]; } j = 0; for (i = 0; i < 256; i++) { j = (j + s[i] + t[i]) % 256; swap(&s[i], &s[j]); } } void __cdecl sub_401619() { int v3; int v4; int v5; int i; int a2 = 42; v4 = 0; v5 = 0; for (i = 0; a2--; k[v4++] = s[(s[v5] + s[i]) % 256]) { i = (i + 1) % 256; v5 = (v5 + s[i]) % 256; v3 = s[i] + 66; s[i] = s[v5] - 33; s[i] ^= 2u; s[v5] = 5 * v3; s[v5] = s[i] - 10; s[v5] += s[i]; s[i] -= 18; } }
int main() { uint8_t v2[42]; uint8_t ket[7] = {49,50,51,52,53,54}; Rc4_Init(ket, 6); sub_401619(); v2[0] = -61; v2[1] = -128; v2[2] = -43; v2[3] = -14; v2[4] = -101; v2[5] = 48; v2[6] = 11; v2[7] = -76; v2[8] = 85; v2[9] = -34; v2[10] = 34; v2[11] = -125; v2[12] = 47; v2[13] = -105; v2[14] = -72; v2[15] = 32; v2[16] = 29; v2[17] = 116; v2[18] = -47; v2[19] = 1; v2[20] = 115; v2[21] = 26; v2[22] = -78; v2[23] = -56; v2[24] = -59; v2[25] = 116; v2[26] = -64; v2[27] = 91; v2[28] = -9; v2[29] = 15; v2[30] = -45; v2[31] = 1; v2[32] = 85; v2[33] = -78; v2[34] = -92; v2[35] = -82; v2[36] = 123; v2[37] = -84; v2[38] = 92; v2[39] = 86; v2[40] = -68; v2[41] = 35; for (int i = 0; i < 42; i++) v2[i] = ((v2[i] - 71) ^ (k[i] & 0xff)); printf("%s",v2); return 0; }
|
题目来源:DASCTF × SU 2022 —— easyre