首页
社区
课程
招聘
[原创]2021祥云杯-Re
发表于: 2021-8-24 02:03 10064

[原创]2021祥云杯-Re

2021-8-24 02:03
10064

一:Rev_Dizzy

拿到程序分析汇编:

 

随便选几个例子:(这个程序一共就三种运算, +-^)

 

图片描述

1
flag[6] += flag[3]

图片描述

1
flag[10] -= flag[27]

图片描述

1
flag[28] ^= flag[24]

如果实在是ida无法反编译,读文件用capstone等直接解析,根据不同的情况手动反编译

 

实际上这道题是可以反编译的,修改下ida配置文件\cfg\hexrays.cfg

 

MAX_FUNCSIZE = 1024
大概时间测了一下,5-8分钟之间

 

图片描述

 

复制出去解析下语句,让它全部符号反过,以及顺序反过

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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
string = """  flag[6] += flag[3];
  flag[10] -= flag[27];
  flag[10] += flag[6];
  flag[14] += flag[3];
  flag[28] ^= flag[24];
  flag[30] += 33;
  flag[12] += 33;
  flag[24] ^= flag[21];
  flag[22] += 33;
  flag[25] += flag[10];
  flag[4] += flag[6];
  flag[12] += 33;
  flag[17] += flag[0];
  flag[20] += flag[17];
  flag[20] -= 55;
  flag[21] -= 54;
  flag[17] -= flag[23];
  flag[1] += 33;
  flag[13] -= 55;
  flag[11] += flag[4];
  flag[5] += flag[13];
  flag[26] ^= flag[19];
  flag[3] += flag[20];
  flag[20] ^= flag[24];
  flag[27] ^= flag[4];
  flag[27] -= 55;
  flag[13] -= 54;
  flag[26] ^= flag[16];
  flag[29] ^= flag[16];
  flag[4] += flag[30];
  flag[31] -= 54;
  flag[18] -= flag[9];
  flag[15] -= flag[30];
  flag[8] += flag[0];
  flag[26] -= 54;
  flag[30] -= flag[29];
  flag[30] -= 54;
  flag[8] -= 54;
  flag[0] -= 54;
  flag[18] += 33;
  flag[31] ^= flag[19];
  flag[15] -= 55;
  flag[26] += flag[9];
  flag[27] -= 55;
  flag[6] -= flag[30];
  flag[31] ^= flag[2];
  flag[12] ^= flag[1];
  flag[29] ^= flag[23];
  flag[24] += 33;
  flag[17] += flag[25];
  flag[11] ^= flag[9];
  flag[16] ^= flag[21];
  flag[14] += flag[13];
  flag[21] += flag[25];
  flag[29] += 33;
  flag[17] += flag[28];
  flag[18] -= flag[7];
  flag[4] ^= flag[13];
  flag[15] -= 55;
  flag[13] ^= flag[14];
  flag[22] += flag[21];
  flag[7] ^= flag[19];
  flag[0] -= 54;
  flag[13] += flag[26];
  flag[26] += flag[4];
  flag[3] ^= flag[12];
  flag[29] ^= flag[18];
  flag[11] ^= flag[4];
  flag[13] += flag[2];
  flag[18] -= 54;
  flag[16] ^= flag[11];
  flag[0] ^= flag[24];
  flag[28] ^= flag[16];
  flag[28] ^= flag[31];
  flag[15] += flag[19];
  flag[30] += 33;
  flag[24] ^= flag[30];
  flag[30] -= 55;
  flag[10] += 33;
  flag[16] ^= flag[31];
  flag[0] ^= flag[8];
  flag[11] -= 55;
  flag[12] -= flag[2];
  flag[21] ^= flag[6];
  flag[3] += flag[31];
  flag[5] ^= flag[25];
  flag[10] += flag[21];
  flag[7] ^= flag[21];
  flag[6] += flag[2];
  flag[29] ^= flag[30];
  flag[15] -= 54;
  flag[0] ^= flag[30];
  flag[16] += flag[17];
  flag[25] ^= flag[29];
  flag[10] -= 55;
  flag[11] ^= flag[30];
  flag[20] += 33;
  flag[8] += flag[16];
  flag[9] -= 54;
  flag[17] -= flag[27];
  flag[11] += flag[8];
  flag[8] ^= flag[2];
  flag[23] ^= flag[31];
  flag[14] += 33;
  flag[10] -= flag[12];
  flag[12] += flag[4];
  flag[7] -= 54;
  flag[21] -= 55;
  flag[3] += flag[7];
  flag[1] += flag[11];
  flag[5] -= flag[28];
  flag[6] ^= flag[17];
  flag[26] += flag[16];
  flag[31] -= 54;
  flag[23] -= flag[9];
  flag[3] += 33;
  flag[25] += 33;
  flag[10] ^= flag[31];
  flag[23] -= 54;
  flag[28] += flag[18];
  flag[25] -= flag[1];
  flag[1] -= flag[8];
  flag[3] -= flag[23];
  flag[26] += flag[21];
  flag[13] += flag[5];
  flag[29] += 33;
  flag[18] -= 55;
  flag[11] -= 54;
  flag[19] += flag[20];
  flag[25] += flag[28];
  flag[24] += 33;
  flag[6] -= flag[10];
  .....
"""
for one in string.splitlines()[::-1]:
    one = one[2:]
    ad = one.find('+')
    sub = one.find('-')
    xor = one.find('^')
    if ad != -1:
        print(one[:ad] + '-' + one[ad+1:])
        continue
    if sub != -1:
        print(one[:sub] + '+' + one[sub+1:])
        continue
    if xor != -1:
        print(one[:xor] + '^' + one[xor+1:])
        continue
    else:
        raise Exception("Error")

