Это продолжение предыдущего поста.
Все файлы для скачивания находятся внизу.
Думаю, что весело будет запустить малварь на вируальной машине, чтобы увидеть его в работе. Так как таблица символов не была удалена, то все понятно по статическому анализу. Но хочу попробовать собрать нужные данные, чтобы написать для него декриптор)
[!] Обязательно сделайте снапшот перед запуском. Так же рекомендую выключить интернет, общие папки и отключить все USB-устройства.
Запуск

На виртуальной машине я создал файл с неким таинственным содержимым) Вам самим предстоит узнать что там)
Этот файл называется important_file.txt. После запуска малваря рядом с ним появились 2 файла: important_file.txt.C_I_0P и README_C_I_0P.TXT. Как и ожидалось))

С помощью утилиты hexdump посмотрю содержимое этих файлов:
important_file.txt:
hexdump -C important_file.txt
00000000 4a be 11 18 a9 c4 e9 2e b8 fe 88 cb 4e a0 df 2e |J...........N...|
00000010 e5 4f dd c9 71 91 01 9e 24 d9 f0 cf |.O..q...$...|
0000001c
important_file.txt.C_I_0P:
hexdump -C important_file.txt.C_I_0P
00000000 00 ae 8b b7 4f d2 8f 7d f5 15 f5 fa a6 cc a5 76 |....O..}.......v|
00000010 d5 7d 41 cc 2d c1 be 2e de 9b c0 a9 98 d6 8b d4 |.}A.-...........|
00000020 3d e0 23 68 0c 44 71 71 35 81 e5 3b 54 35 e9 6d |=.#h.Dqq5..;T5.m|
00000030 f6 07 83 e3 54 3d 6f 22 3f ce 5f b0 36 fb e5 96 |....T=o"?._.6...|
00000040 8a 51 5a 40 e4 ef c5 d6 9c 1e 1f 9e 02 07 bd 8f |.QZ@............|
00000050 21 8b 2c 2a c9 c8 31 77 b5 90 38 3e e0 5d 85 92 |!.,*..1w..8>.]..|
00000060 59 fc 26 70 4b 97 05 fd 01 68 f3 3a 2b b1 29 79 |Y.&pK....h.:+.)y|
00000070 ec 96 da 9e 74 2d 00 00 00 00 00 00 00 00 00 00 |....t-..........|
00000080 00 ae 7e 03 00 80 81 00 00 01 00 00 00 00 00 00 |..~.............|
00000090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000a0 00 1c 00 00 00 00 00 00 00 00 10 00 00 08 00 00 |................|
000000b0 00 00 00 00 00 d1 e8 4a 68 13 67 a3 17 d1 e8 4a |.......Jh.g....J|
000000c0 68 13 67 a3 17 fd e8 4a 68 64 1c 3c 2d ae 7e 03 |h.g....Jhd.<-.~.|
000000d0 00 00 00 00 00 01 00 00 00 00 40 80 40 1c 00 00 |..........@.@...|
000000e0 00 00 00 00 00 41 00 00 00 75 00 00 00 00 00 00 |.....A...u......|
000000f0 00 2f ff 7f 40 88 03 80 40 35 8a 04 08 18 ff 7f |./..@...@5......|
00000100
Ничего не понятно, но очень интересно. Файл зашифрован, поэтому он так и выглядит. Убиваю все признаки малвары через kill, сохраняю эти файлы себе на основную тачку)
P.S: Я пропатчил функцию do_heartbeat(), чтобы она шифровала файлы только в одной директории. Безопасность прежде всего)
Написание декриптора
Начну разбираться, как расшифровать мой файл. Ранее я уже понял, что для шифрования используется алгоритм RC4. О нем я нашел следующую информацию:
Это потоковый шифр с переменным размером ключа. Работает в режиме OFB. Для шифрования использует S-блок размером 8x8. Его элементы представляют собой перестановку чисел от 0 до 255, а перестановка зависит от ключа переменной длины. В алгоритме используется два счетчика i и j, которые инициализируются нулями.
Так же в прошлый раз из кода я уже вытащил ключ:
master_key = 'Jfkdskfku2ir32y7432uroduw8y7318i9018urewfdsZ2Oaifwuieh~~cudsffdsd'
Второй ключ для файла я возьму из important_file.txt.C_I_0P. Через wc посмотрю его длину:
$ wc important_file.txt.C_I_0P
0 3 256 important_file.txt.C_I_0P
Можно увидеть, что всего в файле 256 символов. Но стоп, если вернуться к функции EncrFile, то можно заметить, что малвара генерирует 117 символов ключа:

