Отправка сообщения в начале и конце обработки

This commit is contained in:
serega6531
2020-04-06 23:52:08 +03:00
parent 733d92cbf8
commit e1b11cfdee
8 changed files with 65 additions and 12 deletions

View File

@@ -7,6 +7,7 @@
Утилита перехвата и анализа трафика для CTF. Утилита перехвата и анализа трафика для CTF.
#### Фичи: #### Фичи:
* Поддерживает перехват живого трафика и обработку pcap файлов
* Поддерживает текстовые и бинарные сервисы * Поддерживает текстовые и бинарные сервисы
* Умеет отображать совпадения паттернов в пакетах цветом * Умеет отображать совпадения паттернов в пакетах цветом
* Подстрока * Подстрока
@@ -51,9 +52,7 @@ git submodule update --init --recursive
В файле необходимо прописать: В файле необходимо прописать:
```bash ```bash
# Интерфейс, на котором производится перехват трафика # Локальный IP сервера на указанном интерфейсе или в pcap файле
PACKMATE_INTERFACE=wlan0
# Локальный IP сервера на указанном интерфейсе
PACKMATE_LOCAL_IP=192.168.1.124 PACKMATE_LOCAL_IP=192.168.1.124
# Имя пользователя для web-авторизации # Имя пользователя для web-авторизации
PACKMATE_WEB_LOGIN=SomeUser PACKMATE_WEB_LOGIN=SomeUser
@@ -61,6 +60,21 @@ PACKMATE_WEB_LOGIN=SomeUser
PACKMATE_WEB_PASSWORD=SomeSecurePassword PACKMATE_WEB_PASSWORD=SomeSecurePassword
``` ```
Если мы перехватываем трафик сервера (лучший вариант, если есть возможность):
```bash
# Режим работы - перехват
PACKMATE_MODE=LIVE
# Интерфейс, на котором производится перехват трафика
PACKMATE_INTERFACE=wlan0
```
Если мы анализируем pcap дамп:
```bash
# Режим работы - анализ файла
PACKMATE_MODE=FILE
# Путь до файла от корня проекта
PACKMATE_PCAP_FILE=dump.pcap
```
### Запуск ### Запуск
После указания нужных настроек в env-файле, можно запустить приложение: После указания нужных настроек в env-файле, можно запустить приложение:
```bash ```bash

View File

@@ -7,6 +7,7 @@
Advanced network traffic flow analyzer for A/D CTFs. Advanced network traffic flow analyzer for A/D CTFs.
#### Features: #### Features:
* Can monitor live traffic or analyze pcap files
* Supports binary and textual services * Supports binary and textual services
* Can highlight found patterns in packets * Can highlight found patterns in packets
* Substring * Substring
@@ -50,9 +51,7 @@ It must be called `.env` and located at the root of the project.
Contents of the file: Contents of the file:
```bash ```bash
# Interface to capture on # Local IP on network interface or in pcap file to tell incoming packets from outgoing
PACKMATE_INTERFACE=wlan0
# Local IP on said interface to tell incoming packets from outgoing
PACKMATE_LOCAL_IP=192.168.1.124 PACKMATE_LOCAL_IP=192.168.1.124
# Username for the web interface # Username for the web interface
PACKMATE_WEB_LOGIN=SomeUser PACKMATE_WEB_LOGIN=SomeUser
@@ -60,6 +59,21 @@ PACKMATE_WEB_LOGIN=SomeUser
PACKMATE_WEB_PASSWORD=SomeSecurePassword 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 ### Launch
After filling in env file you can launch the app: After filling in env file you can launch the app:
```bash ```bash

View File

@@ -20,7 +20,7 @@ services:
network_mode: "host" network_mode: "host"
image: packmate-app:v1 image: packmate-app:v1
command: [ 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}", "-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}", "--spring.datasource.username=$${DB_USER}", "--spring.datasource.password=$${DB_PASSWORD}",
"--capture-mode=$${MODE}", "--pcap-file=$${PCAP_FILE}", "--capture-mode=$${MODE}", "--pcap-file=$${PCAP_FILE}",

View File