然后复制出来粘贴,然后将flag逆向运算一次就得到flag,比较简单

 

图片描述

 

之前没想那么多,拿到就直接angr上手,在设置了基址,填写了符号变量,用hook跳过了那个中间的那个test循环等.....,结果跑了很久没跑出来,生成式子太难解

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
# _*_ coding: utf-8 _*_
# editor: SYJ
# function: Reversed By SYJ
"""
describe:
 
"""
import angr
import claripy
import logging
logging.getLogger('angr').setLevel('DEBUG')
 
path = r"D:\CTF\COMPETITIONS\2021xiangyunbei\Rev_Dizzy\Dizzy.exe"
base = 0x400000
proj = angr.Project(path, main_opts={'base_addr': base})          #  load_options={"auto_load_libs": False}
init_state = proj.factory.blank_state(addr=0x004011C3)
flag = claripy.BVS("flag", 8 * 32)
init_state.memory.store(0x0043841C, flag)
 
for char in flag.chop(bits=8):
    init_state.add_constraints(char > 32, char < 127)
 
step_length = 81
hook_address = 0x0043306F
 
@proj.hook(hook_address, length=step_length)          # 在对应地址设置钩子,length=参数是设置要跳过的字节数
def our_function(state):
    pass
 
simulation = proj.factory.simgr(init_state)     # veritesting=True
stop_address = 0x0043413E                       # 找到调用那个让路径爆炸的函数之前的地址 for循环比较
simulation.explore(find=stop_address)
if simulation.found:
    for x in simulation.found:
        solution_state = x
        constrained_bitvector = solution_state.memory.load(0x0043841C, 32)
        cmp_arr = [0x27, 0x3C, 0xE3, 0xFC, 0x2E, 0x41, 0x7, 0x5E, 0x62, 0xCF, 0xE8, 0xF2, 0x92, 0x80, 0xE2, 0x36, 0xB4, 0xB2, 0x67, 0x77, 0xF, 0xF6, 0xD, 0xB6, 0xED, 0x1C, 0x65, 0x8A, 0x7, 0x53, 0xA6, 0x66]
        index = 0
        for char in constrained_bitvector.chop(bits=8):
            solution_state.solver.add(constrained_bitvector == cmp_arr[index])
            index += 1
        user_input_string = solution_state.solver.eval(constrained_bitvector, cast_to=bytes).decode('utf-8')
        print("flag{}".format(user_input_string))
else:
    raise Exception('Could not find the solution')

二:勒索解密

先根据题意在C盘下创建一个XX_TEST_XX文件夹,里面创建一个文件叫a.bmp,至于内容随便填写

 

直接开始调试

 

main函数前面先获取了a.bmp的路径名,然后创建了一个后缀ctf_crypter的路径名

 

