Salut à tous, aujourd’hui je voulais m’arrêter sur un cas d’utilisation « à la con 🙂 » de Splunk et plus exactement comment transformer un tableau avec plusieurs colonnes dates en évènements. Niveau contexte, on m’a demandé de suivre les status d’offenses (incident) d’un QRadar dans un Splunk (oui, je sais, ça à l’air con dit comme ça, juste… enfin bref cherchez pas…). Mais comme ce serait trop simple d’avoir des évènements « carrés » qui vous indique ouverture, fermeture, activité, etc. je n’avais à ma disposition que l’option des calls API Rest. Et comme on a beaucoup d’offenses, je ne peux pas non plus faire un fulldump et construire un lookup avec toutes mes offenses. Du coup dernière option jouable faire des exports réguliers des offenses ouvertes ou fermées. En gros, j’exporte mes données avec ces quelques lignes de PowerShell qui interrogent l’API QRadar au début de chaque heure :
function ConvertTo-UnixDateMs ($PSDate) {
$epoch = [timezone]::CurrentTimeZone.ToLocalTime([datetime]'1/1/1970')
return (New-TimeSpan -Start $epoch -End $PSDate).TotalSeconds * 1000
}
$start = ConvertTo-UnixDateMs -PSDate ([DateTime]::Today.AddHours($now.Hour - 1))
$end = $start + (2 * 3600 * 1000)
((Invoke-RestMethod ("$urlQradarapi"+"/siem/offenses%3Ffilter%3Dclose_time%20%3E%20"+"$start"+"%20and%20close_time%20%3C%20"+"$end"+"%20or%20start_time%20%3E%20"+"$start"+"%20and%20start_time%20%3C%20"+"$end") -Method GET -Headers @{Version=$apiversion;Accept='application/json';SEC=$apikey}) ConvertTo-Json -Depth 100 | Out-File ("$outoffensesfile") -Encoding utf8)
Et le résultat est un fichier JSON avec le détail des offenses qui ont été ouvertes ou fermés sur l’heure précédente.
{ "last_persisted_time": 1611564718000, [...] "source_network": "NETWORK INTERNE", "category_count": 9, "close_time": null, "remote_destination_count": 0, "start_time": 1611564541223, "magnitude": 5, "last_updated_time": 1611564696658, "credibility": 2, "id": 374965, "categories": [ "Misc Recon Event", "TCP Reconnaissance" ], "severity": 6, "policy_category_count": 1, "closing_reason_id": null, "device_count": 2, "first_persisted_time": 1611564543000, "offense_type": 0, [...] "status": "OPEN" },
Du coup, avec tout petit reformatage je me retrouve avec ce genre de tableau en entrée :
index="qradar-offenses" | table id start_time close_time status
id | start_time | close_time | status |
1 | 2021-01-23 13h15 | 2021-02-09 14h39 | CLOSED |
2 | 2021-02-09 14h18 | OPEN | |
3 | 2021-02-09 14h18 | 2021-02-09 14h30 | CLOSED |
A partir de ça on peut facilement suivre les ouvertures ou fermeture en calquant le _time sur nos start_time et close_time. Mais suivre la quantité ouverte en temps réel ce n’est pas « évident », car techniquement on a 2 « temps » dans une seule ligne et Splunk ne propose qu’une variable _time à utiliser pour le timechart.
Donc je me suis gratté la tête un moment et j’ai fini par sortir cette requête qui permet de splitter les lignes en 2 et de régler le temps à open ou closed en fonction du status de nos offenses. Sans transition
index="qradar-offenses" | table id start_time close_time status
| eval start_time=start_time/1000 | eval close_time=close_time/1000 | eval duration=close_time-start_time
| stats first(start_time) as start_time last(close_time) as close_time last(duration) as duration by id
| eval mvstatus="CLOSED:OPEN" | makemv delim=":" mvstatus | mvexpand mvstatus
| where NOT (isnull(close_time) AND mvstatus="CLOSED")
| eval _time=case(mvstatus=="OPEN",start_time,mvstatus=="CLOSED",close_time) | eval action=case(mvstatus=="OPEN",1,mvstatus=="CLOSED",-1)
| convert ctime(close_time) | convert ctime(start_time) | sort _time | streamstats sum(action) as nb_open | timechart span=15m max(nb_open) as nb_open
Pour ceux qui n’auront pas compris l’astuce a lieu au moment du « eval mvstatus
» jusqu’au « eval=_time
» où on duplique toutes les lignes à partir d’un champs multivalué créé artificiellement, tout ce qui passe avant et après c’est du cosmétique. Je vous laisse détricoter le truc pour vous en rendre compte par vous-même :-).
Voilà c’est tout sur comment transformer un tableau avec plusieurs colonnes dates en évènements avec Splunk, comme j’ai dit : un cas d’usages « à la con », mais le grattage de tête sur comment on fait dans ce cas était plutôt intéressant et je soupçonne qu’il y ait pas mal de cas un peu plus sérieux où on peut s’en resservir. Geekez bien ?