Add feature for capture attack details to the pcap file
This commit is contained in:
parent
b37d4743ba
commit
5405307a30
|
@ -88,6 +88,9 @@ unsigned int recalculate_speed_timeout = 1;
|
|||
// Send or not any details about attack for ban script call over stdin
|
||||
bool notify_script_pass_details = true;
|
||||
|
||||
// We could collect attack dumps in pcap format
|
||||
bool collect_attack_pcap_dumps = false;
|
||||
|
||||
bool unban_only_if_attack_finished = true;
|
||||
|
||||
// Variable with all data from main screen
|
||||
|
@ -210,6 +213,8 @@ unsigned int max_ips_in_list = 7;
|
|||
// Number of lines for sending ben attack details to email
|
||||
unsigned int ban_details_records_count = 500;
|
||||
|
||||
// We haven't option for configure it with configuration file
|
||||
unsigned int number_of_packets_for_pcap_attack_dump = 500;
|
||||
|
||||
// log file
|
||||
log4cpp::Category& logger = log4cpp::Category::getRoot();
|
||||
|
@ -1348,6 +1353,15 @@ void process_packet(simple_packet& current_packet) {
|
|||
ban_list_details[current_packet.src_ip].size() < ban_details_records_count) {
|
||||
|
||||
ban_list_details_mutex.lock();
|
||||
|
||||
if (collect_attack_pcap_dumps) {
|
||||
// this code SHOULD NOT be called without mutex!
|
||||
if (current_packet.packet_payload_length > 0 && current_packet.packet_payload_pointer != NULL) {
|
||||
ban_list[current_packet.src_ip].pcap_attack_dump.write_packet(current_packet.packet_payload_pointer,
|
||||
current_packet.packet_payload_length);
|
||||
}
|
||||
}
|
||||
|
||||
ban_list_details[current_packet.src_ip].push_back(current_packet);
|
||||
ban_list_details_mutex.unlock();
|
||||
}
|
||||
|
@ -1457,6 +1471,15 @@ void process_packet(simple_packet& current_packet) {
|
|||
ban_list_details[current_packet.dst_ip].size() < ban_details_records_count) {
|
||||
|
||||
ban_list_details_mutex.lock();
|
||||
|
||||
if (collect_attack_pcap_dumps) {
|
||||
// this code SHOULD NOT be called without mutex!
|
||||
if (current_packet.packet_payload_length > 0 && current_packet.packet_payload_pointer != NULL) {
|
||||
ban_list[current_packet.dst_ip].pcap_attack_dump.write_packet(current_packet.packet_payload_pointer,
|
||||
current_packet.packet_payload_length);
|
||||
}
|
||||
}
|
||||
|
||||
ban_list_details[current_packet.dst_ip].push_back(current_packet);
|
||||
ban_list_details_mutex.unlock();
|
||||
}
|
||||
|
@ -2508,6 +2531,16 @@ void execute_ip_ban(uint32_t client_ip, map_element speed_element, map_element a
|
|||
current_attack.average_out_bytes = average_speed_element.out_bytes;
|
||||
current_attack.average_out_flows = average_speed_element.out_flows;
|
||||
|
||||
if (collect_attack_pcap_dumps) {
|
||||
bool buffer_allocation_result = current_attack.pcap_attack_dump.allocate_buffer( number_of_packets_for_pcap_attack_dump );
|
||||
|
||||
if (!buffer_allocation_result) {
|
||||
logger << log4cpp::Priority::ERROR << "Can't allocate buffer for attack, switch off this option completely ";
|
||||
collect_attack_pcap_dumps = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ban_list_mutex.lock();
|
||||
ban_list[client_ip] = current_attack;
|
||||
ban_list_mutex.unlock();
|
||||
|
@ -2917,6 +2950,27 @@ void send_attack_details(uint32_t client_ip, attack_details current_attack_detai
|
|||
|
||||
print_attack_details_to_file(attack_details.str(), client_ip_as_string, current_attack_details);
|
||||
|
||||
if (collect_attack_pcap_dumps) {
|
||||
std::string ban_timestamp_as_string = print_time_t_in_fastnetmon_format(current_attack_details.ban_timestamp);
|
||||
std::string attack_pcap_dump_path = attack_details_folder + "/" + client_ip_as_string + "_" + ban_timestamp_as_string + ".pcap";
|
||||
|
||||
int pcap_fump_filedesc = open(attack_pcap_dump_path.c_str(), O_WRONLY|O_CREAT);
|
||||
if (pcap_fump_filedesc <= 0) {
|
||||
logger << log4cpp::Priority::ERROR << "Can't open file for storing pcap dump: " << attack_pcap_dump_path;
|
||||
} else {
|
||||
ssize_t wrote_bytes = write(pcap_fump_filedesc,
|
||||
(void*)current_attack_details.pcap_attack_dump.get_buffer_pointer(),
|
||||
current_attack_details.pcap_attack_dump.get_used_memory());
|
||||
|
||||
if (wrote_bytes != current_attack_details.pcap_attack_dump.get_used_memory()) {
|
||||
logger << log4cpp::Priority::ERROR << "Can't wrote all attack details to the disk correctly";
|
||||
}
|
||||
|
||||
// Freeup memory
|
||||
current_attack_details.pcap_attack_dump.deallocate_buffer();
|
||||
}
|
||||
}
|
||||
|
||||
// Pass attack details to script
|
||||
if (file_exists(notify_script_path)) {
|
||||
logger << log4cpp::Priority::INFO
|
||||
|
|
|
@ -10,12 +10,15 @@
|
|||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "packet_storage.h"
|
||||
|
||||
// simplified packet struct for lightweight save into memory
|
||||
class simple_packet {
|
||||
public:
|
||||
simple_packet()
|
||||
: sample_ratio(1), src_ip(0), dst_ip(0), source_port(0), destination_port(0), protocol(0),
|
||||
length(0), flags(0), number_of_packets(1), ip_fragmented(false), ip_protocol_version(4), ttl(0) {
|
||||
length(0), flags(0), number_of_packets(1), ip_fragmented(false), ip_protocol_version(4), ttl(0),
|
||||
packet_payload_pointer(NULL), packet_payload_length(0) {
|
||||
|
||||
ts.tv_usec = 0;
|
||||
ts.tv_sec = 0;
|
||||
|
@ -37,6 +40,8 @@ class simple_packet {
|
|||
uint8_t flags; /* tcp flags */
|
||||
bool ip_fragmented; /* If IP packet fragmented */
|
||||
struct timeval ts;
|
||||
void* packet_payload_pointer;
|
||||
int packet_payload_length;
|
||||
};
|
||||
|
||||
typedef std::pair<uint32_t, uint32_t> subnet_t;
|
||||
|
@ -147,6 +152,8 @@ class attack_details : public map_element {
|
|||
int ban_time; // seconds of the ban
|
||||
|
||||
subnet_t customer_network;
|
||||
|
||||
packet_storage_t pcap_attack_dump;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -113,6 +113,10 @@ bool parse_raw_packet_to_simple_packet(u_char* buffer, int len, simple_packet& p
|
|||
return false;
|
||||
}
|
||||
|
||||
// We need this for deep packet inspection
|
||||
packet.packet_payload_length = len;
|
||||
packet.packet_payload_pointer = (void*)buffer;
|
||||
|
||||
packet.ip_protocol_version = packet_header.extended_hdr.parsed_pkt.ip_version;
|
||||
|
||||
if (packet.ip_protocol_version == 4) {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef PACKET_STORAGE_H
|
||||
#define PACKET_STORAGE_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "fastnetmon_pcap_format.h"
|
||||
|
||||
class packet_storage_t {
|
||||
|
@ -24,7 +26,9 @@ class packet_storage_t {
|
|||
if (memory_pointer != NULL) {
|
||||
this->buffer_size = memory_size_in_bytes;
|
||||
memory_pos = memory_pointer;
|
||||
return true;
|
||||
|
||||
// Add header to newely allocated memory block
|
||||
return this->write_header();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -244,6 +244,10 @@ void parse_packet_pf_ring(const struct pfring_pkthdr* h, const u_char* p, const
|
|||
packet.source_port = h->extended_hdr.parsed_pkt.l4_src_port;
|
||||
packet.destination_port = h->extended_hdr.parsed_pkt.l4_dst_port;
|
||||
|
||||
// We need this for deep packet inspection
|
||||
packet.packet_payload_length = h->len;
|
||||
packet.packet_payload_pointer = (void*)p;
|
||||
|
||||
packet.length = h->len;
|
||||
packet.protocol = h->extended_hdr.parsed_pkt.l3_proto;
|
||||
packet.ts = h->ts;
|
||||
|
|
|
@ -19,11 +19,6 @@ int main() {
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (!packet_storage.write_header()) {
|
||||
printf("Can't write header");
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned char payload1[] = { 0x90,0xE2,0xBA,0x83,0x3F,0x25,0x90,0xE2,0xBA,0x2C,0xCB,0x02,0x08,0x00,0x45,0x00,0x00,0x2E,0x00,0x00,0x00,0x00,0x40,0x06,0x69,0xDC,0x0A,0x84,0xF1,0x83,0x0A,0x0A,0x0A,0xDD,0x04,0x01,0x00,0x50,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x50,0x02,0x00,0x0A,0x9A,0x92,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
|
||||
|
||||
if (!packet_storage.write_packet(payload1, sizeof(payload1))) {
|
||||
|
|
Loading…
Reference in New Issue