Salut à tous, ça fait une paye que je vous ai pas fait un peu de Splunk, non ? et récemment au taf j’ai trouvé 5 min pour réimplémenter une requête rigolote pour calculer la distance entre 2 points GPS avec Splunk.
Pour vous faire la genèse du truc, on supervise beaucoup nos connexions VPN depuis le confinement du printemps bizarrement :-). D’ailleurs dans mon article MISC de septembre, je vous ai mis une requête pour surveiller les doubles connexions simultanées d’un(des) utilisateur(s) , qui est également super pratique pour limiter les abus autour des connexions à distances dans un cadre de surcharge de vos passerelles.
Les logs VPN font vraiment parti des logs intéressants car ils ramènent l’analyse au « monde réel ». En effet, les VPNs sont souvent utilisés dans des situations de nomadisme ou de télétravail et combiné avec les informations de géolocalisation : ça fait des chocopics !
Du coup, je vous donne la requête « as-it » :
index=$vpn "Session started" OR "Session ended" | sort 0 user, _time
| streamstats window=1 current=f values(_time) as last_time values(src_ip) as last_src_ip by user
| where last_src_ip != src_ip AND _time - last_time < 8*60*60
| iplocation last_src_ip | rename lat as last_lat lon as last_lon | eval last_City=City,last_Country=Country,last_Region=Region
| iplocation src_ip
| eval rlat1 = pi()*last_lat/180, rlat2=pi()*lat/180, rlat = pi()*(lat-last_lat)/180, rlon= pi()*(lon-last_lon)/180 | eval a = sin(rlat/2) * sin(rlat/2) + cos(rlat1) * cos(rlat2) * sin(rlon/2) * sin(rlon/2) | eval c = 2 * atan2(sqrt(a), sqrt(1-a)) | eval distance = 6371 * c, time_difference_hours = round((_time - last_time) / 3600,2), speed=round(distance/ ( time_difference_hours),2) | fields - rlat* a c
| where distance>=1
| eval day=strftime(_time, "%Y-%m-%d")
| eval hour=strftime(_time, "%H:%M:%S")
| eval previous_hour=strftime(last_time, "%H:%M:%S")
| eval GPS_pos=lat+","+lon
| eval previous_GPS_pos=last_lat+","+last_lon
| eval previous_location = last_Country+", "+last_Region+", "+last_City
| eval moved_to = Country+", "+Region+", "+City
| stats values(dest_nt_host) as hostname dc(dest_nt_host) as nb_host values(moved_to) as moved_to values(previous_location) as previous_location values(GPS_pos) as GPS_pos values(previous_GPS_pos) as previous_GPS_pos max(speed) as max_speed_kph min(time_difference_hours) as min_time_difference_hours, values(hour) as hour, values(previous_hour) as previous_hour by day user src_ip last_src_ip distance
| eval n = coalesce(mvfilter(match(previous_location,"\, \, $")), mvfilter(match(moved_to,"\, \, $")))
| eval m= coalesce(mvfilter(match(GPS_pos,"48.85340,2.34880")), mvfilter(match(previous_GPS_pos,"48.85340,2.34880")))
| where max_speed_kph>=135 AND distance>100 AND min_time_difference_hours>1 AND isnull(n) AND isnull(m) AND previous_GPS_pos!=GPS_pos
| fields - n m
Du coup, j’ai pas sortie la requête de mon chapeau,c’est important de rappeler qu’elle sort de l’App Splunk Security Essentials qui, si vous ne la connaissez pas encore, est une mine sans fin d’idées de trucs à superviser avec parfois les requêtes SPL en exemple pour mieux les implémenter en interne.
Bon la limitation de l’exercive de calculer la distance entre 2 points GPS avec Splunk, c’est que la géolocalisation IP n’est pas parfaite et que souvent certaines IP remontent au centre de Paris par défaut (notament chez les opérateurs téléphonique) mais bon, en multicountry on trouve 2-3 excès de vitesse rigolo quand même.
Voilà, c’est tout pour aujourd’hui pour moi : Splunkez-bien !