Как часто шутят у меня в отделе — произошел киберобман) При первичном просмотре я не особо обратил внимание на функцию CreateKey, но вот сейчас она пригодится)

Действительно, пишет она 256 байт, из которых 117 — это ключ. Ключ хранится в стеке, в функцию передается его адрес. Значит в файл записывается часть стека. К интересному можно отнести len, так как это длина зашифрованной части файла.

Значит из файла important_file.txt.C_I_0P по смещению 0x75 + 0x58 + 0x8 + 0x4 + 0x4 можно вытащить len. Так же можно заметить, что перед вызовом функции CreateKey ключ к файлу шифруется с помощью ssKeyKey:
_rc4Full(szKeyKey, v3 - 1, rc4_key, 117u);
Createkey(pathname, rc4_key);
Обобщив всю информацию, можно составить следующий алгоритм для дешифрования:
- Взять имя зашифрованного файла;
- Прочитать файл с названием, состоящим из имени этого файла и расширения
.C_I_0P; - Расшифровать первые 117 байт с помощью алгоритма
RC4, чтобы получить ключ для дешифровки файла; - По смещению
0x75 + 0x58 + 0x8 + 0x4 + 0x4получить длину зашифрованной части файлаlen; - Расшифровать
lenбайт зашифрованного файла, добавить оставшиеся байты и сохранить на диск;
Напишу код на Python:
from arc4 import ARC4
import sys
import struct
def get_file_key(file: str) -> bytes:
key_file_name = file + '.C_I_0P'
print(f'[*] Read encrypted file key from {key_file_name}')
with open(key_file_name, 'rb') as f:
key = f.readline()
return key
def main(file: str) -> None:
master_key = (b'Jfkdskfku2ir32y7432uroduw8y7318i90'
b'18urewfdsZ2Oaifwuieh~~cudsffdsd')
gen_len = 0x75
file_key = get_file_key(file)
print('[*] Extract encrypetd file len')
# 0x58 + 0x75 + 0x8 + 0x4 + 0x4
file_len_offset = 0x58 + 0x75 + 0x8 + 0x4 + 0x4
try:
encr_file_size = struct.unpack(
'Q',
file_key[file_len_offset: file_len_offset + 0x8]
)[0]
except struct.error:
print('[-] Wrong encrypted file len')
print('[*] Decrypt file key')
cryptor = ARC4(master_key)
file_rc4_key = cryptor.decrypt(file_key)[:gen_len]
with open(file, 'rb') as f:
crypted_file = f.read()
cryptor = ARC4(file_rc4_key)
decrypted_file = cryptor.decrypt(crypted_file[:encr_file_size])
decrypted_file += crypted_file[encr_file_size:]
decrypted_file_path = file + '.decrypted'
print(f'[*] Save decrypted file to {decrypted_file_path}')
with open(file + '.decrypted', 'wb') as f:
f.write(decrypted_file)
print('[*] Done')
if __name__ == '__main__':
if len(sys.argv) != 2:
print(f'Usage {sys.argv[0]} <encrypted file>')
else:
main(sys.argv[1])
Протестировал на своем файле. Предлагаю и вам)
Файлы для скачивания
Malware Link: Virus Total
important_file.txt: Скачать
important_file.txt.C_I_0P: Скачать