首页
社区
课程
招聘
[原创]HW行动 rdpscan后门简单分析
发表于: 2019-7-27 16:24 7392

[原创]HW行动 rdpscan后门简单分析

2019-7-27 16:24
7392

笔者目前是初学者,该文章的分析的每一步都是经过实践与参考他人分析报告而输出。

分析时间花了三个星期,文中如有错误,欢迎各位指正。


文件名称 :rdpscan.exe

文件大小 :85504 byte

文件类型 :PE32 executable for MS Windows (console) Intel 80386 32-bit

MD5:d0840aeb2642d718f325a07a4b7f6751

SHA1:ae77ca712670176650b01d30e6fe4801e90fafe2

SHA256:9966826ada8b1f366a9e7b9b1e7c430a2a49dda60eb7025c7481295e3ab7f9e4


文件名称 :ssleay32.dll

文件大小 :67416 byte

文件类型 :data

MD5:27b0374083f46693df15c0e3fffad070

SHA1:0eb87babebc32e526f6128fc4be3686c034c4185

SHA256:948e2def7339cf87071913148705bbba3cd9a8279c6157251036d6fac59983d5


拿到文件后,是个压缩包,进行解压后,发现如下文件。




有个exe文件,查下壳。

无壳,发现是VS2013编写的控制台程序。


rdpscan.exe 因为之前国内厂商已经检测,并且已经添加特征库,所以在线分析会被检测出。

https://www.virustotal.com/gui/file/9966826ada8b1f366a9e7b9b1e7c430a2a49dda60eb7025c7481295e3ab7f9e4/detection


得到的特征为木马后门


ssleay32.dll(shellcode) 由于关键信息数据已加密,静态分析时则无法检测。

https://www.virustotal.com/gui/file/948e2def7339cf87071913148705bbba3cd9a8279c6157251036d6fac59983d5/detection


微步云沙箱检测如下,结果是该文件为安全:

这与自己在本地虚拟机运行时一致,当第一次拿到样本时,当晚就在虚拟机里实际运行,直接提示缺失组件,无法成功运行。

因为后门编译为debug版本,没有找到对应的运行库,无法运行,导致沙箱无法对其进行恶意性行为检测。

https://s.threatbook.cn/report/file/0b5a6f745a47e2cb83c167e1f53f92db38f21e07a73f8600fc58dbc73cd927a7/?env=win7_sp1_enx64_office2013

如果要实际运行,本地需要安装VS2015以上版本后才会自带VC运行库。

直接在网上搜索VCRUNTIME140.dll缺失,会找到一些解决文章, 但是经过实践,都失败了,无法安装运行库。

最后只能退而求其次,安装了VS2015,因为会自带所需运行库。

附一个视频,安装VCRUNTIME140.dll。还未实验,不知道是否能行。

https://www.youtube.com/watch?v=AqxebQEFU64

该rdpscan扫描工具参考了之前网上公布的工具源码,所以按照之前网上的分析步骤,先去源项目的github查下源码。

https://github.com/robertdavidgraham/rdpscan/blob/master/src/main.c

经过仔细对比,在471-190行之间的代码被加入了一个判断,如果条件成立就跳转执行恶意代码。


sub_405040为触发函数,执行完后,如果返回值为0,则直接跳转。

逻辑是只要在命令行里正常输入IP地址后,一回车执行就会设置返回值为0。

接着来到LABEL_20进行分析

暂时没啥用,后面没发现出现。

CreateMutex函数的作用是找出当前系统是否已经存在指定进程的实例,如果没有则创建一个互斥体。

然后得到调用GetLastError得到的错误码,如果执行成功,就直接进入到如下部分:

sub_405940函数的作用是读取ssleay32.dll文件内容,放入之前创建的虚拟内存空间中,之后通过CreateThread新开线程执行,那可以猜测ssleay32.dll为需要执行的后门代码。

IDA打开ssleay32.dll看看

IDA静态分析与ollydbg动态分析时一致,

现在动态分析下,刚分析时需要下的断点

00405D73  |.  FFD7          call edi       ;  kernel32.CreateThread

之后创建了新线程后,该线程就执行了ssleay32.dll内容。shellcode前面是通过FS寄存器找到kernel32.dll基址,之后找到

00C9F45C   75F11222  kernel32.GetProcAddress

00C9F454   75F148D7  kernel32.LoadLibraryA

00C9F450   75F11826  kernel32.VirtualAlloc

这三个函数地址, 此时的基址为0x01F20000,但偏移是不变的。



