HGAME-Week4-Writeup

Week4

Re

1.vm

​ 这部分逻辑很清晰,重点在中间这个加密的部分,点进去查看这个函数发现 switch-case 应该是vm,每个case都是一个 opcode

​ 题目里说 ovm++ hates debugger ,那就先调试一下,调试后可以猜测出具体的加密部分

​ 输入的 flag 先是经过异或加密,之后又有减法操作,加密后与密文进行比较,写脚本解一下就能得到 flag

1
2
3
4
5
6
7
8
9
10
11
12
13
cipher = [0xcf,0xbf,0x80,0x3b,0xf6,0xaf,0x7e,0x02,0x24,0xed,0x70,0x3a,0xf4,0xeb,0x7a,0x4a,0xe7,0xf7,0xa2,0x67,0x17,0xf0,0xc6,0x76,0x36,0xe8,0xad,0x82,0x2e,0xdb,0xb7,0x4f,0xe6,0x09]
table1 = [0xFE,0x21,0x44,0x67,0x8A,0xAD,0xD0,0xF3,0x16,0x39,0x5c,0x7f,0xa2,0xc5,0xe8,0x0b,0x2e,0x51,0x74,0x97,0xba,0xdd,0x00,0x23,0x46,0x69,0x8c,0xaf,0xd2,0xf5,0x18,0x3b,0x5e,0x81]
table2 = [0x7a,0x1a,0xba,0x5a,0xfa,0x9a,0x3a,0xda,0x7a,0x1a,0xba,0x5a,0xfa,0x9a,0x3a,0xda,0x7a,0x1a,0xba,0x5a,0xfa,0x9a,0x3a,0xda,0x7a,0x1a,0xba,0x5a,0xfa,0x9a,0x3a,0xda,0x7a,0x1a]

for i in range(34):
if cipher[i] + table2[33-i] < 256:
cipher[i] += table2[33-i]
else:
cipher[i] = cipher[i] + table2[33-i] - 256

for i in range(34):
cipher[i] ^= table1[33-i]
print(chr(cipher[i]),end = "")

​ 这道题标准解法应该不是这样解的,而是要先要翻译出对应的汇编代码再分析,但这部分我还不太明白之后再补上吧

2.A 5 Second Challenge

​ 这题要感谢小圆学长的耐心回答!!

​ 下载得到的是用unity制作的扫雷游戏,刚开始为了获得源码用 il2cppdumper 处理 GameAssembly.dll ,但发现处理后得到的不全,之后问了一下小圆学长发现源码已经给了。

​ 打开 AFiveSecondChallenge.cpp ,源码里有 getUnixtime 这类获取时间的函数,游戏时间超过 5s 就会显示超时,用锁住系统时间的软件可以避开这一检测。锁定时间后就可以开始玩扫雷,几局下来后会发现雷的位置能构成二维码

​ 根据题目提示,把 managed 文件夹下的 dll 拖到 ida 里,会发现有一个函数被nop掉了,定位到源码里查看(il2cpp的中间文件有些混乱,删除了影响判断的部分)

​ 这里的 return 判断是否是雷的位置,本来分析到这里已经很清楚了但是因为我完全不懂类和方法什么的看了挺久

​ GetAt函数的返回值没在源码里看到有初始赋值于是迷惑了好久,又去问了一下小圆学长这部分是在哪里初始化过,得到回复说是在那个 dll 里面。

​ 但是我在我下载的东西里面没发现 m_Items 初始化的部分,去网站上重新下载并拖到 ilspy ,得到了这个数组里的值

​ 接下来就是写脚本解题

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
41
42
43
44
45
46
#include<stdio.h>
#include<math.h>

double matrix[45][15][3] = ;

double GetAt(i, j, k)
{
int iBound = 45; //45
int jBound = 15; //15
int kBound = 3; //3
return matrix[i][j][k];
}
int main()
{
int y,x;
FILE* fp;
fp = fopen("************" , "w");
int a[45][45];
int i, j;
for (y = 0; y < 45; y++)
{
for (x = 0; x < 45; x++)
{
double L_8 = GetAt(y, x / 3, 0);
double L_14 = GetAt(y, x / 3, 1);
double V_0 = L_14;
double L_20 = GetAt(y, x / 3, 2);
double V_1 = L_20;
double V_2 = fmod(x, 3.0f) - 1.0f;
a[x][y] = L_8* V_2* V_2 + V_0 * V_2 + V_1 > 0.0 ? 1 : 0; //1是雷
}
}

for (i = 0; i < 45; i++)
{
for (j = 0; j < 45; j++)
{
printf("%d", a[j][i]);
if (a[j][i] == 1)
fprintf(fp, "%d,%d\n", j, i);
}
printf("\n");
}
fclose(fp);
return 0;
}
1
2
3
4
5
6
import matplotlib.pyplot as plt
import numpy as np

