启动技术
病毒木马植入模块成功植入计算机之后,便会启动攻击模块来对用户计算机数据实施窃取和回传等操作。通常植入和攻击是分开在不同的模块之中的,这里的模块指的是DLL、exe或者其他加密的PE文件。只有当前植入模块成功运行后,方可继续执行攻击模块,同时会删除植入模块的数据和文件。模块化开发的好处不单单是便于开发管理,同时也可以减小因某一模块失败而造成整个程序暴露的风险。
创建进程API
创建进程API主要有三个:
- WinExec
- ShellExecute
- CreateProcess
除了可以创建进程外,还能执行CMD命令;
Winexec
运行指定的程序
UINT WINAPI WinExec(
_In_ LPCTSTR lpCmdLine,
_In_ UINT uCmdShow)
参数说明:
- lpCmdLine:要执行应用程序的命令行,如果在该参数中的可执行文件不包括目录路径,则系统将按照以下顺序搜索可执行文件:
- 应用程序目录
- 当前目录
- windows系统目录
- windows目录
- path环境变量列出的目录
- uCmdShow:显示选项
- SW_HIDE表示隐藏窗口并激活其他窗口
- SW_SHOWNORMAL表示激活并显示另一个窗口
返回值
- 如果函数成功,则返回值大于31
- 如果函数失败,则返回值是以下错误值之一
值 | 含义 |
---|---|
0 | 系统内存或资源不足 |
ERROR_BAD_FORMAT | exe文件无效 |
ERROR_FILE_NOT_FOUND | 找不到指定文件 |
ERROR_PATH_NOT_FOUND | 找不到指定目录 |
示例程序
通过winExec API启动计算器窗口;
// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#undef UNICODE
#include <Windows.h>
#include <stdio.h>
#include "resource.h"
BOOL WinExec_Test(char* pszExePath, UINT uiCmdShow)
{
UINT uiRet = 0;
uiRet = WinExec(pszExePath, uiCmdShow);
if (uiRet > 31)
{
return TRUE;
}
return FALSE;
}
int main()
{
char pszExePath[40] = "C:\\Windows\\System32\\calc.exe";
BOOL flag = WinExec_Test(pszExePath, SW_SHOWNORMAL);
if (flag == TRUE)
{
printf("success\n");
}
return 0;
}
可见,已经把计算器窗口打开了。
不加绝对路径,直接启动也是可以的。
int main()
{
char pszExePath[40] = "calc.exe";
BOOL flag = WinExec_Test(pszExePath, SW_HIDE);
if (flag == TRUE)
{
printf("success\n");
}
return 0;
}
ShellExecute
运行一个外部程序(或者打开一个已注册的文件、目录,或打印一个文件等),对外部程序进行一定程度的控制。
HINSTANCE ShellExecute(
_In_opt_ HWND hwnd,
_In_opt_ LPCTSTR lpOperation,
_In_ LPCTSTR lpFile,
_In_opt_ LPCTSTR lpParameters,
_In_opt_ LPCTSTR lpDirectory,
_In_ INT nShowCmd)
参数
- hwnd:用于显示UI或错误消息的父窗口句柄。如果操作不与窗口关联,此值可以为NULL。
- lpOperation:指向以空字符结尾的字符串的指针,在本例中称为动词,用于指定要执行的操作。常使用的动词有:
- edit:启动编辑器并打开文档进行编辑,如果文件不是文档文件,则失败。
- explore:探索由lpFile指定的文件夹。
- find:在由lpDirectory指定的目录中启动搜索
- open:打开由lpFile参数指定的项目,可以是文件也可以是文件夹
- print:打印lpFIle参数指定的文件,如果不是文档则失败。
- NULL:如果可用使用默认动词,不过不可用使用打开动词,如果都不可用,则使用注册表中列出的第一个动词
- lpFIle:指向以空字符结尾的字符串的指针,该字符串要在其上执行指定谓词的文件或对象。要指定一个shell名称空间对象,传递完全限定的解析名称,如果lpDirectory使用相对路径,那么lpFIle就不要用绝对路径。
- lpParameters:如果lpFIle指定一个可执行文件,则此参数是一个指向以空字符结尾的字符串的指针,该字符串指定要传递给应用程序的参数。如果lpFIle是一个文档文件,则该参数为NULL。
- lpDirectory:指向以空字符终止的字符串的指针,该字符串指定操作的默认目录。如果此值为NULL,则使用当前的工作目录。
- nShowCmd:与WinExec API中该参数一致。
返回值
如果函数成功,则返回值大于32,否则将返回错误值,指示失败原因。
示例程序
// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#undef UNICODE
#include <Windows.h>
#include <stdio.h>
#include "resource.h"
#include "ConsoleApplication1.h"
BOOL ShellExecute_Test(char* pszExePath, char* lpDIrec, UINT uiCmdShow)
{
HINSTANCE hinstance = 0;
hinstance = ShellExecute(NULL, "open", pszExePath, NULL, lpDIrec, uiCmdShow);
if ((DWORD)hinstance > 32)
{
return TRUE;
}
return FALSE;
}
int main()
{
char pszExePath[40] = "calc.exe";
char lpDIrec[40] = "C:\\Windows\\System32";
BOOL flag = ShellExecute_Test(pszExePath, lpDIrec, SW_HIDE);
if (flag == TRUE)
{
printf("success\n");
}
return 0;
}
运行窗口:
CreateProcess
创建一个新进程及主线程,新进程在调用进程的安全的上下文中运行。
BOOL WINAPI CreateProcess(
10个参数)
参数
与WinExec以及ShellExecute函数相比较而言,CreateProcess函数的参数更多,使用起来更复杂。我们着重关注以下5个参数:
- 执行模块名称lpApplicationName
- 执行命令行的参数 lpCommandLine
- 控制进程优先级和创建进程标志的参数 dwCreationFlags
- 指向STARTUPINFO信息结构的参数lpStartupInfo
- 指向PROCESS_INFORMATION信息结构的参数lpProcessInformation
返回值
- 如果函数成功,返回值非0
- 如果函数失败,返回值为0
示例程序
// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <windows.h>
#include <stdio.h>
#include "resource.h"
#include "ConsoleApplication1.h"
BOOL CreateProcess_Test(LPWSTR pszExePath, UINT uiCmdShow)
{
STARTUPINFO si = { 0 };
PROCESS_INFORMATION pi;
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = uiCmdShow;
BOOL bRet = CreateProcess(NULL, pszExePath, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
if (bRet)
{
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return TRUE;
}
return FALSE;
}
int main()
{
wchar_t pszExePath[20] = L"calc.exe";
BOOL flag = CreateProcess_Test(pszExePath, SW_HIDE);
if (flag == TRUE)
{
printf("success\n");
}
return 0;
}
小结
- SW_HIDE的隐藏窗口只能隐藏CMD命令行窗口,对于其他程序窗口不能成功隐藏。
- 在用户层上,通常利用WMI或者通过HOOK API来监控进程的创建
- EnumWindows函数可以枚举所有屏幕上的顶层窗口,包括隐藏窗口