Add feature for capture attack details to the pcap file

This commit is contained in:
Pavel Odintsov 2015-07-16 22:42:11 +02:00
parent b37d4743ba
commit 5405307a30
6 changed files with 75 additions and 7 deletions

View File

@ -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

View File

@ -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;
};

View File

@ -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) {

View File

@ -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;
}

View File

@ -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;

View File

@ -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))) {