Conti Ransomware malware leak WITH LOCKER
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

209 lines
8.9 KiB

ТЕХНИЧЕСКОЕ ЗАДАНИЕ
АВТОМАТИЧЕСКИЙ ПОИСК АНТИВИРУСНЫХ ДЕТЕКТОВ В ИСХОДНОМ КОДЕ
ЦЕЛЬ
Уменьшить время чистки от антивирусных детектов путем автоматизации процесса.
ИДЕЯ
Обычный алгоритм чистки следующий:
Этап 1
1 берем проект, который нужно почистить
2 комментируем вообще все функции и глобальные переменные
3 делаем сборку в боевом профиле
4 получившийся бинарник заливаем на dyncheck и проверяем
5 если число детектов меньше заданного порога, гото этап 2, иначе
6 раскомментируем одну функцию (согласно графу зависимостей)
7 гото 3
Этап 2
для каждой найденной функции с детектами, отсекаем #ifdef'ом части функции по тому же принципу,
до тех пор пока не дойдем до одной строчки либо блока кода.
Есть оптимизация на шаге 6 - можно раскомментировать сразу несколько функций, оптимистично полагая что детект не здесь)
Если запилить программу, которая умеет разобрать исходники, построить граф зависимостей функций, и вставлять #ifdef FUNCTION1_NEVER .. #endif
в теле этих функций, то процесс можно автоматизировать.
РЕАЛИЗАЦИЯ
Программа должна быть оформлена как консольная утилита и написана на C++.
По возможности обеспечить кросс-платформенность.
Интерфейс пользователя - ключи командной строки (getopt) и вывод на stdout/stderr.
Нужно реализовать описанный выше алгоритм со следующими граничными условиями:
* поддержка проектов Visual Studio начиная с 2010, включает в себя:
- задание профиля сборки (Release/x64)
- запуск компиляции на каждой итерации и поиск собранного файла там, где сказано в файле проекта
* точка расширения на функции антивирусной проверки (используемой на шаге 5)
- принцип плагина - должна быть функция bool avcheck(const char* path), которую легко заменить для разных инструментов проверки -
как для локальных антивирусов, так и для интеграции с онлайн-сервисами
* анализ кода должен исключать заведомо сложные случаи, такие как
- template<>
- рекурсию в библиотечные исходники, включая CRT/STL/WinAPI
- все что усложняет реализацию, должно быть оговорено и упрощено.
Проще привести код к удобному для анализа виду, чем усложнять анализатор.
* объяснение на stdout что происходит:
Этап 1
итерация 1, закомментировано 1801 функция, число детектов 0
итерация 2, закомментировано 900 функция, число детектов 18
..
итерация 100, закомментировано 50 функций, число детектов 0
Этап 2
Функция foo(), убраны строки 100..200, число детектов 0
Функция foo(), убраны строки 190..200, число детектов 0
Функция foo(), убраны строки 195..200, число детектов 18
Детекты найдены в функциях:
foo(): 195..200
bar(): 400..402
dumb(): 151..152
Можно переделать готовые подходящие анализаторы кода - сейчас много статических анализаторов с готовым модулем синтаксического разбора.
РЕАЛИЗАЦИЯ, ВАРИАНТ №2, УПРОЩЕННЫЙ
Делаем то же самое без разбора исходного кода, путем анализа карты функций компоновщика (параметр /MAP компоновщика):
- заказываем у компоновщика карту бинарника ключом /map
- парсим выходную карту, находим границы функций
- зануляем функции ПРЯМО В БИНАРНИКЕ
Так можно избежать парсинга исходников на этапе 1 (на этапе 2 к сожалению не получится)
Но и реализация хотя бы в объеме этапа 1 очень сильно облегчила бы жизнь.
Т.к. в карте появляется слишком много левых символов, которые вовсе не требуют анализа (функции из CRT, всякая служебная мелочь),
то нужны дополнительные инструменты в интерфейсе программы:
- маски для исключения символов (черный список)
- маски списка проверки объектных файлов (.obj) (белый список)
- маски списка проверки символов
Также мелкие символы можно отсечь по размеру (см.ниже алгоритм)
Есть похожая реализация
https://github.com/vxlabinfo/SignFinder
основана на статьях
https://vxlab.info/%d1%87%d0%b8%d1%81%d1%82%d0%ba%d0%b0-pe32-%d1%87%d0%b0%d1%81%d1%82%d1%8c-1/
https://vxlab.info/%d1%87%d0%b8%d1%81%d1%82%d0%ba%d0%b0-pe32-%d1%87%d0%b0%d1%81%d1%82%d1%8c-2/
сайт уже протух, но остались копии, например здесь
https://ru-sfera.org/threads/chistka-ot-signaturnogo-detekta-antivirusov.2870/
Оттуда можно взять эвристики проверок отдельных секций, заголовков и импорта.
АЛГОРИТМ ПРОВЕРКИ
На входе алгоритма - нераскрашенный список символов (функций и глобальных данных).
На выходе алгоритма - раскрашенный список символов, так что каждому символу присвоен цвет - белый или черный.
Цель алгоритма - раскрасить все функции за минимальное число шагов.
Алгоритм:
1. Первый проход по списку: помечаем как "белые" все символы по списку исключения/не содержащиеся в списках проверки
2. Сортируем список по занимаемому в памяти размеру символа
3. Символы с размером ниже некоторого порога (настройка или эвристически определяемого значение) сразу можно раскрасить "белым"
На этом шаге следует занулить все нераскрашенные символы и сделать АВ-проверку.
Если проверка даст детект, выводим предупреждение что в бинарном файле есть детекты на самой первой итерации и завершаем работу.
Иначе, разнуляем все нераскрашенные символы.
Далее в алгоритме необходимо помнить состояние:
- список текущих проверяемых символов ("текущий список")
- список раскрашенных символов.
До конца работы алгоритма:
- Белые символы должны быть разнулены
- Черные символы должны быть занулены
4. Делаем отбор в текущий список: половина (50%) нераскрашенных символов файла
5. Разнуляем не раскрашенные символы текущего списка
6. АВ проверка - вызываем функцию проверки av_check()
7. Детект есть?
- нет: пометили разнуленную часть текущего списка как "белый", продолжаем выполнение (гото 8)
- да:
в разнуленной части 1 символ?
- да: пометили как черный, занулили до конца проверки, гото 6
- нет: занулили половину (50%) нераскрашенной части текущего списка, гото 6
8. Если остались нераскрашенные символы в текущем списке, гото 5
9. Если остались нераскрашенные символы в файле, гото 4
На этот алгоритм можно написать unit-тест, заставив av_check() выдавать детекты только на конкретный список функций.
USAGE
-i <input exe file> проверяемый файл. Аргумент обязательный.
-m <input map file> карта компоновщика .map. Аргумент обязательный.
-d <workdir> рабочий каталог, куда складываем промежуточные файлы. По умолчанию текущий.
-s <section> список тестируемых секций (.text, .data ...). Можно указать -s несколько раз, например -s .text -t .data.
По умолчанию все секции.
-z <Minimum size threshold> исключить из проверки символы размером меньше чем указанный; размер в байтах. По умолчанию 0 (нет порога).
-a defender|dyncheck проверка на указанном антивирусе. Умолчания нет, аргумент обязательный.
-f <functionmask> проверять только символы с именем, удовлетворяющим маске. Можно указать -f несколько раз, например -f symb1* -f symb2*
-M <modulename> проверять только символы из указанных модулей. Можно указать -f несколько раз, например -m module1* -m module2*
Аргументы -s, -z, -f, -M комбинируются по логическому И (пересечение множеств), т.е. уменьшают диапазон проверки.
ИНТЕГРАЦИЯ С АВ-ДВИЖКАМИ
На первом этапе обязательны интеграции с Windows Defender (Windows 10) и dyncheck.com через API.
Далее код на Powershell
* Объект Defender
$Defender = @{
#MALWAREPROTECTION_*
SCAN_STARTED = 1000
SCAN_COMPLETED = 1001
MALWARE_DETECTED = 1006
BEHAVIOR_DETECTED = 1015
STATE_MALWARE_DETECTED = 1116
STATE_MALWARE_ACTION_TAKEN = 1117
StartTime = $null
IsRunning = $false
ScanProc = $null
ScanId = $null
LastScanId = $null
}
* Запуск Windows Defender
$Defender.ScanProc = Start-Process `
-FilePath "$($env:programfiles)\Windows Defender\mpcmdrun.exe" `
-ArgumentList '-Scan', '-ScanType 3', "-File $f" `
-PassThru -NoNewWindow #-Wait
$Defender.StartTime = (Get-Date).AddSeconds(-5)
$Defender.IsRunning = $true
* Получение идентификатора проверки, для последующего чтения журнала:
$ScanStarted = Get-WinEvent -LogName "Microsoft-Windows-Windows Defender/Operational" |
Where-Object {
$_.TimeCreated -ge $Defender.StartTime -and
$_.Id -eq $Defender.SCAN_STARTED
}
if ($ScanStarted)
{
$Defender.ScanId = $ScanStarted.Properties[$ScanId].Value
$Defender.LastScanId = $Defender.ScanId
}
* Проверка завершения сканирования:
$ScanCompleted = Get-WinEvent -LogName "Microsoft-Windows-Windows Defender/Operational" |
Where-Object {
$_.TimeCreated -ge $Defender.StartTime -and
$_.Id -eq $Defender.SCAN_COMPLETED -and
$_.Properties[$ScanId].Value -eq $Defender.ScanId
}
* Наличие детекта в образце:
$MalwareDetected = Get-WinEvent -LogName "Microsoft-Windows-Windows Defender/Operational" |
Where-Object {
$_.TimeCreated -ge $Defender.StartTime -and
$_.Id -in `
$Defender.MALWARE_DETECTED, `
$Defender.BEHAVIOR_DETECTED, `
$Defender.STATE_MALWARE_DETECTED `
На втором этапе, нужна интеграция с:
- Eset NOD32
- Kaspersky
- Norton Antivirus
Третий этап:
- Avast