PIXNET Logo登入

Rootkit --逆向工程技術--

跳到主文

Rootkit與逆向工程技術研討 歡迎指教:P

部落格全站分類:數位生活

  • 相簿
  • 部落格
  • 留言
  • 名片
  • 7月 01 週五 201109:05
  • [原創]SkinMagic的分析 - 16進制編輯器的妙用

SkinMagic1
前言:之前用了個能自動美化VB的Skin,用的挺爽
但今天突然想美化VC,卻臨時找不到Skin來用
G狗了一下,找到了個SkinMagic v2.4的美化Skin
這是官網效果:
(繼續閱讀...)
文章標籤

殘月影 發表在 痞客邦 留言(0) 人氣(407)

  • 個人分類:應用層_資安研究
▲top
  • 6月 30 週四 201112:48
  • [原創]PECompact 2.x -> Jeremy Collake 手脫筆記 - 分析某款大陸抓Flash的軟體


這是一款專門用來直接從記憶體內抓Flash的軟體,非常的實用
經測試能抓到被 "加密過的Flash檔案" ,當然這絕不是為他打廣告
因為我下了快樂檔用,發現全是亂碼
 
(繼續閱讀...)
文章標籤

殘月影 發表在 痞客邦 留言(0) 人氣(669)

  • 個人分類:應用層-脫殼筆記
▲top
  • 6月 23 週四 201114:05
  • [分享]淺談脫殼中的Dump技術

前言:
    “知者不言,言者不知” 
                                     ----老子 《道德經》
   你會dump嗎?
   你還是只在OEP處dump嗎?
   你知道dump的原理嗎?
   你遇到過anti-dump的殼嗎,你知道如何對付它嗎?
   你明白幾種dump工具的優劣嗎?
   請原諒我,一開始就這麼不識趣的拋出了這幾個無厘頭的問題。我記得龍應台說過:正因為我那時什麼都不懂,
(繼續閱讀...)
文章標籤

殘月影 發表在 痞客邦 留言(1) 人氣(275)

  • 個人分類:應用層_資安研究
▲top
  • 6月 13 週一 201122:04
  • Rootkit高階技術盛會--HIT2011 台灣駭客嘉年華

官網:台灣駭客年會 HIT2011
一年一度難得的盛會又來囉!!!
台灣Rootkit技術最高的研討會~
(繼續閱讀...)
文章標籤

殘月影 發表在 痞客邦 留言(0) 人氣(304)

  • 個人分類:驅動層_Rootkit資安研究
▲top
  • 6月 07 週二 201123:42
  • [分享]剖析虛擬機的檢測技術

對岸一篇質量非常高的
頗析虛擬機檢測技術,共計6種檢測
用到了IDT等等的內核技術  
我整理成了繁中PDF格式  分享給大家
(繼續閱讀...)
文章標籤

殘月影 發表在 痞客邦 留言(1) 人氣(189)

  • 個人分類:驅動層_Rootkit資安研究
▲top
  • 6月 06 週一 201122:53
  • [分享]探索PE檔案內幕-Win32可執行檔案格式之旅


一本關於PE檔案格式非常好的原文著作
我翻譯成繁中化供大家學習囉
 
下載地址:點我
(繼續閱讀...)
文章標籤

殘月影 發表在 痞客邦 留言(1) 人氣(441)

  • 個人分類:應用層_資安研究
▲top
  • 6月 01 週三 201100:45
  • 隱藏驅動 搜尋方法(可找出某Np開頭的遊戲保護)

Rootkit
下面是關鍵代碼,可以查找斷開 PsLoadedModuleList 鏈的驅動,比如 某Np開頭的遊戲保護

PDIRECTORY_BASIC_INFORMATION    pDriverBuffer = NULL;


pDriverBuffer = (PDIRECTORY_BASIC_INFORMATION)m_cSysInfo.QueryDirectoryObject(L"\\Driver", &uMemSize);


查找驅動物件目錄下的所有物件,查找代碼如下。

