Винлокеры и криптолокеры настолько мощно достали мировую общественность, что мы решили не оставаться в стороне и немного пофантазировать на тему: а что было бы, если бы злохакеры писали их на сишарпе?

WARNING

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

Принцип работы

Рис. 1. Блок-схема
Рис. 1. Блок-схема

Начинаем, как всегда, с алгоритма. Главные моменты рассматриваемой программы уместились на двух картинках, первый рисунок представляет собой блок-схему, а второй показывает диаграмму классов из Visual Studio.

Из схемы мы видим, что при каждом запуске программа первым делом задается вопросом: а что вообще здесь происходит? И если ответ ей не понравится, она благополучно закрывается, не производя никаких серьезных действий. Сделано это для повышения стабильности работы и безопасности самой программы, можно также добавить выборочный запуск, основываясь на версии ОС или любом другом параметре (даже частоте ядра CPU).

Класс GetInfo возвращает своему клиенту следующую информацию:

  • версию ОС Environment.OSVersion;
  • версию BIOS ManagementObjectSearcher("SELECT * FROM Win32_BIOS");
  • имя пользователя Environment.GetEnvironmentVariable("USERNAME");
  • архитектуру процессора Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE").

Требование прав администратора и проверка их наличия производится двумя способами:

  • в файле app.manifest задается строка <requestedExecutionLevel level="requireAdministrator" uiAccess="false";
  • так как в Windows XP нет UAC, то в коде проверяем значение WindowsBuiltInRole.Administrator и если ответ false, то перезапускаемся с processInfo.Verb = "runas".
Рис. 2. Классы
Рис. 2. Классы

После получения и анализа этой информации наступает этап «проверки файла». Название этапа, конечно, условное, суть его — не допустить повторного заражения текущей операционной системы. Для этого используются флаги присутствия, это может быть ключ реестра или обычный файл. Если флаг не обнаружен, то пользователю, запустившему программу, выдается окно с фиктивной ошибкой, затем происходит инсталляция винлокера и далее выход. На этом все — никаких активных действий и logoff, ждем следующего запуска/загрузки или смены пользователя.

Как только это произошло и два предыдущих условия вернули сначала «НЕТ», а затем «ДА», наступает этап проверки запуска. Его задача — определить, требуется ли шифровать системные файлы, которые задаются массивом строк fileToCrypt (explorer, regedit, cmd и так далее), или оно было выполнено ранее. В коде винлокера для поиска текущей директории Windows был выбран метод Environment.ExpandEnvironmentVariables("%windir%"), так как он корректно отрабатывал и на Windows XP, и на Windows 8.1. Также на всякий случай ведется сканирование запущенных процессов KillProcess.DoJob() и, если они активны, попытка закрыть их, чтобы исключить возникновение ошибки при доступе на запись. Алгоритм шифрования и пароль могут быть любыми и любой сложности, от случайных до выданных по сети подконтрольным сервером. Можно даже использовать социальные сети для их генерации или размещения (как на доску объявлений). Следует заметить, что пароль, переданный по сети и никак не сохраненный в теле программы, значительно повышает его эффективность, в «Испытании» расскажу об этом подробнее. Когда все перечисленные действия выполнены успешно, программа переходит к главной форме винлокера.

public partial class FormHide : Form
...
private static void DoJobTwo(){
if (...)
    {...
    KillProcess.DoJob();
    FileCryptDecrypt.DoJob();
    }
UserQuest.DoJob();
...
public static class UserQuest
{
    public static KeyboardHook kh;
    public static void DoJob()
    {
        using (kh = new KeyboardHook())
        {
            Application.Run(new MainForm_UserQuest()); //Запуск главной формы
        }
    }
}

В коде можно заметить, что перед запуском MainFormUserQuest активируется класс KeyboardHook, который и выполняет перехват нажатия всех клавиш клавиатуры, используя низкоуровневый API-интерфейс. Затем происходит их фильтрация с перенаправлением в строку ответа главной формы. И так как свободно работает только мышка, кнопки Del и Backspace были переназначены для очищения набранного текста (e.KeyCode == (int)Keys.Delete -> textBoxInput.Clear()). Отфильтрованы заглавные буквы D с цифр клавиатуры (e.KeyName.Replace("D", "")), что в итоге позволило набрать все возможные символы, которые могут встретиться в сгенерированном пароле, удобно и без проблем.

Рис. 3. Главная форма
Рис. 3. Главная форма
if (textBox_Input.Text.ToUpper() == Answer())
{
    MessageBox.Show("Отлично, сейчас я все верну на место");
    try
    {
        FileCryptDecrypt.DoJob();
        RegEdit.ReturnExplorer();
        DeleteOurFiles();
        KillProcess.StartExplorer();
        Application.ExitThread();
    }
    ...
}

В этом примере правильный ответ имеет вид строки md5Hash(GetInfo.UserName() + GetInfo.ProcArchitecture()), и в случае его ввода винлокер полностью возобновляет работоспособность операционной системы — расшифровывает файлы, удаляет ключи реестра и флаги присутствия. Известно, что запущенный процесс не может удалить сам себя (исключение — NTFS-потоки), но, используя код из статьи «Социальный ботлоадер», можно создать батник, добивающий последний исполняемый файл и себя заодно по истечении десяти секунд пинга (ping 1.1.1.1 -n 1 -w 10000 > nul). Замечу, что пароль, который требуется ввести пользователю, никак не связан с паролем, который использовался при шифровании системных файлов.

На этом все, основные внутренние процессы винлокера разобраны, перейдем к следующему этапу.

Испытание

Так как цели нашего повествования исключительно образовательные, испытание будет проводиться на виртуальных машинах. Запускаем VirtualBox и Windows различных версий, вылавливаем все ошибки в процессе работы программы.

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

Когда же все заработало, я попытался его снять стандартными способами. Безопасный режим и правка реестра не помогут, ведь загрузка с зашифрованного файла explorer.exe невозможна. Восстановление системы своими силами тоже не поможет, файл rstrui.exe был в списке массива fileToCrypt. Удаление файла винлокера не самый лучший выход, ведь только в нем есть метод расшифровки. В коде не содержатся все пути резервных копий реестра и DLL-файлов для разных версий Windows, нет и метода удаления точек восстановления, которыми многие пользуются. Зато у нас в программе содержится одна лазейка, о которой внимательный читатель наверняка уже успел подумать, — если найти правильный флаг присутствия на этапе проверки шифрования и удалить его, то винлокер без ввода пароля вернет файлы обратно в рабочее состояние, вызвав метод FileCryptDecrypt.DoJob(). Избежать этого можно усложнением процедуры проверки, например, флагом может быть возможность прочитать цифровую подпись одного из зашифрованных файлов. В этом случае такой трюк не пройдет, хотя величие всея сети и тут значительно превосходит возможности для изобретений и флаг уже не понадобиться, ибо пароля в программе нет.

Заключение

Не стоит воспринимать рассмотренный «винлокер» как один из полноценных криптолокеров, это не так. Файлы пользователя не страдают и не искажаются, их содержимое не передается третьим лицам. Другими словами, все нажитое честным трудом остается, а «страдает» исключительно приобретенная в аренду операционная система. Которую к тому же легко переставить. На этом все, желаю добра и приятной работы.

  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    10 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии