From e1b11cfdee7cb1d88294c2312e035c8eb483dfd5 Mon Sep 17 00:00:00 2001 From: serega6531 Date: Mon, 6 Apr 2020 23:52:08 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D1=82=D0=BF=D1=80=D0=B0=D0=B2=D0=BA?= =?UTF-8?q?=D0=B0=20=D1=81=D0=BE=D0=BE=D0=B1=D1=89=D0=B5=D0=BD=D0=B8=D1=8F?= =?UTF-8?q?=20=D0=B2=20=D0=BD=D0=B0=D1=87=D0=B0=D0=BB=D0=B5=20=D0=B8=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BD=D1=86=D0=B5=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1?= =?UTF-8?q?=D0=BE=D1=82=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 20 ++++++++++++++++--- README_EN.md | 20 ++++++++++++++++--- docker-compose.yml | 2 +- .../ApplicationConfiguration.java | 4 +++- .../model/enums/SubscriptionMessageType.java | 6 +++++- .../packmate/pcap/FilePcapWorker.java | 8 ++++++++ .../packmate/service/PcapService.java | 7 ++++++- .../packmate/service/SubscriptionService.java | 10 ++++++++-- 8 files changed, 65 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index e03a52f..512a313 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ Утилита перехвата и анализа трафика для CTF. #### Фичи: +* Поддерживает перехват живого трафика и обработку pcap файлов * Поддерживает текстовые и бинарные сервисы * Умеет отображать совпадения паттернов в пакетах цветом * Подстрока @@ -51,9 +52,7 @@ git submodule update --init --recursive В файле необходимо прописать: ```bash -# Интерфейс, на котором производится перехват трафика -PACKMATE_INTERFACE=wlan0 -# Локальный IP сервера на указанном интерфейсе +# Локальный IP сервера на указанном интерфейсе или в pcap файле PACKMATE_LOCAL_IP=192.168.1.124 # Имя пользователя для web-авторизации PACKMATE_WEB_LOGIN=SomeUser @@ -61,6 +60,21 @@ PACKMATE_WEB_LOGIN=SomeUser PACKMATE_WEB_PASSWORD=SomeSecurePassword ``` +Если мы перехватываем трафик сервера (лучший вариант, если есть возможность): +```bash +# Режим работы - перехват +PACKMATE_MODE=LIVE +# Интерфейс, на котором производится перехват трафика +PACKMATE_INTERFACE=wlan0 +``` +Если мы анализируем pcap дамп: +```bash +# Режим работы - анализ файла +PACKMATE_MODE=FILE +# Путь до файла от корня проекта +PACKMATE_PCAP_FILE=dump.pcap +``` + ### Запуск После указания нужных настроек в env-файле, можно запустить приложение: ```bash diff --git a/README_EN.md b/README_EN.md index 5b22879..5f8b3bf 100644 --- a/README_EN.md +++ b/README_EN.md @@ -7,6 +7,7 @@ Advanced network traffic flow analyzer for A/D CTFs. #### Features: +* Can monitor live traffic or analyze pcap files * Supports binary and textual services * Can highlight found patterns in packets * Substring @@ -50,9 +51,7 @@ It must be called `.env` and located at the root of the project. Contents of the file: ```bash -# Interface to capture on -PACKMATE_INTERFACE=wlan0 -# Local IP on said interface to tell incoming packets from outgoing +# Local IP on network interface or in pcap file to tell incoming packets from outgoing PACKMATE_LOCAL_IP=192.168.1.124 # Username for the web interface PACKMATE_WEB_LOGIN=SomeUser @@ -60,6 +59,21 @@ PACKMATE_WEB_LOGIN=SomeUser PACKMATE_WEB_PASSWORD=SomeSecurePassword ``` +If we are capturing live traffic (best option if possible): +```bash +# Mode: capturing +PACKMATE_MODE=LIVE +# Interface to capture on +PACKMATE_INTERFACE=wlan0 +``` +If we are analyzing pcap dump: +```bash +# Mode: dump analyzing +PACKMATE_MODE=FILE +# Path to pcap file from project root +PACKMATE_PCAP_FILE=dump.pcap +``` + ### Launch After filling in env file you can launch the app: ```bash diff --git a/docker-compose.yml b/docker-compose.yml index f0709f3..efcbc53 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,7 +20,7 @@ services: network_mode: "host" image: packmate-app:v1 command: [ - "java", "-Djava.net.preferIPv4Stack=true", "-Djava.net.preferIPv4Addresses=true", + "java", "-Djava.net.preferIPv4Stack=true", "-Djava.net.preferIPv4Addresses=true", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8000", "-jar", "/app/app.jar", "--spring.datasource.url=jdbc:postgresql://127.0.0.1:65001/$${DB_NAME}", "--spring.datasource.username=$${DB_USER}", "--spring.datasource.password=$${DB_PASSWORD}", "--capture-mode=$${MODE}", "--pcap-file=$${PCAP_FILE}", diff --git a/src/main/java/ru/serega6531/packmate/configuration/ApplicationConfiguration.java b/src/main/java/ru/serega6531/packmate/configuration/ApplicationConfiguration.java index fcfcee9..cbec7ef 100644 --- a/src/main/java/ru/serega6531/packmate/configuration/ApplicationConfiguration.java +++ b/src/main/java/ru/serega6531/packmate/configuration/ApplicationConfiguration.java @@ -22,6 +22,7 @@ import ru.serega6531.packmate.pcap.LivePcapWorker; import ru.serega6531.packmate.pcap.PcapWorker; import ru.serega6531.packmate.service.ServicesService; import ru.serega6531.packmate.service.StreamService; +import ru.serega6531.packmate.service.SubscriptionService; import java.net.UnknownHostException; @@ -48,6 +49,7 @@ public class ApplicationConfiguration extends WebSecurityConfigurerAdapter imple @Autowired public PcapWorker pcapWorker(ServicesService servicesService, StreamService streamService, + SubscriptionService subscriptionService, @Value("${local-ip}") String localIpString, @Value("${interface-name}") String interfaceName, @Value("${pcap-file}") String filename, @@ -55,7 +57,7 @@ public class ApplicationConfiguration extends WebSecurityConfigurerAdapter imple if(captureMode == CaptureMode.LIVE) { return new LivePcapWorker(servicesService, streamService, localIpString, interfaceName); } else { - return new FilePcapWorker(servicesService, streamService, localIpString, filename); + return new FilePcapWorker(servicesService, streamService, subscriptionService, localIpString, filename); } } diff --git a/src/main/java/ru/serega6531/packmate/model/enums/SubscriptionMessageType.java b/src/main/java/ru/serega6531/packmate/model/enums/SubscriptionMessageType.java index 1d44fda..d757866 100644 --- a/src/main/java/ru/serega6531/packmate/model/enums/SubscriptionMessageType.java +++ b/src/main/java/ru/serega6531/packmate/model/enums/SubscriptionMessageType.java @@ -1,5 +1,9 @@ package ru.serega6531.packmate.model.enums; public enum SubscriptionMessageType { - SAVE_SERVICE, SAVE_PATTERN, DELETE_SERVICE, DELETE_PATTERN, NEW_STREAM, COUNTERS_UPDATE + SAVE_SERVICE, SAVE_PATTERN, + DELETE_SERVICE, DELETE_PATTERN, + NEW_STREAM, + COUNTERS_UPDATE, + PCAP_STARTED, PCAP_STOPPED } diff --git a/src/main/java/ru/serega6531/packmate/pcap/FilePcapWorker.java b/src/main/java/ru/serega6531/packmate/pcap/FilePcapWorker.java index f74fea2..6276cb0 100644 --- a/src/main/java/ru/serega6531/packmate/pcap/FilePcapWorker.java +++ b/src/main/java/ru/serega6531/packmate/pcap/FilePcapWorker.java @@ -7,8 +7,11 @@ import org.pcap4j.core.PcapNativeException; import org.pcap4j.core.Pcaps; import org.pcap4j.packet.Packet; import ru.serega6531.packmate.model.enums.Protocol; +import ru.serega6531.packmate.model.enums.SubscriptionMessageType; +import ru.serega6531.packmate.model.pojo.SubscriptionMessage; import ru.serega6531.packmate.service.ServicesService; import ru.serega6531.packmate.service.StreamService; +import ru.serega6531.packmate.service.SubscriptionService; import java.io.EOFException; import java.io.File; @@ -17,13 +20,16 @@ import java.net.UnknownHostException; @Slf4j public class FilePcapWorker extends AbstractPcapWorker { + private final SubscriptionService subscriptionService; private final File file; public FilePcapWorker(ServicesService servicesService, StreamService streamService, + SubscriptionService subscriptionService, String localIpString, String filename) throws UnknownHostException { super(servicesService, streamService, localIpString); + this.subscriptionService = subscriptionService; file = new File(filename); if(!file.exists()) { @@ -67,5 +73,7 @@ public class FilePcapWorker extends AbstractPcapWorker { closeAllStreams(Protocol.TCP); closeAllStreams(Protocol.UDP); + + subscriptionService.broadcast(new SubscriptionMessage(SubscriptionMessageType.PCAP_STOPPED, null)); } } diff --git a/src/main/java/ru/serega6531/packmate/service/PcapService.java b/src/main/java/ru/serega6531/packmate/service/PcapService.java index b503bd3..dacb64e 100644 --- a/src/main/java/ru/serega6531/packmate/service/PcapService.java +++ b/src/main/java/ru/serega6531/packmate/service/PcapService.java @@ -4,6 +4,8 @@ import lombok.Getter; import org.pcap4j.core.PcapNativeException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import ru.serega6531.packmate.model.enums.SubscriptionMessageType; +import ru.serega6531.packmate.model.pojo.SubscriptionMessage; import ru.serega6531.packmate.pcap.PcapWorker; @Service @@ -12,16 +14,19 @@ public class PcapService { @Getter private boolean started = false; + private final SubscriptionService subscriptionService; private final PcapWorker worker; @Autowired - public PcapService(PcapWorker worker) { + public PcapService(SubscriptionService subscriptionService, PcapWorker worker) { + this.subscriptionService = subscriptionService; this.worker = worker; } public synchronized void start() throws PcapNativeException { if(!started) { started = true; + subscriptionService.broadcast(new SubscriptionMessage(SubscriptionMessageType.PCAP_STARTED, null)); worker.start(); } } diff --git a/src/main/java/ru/serega6531/packmate/service/SubscriptionService.java b/src/main/java/ru/serega6531/packmate/service/SubscriptionService.java index 207a978..c4092f0 100644 --- a/src/main/java/ru/serega6531/packmate/service/SubscriptionService.java +++ b/src/main/java/ru/serega6531/packmate/service/SubscriptionService.java @@ -2,6 +2,7 @@ package ru.serega6531.packmate.service; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -39,10 +40,15 @@ public class SubscriptionService { log.info("User unsubscribed: {}", Objects.requireNonNull(session.getRemoteAddress()).getHostName()); } - void broadcast(SubscriptionMessage message) { + /** + * Вызов потокобезопасный + */ + @SneakyThrows + public void broadcast(SubscriptionMessage message) { + final TextMessage messageJson = objectToTextMessage(message); subscribers.forEach(s -> { try { - s.sendMessage(objectToTextMessage(message)); + s.sendMessage(messageJson); } catch (IOException | SockJsTransportFailureException e) { log.warn("WS", e); }