网络天下|黑客安全|-黑客中国|免费BLOG|黑客安全|安全检测|视频教学|最新音乐|免费游戏|免费软件|安全技术|技术探讨|安全教程

所属分类: 网络收集 更新日期:2008-4-29 17:57:34 阅读次数:230

木马编程DIY之系统服务



对系统服务的管理几乎是目前的木马必不可少的功能,比如神气儿、上兴远程控制等,都提供了此项服务。要是我们能给自己编写的木马也加上这个功能,看着也不赖哦。好啦,废话不多说,下面开始干活!

  取得配置权限

  在对服务进行管理设置前,我们需要以相应的权限打开服务,本文通过下面的两个API来实现操作。

SC_HANDLE OpenSCManager(

LPCTSTR lpMachineName,

// pointer to machine name string

LPCTSTR lpDatabaseName,

// pointer to database name string

DWORD dwDesiredAccess // type of access

);

SC_HANDLE OpenService(

SC_HANDLE hSCManager,

// handle to service control manager database

LPCTSTR lpServiceName,

// pointer to name of service to start

DWORD dwDesiredAccess

// type of access to service

);


  对于系统服务的管理,通常情况下我们是以完全权限打开的,要实现这个功能,我们可以使用下面的代码来操作。

SC_HANDLE scm;
SC_HANDLE service;

if((scm=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS))==NULL)

{ Printf("OpenSCManager Error\n");

}

service=OpenService(scm,ServerName,SERVICE_ALL_ACCESS);

if(!service)

{ Printf("OpenService error!\n");

}


  这样,就可以通过Service句柄对服务进行各种操作了。

  枚举基本服务信息

  想要对服务进行设置,就需要知道服务的当前信息。其中对我们有用的通常是以下几项:服务名称、显示名称、启动状态、启动方式和程序路径等。这些信息我们可以通过API函数EnumServicesStatus来实现,它的原形如下:

BOOL EnumServicesStatus(
SC_HANDLE hSCManager,

 // handle to service control manager database

DWORD dwServiceType,

 // type of services to enumerate

DWORD dwServiceState,

 // state of services to enumerate

LPENUM_SERVICE_STATUS lpServices,

// pointer to service status buffer

DWORD cbBufSize,

 // size of service status buffer

LPDWORD pcbBytesNeeded,

 // pointer to variable for bytes needed

LPDWORD lpServicesReturned,

// pointer to variable for number returned

LPDWORD lpResumeHandle

 // pointer to variable for next entry

 );


  在上面的代码中,LPENUM_SERVICE_STATUS lpServices是一个结构,其原形如下:

typedef struct _ENUM_SERVICE_STATUS { // ess

LPTSTR lpServiceName;

LPTSTR lpDisplayName;

SERVICE_STATUS ServiceStatus;

} ENUM_SERVICE_STATUS, *LPENUM_SERVICE_STATUS;


  这个结构中包含服务名称、显示名称、启动状态。虽然它所返回的信息是极为有限的,但它是一次枚举所有的服务信息的。在要求不高的情况下,用它还是相当方便的。下面的示例代码可以枚举系统中所有服务的基本信息,实现代码如下所示。

LPENUM_SERVICE_STATUS lpServices = NULL;

DWORD nSize = 0;

DWORD n;

DWORD nResumeHandle = 0;

lpServices=(LPENUM_SERVICE_STATUS) LocalAlloc(LPTR, 64 * 1024);   //注意分配足够的空间

EnumServicesStatus(scm,SERVICE_WIN32,SERVICE_STATE_ALL,(LPENUM_SERVICE_STATUS)lpServices,64 * 1024,&nSize,&n,&nResumeHandle);

for ( i = 0; i < n; i++)

{

Printf("服务名称: %s",lpServices.lpServiceName);

Printf("显示名称: %s",lpServices.lpDisplayName);

if ( lpServices.ServiceStatus.dwCurrentState!=SERVICE_STOPPED)

{ Printf("启动状态: 已启动\n");

}

}


  枚举详细服务信息

  如果想要得到更详细的服务信息,我们可以使用另一个API函数QueryServiceConfig来获得,它的原形如下所示。

BOOL QueryServiceConfig(
SC_HANDLE hService, // handle of service

LPQUERY_SERVICE_CONFIG lpServiceConfig,

// address of service config. structure

DWORD cbBufSize,

// size of service configuration buffer

LPDWORD pcbBytesNeeded

 // address of variable for bytes needed

 );