图片描述
然后下方,将a.bmp的路径填写到phProv[3]地址开始处,将变换后的路径放到phProv[11]地址处

 

图片描述
然后就进入关键加密函数:

 

图片描述

 

里面前两个函数先对key进行变化:

 

图片描述

 

变化后赋值到v9,然后用v9和_time64(0)给pdata赋值

 

图片描述
图片描述

 

这里就是一些<wincrypt.h>头文件包含的库函数了

 

0x800C代表sha-256

 

0x660E代表AES-128

 

上面创建hash算法sha-256,将key添加到了散列对象

 

并创建AES-128的密钥

 

下面生成RSA的公钥

 

图片描述

 

然后就是RSA加密函数:

 

图片描述

 

将key进行了RSA加密

 

然后继续

 

图片描述

 

下面进入将文件内容进行AES加密的函数

 

图片描述

 

里面先判断文件内容的长度(16分隔),然后CryptEncrypt用AES加密文件内容

 

图片描述

 

最后的sub_EF1400函数中,就是排列我们加密后的文件的输出格式

 

图片描述

 

图片描述

 

显然是先存放AES加密之后的文件内容,然后存放完了之后存放128字节的RSA(key)的内容,最后再存放0x80(RSA加密了key之后的长度)

 

解题思路:

 

这个time(0),可以将.ctf_crypter文件的修改时间转换为时间戳,可以得到key,也可采取爆破(爆破修改时间周围)

 

.bmp文件头的1-2字节:424dh = 'BM',表示这是Windows支持的位图格式。有很多声称开头两个字节必须为'BM'才是位图文件,从上表来看应为开头两个字节必须为'BM'才是Windows位图文件。

 

解密脚本:

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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#include <iostream>
#define  _CRT_SECURE_NO_WARNINGS
#include <Windows.h>
#include <stdio.h>
#include <wincrypt.h>                  //用的这个库里面的加解密函数
#pragma comment(lib, "Advapi32.lib")
#pragma comment(lib, "Crypt32.lib")
 
//const char* pubkey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCJ7DFnM7uJiQYyozOgYTJs6oT9nRadxeyYux9/q/+hRcdKolSwRio0TOmpvmNrRttsyOPx01V8Cami2KonF2xqEzAg0OcDh6K1gzzBLxqI6XBipi4gJ/24OaXYFFr7CHCxBXeQDVjbPa53Kn2bOwknMT6+MuzNMoN4bFMa/p7QJQIDAQAB";
//byte keyinfo[1000000] = { 0 };
//byte keyinfo2[1000000] = { 0 };
 
void hexDump(void* data_ptr, size_t size)         //16进制dump函数
{
    int i;
    size_t offset = 0;
    unsigned char* data = (unsigned char*)data_ptr;
    while (offset < size)
    {
        printf("%04x  ", offset);
        for (i = 0; i < 16; i++)
        {
            if (i % 8 == 0) putchar(' ');
            if (offset + i < size)
            {
                printf("%02x ", data[offset + i]);
            }
            else
            {
                printf("   ");
            }
        }
        printf("   ");
        for (i = 0; i < 16 && offset + i < size; i++)
        {
            if (isprint(data[offset + i]))
            {
                printf("%c", data[offset + i]);
            }
            else
            {
                putchar('.');
            }
        }
        putchar('\n');
        offset += 16;
    }
}
 
