Работа над фильтрацией через libpcap

This commit is contained in:
serega6531
2020-04-13 00:45:48 +03:00
parent 88323dc883
commit 9720619eb8
7 changed files with 52 additions and 2 deletions

View File

@@ -5,6 +5,7 @@ import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.concurrent.BasicThreadFactory; import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.ImmutablePair;
import org.pcap4j.core.BpfProgram;
import org.pcap4j.core.PacketListener; import org.pcap4j.core.PacketListener;
import org.pcap4j.core.PcapHandle; import org.pcap4j.core.PcapHandle;
import org.pcap4j.packet.IpV4Packet; import org.pcap4j.packet.IpV4Packet;
@@ -36,6 +37,8 @@ public abstract class AbstractPcapWorker implements PcapWorker, PacketListener {
protected PcapHandle pcap = null; protected PcapHandle pcap = null;
protected final ExecutorService loopExecutorService; protected final ExecutorService loopExecutorService;
protected String filter = null;
// во время работы должен быть != null // во время работы должен быть != null
protected ExecutorService processorExecutorService; protected ExecutorService processorExecutorService;
@@ -255,4 +258,17 @@ public abstract class AbstractPcapWorker implements PcapWorker, PacketListener {
}).get(); }).get();
} }
@Override
@SneakyThrows
public void setFilter(String filter) {
this.filter = filter;
applyFilter();
}
@SneakyThrows
protected void applyFilter() {
if(filter != null && pcap != null && pcap.isOpen()) {
pcap.setFilter(filter, BpfProgram.BpfCompileMode.OPTIMIZE);
}
}
} }

View File

@@ -44,6 +44,9 @@ public class FilePcapWorker extends AbstractPcapWorker {
public void start() { public void start() {
log.info("Using file " + file.getAbsolutePath()); log.info("Using file " + file.getAbsolutePath());
pcap = Pcaps.openOffline(file.getAbsolutePath()); pcap = Pcaps.openOffline(file.getAbsolutePath());
applyFilter();
loopExecutorService.execute(this::runScan); loopExecutorService.execute(this::runScan);
} }

View File

@@ -37,6 +37,8 @@ public class LivePcapWorker extends AbstractPcapWorker {
log.info("Using interface " + device.getName()); log.info("Using interface " + device.getName());
pcap = device.openLive(65536, PcapNetworkInterface.PromiscuousMode.PROMISCUOUS, 100); pcap = device.openLive(65536, PcapNetworkInterface.PromiscuousMode.PROMISCUOUS, 100);
applyFilter();
try { try {
log.info("Intercept started"); log.info("Intercept started");
pcap.loop(-1, this, loopExecutorService); pcap.loop(-1, this, loopExecutorService);

View File

@@ -18,4 +18,6 @@ public interface PcapWorker {
*/ */
int closeTimeoutStreams(Protocol protocol, long timeoutMillis); int closeTimeoutStreams(Protocol protocol, long timeoutMillis);
void setFilter(String filter);
} }

View File

@@ -59,10 +59,10 @@ public class PatternService {
patterns.put(id, saved); patterns.put(id, saved);
if (enabled) { if (enabled) {
log.info("Включен паттерн {} со значением {}", pattern.getName(), pattern.getValue()); log.info("Enabled pattern '{}' with value '{}'", pattern.getName(), pattern.getValue());
subscriptionService.broadcast(new SubscriptionMessage(SubscriptionMessageType.ENABLE_PATTERN, id)); subscriptionService.broadcast(new SubscriptionMessage(SubscriptionMessageType.ENABLE_PATTERN, id));
} else { } else {
log.info("Выключен паттерн {} со значением {}", pattern.getName(), pattern.getValue()); log.info("Disabled pattern '{}' with value '{}'", pattern.getName(), pattern.getValue());
subscriptionService.broadcast(new SubscriptionMessage(SubscriptionMessageType.DISABLE_PATTERN, id)); subscriptionService.broadcast(new SubscriptionMessage(SubscriptionMessageType.DISABLE_PATTERN, id));
} }
} }

View File

@@ -1,14 +1,20 @@
package ru.serega6531.packmate.service; package ru.serega6531.packmate.service;
import lombok.Getter; import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
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.CtfService;
import ru.serega6531.packmate.model.enums.SubscriptionMessageType; import ru.serega6531.packmate.model.enums.SubscriptionMessageType;
import ru.serega6531.packmate.model.pojo.SubscriptionMessage; import ru.serega6531.packmate.model.pojo.SubscriptionMessage;
import ru.serega6531.packmate.pcap.PcapWorker; import ru.serega6531.packmate.pcap.PcapWorker;
import java.util.Collection;
import java.util.stream.Collectors;
@Service @Service
@Slf4j
public class PcapService { public class PcapService {
@Getter @Getter
@@ -31,4 +37,18 @@ public class PcapService {
} }
} }
public void updateFilter(Collection<CtfService> services) {
final String ports = services.stream()
.map(CtfService::getPort)
.map(p -> "port " + p)
.collect(Collectors.joining(" or "));
final String format = "(tcp or udp) and (%s)";
String filter = String.format(format, ports);
log.info("New filter: " + filter);
worker.setFilter(filter);
}
} }

View File

@@ -23,6 +23,7 @@ public class ServicesService {
private final ServiceRepository repository; private final ServiceRepository repository;
private final SubscriptionService subscriptionService; private final SubscriptionService subscriptionService;
private final PcapService pcapService;
private final InetAddress localIp; private final InetAddress localIp;
@@ -31,9 +32,11 @@ public class ServicesService {
@Autowired @Autowired
public ServicesService(ServiceRepository repository, public ServicesService(ServiceRepository repository,
SubscriptionService subscriptionService, SubscriptionService subscriptionService,
PcapService pcapService,
@Value("${local-ip}") String localIpString) throws UnknownHostException { @Value("${local-ip}") String localIpString) throws UnknownHostException {
this.repository = repository; this.repository = repository;
this.subscriptionService = subscriptionService; this.subscriptionService = subscriptionService;
this.pcapService = pcapService;
this.localIp = InetAddress.getByName(localIpString); this.localIp = InetAddress.getByName(localIpString);
repository.findAll().forEach(s -> services.put(s.getPort(), s)); repository.findAll().forEach(s -> services.put(s.getPort(), s));
@@ -67,9 +70,13 @@ public class ServicesService {
public CtfService save(CtfService service) { public CtfService save(CtfService service) {
log.info("Added or edited service '{}' at port {}", service.getName(), service.getPort()); log.info("Added or edited service '{}' at port {}", service.getName(), service.getPort());
final CtfService saved = repository.save(service); final CtfService saved = repository.save(service);
services.put(saved.getPort(), saved); services.put(saved.getPort(), saved);
subscriptionService.broadcast(new SubscriptionMessage(SubscriptionMessageType.SAVE_SERVICE, saved)); subscriptionService.broadcast(new SubscriptionMessage(SubscriptionMessageType.SAVE_SERVICE, saved));
pcapService.updateFilter(findAll());
return saved; return saved;
} }