2022 强网逆向部分题解
前言
整个比赛打下来就只有坐牢、坐牢还是坐牢…萌新逆向选手拿到的都是一堆ELF然后进行着一堆奇怪的函数…完全看不懂…或许只有GameMaster算是我能看懂的题目吧…
GAME MASTER
感觉整场比赛下来的逆向签到题目,本质上是一个C#编写的一个21点游戏,因为看不懂C#只能连蒙带猜的看,毕竟和C还是长得有些相似,还算好理解…
我们将其拖入到PE中进行查看

可以很明显的发现是一个C#文件,使用dnSpy(32位)进行打开,直接可以找到关键的主函数
 
可以很明显的发现程序加载了附件中的game message,我们往下翻可以发现下面这些特殊操作:
 
程序中似乎可以输入作弊码,同时在goldFunc中我们可以看到每一种作弊码对应的效果,有加钱的有减赌注的…同时我们也发现了几个有点不一样的作弊码,他们对我们之前加载的game message进行了操作,如下图:

 

大致可以看出来程序将game message进行了异或以及AES ECB的解密,对此我们尝试输入对应的作弊码,发现game message没有什么变化…不知道是不是因为程序没有将写完后的数据关闭,而导致数据仍然停留在内存中,我也看不懂C#,也不是很清楚…
尝试输入作弊码的师傅可能需要注意一下,第一个大的前缀作弊码输入完后需要再输入一位字符(可以随意输入),之后再进行输入第二段作弊码
对此我们采取手动进行解密game message的信息,写出如下Python脚本
| 1 |  | 
之后我们可以将我们的game message拖入到010中进行查看,可以发现整个文件是一个PE文件加上了一堆奇怪的东西
 
之后我们可以恢复得到一个exe,将其拖入PE,同样发现其是一个C#文件,我们同样直接拖入到dnSpy进行分析查看
 
我们可以发现其中的主要关键为其中的Check1整个函数,在其中我们缺少对应的x、y、z,如果我们采用手逆的话可能会有些麻烦,我们可以直接利用Z3对其进行约束求解,将解密得到的x、y、z直接应用到下面,按程序逻辑进行执行即可得到对应题目的flag,写出脚本如下:
| 1 |  | 
之后就可以直接得到flag啦 ~
EasyRE
又是一个说自己easy的题目,CTF里面的easy以及baby的题目都不能相信,基本上就是不easy和卑鄙了,当然或许有些题是真的easy以及baby难度
拿到程序我们将其拖入IDA中,可以看到程序去除了对应的符号表,显得每一个函数十分的难看,这里我们借助一下Finger插件进行恢复一下符号,之后我们可以快速的找到程序的主函数

可以看到程序创建了一个子进程re3,我们将写完的程序进行提出来,我们将其拖入进IDA可以发现有大量红色的未反编译出的函数,我们手动修复的同时可以发现在一处出现了我们父进程的那两个数字0xCAFEB055和0xCAFE1055,同时中间的大部分数据无法还原,因此猜测可能是一个SMC

我们此时回到父进程进行观察那个循环中if语句对应的操作

可以看到函数中存在有sys_ptrace以及两个关键的if判断语句对我们的产生的异常信号进行处理,对于sys_ptrace的一些知识点可以参考
其中关键的部分在于对于ptrace的一些参数:
| Request | Description | 
|---|---|
| PTRACE_TRACEME | 进程被其父进程跟踪,其父进程应该希望跟踪子进程。该值仅被tracee使用,其余的request值仅被tracer使用 | 
| PTRACE_PEEKTEXT, PTRACE_PEEKDATA | 从tracee的addr指定的内存地址中读取一个字节作为ptrace()调用的结果 | 
| PTRACE_PEEKUSER | 从tracee的USER区域中便宜为addr处读取一个字节,该值保存了进程的寄存器和其他信息 | 
| PTRACE_POKETEXT, PTRACE_POKEDATA | 向tracee的addr内存地址处复制一个字节数据 | 
| PTRACE_POKEUSER | 向tracee的USER区域中偏移为addr地址处复制一个字节数据 | 
| PTRACE_GETREGS | 复制tracee的通用寄存器到tracer的data处 | 
| PTRACE_GETFPREGS | 复制tracee的浮点寄存器到tracer的data处 | 
| PTRACE_GETREGSET | 读取tracee的寄存器 | 
| PTRACE_SETREGS | 设置tracee的通用寄存器 | 
| PTRACE_SETFPREGS | 设置tracee的浮点寄存器 | 
| PTRACE_CONT | 重新运行stopped状态的tracee进程 | 
| PTRACE_SYSCALL | 重新运行stopped状态的tracee进程,但是使tracee在系统调用的下一个entry或从系统调用退出或在执行一条指令后stop | 
| PTRACE_SINGLESTEP | 设置单步执行标志 | 
| PTRACE_ATTACH | 跟踪指定pid的进程 | 
| PTRACE_DETACH | 结束跟踪 | 
通过这个我们可以还原ptrace函数的操作,我们进入到sub_401BB1函数中,观察可以确定其是一个SMC的解密操作
对此我们可以通过调试时加入断点,来进行提取对应的异或数据值


对此我们可以得到对应的异或数据
| 1 |  | 
之后我们就可以编写一个IDAPython脚本将我们之前得到的re3手动SMC解密回去
| 1 |  | 
解密完成后将发送int 3指令等传给父进程的数进行patch处理,随后构建函数,通过一定分析我们可以发现这个函数将我们的输入进行保存,随后进行check,经过一些资料的查找发现这个是一个数织游戏,其将我们的数据进行统计1的个数放在第一位,随后进行check我们的输入
对于求解这个我们需要注意的是,这个静态下直接提取得到的行列数据是有一定问题的,这行与列是在init被相应修改了,我们可以尝试直接调试拿取数据

我们将数据提取,可以直接到在线网站进行求解
