Тип паттерна IGNORE
This commit is contained in:
@@ -13,6 +13,7 @@
|
|||||||
* Подстрока
|
* Подстрока
|
||||||
* Регулярное выражение
|
* Регулярное выражение
|
||||||
* Бинарная подстрока
|
* Бинарная подстрока
|
||||||
|
* Умеет автоматически удалять стримы с определенным контентом, которые не нужно отображать
|
||||||
* Умеет сохранять стримы в избранное и отображать только избранные стримы
|
* Умеет сохранять стримы в избранное и отображать только избранные стримы
|
||||||
* Работает с несколькими сервисами на разных портах, может отображать стримы для конкретных сервисов и паттернов
|
* Работает с несколькими сервисами на разных портах, может отображать стримы для конкретных сервисов и паттернов
|
||||||
* Поддерживает навигацию по стримам с помощью горячих клавиш
|
* Поддерживает навигацию по стримам с помощью горячих клавиш
|
||||||
@@ -95,8 +96,8 @@ sudo docker-compose up --build -d
|
|||||||
### Начало работы
|
### Начало работы
|
||||||
При попытке зайти в web-интерфейс впервые, браузер спросит логин и пароль,
|
При попытке зайти в web-интерфейс впервые, браузер спросит логин и пароль,
|
||||||
который указывался в env-файле.
|
который указывался в env-файле.
|
||||||
После успешного входа необходимо открыть настройки кликом по шестеренкам в правом
|
При необходимости можно настроить дополнительные параметры по кнопке с шестеренками в верхнем
|
||||||
верхнем углу, затем ввести логин и пароль API, указанный при входе.
|
правом углу экрана.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -110,6 +111,8 @@ sudo docker-compose up --build -d
|
|||||||
Для удобного отлова флагов в приложении существует система паттернов.
|
Для удобного отлова флагов в приложении существует система паттернов.
|
||||||
Чтобы создать паттерн, нужно открыть выпадающее меню `Patterns` и нажать кнопку `+`,
|
Чтобы создать паттерн, нужно открыть выпадающее меню `Patterns` и нажать кнопку `+`,
|
||||||
затем указать нужный тип поиска, сам паттерн, цвет подсветки в тексте и прочее.
|
затем указать нужный тип поиска, сам паттерн, цвет подсветки в тексте и прочее.
|
||||||
|
Если выбрать тип паттерна IGNORE, то стримы, попадающие под шаблон, автоматически будут удаляться.
|
||||||
|
Это может пригодиться, чтобы не засорять БД трафиком с эксплоитами, которые уже были запатчены.
|
||||||
|
|
||||||
В режиме LIVE система начнет автоматически захватывать стримы и отображать их в сайдбаре.
|
В режиме LIVE система начнет автоматически захватывать стримы и отображать их в сайдбаре.
|
||||||
В режиме FILE для начала обработки файла нужно нажать соответствующую кнопку в сайдбаре.
|
В режиме FILE для начала обработки файла нужно нажать соответствующую кнопку в сайдбаре.
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ Advanced network traffic flow analyzer for A/D CTFs.
|
|||||||
* Substring
|
* Substring
|
||||||
* Regular expression
|
* Regular expression
|
||||||
* Binary substring
|
* Binary substring
|
||||||
|
* Can automatically delete streams with content that you don't need
|
||||||
* Can make certain streams favorite and show only favorite streams
|
* Can make certain streams favorite and show only favorite streams
|
||||||
* Supports several simultaneous services, can show streams for a specific service or pattern
|
* Supports several simultaneous services, can show streams for a specific service or pattern
|
||||||
* Allows navigating streams using shortcuts
|
* Allows navigating streams using shortcuts
|
||||||
@@ -89,7 +90,7 @@ If everything went fine, Packmate will be available on port `65000` from any hos
|
|||||||
When you open a web interface for the first time, you will be asked for a login and password
|
When you open a web interface for the first time, you will be asked for a login and password
|
||||||
you specified in the env file.
|
you specified in the env file.
|
||||||
After entering the credentials, open the settings by clicking the cogs
|
After entering the credentials, open the settings by clicking the cogs
|
||||||
in the top right corner and enter the specified login and password again.
|
in the top right corner and modify additional parameters.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -104,6 +105,8 @@ then fill in the service name, port, and optimizations to perform on streams.
|
|||||||
For a simple monitoring of flags, there is a system of patterns.
|
For a simple monitoring of flags, there is a system of patterns.
|
||||||
To create a pattern, open `Patterns` dropdown menu, press `+`, then
|
To create a pattern, open `Patterns` dropdown menu, press `+`, then
|
||||||
specify the type of pattern, the pattern itself, highlight color and other things.
|
specify the type of pattern, the pattern itself, highlight color and other things.
|
||||||
|
If you choose IGNORE as the type of a pattern, all matching streams will be automatically deleted.
|
||||||
|
This can be useful to filter out exploits you have already patched against.
|
||||||
|
|
||||||
In LIVE mode the system will automatically capture streams and show them in a sidebar.
|
In LIVE mode the system will automatically capture streams and show them in a sidebar.
|
||||||
In FILE mode you'll have to press appropriate button in a sidebar to start processing a file.
|
In FILE mode you'll have to press appropriate button in a sidebar to start processing a file.
|
||||||
|
|||||||
2
frontend
2
frontend
Submodule frontend updated: fb3637a8b2...a8e75766a1
Binary file not shown.
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
@@ -3,9 +3,7 @@ package ru.serega6531.packmate.model;
|
|||||||
import lombok.*;
|
import lombok.*;
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
import org.hibernate.annotations.GenericGenerator;
|
||||||
|
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.*;
|
||||||
import javax.persistence.GeneratedValue;
|
|
||||||
import javax.persistence.Id;
|
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@GenericGenerator(
|
@GenericGenerator(
|
||||||
@@ -22,13 +20,18 @@ import javax.persistence.Id;
|
|||||||
@Builder
|
@Builder
|
||||||
@Getter
|
@Getter
|
||||||
@ToString
|
@ToString
|
||||||
@EqualsAndHashCode
|
@EqualsAndHashCode(exclude = "packet")
|
||||||
public class FoundPattern {
|
public class FoundPattern {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(generator = "found_pattern_generator")
|
@GeneratedValue(generator = "found_pattern_generator")
|
||||||
private int id;
|
private int id;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "packet_id", nullable = false)
|
||||||
|
@Setter
|
||||||
|
private Packet packet;
|
||||||
|
|
||||||
private int patternId;
|
private int patternId;
|
||||||
|
|
||||||
private int startPosition;
|
private int startPosition;
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
package ru.serega6531.packmate.model;
|
package ru.serega6531.packmate.model;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.*;
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
import org.hibernate.annotations.GenericGenerator;
|
||||||
|
|
||||||
import javax.persistence.*;
|
import javax.persistence.*;
|
||||||
@@ -24,6 +21,7 @@ import java.util.Set;
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@Builder
|
@Builder
|
||||||
@Table(indexes = { @Index(name = "stream_id_index", columnList = "stream_id") })
|
@Table(indexes = { @Index(name = "stream_id_index", columnList = "stream_id") })
|
||||||
|
@EqualsAndHashCode(exclude = "stream")
|
||||||
public class Packet {
|
public class Packet {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@@ -40,7 +38,7 @@ public class Packet {
|
|||||||
@JoinColumn(name = "stream_id", nullable = false)
|
@JoinColumn(name = "stream_id", nullable = false)
|
||||||
private Stream stream;
|
private Stream stream;
|
||||||
|
|
||||||
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
@OneToMany(mappedBy = "packet", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
||||||
private Set<FoundPattern> matches;
|
private Set<FoundPattern> matches;
|
||||||
|
|
||||||
private long timestamp;
|
private long timestamp;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package ru.serega6531.packmate.model;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import org.hibernate.annotations.GenericGenerator;
|
import org.hibernate.annotations.GenericGenerator;
|
||||||
|
import ru.serega6531.packmate.model.enums.PatternActionType;
|
||||||
import ru.serega6531.packmate.model.enums.PatternDirectionType;
|
import ru.serega6531.packmate.model.enums.PatternDirectionType;
|
||||||
import ru.serega6531.packmate.model.enums.PatternSearchType;
|
import ru.serega6531.packmate.model.enums.PatternSearchType;
|
||||||
|
|
||||||
@@ -39,6 +40,8 @@ public class Pattern {
|
|||||||
|
|
||||||
private PatternDirectionType directionType;
|
private PatternDirectionType directionType;
|
||||||
|
|
||||||
|
private PatternActionType actionType;
|
||||||
|
|
||||||
@ManyToMany(mappedBy = "foundPatterns", fetch = FetchType.LAZY)
|
@ManyToMany(mappedBy = "foundPatterns", fetch = FetchType.LAZY)
|
||||||
private List<Stream> matchedStreams;
|
private List<Stream> matchedStreams;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package ru.serega6531.packmate.model.enums;
|
||||||
|
|
||||||
|
public enum PatternActionType {
|
||||||
|
FIND, IGNORE
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package ru.serega6531.packmate.model.pojo;
|
package ru.serega6531.packmate.model.pojo;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import ru.serega6531.packmate.model.enums.PatternActionType;
|
||||||
import ru.serega6531.packmate.model.enums.PatternDirectionType;
|
import ru.serega6531.packmate.model.enums.PatternDirectionType;
|
||||||
import ru.serega6531.packmate.model.enums.PatternSearchType;
|
import ru.serega6531.packmate.model.enums.PatternSearchType;
|
||||||
|
|
||||||
@@ -11,8 +12,9 @@ public class PatternDto {
|
|||||||
private boolean enabled;
|
private boolean enabled;
|
||||||
private String name;
|
private String name;
|
||||||
private String value;
|
private String value;
|
||||||
private String color; // для вставки в css
|
private String color;
|
||||||
private PatternSearchType searchType;
|
private PatternSearchType searchType;
|
||||||
private PatternDirectionType directionType;
|
private PatternDirectionType directionType;
|
||||||
|
private PatternActionType actionType;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import ru.serega6531.packmate.model.FoundPattern;
|
import ru.serega6531.packmate.model.FoundPattern;
|
||||||
import ru.serega6531.packmate.model.Pattern;
|
import ru.serega6531.packmate.model.Pattern;
|
||||||
|
import ru.serega6531.packmate.model.enums.PatternActionType;
|
||||||
import ru.serega6531.packmate.model.enums.PatternDirectionType;
|
import ru.serega6531.packmate.model.enums.PatternDirectionType;
|
||||||
import ru.serega6531.packmate.model.enums.PatternSearchType;
|
import ru.serega6531.packmate.model.enums.PatternSearchType;
|
||||||
import ru.serega6531.packmate.model.enums.SubscriptionMessageType;
|
import ru.serega6531.packmate.model.enums.SubscriptionMessageType;
|
||||||
@@ -45,11 +46,11 @@ public class PatternService {
|
|||||||
return patterns.values();
|
return patterns.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<FoundPattern> findMatches(byte[] bytes, boolean incoming) {
|
public Set<FoundPattern> findMatches(byte[] bytes, PatternDirectionType directionType, PatternActionType actionType) {
|
||||||
final List<Pattern> list = patterns.values().stream()
|
final List<Pattern> list = patterns.values().stream()
|
||||||
.filter(Pattern::isEnabled)
|
.filter(Pattern::isEnabled)
|
||||||
.filter(p -> p.getDirectionType() == (incoming ? PatternDirectionType.INPUT : PatternDirectionType.OUTPUT)
|
.filter(p -> p.getActionType() == actionType)
|
||||||
|| p.getDirectionType() == PatternDirectionType.BOTH)
|
.filter(p -> p.getDirectionType() == directionType || p.getDirectionType() == PatternDirectionType.BOTH)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
return new PatternMatcher(bytes, list).findMatches();
|
return new PatternMatcher(bytes, list).findMatches();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.transaction.annotation.Propagation;
|
import org.springframework.transaction.annotation.Propagation;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import ru.serega6531.packmate.model.*;
|
import ru.serega6531.packmate.model.*;
|
||||||
|
import ru.serega6531.packmate.model.enums.PatternActionType;
|
||||||
|
import ru.serega6531.packmate.model.enums.PatternDirectionType;
|
||||||
import ru.serega6531.packmate.model.enums.SubscriptionMessageType;
|
import ru.serega6531.packmate.model.enums.SubscriptionMessageType;
|
||||||
import ru.serega6531.packmate.model.pojo.*;
|
import ru.serega6531.packmate.model.pojo.*;
|
||||||
import ru.serega6531.packmate.repository.StreamRepository;
|
import ru.serega6531.packmate.repository.StreamRepository;
|
||||||
@@ -99,11 +101,20 @@ public class StreamService {
|
|||||||
countingService.countStream(service.getPort(), packets.size());
|
countingService.countStream(service.getPort(), packets.size());
|
||||||
|
|
||||||
packets = new StreamOptimizer(keysHolder, service, packets).optimizeStream();
|
packets = new StreamOptimizer(keysHolder, service, packets).optimizeStream();
|
||||||
processUserAgent(packets, stream);
|
|
||||||
|
|
||||||
|
if (isStreamIgnored(packets)) {
|
||||||
|
log.debug("New stream is ignored");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
processUserAgent(packets, stream);
|
||||||
Stream savedStream = save(stream);
|
Stream savedStream = save(stream);
|
||||||
|
|
||||||
Set<Pattern> foundPatterns = getFoundPatterns(packets, savedStream);
|
for (Packet packet : packets) {
|
||||||
|
packet.setStream(savedStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<Pattern> foundPatterns = matchPatterns(packets);
|
||||||
savedStream.setFoundPatterns(foundPatterns);
|
savedStream.setFoundPatterns(foundPatterns);
|
||||||
savedStream.setPackets(packets);
|
savedStream.setPackets(packets);
|
||||||
savedStream = save(savedStream);
|
savedStream = save(savedStream);
|
||||||
@@ -139,13 +150,16 @@ public class StreamService {
|
|||||||
return "" + alphabet[hash % l] + alphabet[(hash / l) % l] + alphabet[(hash / (l * l)) % l];
|
return "" + alphabet[hash % l] + alphabet[(hash / l) % l] + alphabet[(hash / (l * l)) % l];
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<Pattern> getFoundPatterns(List<Packet> packets, Stream savedStream) {
|
private Set<Pattern> matchPatterns(List<Packet> packets) {
|
||||||
Set<Pattern> foundPatterns = new HashSet<>();
|
Set<Pattern> foundPatterns = new HashSet<>();
|
||||||
|
|
||||||
for (Packet packet : packets) {
|
for (Packet packet : packets) {
|
||||||
packet.setStream(savedStream);
|
PatternDirectionType direction = packet.isIncoming() ? PatternDirectionType.INPUT : PatternDirectionType.OUTPUT;
|
||||||
final Set<FoundPattern> matches = patternService.findMatches(packet.getContent(), packet.isIncoming());
|
final Set<FoundPattern> matches = patternService.findMatches(packet.getContent(), direction, PatternActionType.FIND);
|
||||||
|
|
||||||
packet.setMatches(matches);
|
packet.setMatches(matches);
|
||||||
|
matches.forEach(m -> m.setPacket(packet));
|
||||||
|
|
||||||
foundPatterns.addAll(matches.stream()
|
foundPatterns.addAll(matches.stream()
|
||||||
.map(FoundPattern::getPatternId)
|
.map(FoundPattern::getPatternId)
|
||||||
.map(patternService::find)
|
.map(patternService::find)
|
||||||
@@ -155,6 +169,18 @@ public class StreamService {
|
|||||||
return foundPatterns;
|
return foundPatterns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isStreamIgnored(List<Packet> packets) {
|
||||||
|
for (Packet packet : packets) {
|
||||||
|
PatternDirectionType direction = packet.isIncoming() ? PatternDirectionType.INPUT : PatternDirectionType.OUTPUT;
|
||||||
|
final Set<FoundPattern> matches = patternService.findMatches(packet.getContent(), direction, PatternActionType.IGNORE);
|
||||||
|
if (!matches.isEmpty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private Stream save(Stream stream) {
|
private Stream save(Stream stream) {
|
||||||
Stream saved;
|
Stream saved;
|
||||||
if (stream.getId() == null) {
|
if (stream.getId() == null) {
|
||||||
|
|||||||
Reference in New Issue
Block a user