hagme week3 RE wp
hagme week3 RE wp
mystery
用ida打开题目发现main函数界面只有ptrace反调试函数,搜索字符串可定位
用7打开大概是这样的(wp上那种)
用8开会好看很多,即主要逻辑(可直接通过字符串定位)
可以看到这里两个函数都有unk_4080
交叉引用
打开func2,因为题目为elf文件,发现func2在初始化函数里面,可以得知rc4加密的密钥在初始化时被修改
所以执行顺序为func2——>func1
动调获取Key的值
Encrypt
使用 CNG 加密数据 - Win32 apps | Microsoft Learn
首先通过一系列函数调用设置算法属性、生成对称密钥并导出密钥,如果这些函数都成功执行,则进入条件判断语句的大括号内部。
获得key
又因为
这里v6=v11
其中memcpy(v11, &unk_1400034A0, *(unsigned int *)v26)将定数据(unk_1400034A0)复制到 v11 指向的内存块中
所以找到IV
获取数据然后转换下形式
key:4c9d7b3eecd0661fa034dc863f5f1fe2
iv:936af225fa6810b8d07c3e5e9ee8ee0d
input:
A4E10F1C53BC42CD8E7154B7F175E35097207197A83B7761406968C1B47B88549F19034470782425F0A96535913A049C4E66BED28B8B2073CEA0CBE939BD6D83
hgame{rever5e_wind0ws_4P1_is_1nter3sting}
下面是当时看的一些函数
- 通过调用
BCryptOpenAlgorithmProvider
函数,使用AES算法初始化一个算法提供程序句柄。 - 使用
BCryptGetProperty
函数和属性BCRYPT_OBJECT_LENGTH
确定密钥对象缓冲区的大小。 - 使用
HeapAlloc
为密钥对象缓冲区(pbKeyObject
)分配内存。 - 使用
BCryptGenerateSymmetricKey
函数,使用算法提供程序句柄、密钥对象缓冲区、密钥长度和密钥数据生成密钥。
findme
打开文件然后发现Buffer
发现数据里面有MZ和90,合理怀疑这个地方藏的是一个exe的数据
(Windows下的exe文件格式有两种:MZ格式、PE格式。MZ格式为较早的exe文件格式,主要用于DOS系统。PE格式是目前Windows下常见的exe文件格式,它兼容MZ格式,本身也是一个MZ格式的可执行文件。)
经尝试,直接获取里面的数据失败,采用脚本获取#include <stdio.h>
将该脚本的exe与题目放在同一个文件夹下后运行,然后生成一个real.exe的文件1,即为要真正分析的文件
打开生成的real.exe,注意这个是32位的😂手动去花
这个地方复习一下花指令,jz和jnz永远跳转类型,把junkcode nop掉
然后选中后c识别代码,p创建函数,f5反汇编得到正常逻辑代码
这个题直接找加密算法找不到
可以看出第一个循环在初始化s盒 byte_403390,改变量名,好看
func2:使用上述func1初始化好的数组 s
进行加密操作
flag长度为32,则构造一个32的数据进行动调
解析 RC4 加密算法(C语言、python)-CSDN博客
这个地方涉及到下标越界的问题,可以直接采用动调每次步过记录result的值(感觉有点麻烦)
exp:
hgame{Fl0w3rs_Ar3_Very_fr4grant}
Crackme
定位找到main函数
(std::exception
是一个 C++ 标准库中的基类,用于表示所有标准异常类的基类。它定义了一个名称为 what()
的虚函数,用于返回一个 C 字符串,即异常的描述信息。因此,如果你在代码中看到某个异常类型是 std::exception
,那么可以认为这个异常类型是一个通用的、基础的异常类型,表示出现了未知的异常情况。通常情况下,具体的异常类型应该是 std::exception
的派生类,以便更好地表达出具体异常的类型和描述信息,从而更好地处理异常情况。)
在 C++ 中,try
和 catch
是用于异常处理的关键字,try
用于尝试执行可能会抛出异常的代码块,而 catch
则用于捕获并处理抛出的异常。
动调
单步一下,然后发现报错
(解释:这是一个 Windows 操作系统的错误提示信息,指示一个程序在执行时遇到了问题。具体而言,错误信息表明程序尝试读取内存中的某个位置,但该内存位置的值为 0xFFFFFFFFFFFFFFFF,也就是无效的内存地址。由于该内存地址无法访问,程序无法读取该内存位置的数据,从而导致了错误。错误代码 “c0000005” 是 Windows 中的通用异常代码,通常表示由于访问违反了内存保护或者其他原因,导致了应用程序终止的问题。线程 ID (tid) “88396” 表示在哪个线程中发生了错误。)
tab然后发现只有try的汇编代码,没有catch的,所以把这3个连续的catch函数给dump(shift + E)下来
export后在文件所在文件夹下生成含该数据的txt
emmmm winhex没试出来
打开010editor选择十六进制导入——另存为(不要后缀名)——导出——得到文件
全选以后p创建函数然后F5反汇编,得到加密代码
hgame{C_p1us_plus_exc3pti0n!!!!}
关于try catch finally:
当我们编写程序时,经常会遇到一些可能会引发异常的代码。为了处理这些异常情况,我们可以使用 try-catch-finally 结构来捕获和处理异常。下面是它的具体用法解释:
- try 块:
- 在 try 块中,我们编写可能会引发异常的代码。这些代码被放置在 try 块中,因为我们希望监视并处理可能发生的异常。
- catch 块:
- 如果在 try 块中的代码引发了异常,那么程序会跳转到 catch 块,并执行 catch 块中的代码。在 catch 块中,我们可以编写针对特定异常类型的处理逻辑,比如打印错误信息、记录日志或者采取其他恢复措施。
- finally 块:
- 无论是否发生异常,finally 块中的代码都会被执行。通常在 finally 块中放置一些清理工作,比如释放资源、关闭文件等操作。
综合起来,try-catch-finally 结构的作用是确保程序在遇到异常时能够进行适当的处理,同时保证一些必要的清理工作得以完成。
举例来说,比如在读取文件时可能会发生文件不存在的异常。我们可以将文件读取的代码放在 try 块中,然后在 catch 块中捕获文件不存在的异常并进行处理,最后在 finally 块中确保文件流得到关闭,以释放资源。这样可以保证程序在面对异常情况时仍能够安全运行,并且不会因为资源未释放而导致问题。