GFSJ1194-【StupidOrangeCat2】
SMC + 摩斯密码 + SM4 + RC5
一个很好的题目 出题人很有水平 拿到题目先运行 这个先运行 其实没啥大问题 除了有些出题人脑残做了个勒索或者一个病毒放在里面 需要你来解密那种不能运行 不过一般都有提醒的 说多了都是痛 给我电脑整重装系统了
好了言归正传 简单玩了一下能看到 要求输入了一个翻译 能看出来这个只有两个字 而且有分割 所以猜测是摩斯 解密出来真是摩斯
喵呜喵呜/呜喵/喵/呜呜喵喵呜喵/呜呜/喵呜/呜呜喵喵呜喵/喵呜呜喵/呜呜喵喵呜喵/呜喵喵喵喵/喵喵喵喵呜/呜呜喵喵呜喵/喵呜喵喵/呜呜喵喵呜喵/呜呜呜喵喵/喵喵喵喵呜
喵 \ - 呜 \ . / =
-.-. .- - ..--.- .. -. ..--.- -..- ..--.- .---- ----. ..--.- -.-- ..--.- ...-- ----.
CAT_IN_X_19_Y_39
到下一个路径 也就是要找key
ida打开 我们能看到是 有很多提示的 有flag
我们去找key 看看哪里调用了 发现无法反编译 往下看看 能看到一团不能反编译的东西 再往下还有
我们再往下看是谁调用了下面一坨东西
int sub_401ED0()
{
int i; // [esp+D0h] [ebp-20h]
int flOldProtect[2]; // [esp+E8h] [ebp-8h] BYREF
__CheckForDebuggerJustMyCode(&unk_46401A);
if ( unk_462A40 == 32 )
{
VirtualProtect(dword_402780, 0x7C5u, 0x40u, (PDWORD)flOldProtect);
for ( i = 0; i < 1989; ++i )
*((_BYTE *)dword_402780 + i) ^= unk_462A40;
}
return 0;
}
这里进行了一个SMC 解密就可以了
s=0x402780
for i in range(1989):
patch_byte(s+i,get_wide_byte(s+i)^32)
解密出来的是真的迷宫图 也就是我们刚刚看到的所玩的游戏 里面还有一个假的图 有兴趣的可以看看
int sub_402780()
{
char v1; // [esp+3DFh] [ebp-82Dh]
char v2; // [esp+3EBh] [ebp-821h]
int v3; // [esp+454h] [ebp-7B8h]
int v4; // [esp+460h] [ebp-7ACh]
int i; // [esp+46Ch] [ebp-7A0h]
int j; // [esp+46Ch] [ebp-7A0h]
char Buffer[42]; // [esp+478h] [ebp-794h] BYREF
__int16 v8; // [esp+4A2h] [ebp-76Ah]
_WORD v9[22]; // [esp+4A4h] [ebp-768h] BYREF
_WORD v10[22]; // [esp+4D0h] [ebp-73Ch] BYREF
_WORD v11[22]; // [esp+4FCh] [ebp-710h] BYREF
_WORD v12[22]; // [esp+528h] [ebp-6E4h] BYREF
_WORD v13[22]; // [esp+554h] [ebp-6B8h] BYREF
_WORD v14[22]; // [esp+580h] [ebp-68Ch] BYREF
_WORD v15[22]; // [esp+5ACh] [ebp-660h] BYREF
_WORD v16[22]; // [esp+5D8h] [ebp-634h] BYREF
_WORD v17[22]; // [esp+604h] [ebp-608h] BYREF
_WORD v18[22]; // [esp+630h] [ebp-5DCh] BYREF
_WORD v19[22]; // [esp+65Ch] [ebp-5B0h] BYREF
_WORD v20[22]; // [esp+688h] [ebp-584h] BYREF
_WORD v21[22]; // [esp+6B4h] [ebp-558h] BYREF
_WORD v22[22]; // [esp+6E0h] [ebp-52Ch] BYREF
_WORD v23[22]; // [esp+70Ch] [ebp-500h] BYREF
_WORD v24[22]; // [esp+738h] [ebp-4D4h] BYREF
_WORD v25[22]; // [esp+764h] [ebp-4A8h] BYREF
_WORD v26[22]; // [esp+790h] [ebp-47Ch] BYREF
_WORD v27[22]; // [esp+7BCh] [ebp-450h] BYREF
char v28[1060]; // [esp+7E8h] [ebp-424h] BYREF
__CheckForDebuggerJustMyCode(&unk_46401A);
printf("@为冒险者,请在迷宫中寻找笨橘猫吧!!\n");
strcpy(Buffer, "00000000000000000000000000000000000000000");
v8 = 0;
strcpy((char *)v9, "0 0 0 0! 0 0 0 0 0 0* 0 0 0");
v9[21] = 0;
strcpy((char *)v10, "0 0 0 00000 00000 0 0 0 0 00000 00000 0 0");
v10[21] = 0;
strcpy((char *)v11, "0 0 0 0 0 0 0");
v11[21] = 0;
strcpy((char *)v12, "0 000 000 0 000 0 0 0 000 000 0 000 0 0 0");
v12[21] = 0;
strcpy((char *)v13, "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0");
v13[21] = 0;
strcpy((char *)v14, "0 0 0 00000 000 000 0 0 0 00000 000 000 0");
v14[21] = 0;
strcpy((char *)v15, "0 0 0 0 0 0 0 0 0 0 0 0");
v15[21] = 0;
strcpy((char *)v16, "0 000 0 0 000 0 0 0 0 000 0 0 000 0 0 0 0");
v16[21] = 0;
strcpy((char *)v17, "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0");
v17[21] = 0;
strcpy((char *)v18, "0 00000 000 000 0 0 0 00000 000 000 0 0 0");
v18[21] = 0;
strcpy((char *)v19, "0 0 0 0 0 0 0 0 0");
v19[21] = 0;
strcpy((char *)v20, "000 0 0 0 000 0 0 0 000 0 0 0 000 0 0 0 0");
v20[21] = 0;
strcpy((char *)v21, "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0");
v21[21] = 0;
strcpy((char *)v22, "0 0000000 0 000 00000 0000000 0 000 00000");
v22[21] = 0;
strcpy((char *)v23, "0@ 0 0 0 0 0 0 0 0");
v23[21] = 0;
strcpy((char *)v24, "0 0 0 0 0 00000000000 0 0 0 0 00000000000");
v24[21] = 0;
strcpy((char *)v25, "0 0 0 0 0 0 0 0 0");
v25[21] = 0;
strcpy((char *)v26, "000 0 00000 0 000 00000 0 00000 0 000 000");
v26[21] = 0;
strcpy((char *)v27, "0 0 0 0 0 0 0 0 0");
v27[21] = 0;
strcpy(v28, "00000000000000000000000000000000000000000");
memset(&v28[42], 0, 1014);
v1 = 0;
v4 = 15;
v3 = 1;
for ( i = 0; i <= 40; ++i )
puts(&Buffer[44 * i]);
while ( v4 != 7 || v3 != 40 )
{
if ( v4 == 1 && v3 == 7 )
{
printf("当你寻找到这里的时候,你发现它是可恶的偷猫人!?\n");
printf("你被抓起来了...\n");
Sleep(0x1388u);
_loaddll(0);
}
if ( v4 == 1 && v3 == 27 )
{
printf("好耶!!!你终于找到了笨橘猫\n");
printf("她的毛上都沾满了污泥,毛发都结成了一块一块\n");
printf("原本灵动皎洁的眼睛都变得黯淡无光\n");
printf("你非常的心疼,你想立马上去带她回家\n");
printf("但是她好像有话和你说,你能解出她的话语嘛...\n");
printf(
"笨橘猫:喵呜喵呜/呜喵/喵/呜呜喵喵呜喵/呜呜/喵呜/呜呜喵喵呜喵/喵呜呜喵/呜呜喵喵呜喵/呜喵喵喵喵/喵喵喵喵呜/呜呜喵喵呜喵/喵呜喵喵/呜呜喵喵呜喵/呜呜呜喵喵/喵喵喵喵呜\n");
sub_402F60();
v1 = 1;
HIBYTE(v27[19]) = (unsigned __int8)"T";
}
if ( v4 == 19 && v3 == 39 && v1 == 1 )
{
printf("你找到了这只可怜的流浪小猫\n");
printf("但是你们不知道怎么逃出这个迷宫\n");
printf("小猫经常在这片区域流浪\n");
printf("这时小猫告诉你,他知道出口在哪里\n");
printf("但是需要你先找到开启出口的钥匙,你能找到它嘛!!!\n");
sub_402410();
LOBYTE(v15[20]) = (unsigned __int8)" ";
}
((void (__thiscall *)(int (***)()))**off_46200C)(off_46200C);
v2 = _getch();
((void (__thiscall *)(int (***)()))**off_46200C)(off_46200C);
switch ( v2 )
{
case 's':
if ( Buffer[44 * v4 + 44 + v3] != 48 )
{
Buffer[44 * v4++ + v3] = 32;
Buffer[44 * v4 + v3] = 64;
}
break;
case 'w':
if ( Buffer[44 * v4 - 44 + v3] != 48 )
{
Buffer[44 * v4-- + v3] = 32;
Buffer[44 * v4 + v3] = 64;
}
break;
case 'a':
if ( Buffer[44 * v4 - 1 + v3] != 48 )
{
Buffer[44 * v4 + v3--] = 32;
Buffer[44 * v4 + v3] = 64;
}
break;
default:
if ( v2 == 100 && Buffer[44 * v4 + 1 + v3] != 48 )
{
Buffer[44 * v4 + v3++] = 32;
Buffer[44 * v4 + v3] = 64;
}
break;
}
sub_42AD51((int)"cls");
for ( j = 0; j <= 40; ++j )
puts(&Buffer[44 * j]);
}
sub_42AD51((int)"cls");
Sleep(0x1F4u);
printf("感谢你找到了笨橘猫并且带小猫咪跑了出来\n");
printf("为了奖励你flag就是CatCTF{第一段翻译+_+第二段key}\n");
printf("非常感谢你的爱心,让我们一起爱护流浪猫吧!!!\n");
printf("其中笨橘猫的那段话语彩蛋你发现了嘛!?\n");
sub_42AD51((int)"pause");
return 0;
}
但是还是不行啊 这个图我们解过了 对不对 这个时候我们要回到我们一开始的地方 也就是显示key对不对的地方 能够发现能显示了
int sub_402410()
{
int j; // [esp+D0h] [ebp-1A0h]
unsigned __int8 v2; // [esp+DFh] [ebp-191h]
char v3; // [esp+EBh] [ebp-185h]
int v4[6]; // [esp+10Ch] [ebp-164h] BYREF
int v5[6]; // [esp+124h] [ebp-14Ch]
int v6[13]; // [esp+13Ch] [ebp-134h] BYREF
char v7[24]; // [esp+170h] [ebp-100h] BYREF
int v8[28]; // [esp+188h] [ebp-E8h] BYREF
int v9[28]; // [esp+1F8h] [ebp-78h] BYREF
int i; // [esp+268h] [ebp-8h]
__CheckForDebuggerJustMyCode(&unk_46401A);
v5[0] = -1821724372;
v5[1] = -310169419;
v5[2] = -295936376;
v5[3] = -519352180;
sub_401AB0(v7, dword_462018);
sub_4021B0((int)v7, v9);
for ( i = 0; i < 26; ++i )
v8[i] = v9[i];
v3 = 0;
v2 = 0;
printf("请输入你找到的key\n");
while ( v3 != 10 )
{
v3 = j___fgetchar();
*((_BYTE *)&v6[6] + v2++) = v3;
}
if ( v2 > 0x11u )
{
printf("长度错误");
Sleep(0x1388u);
_loaddll(0);
}
for ( j = 0; j < 4; ++j )
v6[j] = SHIBYTE(v6[j + 6]) | (SBYTE2(v6[j + 6]) << 8) | (SBYTE1(v6[j + 6]) << 16) | (SLOBYTE(v6[j + 6]) << 24);
sub_401950(v6, v4, v8);
for ( i = 0; i < 4; ++i )
{
if ( v4[i] != v5[i] )
{
printf("这把钥匙好像打不开大门\n");
Sleep(0x1388u);
_loaddll(0);
}
}
return printf("成功了,大门已经打开,快点跑出去吧!!!\n");
}
发现是一个RC5 看着并没有魔改 从网上找一个解密脚本就可以了
int __cdecl sub_4021B0(int a1, _DWORD *a2)
{
int result; // eax
unsigned int v3; // [esp+Ch] [ebp-13Ch]
unsigned int v4; // [esp+Ch] [ebp-13Ch]
int v5[6]; // [esp+D4h] [ebp-74h]
int v6; // [esp+ECh] [ebp-5Ch]
unsigned int v7; // [esp+F8h] [ebp-50h]
unsigned int v8; // [esp+104h] [ebp-44h]
unsigned int v9; // [esp+110h] [ebp-38h]
int v10; // [esp+11Ch] [ebp-2Ch]
int i; // [esp+128h] [ebp-20h]
int v12; // [esp+134h] [ebp-14h]
int v13; // [esp+140h] [ebp-8h]
__CheckForDebuggerJustMyCode(&unk_46401A);
v13 = 0xB7E15163;
v12 = 0x9E3779B9;
v10 = dword_462010 / 8;
v6 = 0;
v7 = 0;
v8 = 0;
v9 = 0;
*a2 = 0xB7E15163;
for ( i = 1; i < dword_46201C; ++i )
a2[i] = v12 + a2[i - 1];
for ( i = 0; i < dword_462020; ++i )
v5[i] = 0;
for ( i = dword_462018 - 1; i != -1; --i )
v5[i / v10] = *(unsigned __int8 *)(i + a1) + (v5[i / v10] << 8);
for ( i = 0; ; ++i )
{
result = 3 * dword_46201C;
if ( i >= 3 * dword_46201C )
break;
v3 = ((v6 + v7 + a2[v9]) >> (dword_462010 - ((dword_462010 - 1) & 3))) | ((v6 + v7 + a2[v9]) << ((dword_462010 - 1) & 3));
a2[v9] = v3;
v7 = v3;
v9 = (v9 + 1) % dword_46201C;
v4 = ((v6 + v3 + v5[v8]) >> (dword_462010 - ((dword_462010 - 1) & (v6 + v3)))) | ((v6 + v3 + v5[v8]) << ((dword_462010 - 1) & (v6 + v3)));
v5[v8] = v4;
v6 = v4;
v8 = (v8 + 1) % dword_462020;
}
return result;
}
exp
import math
MASK = 0xffffffff
P = 0xB7E15163
Q = 0x9E3779B9
w = 32
r = 12
b = 16
c = 4
t = 26
def rol(x, n):
n &= 31
x &= MASK
return ((x << n) | (x >> (32 - n))) & MASK
def ror(x, n):
n &= 31
x &= MASK
return ((x >> n) | (x << (32 - n))) & MASK
key = [0] * 16
key[0] = 3
for i in range(1, 16):
key[i] = int(math.pow(3.0, float(i))) % (255 - i)
L = [0] * 4
for i in range(15, -1, -1):
L[i // 4] = (key[i] + (L[i // 4] << 8)) & MASK
S = [0] * t
S[0] = P
for i in range(1, t):
S[i] = (S[i - 1] + Q) & MASK
A = B = 0
i = j = 0
for _ in range(3 * t):
A = S[i] = rol((S[i] + A + B) & MASK, 3)
B = L[j] = rol((L[j] + A + B) & MASK, A + B)
i = (i + 1) % t
j = (j + 1) % c
def decrypt_block(A, B):
for i in range(r, 0, -1):
B = ror((B - S[2 * i + 1]) & MASK, A) ^ A
A = ror((A - S[2 * i]) & MASK, B) ^ B
A &= MASK
B &= MASK
B = (B - S[1]) & MASK
A = (A - S[0]) & MASK
return A, B
cipher = [
-1821724372 & MASK,
-310169419 & MASK,
-295936376 & MASK,
-519352180 & MASK,
]
plain_words = []
for i in range(0, 4, 2):
a, b = decrypt_block(cipher[i], cipher[i + 1])
plain_words.append(a)
plain_words.append(b)
flag = b''.join(x.to_bytes(4, 'big') for x in plain_words)
print(flag.decode())
解出来第二段key
LIKE_OR_LOVE_CAT
所以我们的flag就是
CatCTF{CAT_IN_X_19_Y_39_LIKE_OR_LOVE_CAT}
其实这题的正常解密就是这样 当然还有不正常的 哈哈哈
当你没有看到哪个谜语是摩斯的时候 你就要去找请输入你的翻译了
int sub_402F60()
{
char v1[27]; // [esp+D0h] [ebp-114h]
unsigned __int8 v2; // [esp+EBh] [ebp-F9h]
char v3; // [esp+F7h] [ebp-EDh]
unsigned int i; // [esp+100h] [ebp-E4h]
char v5[140]; // [esp+10Ch] [ebp-D8h] BYREF
char v6[28]; // [esp+198h] [ebp-4Ch] BYREF
char v7[28]; // [esp+1B4h] [ebp-30h] BYREF
char v8[20]; // [esp+1D0h] [ebp-14h] BYREF
__CheckForDebuggerJustMyCode(&unk_46401A);
qmemcpy(v8, "wuwuwuyoucatchme", 16);
v3 = 0;
v2 = 0;
printf("请输入你的翻译\n");
while ( v3 != 10 )
{
v3 = j___fgetchar();
v7[v2++] = v3;
}
v1[0] = -74;
v1[1] = 117;
v1[2] = -31;
v1[3] = 121;
v1[4] = 112;
v1[5] = -63;
v1[6] = 39;
v1[7] = 72;
v1[8] = 9;
v1[9] = 11;
v1[10] = -74;
v1[11] = 77;
v1[12] = 2;
v1[13] = -68;
v1[14] = 6;
v1[15] = 25;
sub_403DF0(v5, v8);
sub_403630(v5, 1, 16, v7, v6);
for ( i = 0; i < 0x10; ++i )
{
if ( v6[i] != v1[i] )
{
printf("笨橘猫好像不是这个意思,再想想吧!!");
Sleep(0x1388u);
_loaddll(0);
}
}
printf("你终于弄懂笨橘猫在说什么了\n");
printf("原来是这样,笨橘猫看见了可怜的小猫咪流浪街头\n");
printf("而且这时有可怕的偷猫人想要偷走小猫,笨橘猫带着小猫逃跑\n");
printf("跑进了下水管道,但是下水道太黑和小猫失散了..\n");
return printf("快去找到小猫吧,她已经在地图上出现了\n");
}
然后找到了这句话 发现前面有一个字符串 应该是key 然后进去到加密函数里面 发现是一个SM4 byte_4531F0 是 SM4 S-box byte_4532F0 是 FK byte_453300 是 CK 然后找一下魔改点 发现没有 我们直接去解密
然后接着去解
评论