PVOID CNativeSysInfo::QueryDirectoryObject(PWSTR pwsDirPath, PULONG puMemSize)
{
    NTSTATUS            ntStatus;
    UNICODE_STRING      usDirPath;
    OBJECT_ATTRIBUTES   oa;
    HANDLE              hDir = NULL;
    PVOID               pBuffer = NULL;
    ULONG               uLength = 0x800;
    ULONG               uContext = 0;
    ULONG               uResult = 0;

    // 判斷函數是否存在
    if(m_lpRtlInitUnicodeString == NULL ||
       m_lpZwOpenDirectoryObject == NULL ||
       m_lpZwQueryDirectoryObject == NULL ||
       m_lpZwClose == NULL)
    {
        return NULL;
    }

    // 打開目錄物件
    m_lpRtlInitUnicodeString(&usDirPath, pwsDirPath);
    InitializeObjectAttributes(&oa, &usDirPath, OBJ_CASE_INSENSITIVE, NULL, NULL);
    ntStatus = m_lpZwOpenDirectoryObject(&hDir, DIRECTORY_QUERY, &oa);
    if(ntStatus != STATUS_SUCCESS)
    {
        TRACE(_T("ZwOpenDirectoryObject failed!"));
        goto _exit;
    }

    // 查詢目錄物件
    do
    {
        if(pBuffer)
            VirtualFree(pBuffer, uLength, MEM_DECOMMIT);

        uLength *= 2;

        pBuffer = VirtualAlloc(NULL, uLength, MEM_COMMIT, PAGE_READWRITE);
        if(pBuffer == NULL)
            goto _exit;

        ntStatus = m_lpZwQueryDirectoryObject(hDir, pBuffer, uLength, FALSE, TRUE, &uContext, &uResult);

    } while(ntStatus == STATUS_MORE_ENTRIES || ntStatus == STATUS_BUFFER_TOO_SMALL);

    // 判斷查詢是否成功完成
    if(ntStatus == STATUS_SUCCESS)
    {
        if(puMemSize)
            *puMemSize = uLength;
    }
    else
    {
        VirtualFree(pBuffer, uLength, MEM_DECOMMIT);
        pBuffer = NULL;
    }

_exit:

    if(hDir)
    {
        m_lpZwClose(hDir);
        hDir = NULL;
    }

    return pBuffer;
}

然後把得到的結果和常規結果比較就可以找到隱藏驅動。隱藏驅動的相關資訊可以通過下面的方式得到。

    PDRIVER_OBJECT          pDrvObject = NULL;

    RtlInitUnicodeString(&usDirPath, (PCWSTR)pvInBuf);
    ntStatus = ObReferenceObjectByName(&usDirPath,
                                       OBJ_CASE_INSENSITIVE,
                                       NULL,
                                       0,
                                       *IoDriverObjectType,
                                       KernelMode,
                                       NULL,
                                       (PVOID*)&pDrvObject);

有了 DRIVER_OBJECT 結構就啥都有了!:)

下面是一個隱藏驅動的例子,用上面的辦法可以發現。

void _EraseDrvFromModList(PDRIVER_OBJECT pDrvObject)
{
    PLDR_DATA_TABLE_ENTRY   pOwen;
    PLDR_DATA_TABLE_ENTRY   pPrev;
    PLDR_DATA_TABLE_ENTRY   pNext;

    pOwen = (PLDR_DATA_TABLE_ENTRY)pDrvObject->DriverSection;
    pPrev = (PLDR_DATA_TABLE_ENTRY)pOwen->InLoadOrderModuleList.Blink;
    pNext = (PLDR_DATA_TABLE_ENTRY)pOwen->InLoadOrderModuleList.Flink;
    pPrev->InLoadOrderModuleList.Flink = (PLIST_ENTRY)pNext;
    pNext->InLoadOrderModuleList.Blink = (PLIST_ENTRY)pPrev;

    pOwen->InLoadOrderModuleList.Flink = (PLIST_ENTRY)pOwen;
    pOwen->InLoadOrderModuleList.Blink = (PLIST_ENTRY)pOwen;
}
(繼續閱讀...)
文章標籤

殘月影 發表在 痞客邦 留言(0) 人氣(343)

  • 個人分類:驅動層_Rootkit資安研究
▲top
  • 5月 31 週二 201123:55
  • 隱藏自身驅動 輕鬆繞過XueTr 0.39檢測

