re2
30
感谢@W22提供的题目
解法
解压压缩包。
txt 文件里是乱码。
exe 文件导入 DIE 分析。是一个 PE32 程序。
导入 IDA,按 F5 查看 main_0 函数伪代码。
int __cdecl main_0(int argc, const char **argv, const char **envp)
{
char v4; // [esp+0h] [ebp-44Ch]
char v5; // [esp+0h] [ebp-44Ch]
char v6; // [esp+0h] [ebp-44Ch]
char v7; // [esp+0h] [ebp-44Ch]
char v8; // [esp+0h] [ebp-44Ch]
char v9; // [esp+0h] [ebp-44Ch]
_DWORD v10[3]; // [esp+194h] [ebp-2B8h] BYREF
int v11; // [esp+1A0h] [ebp-2ACh]
FILE *v12; // [esp+1ACh] [ebp-2A0h]
FILE *v13; // [esp+1B8h] [ebp-294h]
char v14[264]; // [esp+1C4h] [ebp-288h] BYREF
char v15[264]; // [esp+2CCh] [ebp-180h] BYREF
char Str1[60]; // [esp+3D4h] [ebp-78h] BYREF
char Str[56]; // [esp+410h] [ebp-3Ch] BYREF
__CheckForDebuggerJustMyCode(&unk_40B027);
memset(Str, 0, 50);
memset(Str1, 0, 50);
memset(v15, 0, 0x100u);
memset(v14, 0, 0x100u);
v11 = 1;
do
{
sub_401037("**************************我的Flag出了什么问题??**************************\n", v4);
sub_401037(asc_406BFC, v5);
sub_401037("**************************那有没有恢复的方法呢??**************************\n", v6);
sub_401037(asc_406CA8, v7);
sub_401037("做出你的选择:\n", v8);
sub_401037("1.充钱\n2.退出\n", v9);
sub_401073("%d", (char)v10);
if ( v10[0] == 1 )
{
v13 = fopen("flag.txt", "r");
if ( !v13 )
{
sub_401037("打开源文件失败!\n", v4);
getchar();
exit(0);
}
v12 = fopen("enflag.txt", "w");
if ( !v12 )
{
sub_401037("找不到加密文件!\n", v4);
getchar();
exit(0);
}
sub_401037("\n请输入您的密钥:", v4);
sub_401073("%s", (char)Str);
sub_401069(Str, Str1);
sub_401028(Str, v15, v14, v13, v12);
}
else if ( v10[0] == 2 )
{
v11 = 0;
}
else
{
sub_401037("\n操作不合法!\n\n", v4);
}
}
while ( v11 );
return 0;
}
顺着 sub_401069 深入,找到 sub_401A70 函数。可以知道,Str1 为 Str 和 0x1F 进行异或运算的结果。
char __cdecl sub_401A70(char *Str, char *Str1)
{
char v3; // [esp+0h] [ebp-E4h]
signed int i; // [esp+D0h] [ebp-14h]
signed int v5; // [esp+DCh] [ebp-8h]
__CheckForDebuggerJustMyCode(&unk_40B027);
v5 = strlen(Str);
for ( i = 0; i < v5; ++i )
Str1[i] += Str[i] ^ 0x1F;
if ( !strcmp(Str1, "DH~mqqvqxB^||zll@Jq~jkwpmvez{") )
sub_401037("充值成功.\n", v3);
else
sub_401037("Error!\n", v3);
return *Str1;
}
用 C++ 写个解密程序。
#include <iostream>
#define AUTHOR "HEX9CF"
using namespace std;
int main() {
string str, str2;
cin >> str2;
for (auto &i : str2) {
str += i ^ 0x1F;
}
cout << str;
return 0;
}
输入:
DH~mqqvqxB^||zll@Jq~jkwpmvez{
输出:
[Warnning]Access_Unauthorized
打开 exe 文件,选择 1。提示打开源文件失败。
根据 enflag.txt 文件名推测,源文件可能是 flag.txt。
加密和解密在很多情况下是可逆的,也就是说,如果知道了加密的算法和密钥,那么就可以通过相同的方式来解密。
复制一份 enflag.txt ,重命名为 flag.txt。
重新打开 exe 文件,选择 1。打开成功。密钥刚刚已经计算出来了:
[Warnning]Access_Unauthorized
打开 enflag.txt,可以看到被解密的 flag。
Flag
flag{RC4&->ENc0d3F1le}
声明
本博客上发布的所有关于网络攻防技术的文章,仅用于教育和研究目的。所有涉及到的实验操作都在虚拟机或者专门设计的靶机上进行,并且严格遵守了相关法律法规。
博主坚决反对任何形式的非法黑客行为,包括但不限于未经授权的访问、攻击或破坏他人的计算机系统。博主强烈建议每位读者在学习网络攻防技术时,必须遵守法律法规,不得用于任何非法目的。对于因使用这些技术而导致的任何后果,博主不承担任何责任。