其中LPQUERY_SERVICE_CONFIG lpServiceConfig也是一个结构,它包含指定服务的详细资料,其原形如下所示。
typedef struct _QUERY_SERVICE_CONFIG { // qsc

DWORD dwServiceType;

DWORD dwStartType;

DWORD dwErrorControl;

LPTSTR lpBinaryPathName;

LPTSTR lpLoadOrderGroup;

DWORD dwTagId;

LPTSTR lpDependencies;

LPTSTR lpServiceStartName;

LPTSTR lpDisplayName;

}QUERY_SERVICE_CONFIG, LPQUERY_SERVICE_

CONFIG;


  很清楚了吧?服务类型、启动类型、程序路径、服务名称、显示名称尽在其中。而下面的示例代码则可以得到程序路径和启动方式,其代码如下所示。

LPQUERY_SERVICE_CONFIG ServicesInfo = NULL;

for ( i = 0; i < n; i++)

{

SC_HANDLE service = NULL;

DWORD nResumeHandle = 0;

service=OpenService(scm,lpServices.lpServiceName,SERVICE_ALL_ACCESS);

ServicesInfo = (LPQUERY_SERVICE_CONFIG) LocalAlloc(LPTR, 64 * 1024);

//注意分配足够的空间

QueryServiceConfig(service,ServicesInfo,64 * 1024,&nResumeHandle);

//枚举各个服务信息

Printf("程序路径: %s",ServicesInfo->lpBinaryPathName);

if(2==ServicesInfo->dwStartType) //启动方式

{

Printf("自动\n");

}

if(3==ServicesInfo->dwStartType)

{

Printf("手动\n");

}

if(4==ServicesInfo->dwStartType)

{ Printf("禁止\n");

}

}

  上面的代码,只要大家根据需要稍加修改,就可以用到自己的程序中了。现在,对于服务信息的显示就算完成了。

  启动/停止服务

  启动一个服务我们可以用StartService函数来实现,不过在启动前得先用QueryServiceStatus检查一下服务的运行状态。具体的实现代码如下所示。

SERVICE_STATUS status;
BOOL isSuccess=QueryServiceStatus(service,&status);

if (!isSuccess)

{

Printf("QueryServiceStatus error!\n");

}

if ( status.dwCurrentState==SERVICE_STOPPED )

{

isSuccess=StartService(service,NULL,NULL);

if (!isSuccess)

{

Printf("启动服务失败!");

}

}


  下面是停止服务的实现代码。

if ( status.dwCurrentState!=SERVICE_STOPPED )
{

isSuccess=ControlService(service,SERVICE_CONTROL_STOP,&status);

if (!isSuccess )

{

Printf("停止服务失败!");

}

}


  创建/删除服务

  创建服务我们使用的API为CreateService,其原形如下所示。

SC_HANDLE CreateService(
SC_HANDLE hSCManager,

 // handle to service control manager database

LPCTSTR lpServiceName,

 // pointer to name of service to start

LPCTSTR lpDisplayName,

 // pointer to display name

DWORD dwDesiredAccess,

 // type of access to service

DWORD dwServiceType, // type of service

DWORD dwStartType, // when to start service

DWORD dwErrorControl,

 // severity if service fails to start

LPCTSTR lpBinaryPathName,

// pointer to name of binary file

LPCTSTR lpLoadOrderGroup,

// pointer to name of load ordering group

LPDWORD lpdwTagId,

// pointer to variable to get tag identifier

LPCTSTR lpDependencies,

 // pointer to array of dependency names

LPCTSTR lpServiceStartName,

// pointer to account name of service

LPCTSTR lpPassword

 // pointer to password for service account

 );

其中DWORD dwStartType是指动方式,有SERVICE_AUTO_START(自动)、SERVICE_DEMAND_START(手动)和SERVICE_DISABLED(禁用)三种方式。此函数的参数比较多,但我们通常只会用到其中的一部分,比如SC_HANDLE hSCManager(用OpenSCManager打开的句柄)、LPCTSTR lpServiceName(服务名称)、LPCTSTR lpDisplayName(显示名称)、DWORD dwStartType(启动方式)和LPCTSTR lpBinaryPathName(程序路径),其它的直接赋值为0或Null就可以了。而下面的代码就可以创建一个名为 LengFeng、路径为C:\LengFeng.EXE的自启动服务。
void CreateServer()

