Доделан поиск сигнатур

This commit is contained in:
serega6531
2019-04-30 22:35:57 +03:00
parent 64507a6d07
commit a121a5550d
6 changed files with 99 additions and 81 deletions

View File

@@ -14,9 +14,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import ru.serega6531.packmate.model.CtfService; import ru.serega6531.packmate.model.CtfService;
import ru.serega6531.packmate.model.Stream;
import ru.serega6531.packmate.model.UnfinishedStream; import ru.serega6531.packmate.model.UnfinishedStream;
import ru.serega6531.packmate.service.*; import ru.serega6531.packmate.service.ServicesService;
import ru.serega6531.packmate.service.StreamService;
import javax.annotation.PreDestroy; import javax.annotation.PreDestroy;
import java.net.Inet4Address; import java.net.Inet4Address;
@@ -31,8 +31,6 @@ public class PcapWorker {
private final ServicesService servicesService; private final ServicesService servicesService;
private final StreamService streamService; private final StreamService streamService;
private final PacketService packetService;
private final StreamSubscriptionService subscriptionService;
private final PcapNetworkInterface device; private final PcapNetworkInterface device;
private PcapHandle pcap = null; private PcapHandle pcap = null;
@@ -51,14 +49,10 @@ public class PcapWorker {
@Autowired @Autowired
public PcapWorker(ServicesService servicesService, public PcapWorker(ServicesService servicesService,
StreamService streamService, StreamService streamService,
PacketService packetService,
StreamSubscriptionService subscriptionService,
@Value("${interface-name}") String interfaceName, @Value("${interface-name}") String interfaceName,
@Value("${local-ip}") String localIp) throws PcapNativeException { @Value("${local-ip}") String localIp) throws PcapNativeException {
this.servicesService = servicesService; this.servicesService = servicesService;
this.streamService = streamService; this.streamService = streamService;
this.packetService = packetService;
this.subscriptionService = subscriptionService;
this.localIp = localIp; this.localIp = localIp;
@@ -115,7 +109,7 @@ public class PcapWorker {
boolean fin = false; boolean fin = false;
boolean rst = false; boolean rst = false;
if(rawPacket.contains(IpV4Packet.class)){ if (rawPacket.contains(IpV4Packet.class)) {
final IpV4Packet.IpV4Header header = rawPacket.get(IpV4Packet.class).getHeader(); final IpV4Packet.IpV4Header header = rawPacket.get(IpV4Packet.class).getHeader();
sourceIp = header.getSrcAddr(); sourceIp = header.getSrcAddr();
destIp = header.getDstAddr(); destIp = header.getDstAddr();
@@ -123,7 +117,7 @@ public class PcapWorker {
destIpString = header.getDstAddr().getHostAddress(); destIpString = header.getDstAddr().getHostAddress();
} }
if(rawPacket.contains(TcpPacket.class)) { if (rawPacket.contains(TcpPacket.class)) {
final TcpPacket packet = rawPacket.get(TcpPacket.class); final TcpPacket packet = rawPacket.get(TcpPacket.class);
final TcpPacket.TcpHeader header = packet.getHeader(); final TcpPacket.TcpHeader header = packet.getHeader();
sourcePort = header.getSrcPort().valueAsInt(); sourcePort = header.getSrcPort().valueAsInt();
@@ -133,7 +127,7 @@ public class PcapWorker {
rst = header.getRst(); rst = header.getRst();
content = packet.getRawData(); content = packet.getRawData();
protocol = Protocol.TCP; protocol = Protocol.TCP;
} else if(rawPacket.contains(UdpPacket.class)) { } else if (rawPacket.contains(UdpPacket.class)) {
final UdpPacket packet = rawPacket.get(UdpPacket.class); final UdpPacket packet = rawPacket.get(UdpPacket.class);
final UdpPacket.UdpHeader header = packet.getHeader(); final UdpPacket.UdpHeader header = packet.getHeader();
sourcePort = header.getSrcPort().valueAsInt(); sourcePort = header.getSrcPort().valueAsInt();
@@ -142,10 +136,11 @@ public class PcapWorker {
protocol = Protocol.UDP; protocol = Protocol.UDP;
} }
if(sourceIpString != null && sourcePort != -1) { if (sourceIpString != null && sourcePort != -1) {
final Optional<CtfService> serviceOptional = findService(sourceIpString, sourcePort, destIpString, destPort); final Optional<CtfService> serviceOptional =
servicesService.findService(localIp, sourceIpString, sourcePort, destIpString, destPort);
if(serviceOptional.isPresent()) { if (serviceOptional.isPresent()) {
String sourceIpAndPort = sourceIpString + ":" + sourcePort; String sourceIpAndPort = sourceIpString + ":" + sourcePort;
String destIpAndPort = destIpString + ":" + destPort; String destIpAndPort = destIpString + ":" + destPort;
@@ -157,7 +152,7 @@ public class PcapWorker {
.content(content) .content(content)
.build(); .build();
if(unfinishedStreams.containsKey(stream)) { if (unfinishedStreams.containsKey(stream)) {
unfinishedStreams.get(stream).add(packet); unfinishedStreams.get(stream).add(packet);
} else { } else {
List<ru.serega6531.packmate.model.Packet> packets = new ArrayList<>(); List<ru.serega6531.packmate.model.Packet> packets = new ArrayList<>();
@@ -169,69 +164,35 @@ public class PcapWorker {
protocol.name().toLowerCase(), serviceOptional.get(), sourceIpString, sourcePort, destIpString, destPort, protocol.name().toLowerCase(), serviceOptional.get(), sourceIpString, sourcePort, destIpString, destPort,
unfinishedStreams.get(stream).size()); unfinishedStreams.get(stream).size());
if(protocol == Protocol.TCP) { if (protocol == Protocol.TCP) {
if(!fins.containsKey(stream)) { if (!fins.containsKey(stream)) {
fins.put(stream, new HashSet<>()); fins.put(stream, new HashSet<>());
} }
if(!acks.containsKey(stream)) { if (!acks.containsKey(stream)) {
acks.put(stream, new HashSet<>()); acks.put(stream, new HashSet<>());
} }
final Set<String> finsForStream = fins.get(stream); final Set<String> finsForStream = fins.get(stream);
final Set<String> acksForStream = acks.get(stream); final Set<String> acksForStream = acks.get(stream);
if(fin) { if (fin) {
finsForStream.add(sourceIpAndPort); finsForStream.add(sourceIpAndPort);
} }
if(ack && finsForStream.contains(destIpAndPort)) { // проверяем destIp, потому что ищем ответ на его fin if (ack && finsForStream.contains(destIpAndPort)) { // проверяем destIp, потому что ищем ответ на его fin
acksForStream.add(sourceIpAndPort); acksForStream.add(sourceIpAndPort);
} }
if(rst || (acksForStream.contains(sourceIpAndPort) && acksForStream.contains(destIpAndPort))) { if (rst || (acksForStream.contains(sourceIpAndPort) && acksForStream.contains(destIpAndPort))) {
log.info("Конец стрима"); streamService.saveNewStream(stream, unfinishedStreams.get(stream));
saveStream(stream);
unfinishedStreams.remove(stream);
fins.remove(stream);
acks.remove(stream);
} }
} }
} }
} }
} }
private void saveStream(UnfinishedStream unfinishedStream) {
final List<ru.serega6531.packmate.model.Packet> packets = unfinishedStreams.get(unfinishedStream);
Stream stream = new Stream();
stream.setProtocol(unfinishedStream.getProtocol());
stream.setStartTimestamp(packets.get(0).getTimestamp());
stream.setEndTimestamp(packets.get(packets.size() - 1).getTimestamp());
stream.setService(findService(
unfinishedStream.getFirstIp().getHostAddress(),
unfinishedStream.getFirstPort(),
unfinishedStream.getSecondIp().getHostAddress(),
unfinishedStream.getSecondPort()
).get());
Stream savedStream = streamService.save(stream);
List<ru.serega6531.packmate.model.Packet> savedPackets = new ArrayList<>();
for (ru.serega6531.packmate.model.Packet packet : packets) {
packet.setStream(savedStream);
savedPackets.add(packetService.save(packet));
}
savedStream.setPackets(savedPackets);
savedStream = streamService.save(savedStream);
subscriptionService.broadcastNewStream(savedStream);
}
private Optional<CtfService> findService(String firstIp, int firstPort, String secondIp, int secondPort) {
if(firstIp.equals(localIp)) {
return servicesService.findByPort(firstPort);
} else if(secondIp.equals(localIp)) {
return servicesService.findByPort(secondPort);
}
return Optional.empty();
}
} }

View File

@@ -10,7 +10,7 @@ import java.util.List;
@Data @Data
@Entity @Entity
@Table(name = "service") @Table(name = "service")
@ToString(of = {"port", "name"}) @ToString(exclude = "streams")
public class CtfService { public class CtfService {
@Id @Id

View File

@@ -3,9 +3,8 @@ package ru.serega6531.packmate.model;
import lombok.Data; import lombok.Data;
import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.GenericGenerator;
import javax.persistence.Entity; import javax.persistence.*;
import javax.persistence.GeneratedValue; import java.util.List;
import javax.persistence.Id;
@Data @Data
@Entity @Entity
@@ -30,4 +29,7 @@ public class Pattern {
private String color; // для вставки в css private String color; // для вставки в css
@ManyToMany(mappedBy = "foundPatterns", cascade = CascadeType.ALL)
private List<Stream> matchedStreams;
} }

View File

@@ -2,14 +2,15 @@ package ru.serega6531.packmate.model;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data; import lombok.Data;
import lombok.ToString;
import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.GenericGenerator;
import ru.serega6531.packmate.Protocol; import ru.serega6531.packmate.Protocol;
import javax.persistence.*; import javax.persistence.*;
import java.util.List; import java.util.List;
import java.util.Set;
@Data @Data
@ToString(exclude = "packets")
@Entity @Entity
@GenericGenerator( @GenericGenerator(
name = "stream_generator", name = "stream_generator",
@@ -40,6 +41,7 @@ public class Stream {
private long endTimestamp; private long endTimestamp;
private Set<Pattern> foundPatterns; @ManyToMany(cascade = CascadeType.ALL)
private List<Pattern> foundPatterns;
} }

View File

@@ -20,6 +20,16 @@ public class ServicesService {
this.repository = repository; this.repository = repository;
} }
public Optional<CtfService> findService(String localIp, String firstIp, int firstPort, String secondIp, int secondPort) {
if(firstIp.equals(localIp)) {
return findByPort(firstPort);
} else if(secondIp.equals(localIp)) {
return findByPort(secondPort);
}
return Optional.empty();
}
public Optional<CtfService> findByPort(int port) { public Optional<CtfService> findByPort(int port) {
return repository.findById(port); return repository.findById(port);
} }

View File

@@ -2,15 +2,16 @@ package ru.serega6531.packmate.service;
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.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.serega6531.packmate.model.Packet;
import ru.serega6531.packmate.model.Pattern; import ru.serega6531.packmate.model.Pattern;
import ru.serega6531.packmate.model.Stream; import ru.serega6531.packmate.model.Stream;
import ru.serega6531.packmate.model.UnfinishedStream;
import ru.serega6531.packmate.repository.StreamRepository; import ru.serega6531.packmate.repository.StreamRepository;
import java.util.HashSet; import java.util.*;
import java.util.List;
import java.util.Optional;
import java.util.Set;
@Service @Service
@Slf4j @Slf4j
@@ -18,26 +19,68 @@ public class StreamService {
private final StreamRepository repository; private final StreamRepository repository;
private final PatternService patternService; private final PatternService patternService;
private final ServicesService servicesService;
private final PacketService packetService;
private final StreamSubscriptionService subscriptionService;
private final String localIp;
@Autowired @Autowired
public StreamService(StreamRepository repository, PatternService patternService) { public StreamService(StreamRepository repository,
PatternService patternService,
ServicesService servicesService,
PacketService packetService,
StreamSubscriptionService subscriptionService,
@Value("${local-ip}") String localIp) {
this.repository = repository; this.repository = repository;
this.patternService = patternService; this.patternService = patternService;
this.servicesService = servicesService;
this.packetService = packetService;
this.subscriptionService = subscriptionService;
this.localIp = localIp;
}
@Transactional
public void saveNewStream(UnfinishedStream unfinishedStream, List<Packet> packets) {
Stream stream = new Stream();
stream.setProtocol(unfinishedStream.getProtocol());
stream.setStartTimestamp(packets.get(0).getTimestamp());
stream.setEndTimestamp(packets.get(packets.size() - 1).getTimestamp());
stream.setService(servicesService.findService(
localIp,
unfinishedStream.getFirstIp().getHostAddress(),
unfinishedStream.getFirstPort(),
unfinishedStream.getSecondIp().getHostAddress(),
unfinishedStream.getSecondPort()
).get());
Stream savedStream = save(stream);
List<ru.serega6531.packmate.model.Packet> savedPackets = new ArrayList<>();
Set<Pattern> matches = new HashSet<>();
for (ru.serega6531.packmate.model.Packet packet : packets) {
packet.setStream(savedStream);
savedPackets.add(packetService.save(packet));
matches.addAll(patternService.findMatching(packet.getContent()));
}
savedStream.setFoundPatterns(new ArrayList<>(matches));
savedStream.setPackets(savedPackets);
savedStream = save(savedStream);
subscriptionService.broadcastNewStream(savedStream);
} }
public Stream save(Stream stream) { public Stream save(Stream stream) {
if(!stream.getPackets().isEmpty()) { Stream saved;
Set<Pattern> matches = new HashSet<>(); if(stream.getId() == null) {
saved = repository.save(stream);
stream.getPackets().forEach(packet -> { log.info("Создан стрим с id {}", saved.getId());
matches.addAll(patternService.findMatching(packet.getContent())); } else {
}); saved = repository.save(stream);
stream.setFoundPatterns(matches);
} }
final Stream saved = repository.save(stream);
log.info("Создан стрим с id {}", saved.getId());
return saved; return saved;
} }