trj.nextgen.insystem или необычный способ внедрения в автозагрузку

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by flacs, 13 Nov 2010.

  1. flacs

    flacs Member

    Joined:
    28 Jan 2009
    Messages:
    81
    Likes Received:
    31
    Reputations:
    6
    Сейчас я постараюсь подробно описать метод wrap'инга DLL, который когда успешно применялся в нашем приватном чите NextGen для Sxe-Injected два года назад.

    Один из необычных вариантов внедрения в автозагрузку компьютера:

    Введение

    У многих на компьютере установлены различные программы, QIP, Miranda, различные фаерволы,
    антивирусы. Некоторые из них запускаются при автозагрузке. Но каждая программа состоит из
    библиотек (DLL), которые подгружаются при старте программы. Бывают системные DLL (ntdll.dll,
    kernel32.dll и др. - так называемые knownDLL), есть и те уже есть в комплекте программы. Что если внедрить свой код в DLL, при запуске ведь код все равно выполнится. Для этого будем юзать специальную технологию wrap'пинга DLL.

    Суть в том чтобы экспортировать все функции из оригинальной DLL, и сделать переход на них.

    Для этого:
    1) Читаем таблицу экспорта, и генерируем скрипт для последующего компилирования, естественно прошлую библиотеку переименовываем, и в скрипте грузим
    2) Будем использовать компилятор DCC32.exe который будет в теле троянца.

    Система wrap инга DLL выглядит сл. образом, чтобы было более понятно возьмем пример сгенерированного скрипта

    Code:
    library __hook;
    function MessageBox(hWnd: LongWord; lpText, lpCaption: PChar; uType: LONGWORD): integer; stdcall; external 'user32.dll' name 'MessageBoxA';
    var hModule : Cardinal;
    __Sum: Integer;
    function Sum: integer;assembler;stdcall;export;
    asm
    jmp __Sum // делаем переход
    end;
    exports
    Sum index 1; // экспортируем
    procedure proc; begin
    hModule := LoadLibrary('___hooked.dll'); // грузим оригинал
    if hModule <> 0 then begin
    __Sum:= Integer( GetProcAddress(hModule, 'Sum') ); // определяем адреса
    end;
    MessageBox(0, 'Works ...', 'xD', 0); end; // тестовая функция для наглядности
    procedure DoDllProc(Reason : LongWord); // EntryPoint
    begin
    case Reason of
    DLL_PROCESS_ATTACH : proc;
    DLL_PROCESS_DETACH : ;
    end; end;
    begin
    if (not Assigned(DllProc)) then begin DllProc := DoDllProc; DoDllProc(DLL_PROCESS_ATTACH); end;
    end.
    
    Суть моей разработки, в том чтобы автоматизировать процесс сбора экспортных функций длл, и компилирование его компилятором DCC32.exe.

    Т.е. в процедуре указываем - путь к нужной DLL, она сама прочитает таблицу экспорта, сгенерирует скрипт,
    извлекет из тела сам компилятор, и системные файлы для компилирования (system.pas, sysinit.pas) - кстати они почти пустые. Скомпилирует библиотеку, переменует оригинал, сделает его скрытым, и запишет нашу подменную длл, в которой выполниться наш код(ну для теста MessageBox сойдет =). Далее после этого запускаем прогу, и вуаля получаем что наша DLL получила управление. Этот метод можно использовать где угодно, где нет проверки контрольной зависимых от ехе DLL, можно даже заменить либы фаервола, и либа получив управление выполнит люой код, в контексте доверенного приложения. Для работы с сетью мнложество программ юзает либу wsock32.dll, можно ее "заврапить" , потом скопировать обе либы в папку с программой, и наша длл получит управление.
    Также заменив либы доверенных приложений, можно есеесно обойти UAC, фаеволы, антивирусы, у них то в правилах все прописано, что запускать а что нет, т.к. пользователю задалбливать нажимать разрешить каждый раз когда он юзает например какой нибудь ICQ клиент.

    Поддерживается листинг экспорта как по имеенам, так и по ординалам.

    Ну вообщем все. И напоследок исходники
    trj.nextgen.insystem.src

    (c) flacs 2010
     
    #1 flacs, 13 Nov 2010
    Last edited: 14 Nov 2010
    1 person likes this.