當系統載入一個驅動時,會為這個驅動建立一個_KLDR_DATA_TABLE_ENTRY結構體,DRIVER_OBJECT結構體的DriverSection成員指向這個結構體。以下是WRK中_KLDR_DATA_TABLE_ENTRY結構體的定義:
typedef struct _KLDR_DATA_TABLE_ENTRY {
    LIST_ENTRY InLoadOrderLinks;
    PVOID ExceptionTable;
    ULONG ExceptionTableSize;
    // ULONG padding on IA64
    PVOID GpValue;
    PNON_PAGED_DEBUG_INFO NonPagedDebugInfo;
    PVOID DllBase;
    PVOID EntryPoint;
    ULONG SizeOfImage;
    UNICODE_STRING FullDllName;
    UNICODE_STRING BaseDllName;
    ULONG Flags;
    USHORT LoadCount;
    USHORT __Unused5;
    PVOID SectionPointer;
    ULONG CheckSum;
    // ULONG padding on IA64
    PVOID LoadedImports;
    PVOID PatchInformation;
} KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY;
其中 PVOID DllBase; 成員指明了驅動的載入基址;
UNICODE_STRING FullDllName;指明了驅動.sys檔的全路徑;
所有驅動的結構體通過InLoadOrderLinks成員連結起來,鏈表頭部為PsLoadedModuleList,因此可以通過遍歷PsLoadedModuleList來得到所有載入的驅動。
在測試中發現,如果將某一驅動的DllBase或FullDllName.buffer填為0,那麼XueTr就不會顯示這個驅動,以下是將DllBase填0時的驗證代碼:
(繼續閱讀...)
文章標籤

殘月影 發表在 痞客邦 留言(0) 人氣(634)

  • 個人分類:驅動層_Rootkit資安研究
▲top
  • 5月 30 週一 201112:15
  • 檔案過濾驅動學習筆記(還原軟體的基礎)

最近幾天學習了下檔案過濾驅動, 這方面的資料確實很少
這篇文章是我這幾天學習的總結, 特此貼出來供大家一起學習,
畢竟是初學檔案過濾驅動, 錯誤之處難免, 還請多多見諒.
下面進入正題
1.DriverEntry常式
(1)創建過濾驅動的控制設備, 以後我們的IO控制碼就是發到這個設備上面
//這裡的設備名與普通設備有所不同.
//當然, 最簡單的可以直接寫成 L"\\Device\\Filemontor";(FileMon中是這麼寫的, 調試過可行)
RtlInitUnicodeString( &nameString, L"\\FileSystem\\Filters\\FileMonitor" );
status = IoCreateDevice( DriverObject,
             0,                     //has no device extension  
                        //這是與其他Attach到別的設備上的設備的不同之處 
             &nameString,
             FILE_DEVICE_DISK_FILE_SYSTEM,
             FILE_DEVICE_SECURE_OPEN,
             FALSE,
             &gSFilterControlDeviceObject );