void decrypt_file(DWORD x)         //文件解密
{
    HCRYPTPROV  ctx;
    HCRYPTHASH  ctx_has;
    HCRYPTKEY  aeskey;
    DWORD v8 = 16;
    DWORD TestData[500] = {0x0EC62FB2, 0x4B54D44F, x, 0x8EB1E721};      //第三个数是time(0)
 
    FILE* fp = fopen("flag.bmp.ctf_crypter", "rb");
    size_t size = 0;
    fseek(fp, 0, SEEK_END);              //文件大小
    size = ftell(fp);
    fseek(fp, 0, SEEK_SET);             //重置文件指针到文件头
    size_t size2 = (size - 0x84) / 16//减去加密后的文件的后两部分
 
    char outname[256] = { 0 };
    sprintf(outname, "data%x.bmp", x);
    FILE* fp2 = fopen(outname, "wb");   //创建.bmp文件
 
    CryptAcquireContextA(&ctx, 0, "Microsoft Enhanced RSA and AES Cryptographic Provider", 0x18, 0xF0000000);
    CryptCreateHash(ctx, 0x800Cu, 0, 0, &ctx_has);
    CryptHashData(ctx_has, (const BYTE*)TestData, 16u, 0);
    CryptDeriveKey(ctx, 0x660Eu, ctx_has, 0, &aeskey);
    BYTE pbData[4] = { 1, 0, 0, 0 };
    BYTE v11[4] = { 1, 0, 0, 0 };
 
    CryptSetKeyParam(aeskey, 4u, pbData, 0);
    CryptSetKeyParam(aeskey, 3u, v11, 0);
    DWORD encLen = 16;
 
    for (int i = 0; i < size2; i++)        //16字节16字节的对文件进行解密
    {
        char buffer[32] = { 0 };
        fread(buffer, 16, 1, fp);
        CryptDecrypt(aeskey, 0, 0, 0, (BYTE*)buffer, &encLen);
        fwrite(buffer, 16, 1, fp2);
    }
 
    fclose(fp);
    fclose(fp2);
    CryptDestroyHash(ctx_has);
    CryptDestroyKey(aeskey);
    CryptReleaseContext(ctx, 0);
}
 
bool test(DWORD x)                  //测试随机数的test函数
{
    DWORD bsize;
    DWORD datalen;
    HCRYPTPROV  ctx;
    HCRYPTHASH  ctx_has;
    HCRYPTKEY  aeskey;
    DWORD v8 = 16;
    DWORD TestData[500] = {0x0EC62FB2, 0x4B54D44F, x, 0x8EB1E721};
    //flag文件加密后文件的前16字节
    unsigned char test[0x20] = {0xB2, 0x02, 0xF8, 0x09, 0x6A, 0x8B, 0x3F, 0x25, 0x94, 0xED, 0xE7, 0xB1, 0xC9, 0xFC, 0x3A, 0xA7};
 
    //char test2[0x20] = "0123456789ABCDEF";
   // char test3[0x20] = { 0xDA, 0x3A, 0xFB, 0x16, 0x3E, 0x14, 0x87, 0xDE, 0xA6, 0xE6, 0xBA, 0xC1, 0x6D, 0xCD, 0x22, 0x05 };
    CryptAcquireContextA(&ctx, 0, "Microsoft Enhanced RSA and AES Cryptographic Provider", 0x18, 0xF0000000);
 
    CryptCreateHash(ctx, 0x800Cu, 0, 0, &ctx_has);
    CryptHashData(ctx_has, (const BYTE*)TestData, 16u, 0);
 
    CryptDeriveKey(ctx, 0x660Eu, ctx_has, 0, &aeskey);
    BYTE pbData[4] = { 1, 0, 0, 0 };
    BYTE v11[4] = { 1, 0, 0, 0 };
    CryptSetKeyParam(aeskey, 4u, pbData, 0);
    CryptSetKeyParam(aeskey, 3u, v11, 0);
    DWORD encLen = 16;
    //CryptEncrypt(aeskey, 0, 0, 0, (BYTE*)test, &encLen, 0x20u);
    //CryptEncrypt(aeskey, 0, 1, 0, (BYTE*)test2, &encLen, 0x20u);
 
    CryptDecrypt(aeskey, 0, 1, 0, (BYTE*)test, &encLen);
    if(test[0] == 0x42 && test[1] == 0x4d)   //.bmp文件头标志
    {
        hexDump(test, 16);
        decrypt_file(x);
        return true;
    }
    /*
    if(test[0] == 0x89 && test[1] == 0x50 && test[1] == 0x4e)
    {
        hexDump(test, 16);
        decrypt_file(x);
        return true;
    }
    if(test[0] == 0xFF && test[1] == 0xD8 && test[1] == 0xFF)
    {
        hexDump(test, 16);
        decrypt_file(x);
        return true;
    }
    */
    CryptDestroyHash(ctx_has);
    CryptDestroyKey(aeskey);
    CryptReleaseContext(ctx, 0);
 
    return false;
}
 
