首页
社区
课程
招聘
源于学校布置的父亲节礼物
2024-6-6 15:50 1439

源于学校布置的父亲节礼物

2024-6-6 15:50
1439

最近龙河河畔的著名学府布置了一项任务:

设计一个“礼物”,藏在家里。让爸爸在父亲节当天想办法寻找并“获取”这个“礼物”内容。

考虑到我爸做程序猿若干年,我直接设计一手父亲节闯关任务,放在U盘,藏起来,作为这个“礼物”

不太清楚我爸的逆向水平(应该不是逆向方面工作者),不敢设计特别麻烦的题目,一点难度都不敢上,都是比较基础的内容,又怕做不出来,所以依托看雪平台,我个人把全部题解和流程发在这里,作为“参考答案”。

第零关

网页效果

设计思路:网易我的世界在没有进行公开预告的时候,在我的世界官网的源代码里藏了一个小彩蛋,表示会更新1.19和1.20双版本。所以,相关信息藏在网页的源代码里。

解题步骤:

①F12

②COPY

③SUCCESS

解题0

本题源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>网页里好像藏着什么东西</title>
<style>
  body {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
    background-color: #f0f0f0;
    font-family: Arial, sans-serif;
    overflow: hidden;
  }
 
  h1 {
    font-size: 3rem;
    animation: fadeIn 2s ease-out;
  }
 
  @keyframes fadeIn {
    0% {
      opacity: 0;
    }
    100% {
      opacity: 1;
    }
  }
</style>
</head>
<body>
<h1>网页里好像藏着什么东西</h1>
<!-- Hidden information -->
<p style="display: none;">看到这串文字意味着通过了入门关卡,请访问不愿意透漏姓名的url下载剩余题目.</p>
</body>
</html>

第一关

设计思路:C++20是一次很重要的特性更新,正确识别C++20代码,就可以做出部分本题。C++中类的继承,以及相关设计模式是发挥C++面向对象特性的重要一部分,考察基本功。代码审查,检查有无后门代码是很重要的一个环节。

题目1

解题步骤:

①尝试运行该程序

报错
报错
报错

②切换为C++20 可以解决关于transform ranges的报错

解题

③Wrapper以纯虚方式声明了Info函数,但是在class ConsoleLog : public Wrapper 并没有给出实现,所以无法实例化抽象类

解题

可以补写Info函数:

1
2
3
4
5
6
void ConsoleLog::Info(const char* format, ...) {
    va_list args;
    va_start(args, format);
    Log("[INFO]: ", format, args);
    va_end(args);
}

也可以直接删掉Wrapper中关于Info函数的声明

④全部修复好后 再次尝试运行 直接喜提锁屏套餐

解题

看来代码有地方藏了“后门”

解题

这里折叠起来的代码有猫腻

解题

对相关代码进行删除即可

⑤再次运行 正确输出:

1
2
[RUN]: Thread:0x4d54
本题目的Key是:不愿意透漏姓名的前半个Keye97df5bb41f79e90bea61b0fb693ff

⑥也可以直接通过执行这部分代码实现Key的获取 但这不是题目设计的本意

1
2
3
4
5
6
7
8
9
10
11
12
char key = 'K';
 
 
auto encryptDecryptChar = [key](char c) { return c ^ key; };
 
 
std::string original = "{y/z.{-|)z)*z}s-y|*xx)x-|*}|zx(}~.r|/-~))z-|r.r{).*}z){-)}rx--";
std::string encrypted = original;
std::ranges::transform(original, encrypted.begin(), encryptDecryptChar);
 
 
std::cout << "本题目的Key是:" << encrypted << std::endl;

第二关

设计思路:考察基本windows逆向功底,可以通过替换dll,hook sleep,hook 导出函数等多重方式解决本道题,也可以直接用工具查看内存明文字符串,等也不失为一种办法,大概需要十五个小时就可以等完了。

解题

解题步骤:

①观察发现给出了目标函数的具体写法,甚至把函数放到dll作为导出函数使用,这种方式这道题难度就很低了。

②先点击执行,尝试删除dll,发现dll被占用 解题

大概就可以推测出来写法是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
typedef void(__stdcall* ReturnMethod)();
 
 
    HMODULE hModule = LoadLibraryA("test_002_dll.dll");
    if (hModule == NULL) {
        MessageBoxA(NULL, "Failed to load DLL.", "Error", MB_ICONERROR);
        return;
    }
 
    // 获取returnMethod函数地址
    ReturnMethod returnMethod = (ReturnMethod)GetProcAddress(hModule, "returnMethod");
    if (returnMethod == NULL) {
        MessageBoxA(NULL, "Failed to get function address.", "Error", MB_ICONERROR);
        FreeLibrary(hModule);
        return;
    }
 
    // 执行returnMethod函数100万次
    for (int i = 0; i < 10000; ++i) {
        returnMethod();
    }

③由于使用的是dll的导出函数 直接踩用最简单的替换dll,新建一个dll项目文件

1
2
3
extern "C" void __declspec(dllexport) returnMethod() {
    return;
}

编译 替换掉test_002_dll.dll

④直接重新执行,没有了Sleep,很快得到了答案

1
291ebb40不愿意透漏姓名的后半个Key

⑤可以直接hook Sleep函数 直接retrun它 也可以达到相同的效果,也可以对导出函数进行hookreturn。这里不再赘述。

使用秘钥获得结果

解题

最后访问这个网页,就可以看到祝福了。

题目还是超级简单的哦 大概率用不上这份题解吧 我觉得~

全部源码已上传附件


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 2
打赏
分享
最新回复 (2)
雪    币: 660
活跃值: (161)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Axinger 2024-6-6 18:12
2
0
挺有意思的 支持一下
雪    币: 19553
活跃值: (60893)
能力值: (RANK:125 )
在线值:
发帖
回帖
粉丝
Editor 2024-6-6 18:23
3
0
爸爸心想:真是谢谢我的好大儿  哈哈哈哈还得做题
游客
登录 | 注册 方可回帖
返回