if (status == STATUS_OBJECT_PATH_NOT_FOUND) {
  RtlInitUnicodeString( &nameString, L"\\FileSystem\\FileMonitor" );
  status = IoCreateDevice( DriverObject,
               0,                      
               &nameString,
               FILE_DEVICE_DISK_FILE_SYSTEM,
               FILE_DEVICE_SECURE_OPEN,
               FALSE,
               &gSFilterControlDeviceObject );
} 
//創建符號連結
RtlInitUnicodeString(&syblnkString, L"\\DosDevices\\FileMonitor");
status = IoCreateSymbolicLink( &syblnkString, &nameString );
if (!NT_SUCCESS(status)) {
  IoDeleteSymbolicLink( &syblnkString );
  status = IoCreateSymbolicLink( &syblnkString, &nameString );
  
  if (!NT_SUCCESS(status)) {
    KdPrint(("創建符號連結失敗~\n"));
    IoDeleteDevice(gSFilterControlDeviceObject);
    return status;
  }
}
(2)設置常式
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
  DriverObject->MajorFunction[i] = SfDispatch;
}
DriverObject->MajorFunction[IRP_MJ_CREATE] = SfCreate;
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = SfFsControl;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = SfCleanupClose;
(3)調用IoRegisterFsRegistrationChange函數來通知我們檔案系統的載入和卷的mount.
2.SfCreate 常式
(1)sfilter的原版中是這麼寫的
if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject)) {
  Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
  Irp->IoStatus.Information = 0;
  IoCompleteRequest( Irp, IO_NO_INCREMENT );
  return STATUS_INVALID_DEVICE_REQUEST;
}
這樣寫的後果是我們用CreateFile函數在R3下打開此控制設備符號連結的時候失敗
我剛開始學習檔過濾驅動的時候對此不是很瞭解, CreateFile老是失敗, 
起初還以為是符號連結名寫錯了, 後來參看了FileMon的代碼才反應過來
於是修改如下:
if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject)) {
    
  Irp->IoStatus.Status = STATUS_SUCCESS;
  Irp->IoStatus.Information = FILE_OPENED;
  IoCompleteRequest( Irp, IO_NO_INCREMENT );
  return STATUS_SUCCESS;
}
(2)根據不同軟體的需要, 編寫此函數的接下來部分
[1]比如我們要阻止病毒在Windows目錄下創建檔, 那麼我們就要在此檔還沒創建的時候得到此檔的全路徑.
要在這個時候得到檔的路徑, 楚狂人也說了有點麻煩. 下面提供一個函數給大家, 用於在檔創建前得到路徑.
BOOLEAN MzfGetFileFullPathPreCreate(PFILE_OBJECT pFile, PUNICODE_STRING path )
{
   NTSTATUS status;
   POBJECT_NAME_INFORMATION pObjName = NULL;
   WCHAR buf[256] = {0};
   void *obj_ptr = NULL;
   ULONG ulRet = 0;
   BOOLEAN bSplit = FALSE;
   if (pFile == NULL) return FALSE;
   if (pFile->FileName.Buffer == NULL) return FALSE;
   pObjName = (POBJECT_NAME_INFORMATION)buf;
   if (pFile->RelatedFileObject != NULL)
      obj_ptr = (void *)pFile->RelatedFileObject;
   else
      obj_ptr = (void *)pFile->DeviceObject;
   status = ObQueryNameString(obj_ptr, pObjName, 256*sizeof(WCHAR), &ulRet);
   if (status == STATUS_INFO_LENGTH_MISMATCH)
   {
      pObjName = (POBJECT_NAME_INFORMATION)ExAllocatePool(NonPagedPool, ulRet);
      if (pObjName == NULL)  return FALSE;
      RtlZeroMemory(pObjName, ulRet);
      status = ObQueryNameString(obj_ptr, pObjName, ulRet, &ulRet);
      if (!NT_SUCCESS(status)) return FALSE;
   }
 //拼接的時候, 判斷是否需要加 '\\'
 if (pFile->FileName.Length > 2 && 
  pFile->FileName.Buffer[0] != L'\\' &&
  pObjName->Name.Buffer[pObjName->Name.Length/sizeof(WCHAR) -1] != L'\\')
    bSplit = TRUE;
 
 ulRet = pObjName->Name.Length + pFile->FileName.Length;
 if (path->MaximumLength < ulRet)  return FALSE;
 RtlCopyUnicodeString(path, &pObjName->Name);
 if (bSplit)
   RtlAppendUnicodeToString(path, L"\\");
 RtlAppendUnicodeStringToString(path, &pFile->FileName);
 if ((void*)pObjName != (void*)buf)
    ExFreePool(pObjName);
 return TRUE;
}
至此, 得到了檔的路徑以後, 我們就可以做出判斷了, 如果要阻止檔創建, 
那麼直接用IoCompleteRequest函數結束此IRP即可, 否則下發
IoSkipCurrentIrpStackLocation( Irp );
return IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp );
[2]要是像FileMon那樣只是記錄系統中創建了哪些檔的話, 我們可以設置此函數的完成常式.
然後等檔創建完成了之後, 只要調用 IoQueryFileDosDeviceName 函數即可知道檔的全路徑了.
設置完成常式如下:
{
  KEVENT waitEvent;
  KeInitializeEvent( &waitEvent, NotificationEvent, FALSE );
  IoCopyCurrentIrpStackLocationToNext( Irp );
  IoSetCompletionRoutine(Irp, SfCreateCompletion, &waitEvent, TRUE, TRUE, TRUE );
  status = IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp );
  if (STATUS_PENDING == status) {
    NTSTATUS localStatus = KeWaitForSingleObject(&waitEvent, Executive, KernelMode, FALSE, NULL);
    ASSERT(STATUS_SUCCESS == localStatus);
  }
  //此處檔已經創建完成了, 我們可以調用IoQueryFileDosDeviceName函數得到檔的全路徑
  //最後結束此IRP
  status = Irp->IoStatus.Status;
  IoCompleteRequest( Irp, IO_NO_INCREMENT );
  return status;
}
3.SfDispatch常式
在此常式中要判斷是不是我們的控制設備, 如果使我們的控制設備, 則要處理相應的IO控制碼.
否則, 下發此IRP
NTSTATUS SfDispatch ( IN PDEVICE_OBJECT DeviceObject,  IN PIRP Irp )
{
  NTSTATUS status = STATUS_SUCCESS;
    PIO_STACK_LOCATION irpStack;
    
    if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject)) {
        Irp->IoStatus.Information = 0;
        irpStack = IoGetCurrentIrpStackLocation( Irp );
    
        switch (irpStack->MajorFunction) {
      
    case IRP_MJ_DEVICE_CONTROL:
      // 此函數用來執行相應的控制碼
      status = SpyCommonDeviceIoControl( Irp->AssociatedIrp.SystemBuffer,
                                                   irpStack->Parameters.DeviceIoControl.InputBufferLength,
                                                   Irp->AssociatedIrp.SystemBuffer,
                                                   irpStack->Parameters.DeviceIoControl.OutputBufferLength,
                                                   irpStack->Parameters.DeviceIoControl.IoControlCode,
                                                   &Irp->IoStatus );
      break;
      
    case IRP_MJ_CLEANUP
      status = STATUS_SUCCESS;
      break;
      
    default:
      status = STATUS_INVALID_DEVICE_REQUEST;
        }
    
        Irp->IoStatus.Status = status;
        IoCompleteRequest( Irp, IO_NO_INCREMENT );
        return status;
    }
  
  //不是我們的控制設備則下發此IRP
    return SfPassThrough( DeviceObject, Irp );
}
IO控制碼也可以在FASTIO常式的SfFastIoDeviceControl函數中處理,如下:
當然, 最簡單的還是在FASTIO常式中返回FALSE. 這樣, 系統便會調用我們上面的SfDispatch函數.
if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject)) {
    
        SpyCommonDeviceIoControl( InputBuffer,
      InputBufferLength,
      OutputBuffer,
      OutputBufferLength,
      IoControlCode,
      IoStatus );
    
        return TRUE;
(繼續閱讀...)
文章標籤

殘月影 發表在 痞客邦 留言(0) 人氣(428)

  • 個人分類:驅動層_Rootkit資安研究
▲top
  • 5月 30 週一 201111:47
  • NetBoxDex v0.1 (NetBox 解壓縮工具源碼)




NetBox 
是一個全新概念的開發平臺,它提供了業界最快速的用於開發 Internet 商業應用的開發和編譯工具。NetBox 支援包括 JavaScript、VBScript、Perl 等目前應用最為廣泛的指令碼語言來構建功能強大和性能穩定的應用伺服器、網路服務器以及 HTML-Based 網路多媒體桌面應用。NetBox 支援目前最為流行的 XML 和 Web Service 工業標準和 ASP、COM、.NET 等流行標準,NetBox 對協力廠商資料庫的完美支援使您新構建的商務應用可以容易的將已有的應用系統整合進來,從而充分利用現有的 IT 資源,大大的節約投資。NetBox 提供的 SSL、TLS 安全協定、RSA、DES 等加密演算法和獨立於應用程式的虛擬機器技術使您的資料得到最大限度的保護。NetBox 提供將應用部署到無線設備的能力。NetBox 提供將您的應用編譯成獨立可執行檔的能力,極大的加快運行速度和代碼安全性。使用 NetBox 開發,大大提高了應用系統的可擴展性、穩定性和安全性。NetBox 的出現也首次讓應用軟體發展商能夠如此快速和容易的構建完整的基於 Internet 強大應用。
(繼續閱讀...)
文章標籤

殘月影 發表在 痞客邦 留言(0) 人氣(189)

  • 個人分類:應用層_資安研究
▲top
«123...5»