int main()
{
    /*
    test(0xaabbccdd);
    for (unsigned i = 0x61000000; i < 0x6120C4CD; i++)
    {
        if (test(i))
        {
            printf("%x\n", i);
        }
 
    }
    */
    DWORD time = 0x611a1105;
    decrypt_file(time);
    system("pause");
    return 0;
}

最后将解密后的.bmp图片文件打开得到flag:

 

图片描述

三:rua

findcrypt查找下特征值:

 

图片描述

 

https://www.cnblogs.com/init0ne/p/14772868.html

 

图片描述

 

它是流式对称加密算法

 

我们随便输入一个字符串,在sub_10000B37C函数中提取出加密后要与比较数据进行比较的数据

 

将其和我们的输入进行异或,即可得到最后用于和flag进行异或的字节流,将其和比较数据进行异或,即可得到flag
至于如何调试,别人mac上运行个dbgserver,填个ip和端口即可

四:InjectDriver.sys

图片描述

 

图片描述

 

先注册好

 

图片描述

 

图片描述

 

我还以为是一个简单的移动数据,就没进去看

 

猜测文件是和某数据进行异或

1
2
3
4
5
6
7
8
dll = [0x4D, 0x5A, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00]   # dll标准文件头
data = [0x93, 0xF7, 0x2E, 0xEF, 0xDD, 0xAD, 0xBE, 0xEF, 0xDA, 0xAD, 0xBE, 0xEF, 0x21, 0x52, 0xBE, 0xEF# 内存中的数据
for i in range(16):
    print(dll[i] ^ data[i], end=' ')
print("")
xor_data = [222, 173, 190, 239]
for x in xor_data:
    print(hex(x)[2:], end='')

图片描述

 

显然key就是:0xdeadbeff

 

后来点进去看见

 

图片描述

 

图片描述

 

接下来解密dll文件并提取出去:

1
2
3
4
5
6
7
# 将内存中的数据提取出进行解密
data = [0x93, 0xF7, 0x2E, 0xEF, 0xDD, 0xAD, 0xBE, 0xEF, 0xDA, 0xAD, 0xBE, 0xEF, 0x21, 0x52, 0xBE, 0xEF, 0x66, 0xAD, 。。。。。] 
xor_key = [222, 173, 190, 239]    # 0xdeadbeef
dll_content = []
for i in range(len(data)):
    dll_content.append(data[i] ^ xor_key[i % 4])
open("D:\\CTF\\COMPETITIONS\\2021xiangyunbei\\Rev_APC\\inject.dll", "wb").write(bytes(dll_content))

提取出来之后搜索下字符串,定位到关键函数sub_1800015C0

 

图片描述

 

调用DeviceIoControl和之前注册好的函数对应

 

图片描述

 

验证下hash函数:

1
2
3
import hashlib
print(hashlib.sha3_256(b"test").hexdigest().lower())
# 36f028580bb02cc8272a9a020f4200e346e276ae664e45ee80745574e2f5ab80

说明getcontenthash就是将这个字符串进行sha3_256

 

然后调试dll,先写个exe,loadlibrary调用这个dll,dll的ida中设置如下

 

图片描述

 

直接在dll中下好断点,就能断在dll中

 

先提取出init_key:

 

图片描述

 

解密脚本:

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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
#include <iostream>
#include <stdio.h>
#define u_char unsigned char
 
void enc_0(unsigned  char * a1, unsigned  char * a2) {
 
    for (int i = 0; i < 32; i ++ )
    {
        a1[i] += 16;
        a2[i] ^= a1[i];
    }
}
 
void enc_0_dec(unsigned  char * a1, unsigned  char * a2) {
 
    for (int i = 0; i < 32; i ++ )
    {
        a2[i] ^= a1[i];
    }
}
 
void enc_1(unsigned char * a1, unsigned char *a2) {
 
    for(int i = 0; i < 32; i++) {
        a1[i] = a1[i] - 80;
        a2[i] ^= (a1[i] << 4);
    }
}
 
void enc_1_dec(unsigned char * a1, unsigned char *a2) {
 
    for(int i = 0; i < 32; i++) {
        u_char  k = (a1[i] << 4) | (a1[i] >> 4);
        a2[i] ^= k;
    }
}
 
void enc_2(unsigned char * a1, unsigned char *a2) {
    for(int i = 0; i < 32; i++) {
        a2[i] ^= a1[i];
    }
}
 
void enc_2_dec(unsigned char * a1, unsigned char *a2) {
    for(int i = 0; i < 32; i++) {
        a2[i] ^= a1[i];
    }
}
 
void enc_3(unsigned char * a1, unsigned char *a2) {
    for(int i = 0 ; i < 32; i++) {
        a1[i] -= 80;
    }
    for (int i = 0; i < 16; ++i) {
        a2[i * 2 + 0] ^= a1[i * 2] << 4;
        a2[i * 2 + 1] ^= a1[i * 2] >> 4;
    }
}
void enc_3_dec(unsigned char * a1, unsigned char *a2) {
    for (int i = 0; i < 16; ++i) {
        a2[i * 2 + 0] ^= a1[i * 2] << 4;
        a2[i * 2 + 1] ^= a1[i * 2] >> 4;
    }
}
 
void enc_4(unsigned char * data1, unsigned char *data2) {
 
    for (int i = 0; i < 16; ++i) {
        u_char v11 = data1[i]; //v11 = *v9;
        data1[i] = data1[31 - i]; //*v9++ = *v10;
        data1[31 - i] = v11;
    }
 
    for(int i = 0; i < 16; i++) {
        u_char v15 = data1[i];
        data1[i] = data1[15 - i];
        data1[15 - i] = v15;
    }
 
    for(int i = 0; i < 16; i++) {             //三个for循环交换之后相当于没变
        u_char v19 = data1[16 + i];
        data1[16 + i] = data1[15 - i];
        data1[15 - i] = v19;
    }
 
    for (int i = 0; i < 32; ++i) {
        data2[i] ^= data1[i];
    }
}
 
void enc_4_dec(unsigned char * data1, unsigned char *data2) {
 
    for (int i = 0; i < 32; ++i) {
        data2[i] ^= data1[i];
    }
 
}
 
void enc_5(unsigned char * data1, unsigned char *data2) {
    for(int i = 0; i < 32; i++) {
        u_char v5 = data1[i];
        u_char v8;
        if ((unsigned char)(v5 - 33) > 0x2E) {
            if ((unsigned char)(v5 - 81) > 0x2e) {
                if(v5 > 128) {
                    v8 = v5 - 48;
                    data1[i] = v8;
                    data2[i] -= v8;
                }
 
            } else {
                v8 = v5 - 48;
                data1[i] = v8;
                data2[i] ^= (v8 >> 4);
            };
        } else {
            v8 = v5 - 80;
            data1[i] = v8;
            data2[i] += v8;
        }
    }
}
 
void enc_5_dec(unsigned char * data1, unsigned char *data2) { // 要上一层的key,以便进行if else判断
    for(int i = 0; i < 32; i++) {
        u_char v5 = data1[i];
        u_char v8;
        if ((unsigned char)(v5 - 33) > 0x2E) {
            if ((unsigned char)(v5 - 81) > 0x2e) {
                if(v5 > 128) {
                    v8 = v5 - 48;
                    data2[i] += v8;
                }
 
            } else {
                v8 = v5 - 48;
                data2[i] ^= (v8 >> 4);
            };
        } else {
            v8 = v5 - 80;
            data2[i] -= v8;
        }
    }
}
 
unsigned char target[32] = {
        0x57, 0xC5, 0x38, 0x1B, 0x3A, 0xA8, 0x34, 0x2F, 0x39, 0x97, 0xC6, 0xE4, 0x04, 0x2F, 0x8F, 0xEE,
        0x5E, 0x51, 0x80, 0x67, 0x24, 0xC9, 0x6F, 0x48, 0x5B, 0x7F, 0xBD, 0xC7, 0xB0, 0xC2, 0xC2, 0xEB
};
 
unsigned char initkey[32] = {
        0xA5, 0x6A, 0xA7, 0x71, 0xB4, 0x77, 0xC6, 0x03, 0xD1, 0x08, 0xDF, 0x18, 0xCE, 0x03, 0xD7, 0x0F,
        0xCC, 0x77, 0xBA, 0x62, 0xAE, 0x6D, 0xDD, 0x18, 0xC0, 0x09, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5
};
 
char seq[] = {5, 5, 4, 4, 5, 4,0,0,4,2,5,5,1,3,1,5,1,2,3,0,3,0,2,3,4,4,3,2,2,5,5,0};
unsigned char subkey[32][32] = {0};
unsigned char nulldata[32] = {0};
int main() {
    memcpy(subkey[0], initkey, 32);
    for(int i = 0; i < 32; i++) {
        switch (seq[i]) {
            case 0:
                enc_0(&subkey[i][0], nulldata);
                break;
            case 1:
                enc_1(&subkey[i][0], nulldata);
                break;
            case 2:
                enc_2(&subkey[i][0], nulldata);
                break;
            case 3:
                enc_3(&subkey[i][0], nulldata);
                break;
            case 4:
                enc_4(&subkey[i][0], nulldata);
                break;
            case 5:
                enc_5(&subkey[i][0], nulldata);
                break;
        }
        for(int j=0;j<32;j++)
        {
            printf("%x ",subkey[i][j]);
        }
        printf("\n");
        memcpy(subkey[i + 1], subkey[i], 32);
    }
 
    for(int i = 31; i >= 0; i--) {
 
        switch (seq[i]) {
            case 0:
                enc_0_dec(&subkey[i][0], target);
                break;
            case 1:
                enc_1_dec(&subkey[i][0], target);
                break;
            case 2:
                enc_2_dec(&subkey[i][0], target);
                break;
            case 3:
                enc_3_dec(&subkey[i][0], target);
                break;
            case 4:
                enc_4_dec(&subkey[i][0], target);
                break;
            case 5:
                unsigned char tmp[32];
                if(i != 0)
                    memcpy(tmp,&subkey[i - 1][0] , 32);
                else if(i == 0)
                    memcpy(tmp,initkey , 32);
                enc_5_dec(tmp, target);
                break;
        }
 
    }
    printf("%s", target);
    return 0;
}

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2021-8-24 09:57 被SYJ-Re编辑 ,原因:
收藏
免费 3
支持
分享
最新回复 (8)
雪    币: 1629
活跃值: (1246)
能力值: ( LV3,RANK:37 )
在线值:
发帖
回帖
粉丝
2
大佬,驱动那个题是在哪个系统下调试成功的,LibraryW = LoadLibraryW(L"DLLInjector.dll");这个DLL文件在哪里
2021-8-27 14:58
0
雪    币: 3660
活跃值: (9330)
能力值: ( LV9,RANK:319 )
在线值:
发帖
回帖
粉丝
3

InjectDLL这个dll就是sys注册加载成功之后会在C:\Windows\Temp目录下生成的,其实也可以看下它解密和生成这个文件的逻辑,自己把sys内存里存放的加密数据提出来解密然后重新写入到一个文件里,如果要加载sys,记得关闭系统签名, 我是用的win10,没调试sys,就加载了一下,写了个exe调用dll的来调试那个dll

2021-8-27 18:44
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
大佬,rua那题,在mac上跑不起来,显示bad CPU type in executable,请问有什么解决方法吗
2021-8-30 10:59
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
师傅,我想问一些问题,就是,为什么0x800C代表sha-256,0x660E代表AES-128,我没查到,然后rsa加密是怎么看出来在那个地方的,还有memmove_0这个地方有什么用,排列加密输出格式是怎么回事
2021-9-2 14:11
0
雪    币: 3660
活跃值: (9330)
能力值: ( LV9,RANK:319 )
在线值:
发帖
回帖
粉丝
6
你搜那几个函数,有 官方文档
2021-9-2 14:30
0
雪    币: 242
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
请教一下师傅.sys文件是用什么调试起来的?不知道怎么动态拿到最后一次LPC的数据...
2021-9-6 20:40
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
8
mb_rtshsaxv 请教一下师傅.sys文件是用什么调试起来的?不知道怎么动态拿到最后一次LPC的数据...
不用调试,直接用sys加载,记得开调试模式,然后就可以了,然后写个loader,用IDA调试就能提取了
2021-9-21 17:04
0
雪    币: 242
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
9
mb_jbrgvmfy 不用调试,直接用sys加载,记得开调试模式,然后就可以了,然后写个loader,用IDA调试就能提取了
感谢师傅!
2021-9-26 15:24
0
游客
登录 | 注册 方可回帖
返回
//