Created
February 8, 2017 23:51
-
-
Save jbradley89/178bbf3944786c494bd78f3df16a5472 to your computer and use it in GitHub Desktop.
A system tap script to detect UDP beacons
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env stap | |
/* | |
/\ \ /\ \__ | |
\ \ \____ __ __ ___ ___ ___ __ \ \ ,_\ ___ _ __ | |
\ \ '__`\ /'__`\ /'__`\ /'___\ / __`\ /' _ `\ /'__`\ \ \ \/ / __`\/\`'__\ | |
\ \ \L\ \/\ __//\ \L\.\_/\ \__//\ \L\ \/\ \/\ \/\ \L\.\_\ \ \_/\ \L\ \ \ \/ | |
\ \_,__/\ \____\ \__/.\_\ \____\ \____/\ \_\ \_\ \__/.\_\\ \__\ \____/\ \_\ | |
\/___/ \/____/\/__/\/_/\/____/\/___/ \/_/\/_/\/__/\/_/ \/__/\/___/ \/_/ | |
*/ | |
/*System Tap arrays must all be global*/ | |
global procnames //holds a list of processes we've seen making udp calls | |
global curr_timestamps //holds the last UDP timestamp seen per process | |
global process_count //holds the number of times we've seen each process make a UDP call*/ | |
global delta_list /*Lookup a time delta by supplying a process_name and which time we saw it | |
IE: {ping:3} = the time delta the 3rd time ping caused a UDP call*/ | |
global ip_lookup_table /* Lookup an IP_address by supplying a process_name and delta | |
IE{process_name, delta} = ip_address */ | |
global beacon_count //Lookup the number of times we've seen a process and a specific time delta | |
global confirmed_beacons //Lookup processes by proc_name and delta that we've confirmed are consistently beaconing | |
/* begin is executed after the kernel module is loaded */ | |
probe begin | |
{ | |
println("Tracking UDP Calls...") | |
} | |
/*Set up a handler for UDP sends*/ | |
probe udp.sendmsg{ | |
ts = gettimeofday_s() | |
procname = execname() | |
procnames[procname] <<< 1 | |
printf(" %15s %15s %15s %5d %5d %15s UDP\n", ctime(ts), saddr, daddr, sport, dport, execname()) | |
/*If the process that made the UDP call is already one we're tracking*/ | |
if (procname in curr_timestamps) | |
{ | |
delta = ts - curr_timestamps[procname] | |
if (delta != 0){ | |
process_count[procname]++ | |
ip_lookup_table[procname,delta] = daddr | |
delta_list[procname, process_count[procname]] = delta | |
} | |
} | |
curr_timestamps[procname] = ts | |
} | |
/* beacon_check function will check for beaconing every 30 seconds */ | |
function beacon_check(){ | |
//for every process we've seen | |
foreach(procname in procnames){ | |
i=0 | |
cached_time_delta = 0 | |
//while i is less than the total number of times we saw the process make a udp call | |
while (i < process_count[procname]) | |
{ | |
current_time_delta = delta_list[procname,i] | |
//Ignore cases where our time delta was 0. Likely duplicate UDP event | |
if (current_time_delta != 0) | |
{ | |
//If we are dealing with the first UDP event, we have nothing to compare it to. Store and move to next pass | |
if (cached_time_delta == 0) | |
{ | |
cached_time_delta = current_time_delta | |
} | |
else | |
{ | |
//If we've seen the same amount of space between two beacons | |
if (cached_time_delta == current_time_delta) | |
beacon_count[procname,current_time_delta]++ | |
//If we've seen this beacon 3 times at a consistent rate | |
if (beacon_count[procname,current_time_delta] > 2) | |
{ | |
if ([procname,current_time_delta] in confirmed_beacons){ | |
; | |
} | |
else | |
{ | |
confirmed_beacons[procname,current_time_delta] = 1 | |
printf("%s is beaconing every %d seconds to %s\n", procname, current_time_delta, ip_lookup_table[procname,current_time_delta]) | |
} | |
} | |
} | |
//save this time delta so we can compare it to the next pass | |
cached_time_delta = current_time_delta | |
} | |
i++ | |
} | |
} | |
} | |
/* Creating a timer that runs our beacon_check every 30 seconds */ | |
probe timer.s(30) | |
{ | |
//print it in red | |
ansi_set_color(31) | |
beacon_check() | |
ansi_reset_color() | |
} | |
/* end runs right before the kernel module is unloaded (ctrl+c) */ | |
probe end | |
{ | |
println("Done!") | |
beacon_check() | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment