-
-
[原创]第八题 惊天阴谋 by k1ee
-
发表于: 2020-12-7 20:46 6208
-
去花,修复各种干扰后,取得程序逻辑如下
注册码分为两部分
魔改的AES,动调取得sbox,手算rsbox,解密。
每一位+0x7F得到第二位
调用API进行解密即可
六种运算的虚拟机,把所有指令打出来,然后分析可以看出有很多重复的部分,懒得写程序提炼,于是手动提炼了一部分,12万行缩小到1.2万行,编译爆破程序求解,16线程106分钟解得所有逆向关系
一个可逆算法,直接算出输入
最令人头痛的算法,我记录了所有和输入有关的运算,发现还是可逆的,也就三处需要记录
每一处输入输出关系也就65423个,因此爆破即可,从后往前还原数据
似乎是个矩阵,不过当时太累了,爆破也不是很难
此题应该多解,我没求出预期解
https://docs.microsoft.com/en-us/windows/win32/debug/pe-format
实际上是从KernelBase和advapi32里找函数
const char
*
username
=
"141E8F96636898EF"
;
const char
*
serial
=
"dd8c5dd5bff047cb86c51fc808254c0950ebd2d9c7e6b34679a6cda7f96ea0f46d105248c68b6534546d34c26534546d34c26534542538d289a28b2d14d06534546614d225146289a28b6614d249a7096d10522538d22538d289a28b48a21b2d14d041a69b2d14d06614d289a28b25146250a28948a21b48c68b48c68b49829948a21b6d105249a7092c345289a28b6534542c34522d14d050a2896d105225146289a28b6d105249a7092d14d049a7096d34c26d10522d14d049a70948a21b2d14d048c68b48a21b49a70925146248c68b41a69b08a69948c68b48c68b498299"
;
uint8_t username_md5[
16
]
=
{
0
};
md5((uint8_t
*
)username, strlen(username), username_md5);
uint8_t username_md5_1[
16
]
=
{
0
};
md5(username_md5,
8
, username_md5_1);
uint8_t username_md5_2[
16
]
=
{
0
};
md5(username_md5
+
8
,
8
, username_md5_2);
uint8_t serial_hex[
224
]
=
{
0
};
char
*
sp
=
(char
*
)serial;
for
(
int
i
=
0
; i <
224
;
+
+
i)
{
sscanf_s(sp,
"%2hhx"
, &serial_hex[i]);
sp
+
=
2
;
}
uint8_t
*
serial_1
=
serial_hex;
uint8_t
*
serial_2
=
serial_hex
+
32
;
uint8_t result1_1[
32
]
=
{
0
};
uint32_t
*
pi
=
(uint32_t
*
)serial_1;
uint32_t
*
po
=
(uint32_t
*
)result1_1;
for
(
int
i
=
0
; i <
8
;
+
+
i)
{
*
po
+
+
=
transform1_1(
*
pi
+
+
);
}
uint8_t result1_2[
32
]
=
{
0
};
memcpy(result1_2, result1_1,
32
);
HCRYPTPROV ctx;
CryptAcquireContextA(&ctx,
0
,
0
,
24
,
0xF0000000
);
HCRYPTHASH
hash
;
CryptCreateHash(ctx,
0x800C
,
0
,
0
, &
hash
);
unsigned char hashData[
20
]
=
{
0x31
,
0x5F
,
0x4C
,
0x30
,
0x56
,
0x33
,
0x5F
,
0x42
,
0x58
,
0x53
,
0x5F
,
0x46
,
0x30
,
0x52
,
0x45
,
0x56
,
0x45
,
0x52
,
0x21
,
0x00
};
CryptHashData(
hash
, hashData,
19
,
0
);
HCRYPTKEY key;
CryptDeriveKey(ctx,
0x6610
,
hash
,
0
, &key);
DWORD
len
=
32
;
CryptEncrypt(key,
0
,
0
,
0
, result1_2, &
len
,
32
);
uint8_t result1_2_trans[
16
]
=
{
0
};
for
(
int
i
=
0
; i <
16
;
+
+
i)
{
result1_2_trans[i]
=
result1_2[
2
*
i];
}
transform1_2(result1_2_trans);
/
/
Equals MD5 Part1
uint8_t result2_1[
32
]
=
{
0
};
transform2_1(serial_2, result2_1);
uint8_t result2_2[
16
]
=
{
0
};
transform2_2(result2_1, result2_2);
transform2_3(result2_2, username_md5_2);
const char
*
username
=
"141E8F96636898EF"
;
const char
*
serial
=
"dd8c5dd5bff047cb86c51fc808254c0950ebd2d9c7e6b34679a6cda7f96ea0f46d105248c68b6534546d34c26534546d34c26534542538d289a28b2d14d06534546614d225146289a28b6614d249a7096d10522538d22538d289a28b48a21b2d14d041a69b2d14d06614d289a28b25146250a28948a21b48c68b48c68b49829948a21b6d105249a7092c345289a28b6534542c34522d14d050a2896d105225146289a28b6d105249a7092d14d049a7096d34c26d10522d14d049a70948a21b2d14d048c68b48a21b49a70925146248c68b41a69b08a69948c68b48c68b498299"
;
uint8_t username_md5[
16
]
=
{
0
};
md5((uint8_t
*
)username, strlen(username), username_md5);
uint8_t username_md5_1[
16
]
=
{
0
};
md5(username_md5,
8
, username_md5_1);
uint8_t username_md5_2[
16
]
=
{
0
};
md5(username_md5
+
8
,
8
, username_md5_2);
uint8_t serial_hex[
224
]
=
{
0
};
char
*
sp
=
(char
*
)serial;
for
(
int
i
=
0
; i <
224
;
+
+
i)
{
sscanf_s(sp,
"%2hhx"
, &serial_hex[i]);
sp
+
=
2
;
}
uint8_t
*
serial_1
=
serial_hex;
uint8_t
*
serial_2
=
serial_hex
+
32
;
uint8_t result1_1[
32
]
=
{
0
};
uint32_t
*
pi
=
(uint32_t
*
)serial_1;
uint32_t
*
po
=
(uint32_t
*
)result1_1;
for
(
int
i
=
0
; i <
8
;
+
+
i)
{
*
po
+
+
=
transform1_1(
*
pi
+
+
);
}
uint8_t result1_2[
32
]
=
{
0
};
memcpy(result1_2, result1_1,
32
);
HCRYPTPROV ctx;
CryptAcquireContextA(&ctx,
0
,
0
,
24
,
0xF0000000
);
HCRYPTHASH
hash
;
CryptCreateHash(ctx,
0x800C
,
0
,
0
, &
hash
);
unsigned char hashData[
20
]
=
{
0x31
,
0x5F
,
0x4C
,
0x30
,
0x56
,
0x33
,
0x5F
,
0x42
,
0x58
,
0x53
,
0x5F
,
0x46
,
0x30
,
0x52
,
0x45
,
0x56
,
0x45
,
0x52
,
0x21
,
0x00
};
CryptHashData(
hash
, hashData,
19
,
0
);
HCRYPTKEY key;
CryptDeriveKey(ctx,
0x6610
,
hash
,
0
, &key);
DWORD
len
=
32
;
CryptEncrypt(key,
0
,
0
,
0
, result1_2, &
len
,
32
);
uint8_t result1_2_trans[
16
]
=
{
0
};
for
(
int
i
=
0
; i <
16
;
+
+
i)
{
result1_2_trans[i]
=
result1_2[
2
*
i];
}
transform1_2(result1_2_trans);
/
/
Equals MD5 Part1
uint8_t result2_1[
32
]
=
{
0
};
transform2_1(serial_2, result2_1);
uint8_t result2_2[
16
]
=
{
0
};
transform2_2(result2_1, result2_2);
transform2_3(result2_2, username_md5_2);
AES_ctx actx;
int
akey[
8
]
=
{
0
};
akey[
0
]
=
0x59206F57
;
akey[
1
]
=
0x59676E6F
;
akey[
2
]
=
0x206E6175
;
akey[
3
]
=
0x75486958
;
akey[
4
]
=
0x4B206E61
;
akey[
5
]
=
0x75586E61
;
akey[
6
]
=
0x754C206E
;
akey[
7
]
=
0x6E61546E
;
AES_init_ctx(&actx, (uint8_t
*
)akey);
AES_ECB_decrypt(&actx, username_md5_1);
AES_ctx actx;
int
akey[
8
]
=
{
0
};
akey[
0
]
=
0x59206F57
;
akey[
1
]
=
0x59676E6F
;
akey[
2
]
=
0x206E6175
;
akey[
3
]
=
0x75486958
;
akey[
4
]
=
0x4B206E61
;
akey[
5
]
=
0x75586E61
;
akey[
6
]
=
0x754C206E
;
akey[
7
]
=
0x6E61546E
;
AES_init_ctx(&actx, (uint8_t
*
)akey);
AES_ECB_decrypt(&actx, username_md5_1);
uint8_t part1_1[
32
]
=
{
0
};
for
(
int
i
=
0
; i <
16
;
+
+
i)
{
part1_1[i
*
2
]
=
username_md5_1[i];
part1_1[i
*
2
+
1
]
=
username_md5_1[i]
+
0x7F
;
}
uint8_t part1_1[
32
]
=
{
0
};
for
(
int
i
=
0
; i <
16
;
+
+
i)
{
part1_1[i
*
2
]
=
username_md5_1[i];
part1_1[i
*
2
+
1
]
=
username_md5_1[i]
+
0x7F
;
}
HCRYPTPROV ctx;
CryptAcquireContextA(&ctx,
0
,
0
,
24
,
0xF0000000
);
HCRYPTHASH
hash
;
CryptCreateHash(ctx,
0x800C
,
0
,
0
, &
hash
);
unsigned char hashData[
20
]
=
{
0x31
,
0x5F
,
0x4C
,
0x30
,
0x56
,
0x33
,
0x5F
,
0x42
,
0x58
,
0x53
,
0x5F
,
0x46
,
0x30
,
0x52
,
0x45
,
0x56
,
0x45
,
0x52
,
0x21
,
0x00
};
CryptHashData(
hash
, hashData,
19
,
0
);
HCRYPTKEY key;
CryptDeriveKey(ctx,
0x6610
,
hash
,
0
, &key);
DWORD
len
=
32
;
CryptDecrypt(key,
0
,
0
,
0
, part1_1, &
len
);
HCRYPTPROV ctx;
CryptAcquireContextA(&ctx,
0
,
0
,
24
,
0xF0000000
);
HCRYPTHASH
hash
;
CryptCreateHash(ctx,
0x800C
,
0
,
0
, &
hash
);
unsigned char hashData[
20
]
=
{
0x31
,
0x5F
,
0x4C
,
0x30
,
0x56
,
0x33
,
0x5F
,
0x42
,
0x58
,
0x53
,
0x5F
,
0x46
,
0x30
,
0x52
,
0x45
,
0x56
,
0x45
,
0x52
,
0x21
,
0x00
};
CryptHashData(
hash
, hashData,
19
,
0
);
HCRYPTKEY key;
CryptDeriveKey(ctx,
0x6610
,
hash
,
0
, &key);
DWORD
len
=
32
;
CryptDecrypt(key,
0
,
0
,
0
, part1_1, &
len
);
uint32_t
*
ansbuf
=
new uint32_t[
0x10000000
];
for
(
int
i
=
0
; i <
16
;
+
+
i)
{
uint32_t val
=
i
*
0x10000000
;
char filename[
128
]
=
{
0
};
sprintf_s(filename,
"E:/Ctf/KCTF2020Q4/KCTF-KeyME/Solver/Solver/Release/%08X_%08X.bin"
, val, val
+
0xFFFFFFF
);
FILE
*
fp;
fopen_s(&fp, filename,
"rb"
);
int
ret
=
fread(ansbuf,
4
,
0x10000000
, fp);
fclose(fp);
for
(
int
k
=
0
; k <
0x10000000
;
+
+
k)
{
uint32_t
input
=
val
+
+
;
uint32_t output
=
ansbuf[k];
for
(
int
t
=
0
; t <
8
;
+
+
t)
{
if
(pi[t]
=
=
output)
{
po[t]
=
input
;
/
/
pos[t].push_back(
input
);
}
}
}
}
delete[] ansbuf;
printf(
"Serial Part 1\n"
);
for
(
int
i
=
0
; i <
32
;
+
+
i)
{
printf(
"%02x"
, part1_2[i]);
}
uint32_t
*
ansbuf
=
new uint32_t[
0x10000000
];
for
(
int
i
=
0
; i <
16
;
+
+
i)
{
uint32_t val
=
i
*
0x10000000
;
char filename[
128
]
=
{
0
};
sprintf_s(filename,
"E:/Ctf/KCTF2020Q4/KCTF-KeyME/Solver/Solver/Release/%08X_%08X.bin"
, val, val
+
0xFFFFFFF
);
FILE
*
fp;
fopen_s(&fp, filename,
"rb"
);
int
ret
=
fread(ansbuf,
4
,
0x10000000
, fp);
fclose(fp);
for
(
int
k
=
0
; k <
0x10000000
;
+
+
k)
{
uint32_t
input
=
val
+
+
;
uint32_t output
=
ansbuf[k];
for
(
int
t
=
0
; t <
8
;
+
+
t)
{
if
(pi[t]
=
=
output)
{
po[t]
=
input
;
/
/
pos[t].push_back(
input
);
}
}
}
}
delete[] ansbuf;
printf(
"Serial Part 1\n"
);
for
(
int
i
=
0
; i <
32
;
+
+
i)
{
printf(
"%02x"
, part1_2[i]);
}
83bde72e2806ce3c8f424e242559a66314bb37008d62a69bfd1a960f8e4102c8
83bde72e2806ce3c8f424e242559a66314bb37008d62a69bfd1a960f8e4102c8
int
buf1[
8
]
=
{
0x18111C1A
,
0x1190C08
,
0x10070B20
,
0x151D0217
,
0x12161B14
,
0xA1E05
,
0xD130309
,
0x1F0E0604
};
int
buf2[
8
]
=
{
0x14161715
,
0x12040C13
,
0xE100603
,
0xF1C180A
,
0x50B001F
,
0x200D1A08
,
0x9111D1E
,
0x1B010219
};
int
buf3[
8
]
=
{
0x11ECEE03
,
0xC050E14
,
0x5F7ED03
,
0xE700F600
,
0xBEFE800
,
0xFF0403F5
,
0xF4061600
,
0xF90918EF
};
uint8_t
*
p1
=
(uint8_t
*
)buf1;
uint8_t
*
p2
=
(uint8_t
*
)buf2;
uint8_t
*
p3
=
(uint8_t
*
)buf3;
uint8_t target_m[
16
]
=
{
0x15
,
0x09
,
0x0c
,
0x1f
,
0x1c
,
0x13
,
0x16
,
0x19
,
0x1d
,
0x03
,
0x10
,
0x0f
,
0x01
,
0x02
,
0x1e
,
0x06
};
for
(
int
i
=
0
; i <
16
;
+
+
i)
{
uint8_t mid
=
target_m[i]
-
p3[i]
+
md5c[i];
cal[i]
=
__ROL__(mid, p1[i] &
7
) ^ p2[i];
}
int
buf1[
8
]
=
{
0x18111C1A
,
0x1190C08
,
0x10070B20
,
0x151D0217
,
0x12161B14
,
0xA1E05
,
0xD130309
,
0x1F0E0604
};
int
buf2[
8
]
=
{
0x14161715
,
0x12040C13
,
0xE100603
,
0xF1C180A
,
0x50B001F
,
0x200D1A08
,
0x9111D1E
,
0x1B010219
};
int
buf3[
8
]
=
{
0x11ECEE03
,
0xC050E14
,
0x5F7ED03
,
0xE700F600
,
0xBEFE800
,
0xFF0403F5
,
0xF4061600
,
0xF90918EF
};
uint8_t
*
p1
=
(uint8_t
*
)buf1;
uint8_t
*
p2
=
(uint8_t
*
)buf2;
uint8_t
*
p3
=
(uint8_t
*
)buf3;
uint8_t target_m[
16
]
=
{
0x15
,
0x09
,
0x0c
,
0x1f
,
0x1c
,
0x13
,
0x16
,
0x19
,
0x1d
,
0x03
,
0x10
,
0x0f
,
0x01
,
0x02
,
0x1e
,
0x06
};
for
(
int
i
=
0
; i <
16
;
+
+
i)
{
uint8_t mid
=
target_m[i]
-
p3[i]
+
md5c[i];
cal[i]
=
__ROL__(mid, p1[i] &
7
) ^ p2[i];
}
uint16_t r2_r1(uint64_t res, uint64_t v3, uint64_t v2)
{
std::vector<
int
> ret;
for
(
int
i
=
65422
; i >
=
0
;
-
-
i)
{
if
(res
=
=
(i
*
(v3
*
v3
%
65423
*
v2
%
65423
)
%
65423
))
{
ret.push_back(i);
}
}
if
(ret.size() !
=
1
)
{
_CrtDbgBreak();
}
return
ret[
0
];
}
uint16_t r2_r2(uint64_t res, uint64_t val, uint64_t bp)
{
std::vector<
int
> ret;
for
(
int
i
=
65422
; i >
=
0
;
-
-
i)
{
uint64_t r
=
((int64_t)(i
-
val
*
bp)
%
65423
+
65423
)
%
65423
;
if
(res
=
=
r)
{
ret.push_back(i);
}
}
if
(ret.size() !
=
1
)
{
_CrtDbgBreak();
}
return
ret[
0
];
}
uint16_t r2_r3(uint64_t res, uint64_t v1, uint64_t v2, uint64_t v3)
{
std::vector<
int
> ret;
for
(
int
i
=
65422
; i >
=
0
;
-
-
i)
{
uint64_t r
=
((int64_t)(i
*
v1
-
v2
*
v3)
%
65423
+
65423
)
%
65423
;
if
(res
=
=
r)
{
ret.push_back(i);
}
}
if
(ret.size() !
=
1
)
{
_CrtDbgBreak();
}
return
ret[
0
];
}
struct re2_op
{
int
bufptr_res;
int
bufptr_another;
uint64_t mul_val1;
uint64_t min_val3;
};
void reverse2_2(uint16_t
*
input
, uint8_t
*
output)
{
uint8_t buf1[
0x370
*
16
]
=
{
0
};
int64_t
*
b1ptr1
=
(int64_t
*
)buf1;
int32_t
*
t1ptr
=
(int32_t
*
)table_trans2;
for
(
int
i
=
0
; i <
16
;
+
+
i)
{
int64_t val1
=
*
t1ptr
+
+
;
for
(
int
k
=
15
; k >
=
0
;
-
-
k)
{
int64_t val2
=
0
;
if
(k >
0
)
{
int64_t val3
=
transform2_calc1(val1, k >>
1
);
val2
=
val3
*
val3
%
65423
;
if
(k &
1
)
val2
=
val2
*
val1
%
65423
;
}
else
{
val2
=
1
;
}
*
b1ptr1
+
+
=
val2;
}
b1ptr1
=
(int64_t
*
)(buf1
+
0x370
*
(i
+
1
));
}
for
(
int
i
=
0
; i <
16
;
+
+
i)
{
uint64_t
*
b1ptr2
=
(uint64_t
*
)(buf1
+
0x80
+
i
*
0x370
);
*
b1ptr2
=
0xDEAD
;
}
std::vector<re2_op> ops;
uint64_t
*
b1ptr3
=
(uint64_t
*
)buf1;
for
(
int
i
=
1
; i <
=
15
;
+
+
i)
{
uint64_t
*
b1ptr7
=
(uint64_t
*
)(buf1
+
0x370
*
i
+
8
*
(i
-
1
));
for
(
int
a1
=
16
-
i; a1 >
=
1
;
-
-
a1)
{
uint64_t val3
=
*
b1ptr7;
uint64_t
*
b1ptr8
=
b1ptr3;
uint64_t
*
b1ptr9
=
b1ptr7;
for
(
int
a2
=
18
-
i; a2 >
=
1
;
-
-
a2)
{
uintptr_t diff3
=
((uintptr_t)b1ptr3
-
(uintptr_t)buf1);
uintptr_t diff7
=
((uintptr_t)b1ptr7
-
(uintptr_t)buf1);
uintptr_t diff8
=
((uintptr_t)b1ptr8
-
(uintptr_t)buf1);
uintptr_t diff9
=
((uintptr_t)b1ptr9
-
(uintptr_t)buf1);
if
(diff9
%
0x370
=
=
0x80
)
{
re2_op op;
op.bufptr_res
=
diff9
/
0x370
;
op.bufptr_another
=
diff8
/
0x370
;
op.mul_val1
=
*
b1ptr3;
op.min_val3
=
val3;
ops.push_back(op);
}
*
b1ptr9
+
+
=
((int64_t)(
*
b1ptr9
*
*
b1ptr3
-
val3
*
*
b1ptr8
+
+
)
%
65423
+
65423
)
%
65423
;
}
b1ptr7
+
=
110
;
}
b1ptr3
+
=
111
;
}
uint16_t
*
op
=
(uint16_t
*
)output;
uint64_t bufrec_1[
16
]
=
{
0
};
int64_t
*
b1p2
=
(int64_t
*
)buf1;
for
(
int
k
=
0
; k <
16
;
+
+
k)
{
int64_t v2
=
*
b1p2;
int64_t v3
=
transform2_calc1(
*
b1p2,
0x7FC6
);
uint16_t ret
=
r2_r1(
input
[k], v3, v2);
for
(
int
t
=
15
; t > k;
-
-
t)
{
ret
=
r2_r2(ret,
input
[t],
*
(uint64_t
*
)(buf1
+
k
*
0x370
+
t
*
8
));
}
bufrec_1[k]
=
ret;
b1p2
+
=
111
;
}
for
(
int
i
=
ops.size()
-
1
; i >
=
0
;
-
-
i)
{
re2_op op
=
ops[i];
bufrec_1[op.bufptr_res]
=
r2_r3(bufrec_1[op.bufptr_res], op.mul_val1, op.min_val3, bufrec_1[op.bufptr_another]);
}
for
(
int
i
=
0
; i <
16
;
+
+
i)
{
op[i]
=
bufrec_1[i];
}
}
uint16_t r2_r1(uint64_t res, uint64_t v3, uint64_t v2)
{
std::vector<
int
> ret;
for
(
int
i
=
65422
; i >
=
0
;
-
-
i)
{
if
(res
=
=
(i
*
(v3
*
v3
%
65423
*
v2
%
65423
)
%
65423
))
{
ret.push_back(i);
}
}
if
(ret.size() !
=
1
)
{
_CrtDbgBreak();
}
return
ret[
0
];
}
uint16_t r2_r2(uint64_t res, uint64_t val, uint64_t bp)
{
std::vector<
int
> ret;
for
(
int
i
=
65422
; i >
=
0
;
-
-
i)
{
uint64_t r
=
((int64_t)(i
-
val
*
bp)
%
65423
+
65423
)
%
65423
;
if
(res
=
=
r)
{
ret.push_back(i);
}
}
if
(ret.size() !
=
1
)
{
_CrtDbgBreak();
}
return
ret[
0
];
}
uint16_t r2_r3(uint64_t res, uint64_t v1, uint64_t v2, uint64_t v3)
{
std::vector<
int
> ret;
for
(
int
i
=
65422
; i >
=
0
;
-
-
i)
{
uint64_t r
=
((int64_t)(i
*
v1
-
v2
*
v3)
%
65423
+
65423
)
%
65423
;
if
(res
=
=
r)
{
ret.push_back(i);
}
}
if
(ret.size() !
=
1
)
{
_CrtDbgBreak();
}
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
看原图
赞赏
雪币:
留言: