逆向攻防世界CTF系列54-crypt
逆向攻防世界CTF系列54-crypt
64位无壳
int __fastcall main(int argc, const char **argv, const char **envp){
strcpy(Str, "12345678abcdefghijklmnopqrspxyz");
memset(&Str[32], 0, 0x60ui64);
memset(v10, 0, 0x17ui64);
sub_1400054D0("%s", v10);
v9 = malloc(0x408ui64);
v3 = strlen(Str);
sub_140001120(v9, Str, v3);
v4 = strlen(v10);
sub_140001240(v9, v10, v4);
for ( i = 0; i < 22; ++i ){
if (((unsigned __int8)v10[i] ^ 0x22) != byte_14013B000[i]){
v5 = (void *)sub_1400015A0(&off_14013B020, "error");
_CallMemberFunction0(v5, sub_140001F10);
return 0;
}
}
v7 = (void *)sub_1400015A0(&off_14013B020, "nice job");
_CallMemberFunction0(v7, sub_140001F10);
return 0;
}
看起来是一个flag解密校验题,先提出byte_14013B000
[
0x9E, 0xE7, 0x30, 0x5F, 0xA7, 0x01, 0xA6, 0x53, 0x59, 0x1B,
0x0A, 0x20, 0xF1, 0x73, 0xD1, 0x0E, 0xAB, 0x09, 0x84, 0x0E,
0x8D, 0x2B, 0x00, 0x00
]
1240和1120应该做了某种处理,跟进看了1240后,发现用到v9,所以先看1120
__int64 __fastcall sub_140001120(_DWORD *a1, __int64 a2, int a3){
*a1 = 0;
a1[1] = 0;
v9 = a1 + 2;
for ( i = 0; i < 256; ++i ) v9[i] = i;
v6 = 0;
result = 0i64;
LOBYTE(v7) = 0;
for ( j = 0; j < 256; ++j ){
v8 = v9[j];
v7 = (unsigned __int8)(*(_BYTE *)(a2 + v6) + v8 + v7);
v9[j] = v9[v7];
v9[v7] = v8;
if ( ++v6 >= a3 )
v6 = 0;
result = (unsigned int)(j + 1);
}
return result;
}
先初始化,然后交换v9[j]和v9[v7]也就是v9[byte(Str[v6]) + v8 + v7],得v9脚本:
def sub_140001120(a2: bytes, a3: int):
v9 = list(range(256)) # 初始化v9为0-255
v6 = 0
v7 = 0
for j in range(256):
v7 = (v7 + a2[v6] + v9[j]) % 256
v9[j], v9[v7] = v9[v7], v9[j]
v6 += 1
if v6 >= a3:
v6 = 0
return v9
def main():
Str = b"12345678abcdefghijklmnopqrspxyz"
v3 = len(Str)
v9 = sub_140001120(Str, v3)
print("v9 = ", v9)
if __name__ == "__main__":
main()
逆向就行
_DWORD *__fastcall sub_140001240(_DWORD *a1, __int64 a2, int a3){
v5 = *a1;
v6 = a1[1];
v9 = a1 + 2;
for ( i = 0; i < a3; ++i ){
v5 = (unsigned __int8)(v5 + 1);
v7 = v9[v5];
v6 = (unsigned __int8)(v7 + v6);
v8 = v9[v6];
v9[v5] = v8;
v9[v6] = v7;
*(_BYTE *)(a2 + i) ^= LOBYTE(v9[(unsigned __int8)(v8 + v7)]);
}
*a1 = v5;
result = a1;
a1[1] = v6;
return result;
}
最终代码:
def sub_140001120(a2: bytes, a3: int):
v9 = list(range(256)) # 初始化v9为0-255
v6 = 0
v7 = 0
for j in range(256):
v7 = (v7 + a2[v6] + v9[j]) % 256
v9[j], v9[v7] = v9[v7], v9[j]
v6 += 1
if v6 >= a3:
v6 = 0
return v9
def sub_140001240(v9: list, v10: list, a3: int):
v5 = 0
v6 = 0
for i in range(a3):
v5 = (v5 + 1) % 256
v7 = v9[v5]
v6 = (v6 + v7) % 256
v9[v5], v9[v6] = v9[v6], v9[v5]
v10[i] ^= v9[(v9[v5] + v9[v6]) % 256]
return v10
def main():
Str = b"12345678abcdefghijklmnopqrspxyz"
v3 = len(Str)
v9 = sub_140001120(Str, v3)
print("v9 = ", v9)
v10 = [
0x9E, 0xE7, 0x30, 0x5F, 0xA7, 0x01, 0xA6, 0x53, 0x59, 0x1B,
0x0A, 0x20, 0xF1, 0x73, 0xD1, 0x0E, 0xAB, 0x09, 0x84, 0x0E,
0x8D, 0x2B
]
v10 = [k ^ 0x22 for k in v10]
print("v10 = ", v10)
v10 = sub_140001240(v9, v10, 22)
for i in range(len(v10)):
print(chr(v10[i]), end="")
if __name__ == "__main__":
main()
flag{nice_to_meet_you}
但其实这是个RC4算法,先生成S盒,再生成密钥流,这种异或类得加密算法只需要重写逻辑即可
- 感谢你赐予我前进的力量
赞赏者名单
因为你们的支持让我意识到写文章的价值🙏
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 Matriy
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果