{

SC_HANDLE scm=NULL;

SC_HANDLE service=NULL;

if((scm=OpenSCManager(NULL,NULL,SC_MANAGER_CREATE_SERVICE))==NULL)

{

Printf("OpenSCManager Error");

}

service=CreateService(scm,"LengFeng","LengFeng",SERVICE_ALL_ACCESS,SERVICE_WIN32_OWN_PROCESS,SERVICE_AUTO_START,SERVICE_ERROR_NORMAL,"C:\LengFeng.EXE",0,0,0,0,0);

if(!service)

Printf("服务创建失败");

CloseServiceHandle(service);

CloseServiceHandle(scm);

}


  要实现删除服务则比较容易,我们只要使用DeleteService即可实现,其代码如下所示。

  BOOL DeleteService( SC_HANDLE hService);

  这里提醒大家一下,SC_HANDLE hService是我们上面用OpenService打开的服务句柄,在删除服务前要注意先用启动/停止服务中介绍的方法停止正在运行的服务才可以。

  配置启动方式

  有时候我们需要对服务的启动方式进行更改,比如将Telnet改为自动运行,对已存在的服务进行配置等。我们可以用ChangeServiceConfig来实现,其原形如下所示。

BOOL ChangeServiceConfig(
SC_HANDLE hService, // handle to service

DWORD dwServiceType, // type of service

DWORD dwStartType, // when to start service

DWORD dwErrorControl,

 // severity if service fails to start

LPCTSTR lpBinaryPathName,

// pointer to service binary file name

LPCTSTR lpLoadOrderGroup,

// pointer to load ordering group name

LPDWORD lpdwTagId,

// pointer to variable to get tag identifier

LPCTSTR lpDependencies,

// pointer to array of dependency names

LPCTSTR lpServiceStartName,

// pointer to account name of service

LPCTSTR lpPassword,

 // pointer to password for service account

LPCTSTR lpDisplayName // pointer to display name

 );


  揉揉眼睛仔细看一下,上面的代码是不是有点面熟?它的参数跟创建服务的CreateService就是一样的嘛!这下就好办了。我们把需要的地方改掉,不需要的就放个Null或SERVICE_NO_CHANGE就行了。

  为了实现安全的更新配置信息,微软要求在执行ChangeServiceConfig之前需要用LockServiceDatabase来锁定服务数据。我测试了一下,有时候虽然会锁定失败,但仍然可以实现对服务配置的更改。下面的示例代码,可以把上面创建的LengFeng服务的启动方式改为“禁止”,其实现代码如下所示。

SC_LOCK sclLock;

sclLock = LockServiceDatabase(scm);

if (sclLock == NULL)

{

if (GetLastError() != ERROR_SERVICE_DATABASE_

LOCKED)

Printf("LockServiceDatabase error\n");

} if (! ChangeServiceConfig(

service, // handle of service

SERVICE_NO_CHANGE, // service type: no change

SERVICE_DISABLED, // 这里做了更改

SERVICE_NO_CHANGE, // error control: no change

NULL, // binary path: no change

NULL, // load order group: no change

NULL, // tag ID: no change

NULL, // dependencies: no change

NULL, // account name: no change

NULL, // password: no change

NULL)) //displayname

{Printf("ChangeServiceConfig error!\n"); }

UnlockServiceDatabase(sclLock);

  至此为止,与系统服务相关的操作,我们就搞个八九不离十了。要想把它们加到自己的木马程序中,我们只要设计一个便于网络传输的结构,然后把代码拷进去就差不多了。在写这个小程序时,我将遇到的问题写在了自己的博客blog.csdn.net/chinafe中,有兴趣的读者可以跟我一起讨论,或者登录黑防官方论坛一起讨论也可。




文章分类

网络收集
支持原创
系统后门

本类热门文章

  google入侵语法整理(242748)
免费Q币,取得相对比较容易(50116)
随便修改别人的QQ号密码(41875)
网上十大黑客软件大曝光(33311)
成为顶级黑客(2003年...(32243)
免费拨打长途固定电话(24951)
QQ密码忘了?打造自己的...(22564)
最详细的黑客教程--第一部(22190)
黑客之八种超级武器(上)(17967)
网吧常见漏洞及利用(16273)
如何让自己成为一名黑客高...(16245)
经典攻击入侵手段(16230)
一分钟入侵WIN9X(14132)
唯一的免费ASP空间(10887)
WEB入侵的过程(8855)

文章搜索



本 站 声 明

  本站的大部分资料,文章都来自网上收集,其版权归作者本人所有,如果有任何侵犯您权益的地方,请联系我,我将马上进行整理,谢谢。

网络天下 版权所有
豫ICP备05013117号 41653354-8
Email: webmaster@lzbiz.com QQ:7787686 TEL:13783172430