@@ -22,6 +22,7 @@ import ru.serega6531.packmate.pcap.LivePcapWorker;
import ru.serega6531.packmate.pcap.PcapWorker; import ru.serega6531.packmate.pcap.PcapWorker;
import ru.serega6531.packmate.service.ServicesService; import ru.serega6531.packmate.service.ServicesService;
import ru.serega6531.packmate.service.StreamService; import ru.serega6531.packmate.service.StreamService;
import ru.serega6531.packmate.service.SubscriptionService;
import java.net.UnknownHostException; import java.net.UnknownHostException;
@@ -48,6 +49,7 @@ public class ApplicationConfiguration extends WebSecurityConfigurerAdapter imple
@Autowired @Autowired
public PcapWorker pcapWorker(ServicesService servicesService, public PcapWorker pcapWorker(ServicesService servicesService,
StreamService streamService, StreamService streamService,
SubscriptionService subscriptionService,
@Value("${local-ip}") String localIpString, @Value("${local-ip}") String localIpString,
@Value("${interface-name}") String interfaceName, @Value("${interface-name}") String interfaceName,
@Value("${pcap-file}") String filename, @Value("${pcap-file}") String filename,
@@ -55,7 +57,7 @@ public class ApplicationConfiguration extends WebSecurityConfigurerAdapter imple
if(captureMode == CaptureMode.LIVE) { if(captureMode == CaptureMode.LIVE) {
return new LivePcapWorker(servicesService, streamService, localIpString, interfaceName); return new LivePcapWorker(servicesService, streamService, localIpString, interfaceName);
} else { } else {
return new FilePcapWorker(servicesService, streamService, localIpString, filename); return new FilePcapWorker(servicesService, streamService, subscriptionService, localIpString, filename);
} }
} }

View File

@@ -1,5 +1,9 @@
package ru.serega6531.packmate.model.enums; package ru.serega6531.packmate.model.enums;
public enum SubscriptionMessageType { 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
} }

View File

@@ -7,8 +7,11 @@ import org.pcap4j.core.PcapNativeException;
import org.pcap4j.core.Pcaps; import org.pcap4j.core.Pcaps;
import org.pcap4j.packet.Packet; import org.pcap4j.packet.Packet;
import ru.serega6531.packmate.model.enums.Protocol; 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.ServicesService;
import ru.serega6531.packmate.service.StreamService; import ru.serega6531.packmate.service.StreamService;
import ru.serega6531.packmate.service.SubscriptionService;
import java.io.EOFException; import java.io.EOFException;
import java.io.File; import java.io.File;
@@ -17,13 +20,16 @@ import java.net.UnknownHostException;
@Slf4j @Slf4j
public class FilePcapWorker extends AbstractPcapWorker { public class FilePcapWorker extends AbstractPcapWorker {
private final SubscriptionService subscriptionService;
private final File file; private final File file;
public FilePcapWorker(ServicesService servicesService, public FilePcapWorker(ServicesService servicesService,
StreamService streamService, StreamService streamService,
SubscriptionService subscriptionService,
String localIpString, String localIpString,
String filename) throws UnknownHostException { String filename) throws UnknownHostException {
super(servicesService, streamService, localIpString); super(servicesService, streamService, localIpString);
this.subscriptionService = subscriptionService;
file = new File(filename); file = new File(filename);
if(!file.exists()) { if(!file.exists()) {
@@ -67,5 +73,7 @@ public class FilePcapWorker extends AbstractPcapWorker {
closeAllStreams(Protocol.TCP); closeAllStreams(Protocol.TCP);
closeAllStreams(Protocol.UDP); closeAllStreams(Protocol.UDP);
subscriptionService.broadcast(new SubscriptionMessage(SubscriptionMessageType.PCAP_STOPPED, null));
} }
} }

View File

@@ -4,6 +4,8 @@ import lombok.Getter;
import org.pcap4j.core.PcapNativeException; import org.pcap4j.core.PcapNativeException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; 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; import ru.serega6531.packmate.pcap.PcapWorker;
@Service @Service
@@ -12,16 +14,19 @@ public class PcapService {
@Getter @Getter
private boolean started = false; private boolean started = false;
private final SubscriptionService subscriptionService;
private final PcapWorker worker; private final PcapWorker worker;
@Autowired @Autowired
public PcapService(PcapWorker worker) { public PcapService(SubscriptionService subscriptionService, PcapWorker worker) {
this.subscriptionService = subscriptionService;
this.worker = worker; this.worker = worker;
} }
public synchronized void start() throws PcapNativeException { public synchronized void start() throws PcapNativeException {
if(!started) { if(!started) {
started = true; started = true;
subscriptionService.broadcast(new SubscriptionMessage(SubscriptionMessageType.PCAP_STARTED, null));
worker.start(); worker.start();
} }
} }

View File

@@ -2,6 +2,7 @@ package ru.serega6531.packmate.service;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -39,10 +40,15 @@ public class SubscriptionService {
log.info("User unsubscribed: {}", Objects.requireNonNull(session.getRemoteAddress()).getHostName()); 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 -> { subscribers.forEach(s -> {
try { try {
s.sendMessage(objectToTextMessage(message)); s.sendMessage(messageJson);
} catch (IOException | SockJsTransportFailureException e) { } catch (IOException | SockJsTransportFailureException e) {
log.warn("WS", e); log.warn("WS", e);
} }