Для получения триального ключа
заполните форму ниже
Team license
Enterprise license
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Бесплатная лицензия PVS-Studio для специалистов Microsoft MVP
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

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

Мне интересно попробовать плагин на:
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте папку
Spam/Junk и нажмите на письме кнопку "Не спам".
Так Вы не пропустите ответы от нашей команды.

>
>
>
Как я программу на вирусы проверял

Как я программу на вирусы проверял

23 Авг 2022
Автор:

Поводом для написания данной статьи послужил диалог в одном телеграмном чате. Кто-то выложил программу для "уникализации" файлов путем изменения хэша MD5, а другой бдительный участник чата проверил ее на Virustotal и из-за двух положительных (и 68 отрицательных) результатов обвинил программу в наличии недекларированных функций, в том числе даже в краже паролей от различных аккаунтов, а всех установивших ее — в "излишках" ума. Увещевания его и рассказ о возможных ложноположительных срабатываниях не дали желаемого результата, беседа перестала быть конструктивной и затухла.

0981_Viruses_check_ru/image1.png

Мы опубликовали и перевели эту статью с разрешения правообладателя. Автор статьи – Stariy. Оригинал опубликован на сайте Habr.

0981_Viruses_check_ru/image2.png

Рисунок 1. Virustotal

Но я (как один из участников того диспута) потерял покой, сон и аппетит, ведь, с одной стороны, если антивирус ругается, то нет повода ему не верить и стоит быть осторожным. С другой — два не самых популярных антивируса, было бы из-за чего беспокоиться. Но самое главное — а если вообще было бы 0 детектов, дает ли это основания быть уверенным в программе? И как быть в таком случае? Ну и еще в довесок было интересно - а как, собственно, меняется MD5, просто добавлением лишних байтов (самый очевидный способ) или как-то по-умному?

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

Исследуем программу

Итак, имеется файл MD5_Hash_Changer.exe, который мы подозреваем в наличии каких-то скрытых функций. Для начала посмотрим его с помощью PEiD:

0981_Viruses_check_ru/image3.png

Рисунок 2. PEiD

Строчка про C#/.NET наводит на мысль о том, что программа написана на Шарпе, что в ряде случаев может позволить обойтись без дизассемблера. Скачиваем бесплатную программу JetBrains dotPeek, которая позволяет получить код на C# из exe-файла (при условии, естественно, что программа изначально написана на C#), и натравливаем ее на исследуемый файл:

0981_Viruses_check_ru/image4.png

Рисунок 3. Смотрим программу в dotPeek

Для начала следует посмотреть раздел Metadata, в котором первым делом необходимо обратить внимание на используемые строки, в которых могут попасться интересные имена, пути, IP-адреса и прочее.

0981_Viruses_check_ru/image5.png

Рисунок 4. Строковые ресурсы в dotPeek

При необходимости можно сразу посмотреть, где конкретно используется интересная строка, если такая окажется. В моем случае ничего подозрительного не обнаружилось, и я перешел к разделу с кодом. Как выяснилось, исходный код программы содержит два класса, Program и MainForm, при этом класс Program вполне стандартный и содержит лишь код запуска главного окна приложения:

using System; using System.Windows.Forms;
namespace MD5_Hash_Changer {
  internal static class Program {
    [STAThread] private static void Main() { 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false);
      Application.Run((Form) new MainForm()); 
    } 
  } 
}

Класс MainForm будет поразвесистее, и на нем следует остановиться подробнее:

0981_Viruses_check_ru/image6.png

Рисунок 5. Код приложения

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

За это отвечает функция

