Тип паттерна IGNORE

This commit is contained in:
serega6531
2020-12-29 21:45:58 +03:00
parent 9e1a01fe51
commit 2026f370ee
11 changed files with 68 additions and 24 deletions

View File

@@ -13,6 +13,7 @@
* Подстрока
* Регулярное выражение
* Бинарная подстрока
* Умеет автоматически удалять стримы с определенным контентом, которые не нужно отображать
* Умеет сохранять стримы в избранное и отображать только избранные стримы
* Работает с несколькими сервисами на разных портах, может отображать стримы для конкретных сервисов и паттернов
* Поддерживает навигацию по стримам с помощью горячих клавиш
@@ -95,8 +96,8 @@ sudo docker-compose up --build -d
### Начало работы
При попытке зайти в web-интерфейс впервые, браузер спросит логин и пароль,
который указывался в env-файле.
После успешного входа необходимо открыть настройки кликом по шестеренкам в правом
верхнем углу, затем ввести логин и пароль API, указанный при входе.
При необходимости можно настроить дополнительные параметры по кнопке с шестеренками в верхнем
правом углу экрана.
![Скриншот настроек](screenshots/Screenshot_Settings.png)
@@ -110,6 +111,8 @@ sudo docker-compose up --build -d
Для удобного отлова флагов в приложении существует система паттернов.
Чтобы создать паттерн, нужно открыть выпадающее меню `Patterns` и нажать кнопку `+`,
затем указать нужный тип поиска, сам паттерн, цвет подсветки в тексте и прочее.
Если выбрать тип паттерна IGNORE, то стримы, попадающие под шаблон, автоматически будут удаляться.
Это может пригодиться, чтобы не засорять БД трафиком с эксплоитами, которые уже были запатчены.
В режиме LIVE система начнет автоматически захватывать стримы и отображать их в сайдбаре.
В режиме FILE для начала обработки файла нужно нажать соответствующую кнопку в сайдбаре.

View File

@@ -13,6 +13,7 @@ Advanced network traffic flow analyzer for A/D CTFs.
* Substring
* Regular expression
* Binary substring
* Can automatically delete streams with content that you don't need
* Can make certain streams favorite and show only favorite streams
* Supports several simultaneous services, can show streams for a specific service or pattern
* 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
you specified in the env file.
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.
![Settings](screenshots/Screenshot_Settings.png)
@@ -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.
To create a pattern, open `Patterns` dropdown menu, press `+`, then
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 FILE mode you'll have to press appropriate button in a sidebar to start processing a file.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

View File

@@ -3,9 +3,7 @@ package ru.serega6531.packmate.model;
import lombok.*;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.*;
@Entity
@GenericGenerator(
@@ -22,13 +20,18 @@ import javax.persistence.Id;
@Builder
@Getter
@ToString
@EqualsAndHashCode
@EqualsAndHashCode(exclude = "packet")
public class FoundPattern {
@Id
@GeneratedValue(generator = "found_pattern_generator")
private int id;
@ManyToOne
@JoinColumn(name = "packet_id", nullable = false)
@Setter
private Packet packet;
private int patternId;
private int startPosition;

View File

@@ -1,9 +1,6 @@
package ru.serega6531.packmate.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.*;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
@@ -24,6 +21,7 @@ import java.util.Set;
@AllArgsConstructor
@Builder
@Table(indexes = { @Index(name = "stream_id_index", columnList = "stream_id") })
@EqualsAndHashCode(exclude = "stream")
public class Packet {
@Id
@@ -40,7 +38,7 @@ public class Packet {
@JoinColumn(name = "stream_id", nullable = false)
private Stream stream;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@OneToMany(mappedBy = "packet", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Set<FoundPattern> matches;
private long timestamp;

View File

@@ -3,6 +3,7 @@ package ru.serega6531.packmate.model;
import lombok.Data;
import lombok.ToString;
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.PatternSearchType;
@@ -39,6 +40,8 @@ public class Pattern {
private PatternDirectionType directionType;
private PatternActionType actionType;
@ManyToMany(mappedBy = "foundPatterns", fetch = FetchType.LAZY)
private List<Stream> matchedStreams;

View File

@@ -0,0 +1,5 @@
package ru.serega6531.packmate.model.enums;
public enum PatternActionType {
FIND, IGNORE
}

View File

@@ -1,6 +1,7 @@
package ru.serega6531.packmate.model.pojo;
import lombok.Data;
import ru.serega6531.packmate.model.enums.PatternActionType;
import ru.serega6531.packmate.model.enums.PatternDirectionType;
import ru.serega6531.packmate.model.enums.PatternSearchType;
@@ -11,8 +12,9 @@ public class PatternDto {
private boolean enabled;
private String name;
private String value;
private String color; // для вставки в css
private String color;
private PatternSearchType searchType;
private PatternDirectionType directionType;
private PatternActionType actionType;
}

View File

@@ -6,6 +6,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import ru.serega6531.packmate.model.FoundPattern;
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.PatternSearchType;
import ru.serega6531.packmate.model.enums.SubscriptionMessageType;
@@ -45,11 +46,11 @@ public class PatternService {
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()
.filter(Pattern::isEnabled)
.filter(p -> p.getDirectionType() == (incoming ? PatternDirectionType.INPUT : PatternDirectionType.OUTPUT)
|| p.getDirectionType() == PatternDirectionType.BOTH)
.filter(p -> p.getActionType() == actionType)
.filter(p -> p.getDirectionType() == directionType || p.getDirectionType() == PatternDirectionType.BOTH)
.collect(Collectors.toList());
return new PatternMatcher(bytes, list).findMatches();
}

View File

@@ -11,6 +11,8 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
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.pojo.*;
import ru.serega6531.packmate.repository.StreamRepository;
@@ -99,11 +101,20 @@ public class StreamService {
countingService.countStream(service.getPort(), packets.size());
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);
Set<Pattern> foundPatterns = getFoundPatterns(packets, savedStream);
for (Packet packet : packets) {
packet.setStream(savedStream);
}
Set<Pattern> foundPatterns = matchPatterns(packets);
savedStream.setFoundPatterns(foundPatterns);
savedStream.setPackets(packets);
savedStream = save(savedStream);
@@ -139,13 +150,16 @@ public class StreamService {
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<>();
for (Packet packet : packets) {
packet.setStream(savedStream);
final Set<FoundPattern> matches = patternService.findMatches(packet.getContent(), packet.isIncoming());
PatternDirectionType direction = packet.isIncoming() ? PatternDirectionType.INPUT : PatternDirectionType.OUTPUT;
final Set<FoundPattern> matches = patternService.findMatches(packet.getContent(), direction, PatternActionType.FIND);
packet.setMatches(matches);
matches.forEach(m -> m.setPacket(packet));
foundPatterns.addAll(matches.stream()
.map(FoundPattern::getPatternId)
.map(patternService::find)
@@ -155,6 +169,18 @@ public class StreamService {
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) {
Stream saved;
if (stream.getId() == null) {