Você não mencionou perl
, mas suponho que não há problema em usar desde que você mencionou awk
, sed
e grep
. Eu escolhi perl
em vez de awk
principalmente porque é muito mais fácil trabalhar com matrizes associativas de vários níveis (um "Hash-of-Hashes" ou "HoH" em perl
lingo) do que em awk
.
#!/usr/bin/perl
use strict;
# array used to keep track of the order each sid was first seen,
# so that they can be printed out in the same order.
# Necessary because perl hashes are inherently un-ordered.
my @order=();
# hashed array to contain the highest rev seen of each sid.
my %S = ();
# count of the number of files we've read completely so far.
my $filenum=0;
while(<>) {
s/^\s*|\s*$//g; # strip leading and trailing spaces
if (m/^$/) { $filenum++ if eof; next }; # skip empty lines
# extract the sid and the rev
my ($sid, $rev) = $_ =~ (m/^.*; sid:(\d+); rev:(\d+)/) ;
# store or update an anonymous hash containing the rev and the entire
# line in the hash, keyed by the sid.
if (defined($S{$sid})) {
$S{$sid} = { rev => $rev, line => $_ } if ( ($rev > $S{$sid}->{rev}) );
} else {
next if ($filenum); # only store sid if we're still reading the 1st file.
push @order, $sid;
$S{$sid} = { rev => $rev, line => $_ };
};
$filenum++ if eof;
};
# if you want output sorted by the sid, comment the first of the next
# two lines and uncomment the second
for my $sid (@order) {
#for my $sid (sort keys %S) {
print $S{$sid}->{line}, "\n";
};
Salve-o como, por exemplo, ./apply-update.pl
e execute-o como ./apply-update.pl all.rules update.rules > out.rules
A saída dos novos arquivos de entrada de amostra será de apenas três linhas (com os sids vistos em all.rules
, atualizados por update.rules
, ou seja, as versões "rev: 2" em vez de "rev: 1"):
alert udp $home_net any -> any 53 (msg:"et trojan copykittens? matryoshka dns lookup 1 (winupdate64 . com)"; content:"|01 00 00 01 00 00 00 00 00 00|"; depth:10; offset:2; content:"|0b|winupdate64|03|com|00|"; nocase; distance:0; fast_pattern; reference:url,www.clearskysec.com/wp- content/uploads/2017/07/operation_wilted_tulip.pdf; classtype:trojan- activity; sid:2024495; rev:2;)
alert udp $home_net any -> any 53 (msg:"et trojan copykittens matryoshka dns lookup 2 (twiter-statics . info)"; content:"|01 00 00 01 00 00 00 00 00 00|"; depth:10; offset:2; content:"|0e|twiter|2d|statics|04|info|00|"; nocase; distance:0; fast_pattern; metadata: former_category trojan; reference:url,www.clearskysec.com/wp- content/uploads/2017/07/operation_wilted_tulip.pdf; reference:md5,752240cddda5acb5e8d026cef82e2b54; classtype:trojan-activity; sid:2024496; rev:2; metadata:affected_product windows_xp_vista_7_8_10_server_32_64_bit, attack_target client_endpoint, deployment perimeter, signature_severity major, created_at 2017_07_25, malware_family matryoshka, performance_impact moderate, updated_at 2017_07_25;)
alert udp $home_net any -> any 53 (msg:"et trojan copykittens cobalt strike dns lookup (cloudflare-analyse . com)"; content:"|01 00 00 01 00 00 00 00 00 00|"; depth:10; offset:2; content:"|12|cloudflare|2d|analyse|03|com|00|"; nocase; distance:0; fast_pattern; threshold:type limit, track by_src, count 1, seconds 60; metadata: former_category trojan; reference:url,www.clearskysec.com/wp- content/uploads/2017/07/operation_wilted_tulip.pdf; reference:md5,752240cddda5acb5e8d026cef82e2b54; classtype:trojan-activity; sid:2024497; rev:2; metadata:affected_product windows_xp_vista_7_8_10_server_32_64_bit, attack_target client_endpoint, deployment perimeter, signature_severity major, created_at 2017_07_25, malware_family cobaltstrike, performance_impact moderate, updated_at 2017_07_26;)
Isso será muitas vezes mais rápido do que qualquer versão bash
- os interpretadores de shell não estão nem um pouco perto do processamento de texto como perl
ou awk
ou python
. Uma linguagem compilada como C
seria muito mais rápida novamente, mas escrever algo assim em C seria provavelmente pelo menos 50 ou 60, talvez até algumas centenas, linhas de código C, não 15 linhas de perl (sem contar os comentários). ou linhas em branco).