一款SQLServer木马分析
最近看到一些国内外的sqlserver服务遭受攻击,可能通过SQL弱口令进入,运行powershell下载执行木马如bNBbZUh.exe。
运行流程分析
bNBbZUh.exe是个Delphi程序,主要功能是释放一个资源包到Temp目录,并启动其中的Engine.exe。
资源包结构如下,Engine.exe启动后会执行其中1.qsp和Setup.txt安装脚本。
Engine.exe实际上是国外软件商Pantaray Research开发的一款打包程序,用于帮助生成EXE/MSI安装包,qsp是其定制的一种安装脚本格式。
安装脚本Setup.txt的功能是拷贝同目录下的3个文件00002#5、00000#0、00001#4到4sa53rzc.yni目录,然后调用cmd.exe执行其中的批处理文件00000#0。
执行批处理是通过cmd < 0这种输入重定向符来进行的。
对应的qsp安装脚本如下
文件名为0的批处理脚本如下,其中的内容经过混淆处理以对抗分析。
经过简单的变量替换处理后解开混淆,可见其主要功能是对文件4和5进行操作,文件5经过定位和拼接MZ头部后生成一个AutoIt3.exe(Medieval.exe.pif),而文件4则是一个Autoit脚本(.a3x)被其调用执行。
直接将该文件后缀名改成.bat,双击运行后也可以展开后续行为。
展开的进程链如下,可以看到文件4被重命名到%random%Medieval.exe.pif,文件5被重命名到重命名到%random%V。执行该Autoit脚本后会启动一个ipconfig.exe作为傀儡进程来运行最终的payload模块。
还有一个比较奇怪的DNS查询,目标域名是“PreDxSYUdmZgdfQbRti.PreDxSYUdmZgdfQbRti”,看起来不像是正常的域名,所以也没查询到该地址的IP地址,其用意暂未深追。
Autoit脚本如下,也是经过混淆处理对抗分析,其中包含一个加密的payload模块。
Payload模块分析
调试器直接附加到傀儡进程ipconfig.exe,查看内存布局可见0x400000地址处存在一块可读可写可执行的内存,其内容是一个加了UPX外壳并且已加载运行的PE模块。
这里需要注意的是正常PE模块加载是将PE程序的各个段分多个连续内存块映射到进程空间加载,比如此程序的UPX0和UPX1数据段,正常应该是分2个连续内存块存储,而此案例却将该PE文件直接放置在一整块内存中加载。此举不知是有意为之还是为方便自身在脚本中的加载操作,但是该技术执行后的一个效果就是直接内存dump此模块可能导致IDA无法正常识别API调用或字符串。以下是直接通过从内存窗口转储该内存块到文件的方式进行dump,再通过IDA解析会发现对该PE的解析异常,入口点地址代码出现偏差,代码的引用字符串和API调用都为空。
而实际上该入口点地址0x4764c0应该是如下的UPX壳入口代码。
Dump方式1
本文简单介绍一下如何使用x64dbg的Scylla插件进行正确dump。点击菜单栏该按钮后弹出插件窗口,发现底下的提示信息存在异常,此插件识别出0x400000地址的模块和大小,但是实际上从内存布局窗口查看进程ipconfig.exe的地址并不是该地址而是另外一个随机加载地址(如0x1D0000),说明进程环境信息被篡改影响了插件的解析。最终插件选定了ntdll.dll模块作为进程“默认地址”,OEP入口点也指向了ntdll的入口地址,这将影响用户搜索IAT导入表的操作及后续的dump操作(正常进程解析正确只需依次点击搜索IAT、dump等按钮即可正常dump成功)。
意识到这点就需要了解IAT导入表搜索的过程,比如此程序我们的目标是找到位于0x400000的payload模块的导入表,可以先尝试在反汇编窗口找到该内存块的代码,找到任意一处类似如下的api调用然后跟随到api的引用地址即可观察到一块连续的API地址引用表区域,此即导入地址表区域。
Scylla插件搜索IAT表的过程也是类似,不过由于此时OEP地址指向的是ntdll的代码区域,则该插件只会在ntdll的内存区域搜索API引用,这就背离了我们搜索payload导入表的初衷。于是简单的修改OEP指向payload入口点地址0x4764c0之后再搜索IAT并获取导入函数表即可。
不过虽然会成功找到引用的API函数表,但是地址表的FThunk地址看起来比较奇怪,原本应该是表示RVA(相对偏移)地址,此时却为类似88XXXXXX的大数值地址,远超过了payload模块本身的size。造成此种现象推测是插件内部将进程基址解析为ntdll地址来计算导致的。要修复此问题,可以使用插件菜单Imports下的save/load tree功能,先导出IAT地址表的xml树信息,修改其中的rva地址,可以使用notepad++的批量替换功能,然后再导入xml到插件中即可。
接着进行dump时要使用File菜单下的dump memory功能,选择指定的内存块地址进行Dump PE操作,否则会出现dump到其他模块的问题。
然后就可以依次点击插件的dump功能区域中PE rebuild和Fix dump功能,最后得到dump文件ipconfig-dump_SCY.exe。此时还有最后一步需要检查,就是PE入口点地址。使用010editor等工具定位到OEP字段,发现该字段也被“修复”成88XXXXXX的大数值地址,简单修复成0x764c0的UPX入口RVA即可。
修复后即可在IDA正常解析API调用和引用字符串进行下一步分析(虽然无法直接运行)。
Dump方式2
除了上述方式选择在程序运行起来后直接调试器附加dump,当然也可以选择在程序运行前进行dump,这种方式的好处就是可以还原原始可运行程序。要在程序运行前dump,需要在傀儡进程创建时调试器附加,可以通过调试父进程下断点,也可以用镜像劫持的方式调试。本文选择前者,手动运行AutoIt脚本后附加进程,然后对CreateProcessW下断,等待程序命中断点,以下通过栈上参数可见创建了一个挂起的ipconfig.exe进程。
本例尝试下WriteProcessMemory失败,否则应该能直接从此进程抠出要注入的原始payload数据。无奈接着把目标指向ipconfig.exe进程,成功创建挂起进程后调试器附加(x64dbg可以附加,OD之类的调试器貌似无法附加),附加运行后直接把ntdll.dll的代码段整块内存下断,然后接着运行父进程。父进程运行后可能会再次命中进程创建的断点,此时看ipconfig.exe进程已经退出,此现象推测是autoit代码尝试分配0x400000地址内存的重试操作,若出现反复重复上述附加下断操作直到ntdll断点命中即可。
命中ntdll代码段后就可以往上滑动,找到0x400000地址已分配存储好payload模块数据,此时对该内存块整块F2下断点即可。
接着F9运行后命中内存断点,此时EIP即停留在payload入口点,可见UPX壳的代码特征如下。这时只需要使用Scylla插件按照和上述一样的Dump memory方式即可dump出可运行的“原始”程序,只不过用IDA分析之前需要简单脱下UPX壳而已。
功能分析
一旦dump出IDA可分析样本,后面分析就显得简单很多。通过字符串就能很容易定位到关键代码,如下往控制台输出的信息可知此模块内置了Remcos远程控制程序,用于对目标机进行远程操作。
远程控制的C2地址信息被加密存放到SETTINGS资源中,解开后可见C2为80.66.75.198:2404。
此程序包含完整的远程控制功能,如核心的文件管理、上传下载和程序执行等。
目前没有反馈
表单载入中...