Отправка сообщения в начале и конце обработки
This commit is contained in:
20
README.md
20
README.md
@@ -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
|
||||||
|
|||||||
20
README_EN.md
20
README_EN.md
@@ -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
|
||||||
|
|||||||
@@ -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}",
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user