2024 强网拟态Re(全解)
serv1ce
#include<stdio.h>
int main()
{
char enc[] = { 0xB9, 0x32, 0xC2, 0xD4, 0x69, 0xD5, 0xCA, 0xFB, 0xF8, 0xFB,
0x80, 0x7C, 0xD4, 0xE5, 0x93, 0xD5, 0x1C, 0x8B, 0xF8, 0xDF,
0xDA, 0xA1, 0x11, 0xF8, 0xA1, 0x93, 0x93, 0xC2, 0x7C, 0x8B,
0x1C, 0x66, 0x01, 0x3D, 0xA3, 0x67 };
//bArr[i3] = (byte)(((str.charAt(i3 % str.length()) - 'w') ^ 23) & 255);
char key_arry[64] = {0};
char key[] = "1liIl11lIllIIl11llII";
for (int i = 0; i < 64; i++) {
key_arry[i] = ((key[i % 20] - 'w') ^ 23) % 256;
}
int num = 11;
char flag[36] = {0};
for (int i = 0; i < 36; i++) {
for (int j = 0; j < '}'; j++) {
if ((char)(num * (j ^ key_arry[i])) == enc[i]) {
flag[i] = j;
}
}
}
printf("%s", flag);
}
easyre
Tracecode,比较长度0x38
两处数据获取
输入测试数据 'A' * 0x38 密文如下
8字节相同,说明加密时8字节一组
先猜一个TEA算法,trace里搜 9E3779B9
执行次数 714 次,714 / 7 = 102,每组执行了102轮
搜到指令 shr r8d,B ,对应XTEA算法中的 (sum>>11),找到KEY读取的代码
0xEF6FD9DB, 0xD2C273D3, 0x6F97E412, 0x72BFD624
测试发现输入前对密文 xor 0xBF
#include <stdio.h>
#include <stdint.h>
/* take 64 bits of data in v[0] and v[1] and 128 bits of key[0] - key[3] */
void encipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {
unsigned int i;
uint32_t v0=v[0], v1=v[1], sum=0, delta=0x9E3779B9;
for (i=0; i < num_rounds; i++) {
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
sum += delta;
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]);
}
v[0]=v0; v[1]=v1;
}
void decipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {
unsigned int i;
uint32_t v0=v[0], v1=v[1], delta=0x9E3779B9, sum=delta*num_rounds;
for (i=0; i < num_rounds; i++) {
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]);
sum -= delta;
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
}
v[0]=v0; v[1]=v1;
}
int main()
{
uint32_t v[]={0x9851E3A1, 0x49765686, 0x812B6B6F, 0x9612CECF, 0x3C3570A2, 0xF15C6231, 0xAA6B77FA, 0xBE056D9E,
0xF8A424E8, 0x0B3A23DB, 0x03CC2016, 0xA92BB5AD, 0x1D789F34, 0x9EF9B92E,0};
uint32_t const k[4]={0xEF6FD9DB, 0xD2C273D3, 0x6F97E412, 0x72BFD624};
unsigned int r=102;//num_rounds建议取值为32
// v为要加密的数据是两个32位无符号整数
// k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位
for(int i = 0; i< 7;i++){
decipher(r, (v + i * 2), k);
}
for(int i = 0;i<14;i++){
v[i] ^= 0xbfbfbfbf;
}
for(int i = 0;i< 0x38 ;i++){
printf("%.2x ", *((char* )(v)+i) & 0xff);
}
printf("\n");
printf("%s\n",v);
return 0;
}
66 6c 61 67 7b 75 5f 61 72 b3 5f 72 65 40 b1 b1 79 5f 67 b0 b0 64 5f 40 74 5f b0 b1 b1 76 6d 5f 64 65 b0 62 66 5f 61 6e 64 5f 61 6e 74 69 5f 64 65 62 75 67 67 65 72 7d
发现仍有乱码,bx,这些转成数字 3x
A_game
有个调试器检测,判断其不是被powershell或者正常打开的就会退出,这里patch了
首先通过读写文件的api定位到关键函数,其中该函数会在退出游戏时调用。
把game.tmp解密产生了game.ps1
ps1是个混淆的powershell脚本,每段脚本最前面是个iex 执行,去掉后运行一下,可直接解密出下一段脚本,
继续运行,得到真正的加密脚本。
对照其加密逻辑解密即可
enc = [38304, 8928, 43673, 25957, 67260, 47152, 16656, 62832,
19480, 66690, 40432, 15072, 63427, 28558, 54606,
47712, 18240, 68187, 18256, 63954, 48384, 14784,
60690, 21724, 53238, 64176, 9888, 54859, 23050,
58368, 46032, 15648, 64260, 17899, 52782, 51968,
12336, 69377, 27844, 43206, 63616]
key2 = [0x70, 0x30, 0x77, 0x65, 0x72]
for i in range(len(enc)):
enc[i] -= key2[i % len(key2)]
for i in range(len(enc)):
enc[i] -= key2[i % len(key2)]
key3 = [0x70, 0x30, 0x77, 0x33, 0x72]
for i in range(len(enc)):
enc[i] = int(enc[i] / key3[i % len(key3)])
for i in range(len(enc)):
enc[i] -= key2[i % len(key2)]
for i in range(len(enc)):
enc[i] -= key2[i % len(key2)]
for i in range(len(enc)):
enc[i] -= key2[i % len(key2)]
def rc4(key, plaintext):
S = list(range(256))
j = 0
for i in range(256):
j = (j + S[i] + key[i % len(key)]) % 256
S[i], S[j] = S[j], S[i]
i = 0
j = 0
ciphertext = []
for k in range(len(plaintext)):
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
t = (S[i] + S[j]) % 256
ciphertext.append(plaintext[k] ^ S[t])
return ciphertext
def enenenenene1_decrypt(encrypted_data):
key = [0x70, 0x6f, 0x77, 0x65, 0x72]
plaintext = ""
for _ in range(36):
current_encrypted_text = encrypted_data[:-len(key)]
current_key = rc4(current_encrypted_text,encrypted_data[-len(key):])
current_encrypted_text = rc4(current_key, current_encrypted_text)
plaintext = current_encrypted_text
return plaintext
decrypted_plaintext = enenenenene1_decrypt(enc)
for c in decrypted_plaintext:
print(chr(c),end="")
babyre
标准AES,KEY 35 77 40 2E CC A4 4A 3F 9A B7 21 82 F9 B0 1F 35
不过这里是无填充的
后面是转成二进制然后求z3
z3转太麻烦了,不如直接爆破
#include <stdio.h>
int check(int a1[])
{
int v1; // r8d
int v2; // ecx
int v3; // ecx
int ANS[12]; // [rsp+8h] [rbp-38h]
int i; // [rsp+38h] [rbp-8h]
unsigned int v7; // [rsp+3Ch] [rbp-4h]
v7 = 1;
for (int i = 0; i < 12; i++)
{
ANS[i] = a1[11 - i];
}
v1 = ANS[2] & ANS[3] & ANS[4] & (ANS[6] == 0) & (ANS[7] == 0) & ANS[8] & ((ANS[9] | ANS[10] | ANS[11]) == 0) & (ANS[5] == 0) & (ANS[1] == 0) | ANS[2] & ANS[4] & ANS[6] & (ANS[8] == 0) & (ANS[9] == 0) & ANS[11] & (ANS[10] == 0) & (ANS[7] == 0) & (ANS[5] == 0) & (ANS[3] == 0) & (ANS[1] == 0) | ANS[1] & (ANS[3] == 0) & (ANS[4] == 0) & (ANS[5] == 0) & ANS[6] & ANS[7] & (unsigned int)(ANS[9] & ANS[10] & (ANS[11])) & (ANS[8] == 0) & (ANS[2] == 0);
v2 = ANS[0] & ANS[1] & ANS[3] & ANS[4] & ANS[5] & ANS[6] & ANS[7] & (ANS[9] == 0) & (unsigned int)(ANS[10] & (ANS[11])) & (ANS[8] == 0) & (ANS[2] == 0) | (ANS[1] == 0) & (ANS[2] == 0) & ANS[3] & ANS[4] & ANS[5] & ANS[7] & ANS[8] & ANS[10] & (ANS[11] == 0) & (ANS[9] == 0) & (ANS[6] == 0) & (ANS[0] == 0) | ANS[0] & (ANS[2] == 0) & ANS[3] & ANS[5] & ANS[7] & ANS[8] & ANS[9] & ANS[11] & (ANS[10] == 0) & (ANS[6] == 0) & (ANS[4] == 0) & (ANS[1] == 0) | ANS[0] & ANS[2] & ANS[3] & ANS[5] & ANS[6] & ANS[8] & ANS[9] & (ANS[10] == 0 & ANS[11] == 0) & (ANS[7] == 0) & (ANS[4] == 0) & (ANS[1] == 0) | (v1 | ANS[1] & ANS[2] & (ANS[4] == 0) & ANS[5] & (ANS[7] == 0) & ANS[8] & ANS[9] & ANS[11] & (ANS[10] == 0) & (ANS[6] == 0) & (ANS[3] == 0)) & (ANS[0] == 0);
v3 = ANS[0] & ANS[1] & (ANS[3] == 0) & (ANS[4] == 0) & ANS[5] & (ANS[7] == 0) & (ANS[8] == 0) & (ANS[9] == 0) & (unsigned int)(ANS[10] & (ANS[11])) & (ANS[6] == 0) & (ANS[2] == 0) | (ANS[1] == 0) & (ANS[2] == 0) & (ANS[3] == 0) & (ANS[4] == 0) & ANS[5] & (ANS[7] == 0) & ANS[8] & ((ANS[9] | ANS[10] | ANS[11]) == 0) & (ANS[6] == 0) & (ANS[0] == 0) | ANS[0] & ANS[1] & ANS[2] & (ANS[4] == 0) & (ANS[5] == 0) & ANS[6] & ANS[7] & (ANS[9] == 0) & ANS[10] & (ANS[11] == 0) & (ANS[8] == 0) & (ANS[3] == 0) | ANS[0] & ANS[2] & (ANS[4] == 0) & (ANS[5] == 0) & ANS[6] & ((ANS[7] | ANS[8] | ANS[9] | ANS[10] | ANS[11]) == 0) & (ANS[3] == 0) & (ANS[1] == 0) | ANS[0] & (ANS[2] == 0) & (ANS[3] == 0) & ANS[4] & ANS[5] & ANS[6] & ANS[7] & (ANS[9] == 0) & ANS[11] & (ANS[10] == 0) & (ANS[8] == 0) & (ANS[1] == 0) | v2;
if (!(ANS[1] & ANS[3] & ANS[5] & ANS[7] & (ANS[9] == 0) & ANS[10] & (ANS[11] == 0) & (ANS[8] == 0) & (ANS[6] == 0) & (ANS[4] == 0) & (ANS[2] == 0) & (ANS[0] == 0) | ANS[0] & ANS[1] & ANS[2] & ANS[3] & (ANS[5] == 0) & (ANS[6] == 0) & ANS[7] & (ANS[9] == 0) & ANS[10] & (ANS[11] == 0) & (ANS[8] == 0) & (ANS[4] == 0) | v3 | ANS[1] & ANS[2] & ANS[3] & ANS[5] & ANS[7] & ((ANS[8] | ANS[9] | ANS[10] | ANS[11]) == 0) & (ANS[6] == 0) & (ANS[4] == 0) & (ANS[0] == 0)))
v7 = 0;
return v7;
}
int main()
{
int ANS[12];
for (int i = 0; i < 16; i++)
{
ANS[8] = i & 0x8 ? 1 : 0;
ANS[9] = i & 0x4 ? 1 : 0;
ANS[10] = i & 0x2 ? 1 : 0;
ANS[11] = i & 0x1 ? 1 : 0;
for (int x = 0; x < 256; x++)
{
for (int j = 0; j < 8; j++)
{
ANS[j] = (x >> (7 - j) & 1) ? 1 : 0;
}
// Check
// for (int q = 0; q < 12; q++)
// {
// printf("%d", ANS[q]);
// }
// printf("\n");
if (check(ANS))
{
printf("%.2x\n", x);
}
}
}
return 0;
}
得到AES后的密文 128fecc28504b24c5bba4acf11360a48
应输入 4d87ef03-77bb-491a-80f5-4620245807c4
0 条评论
可输入 255 字