diff --git a/README.md b/README.md index 2b5fc40..5b92747 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,14 @@ * Расшифровывает TLS на RSA при наличии приватного ключа  -## Клонирование + +## Быстрый запуск +Для быстрого запуска Packmate следует использовать [этот стартер](https://gitlab.com/packmate/starter/-/blob/master/README.md). + +## Полный запуск +Ниже следует инструкция для тех, кто хочет собрать Packmate самостоятельно. + +### Клонирование Поскольку этот репозиторий содержит фронтенд как git submodule, его необходимо клонировать так: ```bash git clone --recurse-submodules https://gitlab.com/packmate/Packmate.git @@ -40,102 +47,20 @@ git pull # Забираем свежую версию мастер-репы и git submodule update --init --recursive ``` -## Подготовка -В этом ПО используется Docker и docker-compose. В образ `packmate-app` пробрасывается -сетевой интерфейс хоста, его название указывается переменной окружения (об этом ниже). - -`packmate-db` настроен на прослушивание порта 65001 с локальным IP. -Файлы БД сохраняются в ./data, поэтому для обнуления базы нужно удалить эту папку. - ### Настройка -Программа берет основные настройки из переменных окружения, поэтому для удобства -можно создать env-файл. -Он должен называться `.env` и лежать в корневой директории проекта. - -В файле необходимо прописать: -```dotenv -# Локальный IP сервера на указанном интерфейсе или в pcap файле -PACKMATE_LOCAL_IP=192.168.1.124 -# Имя пользователя для web-авторизации -PACKMATE_WEB_LOGIN=SomeUser -# Пароль для web-авторизации -PACKMATE_WEB_PASSWORD=SomeSecurePassword -``` - -Если мы перехватываем трафик сервера (лучший вариант, если есть возможность): -```dotenv -# Режим работы - перехват -PACKMATE_MODE=LIVE -# Интерфейс, на котором производится перехват трафика -PACKMATE_INTERFACE=wlan0 -``` -Если мы анализируем pcap дамп: -```dotenv -# Режим работы - анализ файла -PACKMATE_MODE=FILE -# Путь до файла от корня проекта -PACKMATE_PCAP_FILE=dump.pcap -``` - -Или если мы хотим посмотреть уже обработанный трафик (например, для разбора после игры): -```dotenv -PACKMATE_MODE=VIEW -``` - -При захвате живого трафика рекомендуется включать удаление старых стримов, иначе ближе к концу -соревнования анализатор будет медленнее работать. -```dotenv -PACKMATE_OLD_STREAMS_CLEANUP_ENABLED=true -# Интервал удаления старых стримов (в минутах). -# Лучше ставить маленькое число, чтобы стримы удалялись маленькими кусками, и это не нагружало систему -PACKMATE_OLD_STREAMS_CLEANUP_INTERVAL=1 -# Насколько старым стрим должен быть для удаления (в минутах от текущего времени) -PACKMATE_OLD_STREAMS_CLEANUP_THRESHOLD=240 -``` - -Чтобы использовать расшифровку TLS, нужно положить соответствующий приватный ключ, который -использовался для генерации сертификата, в папку `rsa_keys`. +[Инструкция](docs/SETUP.md) ### Запуск После указания нужных настроек в env-файле, можно запустить приложение: ```bash -sudo docker-compose up --build -d +sudo docker compose up --build -d ``` При успешном запуске Packmate будет видно с любого хоста на порту `65000`. - -### Начало работы -При попытке зайти в web-интерфейс впервые, браузер спросит логин и пароль, -который указывался в env-файле. -При необходимости можно настроить дополнительные параметры по кнопке с шестеренками в верхнем -правом углу экрана. - - - -Все настройки сохраняются в local storage и теряются только при смене IP-адреса или порта сервера. +БД будет слушать на порту 65001, но будет разрешать подключения только с localhost. ## Использование -Сначала нужно создать сервисы, находящиеся в игре. -Для этого вызывается диалоговое окно по нажатию кнопки `+` в навбаре, -где можно указать название и порт сервиса, а также дополнительные опции. - -Для удобного отлова флагов в приложении существует система паттернов. -Чтобы создать паттерн, нужно открыть выпадающее меню `Patterns` и нажать кнопку `+`, -затем указать нужный тип поиска, сам паттерн, цвет подсветки в тексте и прочее. -Если выбрать тип паттерна IGNORE, то стримы, попадающие под шаблон, автоматически будут удаляться. -Это может пригодиться, чтобы не засорять БД трафиком с эксплоитами, которые уже были запатчены. - -В режиме LIVE система начнет автоматически захватывать стримы и отображать их в сайдбаре. -В режиме FILE для начала обработки файла нужно нажать соответствующую кнопку в сайдбаре. -При нажатии на стрим в главном контейнере выводится список пакетов; -между бинарным и текстовым представлением можно переключиться по кнопке в сайдбаре. - -### Горячие клавиши -Для быстрой навигации по стримам можно использовать следующие горячие клавиши: -* `Ctrl+Up` -- переместиться на один стрим выше -* `Ctrl+Down` -- переместиться на один стрим ниже -* `Ctrl+Home` -- перейти на последний стрим -* `Ctrl+End` -- перейти на первый стрим +[Инструкция](docs/USAGE.md)
+
+### Создание сервисов
+Сначала нужно создать сервисы, находящиеся в игре. Если не сделать этого, то никакие стримы не будут сохраняться!
+Для этого вызывается диалоговое окно по нажатию кнопки `+` в навбаре,
+где можно указать название и порт сервиса, а также дополнительные опции.
+
+
+
+#### Параметры сервиса:
+1. Имя
+2. Порт (если сервис использует несколько портов, нужно создать по сервису на каждый порт)
+3. Chunked transfer encoding: автоматически раскодировать [подобные](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding#chunked_encoding) http пакеты
+4. Urldecode: автоматически проводить urldecode пакетов. Стоит включать по умолчанию в http сервисах.
+5. Merge adjacent packets: автоматически склеивать соседние пакеты в одном направлении. Стоит включать по умолчанию в небинарных сервисах.
+6. Inflate WebSockets: автоматически разархивировать [сжатые](https://www.rfc-editor.org/rfc/rfc7692) websocket-пакеты.
+7. Decrypt TLS: автоматически расшифровывать TLS-трафик (HTTPS).
+Работает только с типами шифрования TLS_RSA_WITH_AES_*, и при наличии приватного ключа, который использовался в сертификате сервера (как Wireshark).
+
+### Создание паттернов
+Для удобного отлова эксплоитов в приложении существует система паттернов.
+Чтобы создать паттерн, нужно открыть выпадающее меню `Patterns` и нажать кнопку `+`,
+затем указать параметры паттерна и сохранить.
+
+Важно: паттерн начнет действовать только на стримы, захваченные после его создания. Но можно использовать Lookback, чтобы проанализировать и стримы в прошлом.
+
+
+
+#### Параметры паттерна:
+1. Имя: оно отображается в списке на стримах, которые содержат этот паттерн.
+2. Паттерн: само содержимое паттерна. Может быть строкой, регулярным выражением или hex-строкой в зависимости от типа паттерна.
+3. Действие паттерна
+ 1. Highlight подсветит найденный паттерн. Пример: поиск флагов.
+ 2. Ignore удалит стрим, содержащий этот паттерн.
+ Пример: вы запатчили сервис от определенной уязвимости и больше не хотите видеть определенный эксплоит в трафике. Можно добавить этот эксплоит как паттерн с типом IGNORE, и он больше не будет сохраняться.
+4. Цвет: этим цветом будут подсвечиваться паттерны с типом Highlight
+5. Метод поиска: подстрока, регулярное выражение, бинарная подстрока
+6. Направление поиска: везде, только в запросах, только в ответах
+7. Сервис: искать в трафике всех сервисов или в каком-то конкретном
+
+### Начало игры
+В режиме LIVE система начнет автоматически захватывать стримы и отображать их в сайдбаре.
+В режиме FILE для начала обработки файла нужно нажать соответствующую кнопку в сайдбаре.
+При нажатии на стрим в главном окне выводится список пакетов;
+между бинарным и текстовым представлением можно переключиться по кнопке в сайдбаре.
+
+### Обзор навбара
+
+
+1. Заголовок
+2. Счетчик SPM - Streams Per Minute, стримов в минуту
+3. Счетчик PPS - Packets Per Stream, среднее количество пакетов в стриме
+4. Кнопка открытия списка паттернов
+5. Список сервисов. В каждом сервисе:
+ 1. Название
+ 2. Порт
+ 3. Счетчик SPM сервиса - позволяет определить наиболее популярные сервисы
+ 4. Кнопка редактирования сервиса
+6. Кнопка добавления нового сервиса
+7. Кнопка открытия настроек
+
+
+### Обзор сайдбара
+
+
+В левой панели Packmate находятся стримы выбранного сервиса.
+Отображается номер стрима, протокол, TTL, сервис, время, хэш User-Agent (для http сервисов) и найденные паттерны.
+
+Совет: иногда на CTF забывают перезаписать TTL пакетов внутри сети. В таком случае по TTL можно отличить запросы от чекеров и от других команд.
+
+Совет #2: по User-Agent можно отличать запросы из разных источников. К примеру, можно предположить, что на скриншоте выше запросы 4 и 5 пришли из разных источников.
+
+Совет #3: нажимайте на звездочку, чтобы добавить интересный стрим в избранное. Этот стрим будет выделен в списке, и появится в списке избранных стримов.
+
+#### Управление просмотром
+
+
+
+1. Пауза: Остановить/возобновить показ новых стримов на экране. Не останавливает перехват стримов и показ другим пользователям! Полезно, если стримы летят слишком быстро.
+2. Избранные: показать только стримы, отмеченные как избранные
+3. Переключить текстовый/hexdump вид
+4. Начать анализ: появляется только при запуске в режиме `FILE`
+5. Промотать список стримов до самого нового
+
+### Обзор меню паттернов
+
+
+1. Кнопка добавления паттерна
+2. Выбор всех стримов (убрать фильтрацию по паттерну)
+3. Список паттернов. В каждой строчке:
+ 1. Описание паттерна
+ 2. Кнопка Lookback - позволяет применить паттерн к стримам, обработанным до создания паттерна.
+ 3. Пауза - паттерн нельзя удалить, но можно поставить на паузу. После этого он не будет применяться к новым стримам.
+
+Совет: создавайте отдельные паттерны для входящих и исходящих флагов. Так легче отличать чекер, кладущий флаги, от эксплоитов.
+
+Совет #2: используйте Lookback для исследования найденных эксплоитов.
+
+Пример: вы обнаружили, что сервис только что отдал флаг пользователю `abc123` без видимых причин.
+Можно предположить, что атакующая команда создала этого пользователя и подготовила эксплоит в другом стриме.
+Но в игре слишком много трафика, чтобы найти этот стрим вручную.
+Тогда можно создать `SUBSTRING` паттерн со значением `abc123` и активировать Lookback на несколько минут назад.
+После этого со включенным фильтром по паттерну будут отображаться только стримы, где упоминался этот пользователь.
+
+### Горячие клавиши
+Для быстрой навигации по стримам можно использовать следующие горячие клавиши:
+* `Ctrl+Up` -- переместиться на один стрим выше
+* `Ctrl+Down` -- переместиться на один стрим ниже
+* `Ctrl+Home` -- перейти на последний стрим
+* `Ctrl+End` -- перейти на первый стрим
\ No newline at end of file
diff --git a/docs/USAGE_EN.md b/docs/USAGE_EN.md
new file mode 100644
index 0000000..e642620
--- /dev/null
+++ b/docs/USAGE_EN.md
@@ -0,0 +1,110 @@
+## Usage
+### Settings
+When attempting to access the web interface for the first time, your browser will prompt for a login and password, which were specified in the env file.
+If necessary, additional parameters can be configured via the gear icon in the top right corner of the screen.
+
+
+
+### Creating Services
+First, you need to create services that are present in the game. If you don't do this, no streams will be saved!
+To do this, a dialog box is called by clicking the `+` button in the navbar,
+where you can specify the name and port of the service, as well as additional options.
+
+
+
+#### Service Parameters:
+1. Name
+2. Port (if the service uses multiple ports, you need to create a Packmate service for each port)
+3. Chunked transfer encoding: automatically decode [chunked](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding#chunked_encoding) HTTP packets
+4. Urldecode: automatically perform URL decoding of packets. Should be enabled by default for HTTP services.
+5. Merge adjacent packets: automatically merge adjacent packets in the same direction. Should be enabled by default for non-binary services.
+6. Inflate WebSockets: automatically decompress [compressed](https://www.rfc-editor.org/rfc/rfc7692) WebSocket packets.
+7. Decrypt TLS: automatically decrypt TLS traffic (HTTPS). Only works with TLS_RSA_WITH_AES_* cipher suites and requires the private key used in the server's certificate (just like Wireshark).
+
+### Creating Patterns
+To conveniently capture exploits in the application, a pattern system exists.
+To create a pattern, open the dropdown menu `Patterns` and click the `+` button,
+then specify the pattern parameters and save.
+
+Important: the pattern will only apply to streams captured after its creation. But you can use Lookback to analyze past streams.
+
+
+
+#### Pattern Parameters:
+1. Name: it will be displayed in the list on streams that contain this pattern.
+2. Pattern: the content of the pattern itself. It can be a string, a regular expression, or a hex string depending on the pattern type.
+3. Pattern ation:
+ 1. Highlight will highlight the found pattern. Example: searching for flags.
+ 2. Ignore will delete the stream containing this pattern.
+ Example: you patched a service from a certain vulnerability and no longer want to see a specific exploit in the traffic. You can add this exploit as a pattern with IGNORE type, and it will no longer be saved.
+4. Color: the color with which patterns of Highlight type will be highlighted.
+5. Search method: substring, regular expression, binary substring
+6. Search type: everywhere, only in requests, only in responses
+7. Service: search in the traffic of all services or in a specific one.
+
+### Game Start
+In LIVE mode, the system will automatically capture streams and display them in the sidebar.
+In FILE mode, click the corresponding button in the sidebar to start processing a file.
+When you click on a stream in the main window, a list of packets is displayed;
+you can switch between binary and text representation using the button in the sidebar.
+
+### Navbar Overview
+
+
+1. Title
+2. SPM counter - Streams Per Minute
+3. PPS counter - (average number of) Packets Per Stream
+4. Button to open the list of patterns
+5. List of services. In each service:
+ 1. Name
+ 2. Port
+ 3. SPM counter for the service - allows you to determine the most popular services
+ 4. Service edit button
+6. Button to add a new service
+7. Button to open settings
+
+### Sidebar Overview
+
+
+Tip: Sometimes during CTFs, admins forget to overwrite the TTL of packets inside the network. In such cases, you can differentiate requests from checkers and other teams based on TTL.
+
+Tip #2: User-Agent can be used to differentiate requests from different sources. For example, in the screenshot above, requests 4 and 5 may have come from different sources.
+
+Tip #3: Click on the star icon to add an interesting stream to your favorites. This stream will be highlighted in the list and will appear in the list of favorite streams.
+
+#### Control Panel
+
+
+
+1. Pause: Stop/resume displaying new streams on the screen. It does not stop intercepting streams or showing them to other users! Useful if streams are flying by too quickly.
+2. Favorites: Show only streams marked as favorites.
+3. Switch text/hexdump view.
+4. Start analysis: Only appears when running in `FILE` mode.
+5. Scroll stream list to the newest.
+
+### Pattern Menu Overview
+
+
+1. Add Pattern Button
+2. Select All Streams (do not filter by pattern)
+3. Pattern List. Each line contains:
+ 1. Pattern Description
+ 2. Lookback Button - applies the pattern to streams processed before the pattern creation.
+ 3. Pause - pattern cannot be deleted, but can be paused. It will not be applied to new streams after pausing.
+
+Tip: Create separate patterns for incoming and outgoing flags to easily distinguish between flag checkers and exploits.
+
+Tip #2: Use Lookback to investigate discovered exploits.
+
+Example: You found that the service just handed out a flag to user `abc123` without an apparent reason.
+You can assume that the attacking team created this user and prepared an exploit in another stream.
+But there is too much traffic in the game to manually find this stream.
+Then you can create a `SUBSTRING` pattern with the value `abc123` and activate Lookback for a few minutes back.
+After that, with the pattern filter enabled, only streams mentioning this user will be displayed.
+
+### Hotkeys
+Use the following hotkeys for quick navigation through streams:
+* `Ctrl+Up` -- Move one stream up.
+* `Ctrl+Down` -- Move one stream down.
+* `Ctrl+Home` -- Go to the last stream.
+* `Ctrl+End` -- Go to the first stream.
\ No newline at end of file
diff --git a/pcaps/dump.pcap b/pcaps/dump.pcap
new file mode 100644
index 0000000..733d568
Binary files /dev/null and b/pcaps/dump.pcap differ
diff --git a/screenshots/Screenshot.png b/screenshots/Screenshot.png
index 520e3ca..88b69ec 100644
Binary files a/screenshots/Screenshot.png and b/screenshots/Screenshot.png differ
diff --git a/screenshots/Screenshot_Navbar.png b/screenshots/Screenshot_Navbar.png
new file mode 100644
index 0000000..beb213a
Binary files /dev/null and b/screenshots/Screenshot_Navbar.png differ
diff --git a/screenshots/Screenshot_Pattern.png b/screenshots/Screenshot_Pattern.png
new file mode 100644
index 0000000..4dbf338
Binary files /dev/null and b/screenshots/Screenshot_Pattern.png differ
diff --git a/screenshots/Screenshot_Patterns.png b/screenshots/Screenshot_Patterns.png
new file mode 100644
index 0000000..a36218f
Binary files /dev/null and b/screenshots/Screenshot_Patterns.png differ
diff --git a/screenshots/Screenshot_Service.png b/screenshots/Screenshot_Service.png
new file mode 100644
index 0000000..5720e5d
Binary files /dev/null and b/screenshots/Screenshot_Service.png differ
diff --git a/screenshots/Screenshot_Sidebar.png b/screenshots/Screenshot_Sidebar.png
new file mode 100644
index 0000000..6ef2baf
Binary files /dev/null and b/screenshots/Screenshot_Sidebar.png differ
diff --git a/screenshots/Screenshot_Sidebar_header.png b/screenshots/Screenshot_Sidebar_header.png
new file mode 100644
index 0000000..a800d6d
Binary files /dev/null and b/screenshots/Screenshot_Sidebar_header.png differ
diff --git a/src/main/java/ru/serega6531/packmate/pcap/FilePcapWorker.java b/src/main/java/ru/serega6531/packmate/pcap/FilePcapWorker.java
index 0f9e178..6eb2b2a 100644
--- a/src/main/java/ru/serega6531/packmate/pcap/FilePcapWorker.java
+++ b/src/main/java/ru/serega6531/packmate/pcap/FilePcapWorker.java
@@ -16,6 +16,7 @@ import ru.serega6531.packmate.service.SubscriptionService;
import java.io.EOFException;
import java.io.File;
import java.net.UnknownHostException;
+import java.util.Arrays;
@Slf4j
public class FilePcapWorker extends AbstractPcapWorker {
@@ -31,8 +32,9 @@ public class FilePcapWorker extends AbstractPcapWorker {
super(servicesService, streamService, localIpString);
this.subscriptionService = subscriptionService;
- file = new File(filename);
+ file = new File("pcaps", filename);
if (!file.exists()) {
+ log.info("Existing files: " + Arrays.toString(new File("pcaps").listFiles()));
throw new IllegalArgumentException("File " + file.getAbsolutePath() + " does not exist");
}
diff --git a/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java b/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java
index e36e9b5..d743ec9 100644
--- a/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java
+++ b/src/main/java/ru/serega6531/packmate/service/optimization/TlsDecryptor.java
@@ -107,7 +107,7 @@ public class TlsDecryptor {
int blockCipherSize = Integer.parseInt(blockCipherParts[1]);
String blockCipherMode = blockCipherParts[2];
- if (!blockCipherAlgo.equals("AES")) { //TODO использовать не только AES256
+ if (!blockCipherAlgo.equals("AES")) {
return;
}
diff --git a/src/main/java/ru/serega6531/packmate/tasks/OldStreamsCleanupTask.java b/src/main/java/ru/serega6531/packmate/tasks/OldStreamsCleanupTask.java
index 7635a3b..f98a21d 100644
--- a/src/main/java/ru/serega6531/packmate/tasks/OldStreamsCleanupTask.java
+++ b/src/main/java/ru/serega6531/packmate/tasks/OldStreamsCleanupTask.java
@@ -2,7 +2,7 @@ package ru.serega6531.packmate.tasks;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import ru.serega6531.packmate.service.StreamService;
@@ -12,7 +12,7 @@ import java.time.temporal.ChronoUnit;
@Component
@Slf4j
-@ConditionalOnProperty(name = "old-streams-cleanup-enabled", havingValue = "true")
+@ConditionalOnExpression("${old-streams-cleanup-enabled:false} && '${capture-mode}' == 'LIVE'")
public class OldStreamsCleanupTask {
private final StreamService service;
diff --git a/src/test/java/ru/serega6531/packmate/StreamOptimizerTest.java b/src/test/java/ru/serega6531/packmate/StreamOptimizerTest.java
index 6f7cd21..c7d01e0 100644
--- a/src/test/java/ru/serega6531/packmate/StreamOptimizerTest.java
+++ b/src/test/java/ru/serega6531/packmate/StreamOptimizerTest.java
@@ -3,6 +3,7 @@ package ru.serega6531.packmate;
import org.apache.commons.lang3.ArrayUtils;
import org.junit.jupiter.api.Test;
import ru.serega6531.packmate.model.Packet;
+import ru.serega6531.packmate.service.optimization.HttpChunksProcessor;
import ru.serega6531.packmate.service.optimization.HttpGzipProcessor;
import ru.serega6531.packmate.service.optimization.HttpUrldecodeProcessor;
import ru.serega6531.packmate.service.optimization.PacketsMerger;
@@ -67,6 +68,18 @@ class StreamOptimizerTest {
assertEquals(2, list.get(3).getContent().length);
}
+ @Test
+ void testChunkedTransferEncoding() {
+ String content = "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n" +
+ "6\r\nChunk1\r\n6\r\nChunk2\r\n0\r\n\r\n";
+
+ List