前言
Windows中,对API函数名进行哈希化通常用于隐藏或保护程序中调用的函数名,以防逆向或者被简单的分析攻击,所以我们更对的需要对拿到的shellcode进行分析调试获取其真正的恶意行为
1.反汇编
本次例子中,bin文件木马选择的是x86,32位的木马进行,使用Ghidra进行反编译直接选择x86架构解析
由于没有文件头,无法告诉Ghidra代码从哪里开始,所以软件不会直接去做反编译,我们需要直接选择
反汇编用快捷键d去反汇编
如果无法反编译后无函数显示,使用f手动定义函数,可以反编译出伪代码供我们后续研究
2.定位函数调用
接下来就需要研究下,各个函数的调用,在该shellcode中的函数调用几乎都是用api hash进行,代码中不会有明显的函数名称,更多是通过对应的hash比较来获取函数地址,通过反编译后我们从函数FUN_00000000
看起,跟进到 FUN_0000008f
函数
可以看到该代码通过函数指针unaff_retaddr 传递hash间接调用不同的函数最后调用函数
看回反汇编视图,我们可以看到在PUSH指令内部的“哈希”值,紧接着是一个CALL RBP
指令调用寄存器执行。这也是之前cs和msf常见的shellcode写法
我们直接用这位师傅的思路对hash进行解密获取
https://www.cnblogs.com/zpchcbd/p/15886229.html
可以看到该处函数的指向解析的函数名称
我们可以用SpeakEasy模拟下仿真shellcode,看该函数与其输出是否一致,确实看到了LoadLibraryA,推导即可得那么 0xa779563a
这个函数就代表着为InternetOpenA函数,可通过后续求证
3.wininet
关于wininet加载,我们可以继续看到此处,push进入的值猜测为十六进制
4.解析api哈希
我们回到前面那个函数 FUN_00000000
,可以看到jmp eax指令跳转到一个code * 函数动态调用,计算函数指针地址并执行
到这里我们可以大概看到这块可能是解析hash的执行位置,我们直接blobrunner,该工具允许在程序运行时配置和触发调试器,创建一个挂起的线程进行shellcode的调试
我们这里直接使用blobrunner进行调试
blobrunner.exe shellcode.bin
可以看到运行后shellcode被加载到以下地址 0x011a0000
然后我们将进程附加到调试器中进行调试,选择blobrunner进程
然后为blobrunner提供的位置创建一个断点
上面在汇编地址中我们也看到了jmp eax的偏移量为0x86,所以我们再设置一个断点在shellcode的0x86
处bp 0x011a0000 + 0x86
然后我们利用blobrunner来执行代码,可以看到我们shellcode的断点
我们可以使用快捷键f7进入到第一个函数,跟踪 call ebp 指令来理解程序的执行流程和功能调用链
用f9直接跟踪到该堆栈中包含断点Call EBP的哈希值为 0x726774c
看到这里我们会想到上面hash解析的 LoadLibraryA
,此刻我们再往下走,如我们所想的一样指针位于jmp eax
的时候解析eax注释的和我们上面解开为一样的
再往下观察可以看到堆栈窗口和函数参数,我们可以看到传递给 LoadLibraryA
的 wininet
字符串
再往下走,重新到达断点 JMP EAX
,通过注释我们又能得到0xa779563a
对应的函数 InternetOpenA
再往下一个函数调用走去,下一个 call ebp
地址为 0xca
,继续下断点走,此时指向的哈希是 0xC69F8957
,再往下进行分析可以得到该值为 InternetConnectA
,利用该函数建立与远程服务器的连接时创建一个新的Internet 连接句柄,与我们上面模拟的相似
至此完成了整个shellcode的hash解密获取到该恶意连接的实现
5.思路
回到这块,可以看到ROR 13这种散列算法,这种也是再Cobalt Strike 和Meterpreter的shellcode的api哈希散列算法,也可以通过这种已知的哈希算法和值去对其进行分析,或者去修改这块的散列算法过一些安全设备