HGame 逆向复现
HGame
Reverse
eazyasm
根据题目可以知道,题目由汇编编写而来,直接拖入ida :

可以看到关键部分(如上图)
程序将[si]先左移4位后再右移4位,把两个得到的结果相加,最后于0x17进行异或之后与一个字符比较,如此循环28次。
在汇编里不难发现对比的字符串:

因此我们可以编写对应的解题脚本了(c++):
1 | |
creakme
直接拖入ida进行反编译
乍一看像是有一个Base64,但实际上是Tea加密的魔改,在每次加密过程中多异或了一次sum

同时我们在编写脚本的时候要注意端序的问题,避免出错
1 | |
Flag Checker
把apk文件直接拖入Jeb


可以明显的看到函数调用了一个RC4、Base64,程序将输入的字符串先以密钥carol进行RC4加密之后把加密后的数据转换为Base64与后面一个字符串进行比较。
于是我们可以写对应脚本
1 | |
猫头鹰是不是猫
拖入ida

可以简单的看到其逆向关键在于sub_1537这个函数,点进去

我们发现核心函数就是sub_1347,继续深入进去

函数不加修改的话可能会有一些难看,稍微修改一下就成上图啦,不难看出来函数主要在进行矩阵的乘法运算由输入的64位字符构成的矩阵与上面的deword_4140、deword_8140两个64*64的矩阵进行乘法运算,之后将得到的值与unk_4040进行比较。
因此我们可以写一个z3进行约束求解:
1 | |
xD MAZE
题目描述是走迷宫,那我们只需要找到对应地图,按照对应方式进行走动就可以了

我们导出对应地图按64*64进行输出,之后按照对应规则行走就可以啦

走出迷宫所需要的输入套上hgame{}就是flag啦
upx magic 0
题目描述有upx壳但是实际上并没有,直接拖入ida进行反编译
通过字符串定位我们可以找到对应加密部分

于是可以直接通过爆破的方式来解决这个题目
1 | |
fakeshell
我们直接拖入ida,找到关键函数

rc4_init和rc4_crypt这两个函数需要稍微修改一下,让其变得更加易于阅读


不难发现这两个函数都是标准的RC4加密,但是我们对最开始的密钥happyhg4me!进行交叉引用会发现后期会被修改成w0wy0ugot1t
所以在编写脚本时需要注意一下密钥,同时加密后的数据也要注意按小端序来进行计算。
脚本如下:
1 | |
creakme 2
将程序拖入ida,通过简易的分析程序,大致可以看出是一个xtea加密

关键函数就是xtea_crypt,key则是v11的0-3

进入函数也不难发现是一个标准的xtea模式下的加密,但是我们观察汇编时会发现delta有一个除 0 异常

那么我们在编写脚本时需要添加上对应的异常处理机制
脚本如下
1 | |
upx magic1


看到题目表述有upx壳我们去试试看,发现提示不含upx壳,但是我们拖入进010可以卡到对应的upx!的压缩标识被修改成upx?了,我们将其还原(文件末尾还有两个修改点),便可以直接脱壳。

同样的我们采用爆破的方式来解这个题目
1 | |
Answer’s Windows
通过字符串定位我们可以找到如下信息

base64_crypt是修改过名称的函数
我们从加密完后的数据看得出来这个不是普通的码表,我们在字符串里面可以找到

两个类似码表的数据,base64的码表长度为64位,我们截取前 64 位进行换表解密,即可得到对应flag,不过需要注意的是在使用线上网站进行解密时需要去除部分\,因为其表示转义,避免网站将其也识别为一个加密后的数据。
creakme3
题目描述中出现了IDA is not a panacea.提示我们换一个工具,我们采用ghidra这个工具来进行逆向分析。
我们稍微修复一下符号表可以在主函数看到
1 | |
可以看出来主函数就是把 a 中的数据进行排序,排完 0x59个数据后然后进行输出,我们看到 a 中的数据可以发现

这样排布的一串数据,我们根据其特点发现是每 8 位一组,同时主函数中的指针指向分别对应着 8 位中的后两位,而所有数据都要按照<=的顺序来进行排列后才会实现输出,我们推断前面的 4 字节就是对应字符,我们把后两个 16 进制进行组合就可以得到一串数字,大概就是对应的序号,我们提取对应数据,进行排序后输出,即可得到flag
1 | |
hardasm
程序整体是AVX2指令集逆向但是根据校外的师傅 P1umH0 的patch方式来进行解题可能会更简单一些。
通过查看汇编可以了解到对应Flag长度为 32 位

同时我们构造一个长度为 32 的伪Flag,对程序进行测试
hgame{abcdefghijklmnopqrstuvwxy}

在程序中我们可以看到每一位都是有一个cmp函数进行对比正确与否,当遇到一个数据不对时就会往下跳转到Error处,在Flag中hgame{}总是正确的,同时我们在调试过程中也可以发现每当有一个输入的字符正确在栈空间内便会有一个0xFF

同时我们也观察到程序是将Error字符串通过lea给rcx,我们可以将其修改,改为输出对应判断后的栈内[rsp+70h+var_50]那么每有一个字符输入正确就会输出一个0xFF,我们可以通过其个数来判断输入的正确性。

我们将程序中的Error和Success部分修改成下图

那么我们便可以通过Python的subprocess库来实现爆破
脚本如下
1 | |
WOW
这个题目其实算是一个自解密?

进行动调我们可以看出来我们输入的Flag是在 3 个函数下进行加密,把加密后的数据存储于Buf2中间,在后面的if语句里存在一个Buf1而这个肯定是 Flag加密后得到的,里面的语句则是跳转到B站对应的视频,继续调试我们在下面的input中可以发现我们的输入,推断出程序可能是一个自解密?因而我们可以在动调时将程序内我们输入的字符串替换成相应的Buf1内的字符串,运行程序到return 0前,在 57 行的input处便可以看到Flag了。