x,y = np.loadtxt('./xy.txt',delimiter=',',unpack=True)
plt.plot(x,y,'.')
plt.show()

3.nllvm

​ 拖到 ida 里发现挺乱的,也没看到控制台输出的那些文字,那就先调试看看

​ 调试后发现这些异或操作得到的就是控制台输出的字符,在输出后又来了一遍异或还原。

​ 接着调试发现判断输入字符串的地方

​ 这一部分异或得到 “CryptoFAILUREforRSA2048Key!!!!!!” 这个字符串,接着来到加密的函数

​ 传入的就是这部分异或得到字符串和输入的 flag,之后看了一下这个函数里面是一些比较复杂的运算猜测是某种算法,我对各种算法不是很熟所以用了 ida 插件 findcrypt ,但是这个插件并没有找到什么算法于是我就去找学长确认了一下

​ 查了各种算法,最后发现加密函数里面的一个函数像是s盒,根据s盒数字判断又是 AES 加密 ( s盒也是异或得到的,这大概是插件检测不出算法的原因 )

​ 在调试过程中可以知道 iv值是 123456789abcdef ,判断是否为正确 flag 的部分与密文进行比较,改变了输出字符的外观(表示是否回到现实)

​ 之后用我在week2写的脚本解就行

​ 查了一下题目里的 llvm ,是一款代码混淆器,具体的是看了这篇文章https://bbs.pediy.com/thread-224484.htm

Misc

1.Akira之瞳-1

​ 查资料知道这种 dump 出来的RAW 文件要在 linux 里用 volatility 看,先查一下系统版本

​ 接着用 pslist 查看一下系统进程,找到可疑的进程后 dump 出来

​ 用 foremost 分离出一个加密的压缩包,本来以为密码还在 raw 文件里面的某个文件里来回看了好多遍,之后用 010editor 打开压缩包后发现提示,zip 密码是系统登陆密码

​ hashdump 一下得到登陆密码的 hash 值

​ 按提示把密码解出来

​ 打开压缩包后发现两张图片,名字是src 和 blind,很容易就想到盲水印,用这个工具 (https://github.com/chishaxie/BlindWaterMark) 提取出水印

​ 图片里小写的 L 是数字1

2.Akira之瞳-2

​ 得到一个加密压缩包和 RAW 文件,同样先查看一下进程,发现 notepad进程 dump出来

​ 在 dump 出来的进程里查一下 password 字符串,得到 zip 密码

​ 打开压缩包得到

​ 这几个文件名好像在哪里见过,翻了一下往年的 writeup 知道container 是加密容器,cookies 是chrome浏览器的 cookie 数据库。但是看 cookies 文件内容和打开加密卷都需要密码,回到 linux 里再查一下有无密码,因为是 notepad 进程那就查 txt 文件

​ 这个 dumpme.txt 很可疑,提取出来发现之前 zip 密码还有后半句。百度一下知道 lastpass 是 chrome 浏览器的插件,用来记录密码的,把 lastpass 和 dump 放在一起搜索找到 volatility 里有 lastpass 这个插件

​ 得到一个密码,下载 ChromeCookiesView ,加载 cookies 文件并输入密码,得到加密容器密码并提示用 VeraCrypt 打开

​ 打开虚拟分区得到一张图片,查 ADS 得知 NTFS 隐写

​ NTFS交换数据流(Alternate Data Streams,简称ADS)是NTFS磁盘格式的一个特性。在NTFS文件系统下,每个文件都可以存在多个数据流,意思是除了主文件流之外还可以有许多非主文件流寄宿在主文件流中,这些利用NTFS数据流寄宿并隐藏在系统中的非主文件流我们称之为ADS流文件。虽然我们无法看到ADS流文件,但它们却是真实存在。

​ 然后用 Ntfs Streams Editor 这个软件查看 ADS 流文件,得到 flag

​ 那个网址里的图是 Akira 学长的新头像

总结

​ 为时四周的 hgme 要结束了,这个寒假学到了很多东西过得很充实,希望以后能继续学习这方面的知识,不断进步

作者

0wl

发布于

2021-03-27

更新于

2021-11-16

许可协议

评论