Skip to content
Permalink
Branch: master
Find file Copy path
2 contributors

Users who have contributed to this file

@boat0 @jugurthab
executable file 106 lines (89 sloc) 3.73 KB
#!/usr/bin/python
#
# dddos.py DDOS dectection system.
#
# Written as a basic tracing example of using ePBF
# to detect a potential DDOS attack against a system.
#
# Copyright (c) 2019 Jugurtha BELKALEM.
# Licensed under the Apache License, Version 2.0 (the "License")
#
# 14-Jan-2019 Jugurtha BELKALEM Created this.
from bcc import BPF
import ctypes as ct
import datetime
prog = """
#include <linux/skbuff.h>
#include <uapi/linux/ip.h>
#define MAX_NB_PACKETS 1000
#define LEGAL_DIFF_TIMESTAMP_PACKETS 1000000
BPF_HASH(rcv_packets);
struct detectionPackets {
u64 nb_ddos_packets;
};
BPF_PERF_OUTPUT(events);
int detect_ddos(struct pt_regs *ctx, void *skb){
struct detectionPackets detectionPacket = {};
// Used to count number of received packets
u64 rcv_packets_nb_index = 0, rcv_packets_nb_inter=1, *rcv_packets_nb_ptr;
// Used to measure elapsed time between 2 successive received packets
u64 rcv_packets_ts_index = 1, rcv_packets_ts_inter=0, *rcv_packets_ts_ptr;
/* The algorithm analyses packets received by ip_rcv function
* and measures the difference in reception time between each packet.
* DDOS flooders send millions of packets such that difference of
* timestamp between 2 successive packets is so small
* (which is not like regular applications behaviour).
* This script looks for this difference in time and if it sees
* more than MAX_NB_PACKETS succesive packets with a difference
* of timestamp between each one of them less than
* LEGAL_DIFF_TIMESTAMP_PACKETS ns,
* ------------------ It Triggers an ALERT -----------------
* Those settings must be adapted depending on regular network traffic
* -------------------------------------------------------------------
* Important: this is a rudimentary intrusion detection system, one can
* test a real case attack using hping3. However; if regular network
* traffic increases above predefined detection settings, a false
* positive alert will be triggered (an example would be the
case of large file downloads).
*/
rcv_packets_nb_ptr = rcv_packets.lookup(&rcv_packets_nb_index);
rcv_packets_ts_ptr = rcv_packets.lookup(&rcv_packets_ts_index);
if(rcv_packets_nb_ptr != 0 && rcv_packets_ts_ptr != 0){
rcv_packets_nb_inter = *rcv_packets_nb_ptr;
rcv_packets_ts_inter = bpf_ktime_get_ns() - *rcv_packets_ts_ptr;
if(rcv_packets_ts_inter < LEGAL_DIFF_TIMESTAMP_PACKETS){
rcv_packets_nb_inter++;
} else {
rcv_packets_nb_inter = 0;
}
if(rcv_packets_nb_inter > MAX_NB_PACKETS){
detectionPacket.nb_ddos_packets = rcv_packets_nb_inter;
events.perf_submit(ctx, &detectionPacket, sizeof(detectionPacket));
}
}
rcv_packets_ts_inter = bpf_ktime_get_ns();
rcv_packets.update(&rcv_packets_nb_index, &rcv_packets_nb_inter);
rcv_packets.update(&rcv_packets_ts_index, &rcv_packets_ts_inter);
return 0;
}
"""
# Loads eBPF program
b = BPF(text=prog)
# Attach kprobe to kernel function and sets detect_ddos as kprobe handler
b.attach_kprobe(event="ip_rcv", fn_name="detect_ddos")
class DetectionTimestamp(ct.Structure):
_fields_ = [("nb_ddos_packets", ct.c_ulonglong)]
# Show message when ePBF stats
print("DDOS detector started ... Hit Ctrl-C to end!")
print("%-26s %-10s" % ("TIME(s)", "MESSAGE"))
def trigger_alert_event(cpu, data, size):
event = ct.cast(data, ct.POINTER(DetectionTimestamp)).contents
print("%-26s %s %ld" % (datetime.datetime.now(),
"DDOS Attack => nb of packets up to now : ", event.nb_ddos_packets))
# loop with callback to trigger_alert_event
b["events"].open_perf_buffer(trigger_alert_event)
while 1:
try:
b.perf_buffer_poll()
except KeyboardInterrupt:
exit()
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.