2023CISCN华中赛区re
2023CISCN华中赛区re
当时出的题
misc3-babyandroid
找so文件,加密过程也不复杂
每三个一组进行加密
这里就是先每个减去65
然后
大概是
y1=(31x1)%26+65
y2=(31x1+39x2)%26+65
y3=(31x1+39x2+52x3)+65
y1,y2,y3为密文存储
我一开始想法是爆出来,没想到组合很多。
但是x1是可以确定的
key=[6, 24, 1, 13, 16, 10, 20, 17, 15]
enc=[0x42, 0x55, 0x5A, 0x53, 0x58, 0x52, 0x4D, 0x4E, 0x41, 0x49, 0x4A, 0x4B, 0x4E, 0x48, 0x49, 0x57, 0x41, 0x59, 0x52, 0x5A, 0x4E, 0x58, 0x43, 0x41, 0x4C, 0x57, 0x58, 0x48, 0x46, 0x4D, 0x4D, 0x4E, 0x4F]
from gmpy2 import*
flag_head=''
for i in range(0,len(enc),3):
x1=((enc[i]-65)*invert(31,26))%26+65
flag_head+=chr(x1)
print(flag_head)#VOSMNUTPXRS
这里发现flag的3个一组为加密的第一个字符全是大写字母
所以推测flag全是大写字母
#include<stdio.h>
unsigned int key[9] = {
0x00000006, 0x00000018, 0x00000001, 0x0000000D, 0x00000010, 0x0000000A, 0x00000014, 0x00000011,
0x0000000F
};
char enc[] = "BUZSXRMNAIJKNHIWAYRZNXCALWXHFMMNO";
int __fastcall hill_encrypt(char* a1,int x)
{
bool v2; // [rsp+7h] [rbp-49h]
int m; // [rsp+8h] [rbp-48h]
int v4; // [rsp+Ch] [rbp-44h]
int k; // [rsp+10h] [rbp-40h]
int j; // [rsp+14h] [rbp-3Ch]
int i; // [rsp+18h] [rbp-38h]
int v8; // [rsp+1Ch] [rbp-34h]
unsigned __int64 v10; // [rsp+48h] [rbp-8h]
int s[3] = {0}; // [rsp+3Ch] [rbp-14h] BYREF
for (j = 0;j<3 ; ++j)
{
s[j] = a1[j] - 65;
}
for (k = 0; k < 3; ++k)
{
v4 = 0;
for (m = 0; m < 3; ++m)
v4 += s[m] * key[3 * k + m];
a1[k] = v4 % 26 + 65;
}
if( (a1[0] == enc[x]) && (a1[1] == enc[x+1])&& (a1[2] == enc[x+2]))
{
return 1;
}
return 0;
}
int main()
{
int i, j, kl, l;
for (int x = 0; x < 33; x += 3)
{
int flag = 0;
for (int i = 65; i <=65+26; i++)
{
for (int j = 65; j < 65 + 26-1; j++)
{
for (int k = 65; k < 65 + 26-1; k++)
{
char temp[3];
temp[0] = i;
temp[1] = j;
temp[2] = k;
if (hill_encrypt(temp, x))
{
printf("%c%c%c",i, j, k);
flag = 1;
}
if (flag)
{
break;
}
}
if (flag)
{
break;
}
}
if (flag)
{
break;
}
}
}
}
这里flag第一位和上面对不上不知道为啥,纯misc脑洞题
这个flag是对的
ravic
上来就混淆,我原本准备的去混淆脚本,但是电脑前端时间换了环境,python库没安装,寄掉了,还好d810救了一命
这里使用ollvm
这里去得比较清楚,这里盲猜base64
没想到直接对了,拿了波一血。
同样去混淆,d810去混淆时间要好久
复盘
fishman
拿到题看到混淆,去混淆脚本直接寄了,报错没办法解决。
主要是去混淆输入的地址感觉是错的。
还是用d810
但是d810没改汇编,我copy下来自己跑下
显然我们可以简化一下
#include<stdio.h>
#include"defs.h"
int unk_3D030 = 0;
int main()
{
int v3; // [rsp+BCh] [rbp-10E4h]
__int64 s2[4]; // [rsp+D0h] [rbp-10D0h] BYREF
char s[32]; // [rsp+F0h] [rbp-10B0h] BYREF
char v6[24]; // [rsp+110h] [rbp-1090h] BYREF
char v7[4168]; // [rsp+128h] [rbp-1078h] BYREF
unsigned __int64 v8; // [rsp+1170h] [rbp-30h]
strcpy(v6, "i_am_a_fish_man");
memset(s, 0, sizeof(s));
s2[0] = 0xBCB6C065E9B49472LL;
s2[1] = 0xDBD7F8723B1F9F9CLL;
s2[2] = 0x925740C949C6E3CDLL;
s2[3] = 0x6B18711A0CF70D06LL;
puts("Pls input flag");
//read(0, s, 0x20uLL);
scanf("%s", s);
v3 = 0;
memcpy(v7, "fishrman", 8LL);
while (v3 < 4)
{
//sub_167F0(v7, &s[8 * v3], &s[8 * v3 + 4]);
++v3;
}
//sub_30990(s, 32LL, v6, 15LL);
if (!memcmp(s, s2, 0x20uLL))
{
puts("you get the flag");
_exit(0);
}
puts("flag is error");
_exit(0);
}
接下来就是继续优化sub_167F0和sub_30990了
这里使用对应的优化后copy到vs里面,速度很慢,这里不在赘述
这里也不知道着加密算法
最后用插件找到了
接着把d810优化过的函数,放到vs里面,利用编译器优化。
直接copy进去,不透明谓词一般是全局变量,我们置为0
不过我们为了消除它的影响,设置为局部变量为0,同时开启release
这样经过vs编译出来的,我们可以看个大概了
下面的函数
还原地有问题,但可以分辨出这是RC4初始化盒子的地方,但是对密文操作没有了,不知道为啥优化没了
这里找到初始的函数猜了一波
void __stdcall init_sbox(_BYTE *s_box, int a2, _BYTE *key, int a4, unsigned __int64 a5)
{
int v5; // esi
int i; // ebx
int j; // eax
unsigned __int8 v8; // bl
char v9[256]; // [esp+14h] [ebp-104h] BYREF
v5 = 0;
memset(v9, 0, sizeof(v9));
for ( i = 0; i < 256; ++i )
{
s_box[i] = i;
v9[i] = key[i % a5];
}
for ( j = 0; j < 256; ++j )
{
v8 = s_box[j];
v5 = (v8 + v9[j] + v5) % 256;
s_box[j] = s_box[v5];
s_box[v5] = v8;
}
}
init_sbox(...)
j=0
index=0
for(int i=0;i<32;i++)
{
j+=1;
j%=256;
index=(index+s_box[j])%256
swap(&s_box[j],&s_box[index]);
index2=(s_box[index]+s_box[j])%256
//这里魔改了
input[i]=(input[i]+s_box[index2]+16-394991376)
}
可以发现16-394991376是没用的
input[i]=(input[i]+s_box[index2])
enc=[0x72, 0x94, 0xB4, 0xE9, 0x65, 0xC0, 0xB6, 0xBC, 0x9C, 0x9F, 0x1F, 0x3B, 0x72, 0xF8, 0xD7, 0xDB, 0xCD, 0xE3, 0xC6, 0x49, 0xC9, 0x40, 0x57, 0x92, 0x06, 0x0D, 0xF7, 0x0C, 0x1A, 0x71, 0x18, 0x6B]
a=[0]*256
key="i_am_a_fish_man"
for i in range(256):
a[i]=i
v6 = 0
for j in range(256):
v6=(ord(key[j%len(key)])+v6+a[j])%256
v3 = a[j]
a[j] = a[v6]
a[v6] = v3
v7 = 0
v8 = 0
for k in range(32):
v8 = (v8 + 1) % 256
v7 = (v7 + a[v8]) % 256
temp = a[v8]
a[v8] = a[v7]
a[v7] = temp
x=(a[(a[v7] + a[v8]) % 256])&0xff
enc[k]-=x
enc[k]&=0xff
print(enc)
#[122, 73, 76, 203, 209, 228, 164, 144, 213, 221, 151, 124, 19, 36, 165, 83, 113, 87, 165, 82, 153, 183, 185, 34, 211, 49, 31, 211, 162, 151, 214, 194]
BLOWFISH解密 脚本:https://www.cnblogs.com/iBinary/p/14883752.html#25完成代码
int main()
{
char enc[] = { 122, 73, 76, 203, 209, 228, 164, 144, 213, 221, 151, 124, 19, 36, 165, 83, 113, 87, 165, 82, 153, 183, 185, 34, 211, 49, 31, 211, 162, 151, 214, 194 ,0};
BLOWFISH_CTX ctx;
char key[] = "fishrman";
size_t len = strlen("fishrman");
BlowFishInit(&ctx, (unsigned char*)key, len);
for (int i = 0; i < 4; i++)
{
BlowFish_Decrypt(&ctx, (unsigned int*)(&enc[8 * i]), (unsigned int*)(&enc[8 * i + 4]));
}
puts(enc);
}
总结一下思路,先用deflat.py脚本报错->d810插件去除部分混淆->findcrypt插件找到加密算法BLOWFISH(猜第一组加密是它)->利用编译器优化找到部分RC4特征猜RC4(发现魔改了一点 异或改加法了)
ps:当时第一个安卓题浪费太多了时间了,这个题之前发现是BLOWFISH+RC4,一把梭哈没出来。上午离比赛结束还有20分钟,当时太急了,魔改没找到。
剩下2个题暂时没思路,未完待续。