其中用到的混淆方法是通过kernel32.dll基址加偏移获取到API函数名称时,取出每个字符然后经过循环算术处理后最后与先前设定的硬编码的值进行比较,如果正确,那么此时就是需要使用到的API函数,避免了直接使用硬编码的API名称进行比较来获取到需要的API函数。


接着检测了这三个API函数是否存在软件断点(与0xCC进行比较),如果存在断点就直接跳转到01F3074E(此时的基址为0x01F20000,但偏移是不变的。)然后退出函数。


调用VirustualAlloc创建一段内存空间,并将一段硬编码的内容(加密的代码指令)复制进来,之后再从其余硬编码内容里复制一段内容作为解密时用到的密钥,最后复制进加密的字符串内容,等待后续解密使用。


之后根据密钥对已复制的内容进行解密,解密完毕后,对密钥部分进行清零。

从加密的字符串数据里,解密出KERNEL32.dll,调用LoadLibraryA加载。

之后从加密的字符内容里,解密出KERNEL32.dll里需要用到的API函数名称,调用GetProcAddress获取地址。


函数如下:

00C9F43C   00DB9C00  ASCII "HeapFree"

00C9F43C   00DB9C00  ASCII "InitializeCriticalSection"

00C9F428   00DB9C00  ASCII "LocalAlloc"

00C9F428   00DB9C00  ASCII "LocalFree"

00C9F428   00DB9C00  ASCII "SetUnhandledExceptionFilter"

00C9F428   00DB9C00  ASCII "TerminateThread"

00C9F428   00DB9C00  ASCII "GetCurrentThread"

00C9F428   00DB9C00  ASCII "GetCurrentProcessId"

00C9F428   00DB9C00  ASCII "CreateFileMappingA"

00C9F428   00DB9C00  ASCII "MapViewOfFile"

00C9F428   00DB9C00  ASCII "UnmapViewOfFile"

00C9F428   00DB9C00  ASCII "EnterCriticalSection"

00C9F428   00DB9C00  ASCII "LeaveCriticalSection"

...

00C9F43C   00DB9C00  ASCII "ExitProcess"


接着通过LoadLibraryA加载解密后的字符串USER32.dll

之后从加密的字符内容里,解密出USER32.dll里需要用到的API函数名称,调用GetProcAddress获取地址。


函数如下:

0211FB30  |02239C00  ASCII "GetForegroundWindow"

0211FB44   02239C00  ASCII "EnumChildWindows"

0211FB30   02239C00  ASCII "wsprintfA"

0211FB30   02239C00  ASCII "EnableWindow"

0211FB30   02239C00  ASCII "GetClassNameA"


接着通过LoadLibraryA加载解密后的字符串ADVAPI32.dll

之后从加密的字符内容里,解密出ADVAPI32.dll里需要用到的API函数名称,调用GetProcAddress获取地址。


函数如下:

0211FB30   02239C00  ASCII "RegCreateKeyExW"

0211FB44   02239C00  ASCII "RegQueryValueExW"

0211FB30   02239C00  ASCII "FreeSid"

0211FB44   02239C00  ASCII "SetSecurityDescriptorDacl"

0211FB30   02239C00  ASCII "InitializeSecurityDescriptor"

0211FB30   02239C00  ASCII "SetEntriesInAclW"

0211FB30   02239C00  ASCII "AllocateAndInitializeSid"

0211FB44   02239C00  ASCII "RegOpenKeyExW"

0211FB30   02239C00  ASCII "RegSetValueExW"

0211FB30   02239C00  ASCII "RegDeleteValueW"

0211FB30   02239C00  ASCII "RegNotifyChangeKeyValue"

0211FB30   02239C00  ASCII "RegEnumValueA"

0211FB30   02239C00  ASCII "RegCloseKey"


接着通过LoadLibraryA加载解密后的字符串WS2_32.dll

之后从加密的字符内容里,解密出WS2_32.dll里需要用到的API函数名称,调用GetProcAddress获取地址。

这是一个与网络操作相关的库,猜测有网络通信功能。


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 3
支持
分享
最新回复 (3)
雪    币: 2322
活跃值: (3029)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
好不容易把后门传过去要运行了, 结果在目标机器上弹出"丢失xxx.dll", 哈哈哈哈哈
2019-7-27 17:08
0
雪    币: 2095
活跃值: (344)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
bjtwokeight 好不容易把后门传过去要运行了, 结果在目标机器上弹出"丢失xxx.dll", 哈哈哈哈哈
我觉得安全人员电脑里面装个VS应该很正常吧,问题不大,楼主是虚拟机没那么多库。
2019-7-28 09:03
0
雪    币: 233
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
还真是狠角色,防不胜防啊
2019-8-9 16:10
0
游客
登录 | 注册 方可回帖
返回
//