private void changeMD5(string[] fileNames) {
  Random random = new Random();
  Thread.Sleep(1000);
  this.Invoke((Delegate) (() => this.btnStartMD5.Enabled = true));
  for (int i = 0; i < fileNames.Length; ++i) {
    if (!this.running) {
      this.Invoke((Delegate) (() => {
        this.btnStartMD5.Text = "Start Change MD5";
        this.running = false; 
      }));
      break; 
    } 
    int length1 = random.Next(2, 7);
    byte[] buffer = new byte[length1];
    for (int index = 0; index < length1; ++index)
      buffer[index] = (byte) 0;
    long length2 = new FileInfo(fileNames[i]).Length;
    if (length2 == 0L) {
      this.Invoke(
        (Delegate) (() => this.dgvMD5.Rows[i].Cells[3].Value = (object) "Empty")
      ); 
    } 
    else {
      using (FileStream fileStream = new FileStream(fileNames[i],
                                                    FileMode.Append)) 
        fileStream.Write(buffer, 0, buffer.Length);
      int bufferSize = length2 > 1048576L ? 1048576 : 4096;
      string md5hash = "";
      using (MD5 md5 = MD5.Create()) {
        using (FileStream inputStream = new FileStream(fileNames[i],
                                                       FileMode.Open,
                                                       FileAccess.Read,
                                                       FileShare.Read,
                                                       bufferSize)) 
          md5hash = BitConverter.ToString(md5.ComputeHash((Stream) inputStream))
                                .Replace("-", "");
      } 
      this.Invoke((Delegate) (() => { 
        if (this.dgvMD5.Rows[i].Cells[2].Value.ToString() != "") 
          this.dgvMD5.Rows[i].Cells[1].Value = 
            this.dgvMD5.Rows[i].Cells[2].Value;
        this.labelItem.Text = (i + 1).ToString();
        this.progressBarStatus.Value = i + 1;
        this.dgvMD5.Rows[i].Cells[2].Value = (object) md5hash;
        this.dgvMD5.Rows[i].Cells[3].Value = (object) "OK"; 
      })); 
    } 
  } 
  this.Invoke((Delegate) (() => { 
    this.btnStartMD5.Text = "Start Change MD5"; this.running = false; 
  }));
}

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

int length1 = random.Next(2, 7);
byte[] buffer = new byte[length1];
for (int index = 0; index < length1; ++index) 
  buffer[index] = (byte) 0;

Затем этот буфер просто дописывается в конец файла:

using (FileStream fileStream = new FileStream(fileNames[i],
                                              FileMode.Append))
  fileStream.Write(buffer, 0, buffer.Length);

и снова вычисляется MD5-хэш уже для измененного файла:

using (FileStream inputStream = new FileStream(fileNames[i],
                                               FileMode.Open,
                                               FileAccess.Read,
                                               FileShare.Read,
                                               bufferSize))
  md5hash = BitConverter.ToString(md5.ComputeHash((Stream) inputStream))
                        .Replace("-", "");

Все, больше ничего интересного тут не происходит. Как видим, программа весьма тривиальна и такого рода "уникализация" конечно формально изменяет хэш файла, но... Судить вам, насколько она пригодна для решения ваших задач.

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

0981_Viruses_check_ru/image7.png

Рисунок 6. Сравниваем файлы

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

Важное дополнение

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

Ссылки

Популярные статьи по теме
Сортировки в C#: OrderBy.OrderBy или OrderBy.ThenBy? Разбираемся, что эффективнее и почему

Дата: 20 Сен 2022

Автор: Сергей Васильев

Предположим, есть задача: нужно отсортировать коллекцию по нескольким ключам. В C# это можно сделать с помощью вызовов OrderBy().OrderBy() или OrderBy().ThenBy(). Но в чём разница между этими вызовам…
ML.NET: можно ли доверять машинному обучению Microsoft?

Дата: 08 Сен 2022

Автор: Андрей Москалёв

В 2018 году Microsoft разработали ML.NET – фреймворк машинного обучения для .NET разработчиков. За прошедшее время эта библиотека претерпела существенные изменения и обзавелась новыми функциями для в…
Чем опасны уязвимые зависимости в проекте и как с этим помогает SCA?

Дата: 06 Сен 2022

Автор: Никита Липилин

Современные приложения почти всегда используют сторонние библиотеки. Если библиотека содержит уязвимость, то уязвимым может оказаться и использующее её приложение. Но как определить наличие таких про…
Соберёмся? Вторая проверка проекта MSBuild

Дата: 01 Сен 2022

Автор: Никита Паневин

MSBuild – популярная сборочная платформа с открытым исходным кодом от Microsoft, которую используют разработчики по всему миру. В далёком 2016 году мы уже проверяли проект при помощи PVS-Studio и наш…
Триквел по Orchard Core. Повторная проверка при помощи PVS-Studio

Дата: 25 Авг 2022

Автор: Алексей Авдеев

В этой статье мы исследуем проект Orchard Core c помощью статического анализатора PVS-Studio и узнаём, так ли привлекателен код платформы, как сайты, созданные на её основе. Итак, пусть поток статиче…

Комментарии (0)

Следующие комментарии
Unicorn with delicious cookie
Мы используем куки, чтобы пользоваться сайтом было удобно. Хотите узнать подробнее?
Принять