2016-05-02 8 views
0

Ich habe das folgende Skript, ursprünglich von @ zdim geschrieben und ich habe es ein wenig optimiert.Drucken Sie Datensätze aus der Protokolldatei mit Perl und Hash-Datenstruktur

#!/usr/bin/perl 

use warnings; 
use strict; 

my $file = "/home/tsec/prototype/logs/extractedlogs/cowrieresult.log"; 
open (LOG, $file); 

# Assemble results for required output in data structure: 
# %rept = { $port => { $usr => { $status => $freq } }; 

my %testhash;#new code 
my %rept; 
my ($ip, $port); 

while (my $line = <LOG>) 
{ 
    if ($line =~ /New connection/) { 
     ($ip, $port) = $line =~ /New connection:\s+([^:]+):(\d+)/; 
     #new code here 
     if($ip){ 
       $testhash{$ip}++; 
     } 
     #end 
     next; 
    } 

    my ($usr, $status) = $line =~ m/login\ attempt \s+ \[ ([^\]]+) \] \s+ (\w+)/x; 
    if ($usr and $status) { 
     $rept{$port}{$usr}{$status}++; 
    } 
    else { warn "Line with an unexpected format:\n$line" } 
} 
#close(LOG); 
#open (LOG, $file); 
#my $frequency = 0; 
#while (my $line = <LOG>){ 
#  if($line =~ /login attempt/){ 

     #split string, get the ip and match it with original $ip 
#  my ($testip) = (split /[\s,:\[\]\/]+/, $line)[-6]; 
     #print "$testip\n"; 
     #this two lines above print ips from login attempt line. 
#  if($testip =~ /$ip/){ 
#    $frequency++; 
#  } 
     #elsif($testip =~ /^(?!$ip)/) { 
       # stop frequency counter and start another one? 
     #  print "$frequency\n"; 
     #  $frequency = 0; 
     #} 

#  } 
#} 
#print "$frequency\n"; 
#close(LOG); 

#new code 
print "ConnectionsOnIP\n"; 
foreach my $ip (sort keys %testhash){ 
     print "$testhash{$ip}\n"; 
} 

print "\n"; 

#new code 
print "Port,Status,AttemptOnPort,AttemptsOnIP,Malicious\n"; 
foreach my $ip (sort keys %testhash){ 
foreach my $port (sort keys %rept) { 
    foreach my $usr (sort keys %{$rept{$port}}) { 
     foreach my $stat (sort keys %{$rept{$port}{$usr}}) { 
       if($port ne ""){ 
      print "$port,$stat,$rept{$port}{$usr}{$stat},$testhash{$ip}\n"; 
       } 
     } 
    } 

} 
} 
#new code 

Wie man sehen kann, mag ich die gewünschte Ausgabe haben, die mit Ausnahme des letzten Variable (AttemptsOnIP) zur Zeit arbeitet ich die AttemptsOnIP Variable will zu einem gewissen Grad zu tun, was der AttemptsOnPort tut:

Port,Status,AttemptsOnPort,ConnectionsOnIP,Malicious 
15853,failed,4,18 
15853,succeeded,4,18 
18693,failed,1,18 
18942,failed,1,18 
18942,succeeded,1,18 
31130,succeeded,1,18 
43041,failed,1,18 
43041,succeeded,1,18 
46321,failed,1,18 
46321,succeeded,1,18 
47417,failed,3,18 
47417,succeeded,3,18 
48713,failed,1,18 
48713,succeeded,1,18 
53653,failed,1,18 
53653,succeeded,1,18 
60563,failed,1,18 
60563,succeeded,1,18 

Ich habe einen Hash namens testhash erstellt und übergab ihm die Variable ip, um sie zu erhöhen. Jetzt möchte ich diese Hash-Variable abhängig von der IP einer einzelnen Ausgabezeile erhöhen. Dies ist das Logfile:

2016-05-02 10:20:56+0000 [SSHService ssh-userauth on HoneyPotTransport,14,183.3.202.172] login attempt [root/[email protected]] failed 
2016-05-02 10:20:57+0000 [SSHService ssh-userauth on HoneyPotTransport,15,183.3.202.172] login attempt [root/[email protected]] failed 
2016-05-02 10:20:57+0000 [SSHService ssh-userauth on HoneyPotTransport,14,183.3.202.172] login attempt [root/123456] succeeded 
2016-05-02 10:20:58+0000 [SSHService ssh-userauth on HoneyPotTransport,15,183.3.202.172] login attempt [root/123456] succeeded 
2016-05-02 10:43:32+0000 [cowrie.ssh.transport.HoneyPotSSHFactory] New connection: 183.3.202.172:55157 (172.17.0.5:2222) [session: 43283650] 
2016-05-02 10:43:46+0000 [cowrie.ssh.transport.HoneyPotSSHFactory] New connection: 183.3.202.172:10319 (172.17.0.5:2222) [session: c7702f86] 
2016-05-02 10:43:53+0000 [cowrie.ssh.transport.HoneyPotSSHFactory] New connection: 183.3.202.172:46321 (172.17.0.5:2222) [session: fe7bb804] 
2016-05-02 10:43:57+0000 [SSHService ssh-userauth on HoneyPotTransport,17,183.3.202.172] login attempt [root/[email protected]] failed 
2016-05-02 10:43:58+0000 [SSHService ssh-userauth on HoneyPotTransport,17,183.3.202.172] login attempt [root/123456] succeeded 
2016-05-02 10:43:59+0000 [cowrie.ssh.transport.HoneyPotSSHFactory] New connection: 183.3.202.172:18693 (172.17.0.5:2222) [session: d74eae96] 
2016-05-02 10:44:02+0000 [SSHService ssh-userauth on HoneyPotTransport,18,183.3.202.172] login attempt [root/[email protected]] failed 
2016-05-02 10:44:03+0000 [cowrie.ssh.transport.HoneyPotSSHFactory] New connection: 183.3.202.172:31130 (172.17.0.5:2222) [session: 3bde7820] 
2016-05-02 10:44:03+0000 [SSHService ssh-userauth on HoneyPotTransport,18,183.3.202.172] login attempt [root/123456] succeeded 
2016-05-02 10:44:05+0000 [cowrie.ssh.transport.HoneyPotSSHFactory] New connection: 183.3.202.172:47417 (172.17.0.5:2222) [session: 3e177c02] 
2016-05-02 10:44:06+0000 [SSHService ssh-userauth on HoneyPotTransport,19,183.3.202.172] login attempt [root/[email protected]] failed 
2016-05-02 10:44:09+0000 [SSHService ssh-userauth on HoneyPotTransport,19,183.3.202.172] login attempt [root/123456] succeeded 
2016-05-02 10:44:10+0000 [SSHService ssh-userauth on HoneyPotTransport,21,183.3.202.172] login attempt [root/[email protected]] failed 
2016-05-02 10:44:11+0000 [SSHService ssh-userauth on HoneyPotTransport,21,183.3.202.172] login attempt [root/123456] succeeded 
2016-05-02 10:44:13+0000 [SSHService ssh-userauth on HoneyPotTransport,20,183.3.202.172] login attempt [root/[email protected]] failed 
2016-05-02 10:44:14+0000 [SSHService ssh-userauth on HoneyPotTransport,20,183.3.202.172] login attempt [root/123456] succeeded 
2016-05-02 11:06:55+0000 [cowrie.ssh.transport.HoneyPotSSHFactory] New connection: 183.3.202.172:13849 (172.17.0.5:2222) [session: b20915b6] 
2016-05-02 11:07:06+0000 [cowrie.ssh.transport.HoneyPotSSHFactory] New connection: 183.3.202.172:61338 (172.17.0.5:2222) [session: cd38fe51] 
2016-05-02 11:07:14+0000 [cowrie.ssh.transport.HoneyPotSSHFactory] New connection: 183.3.202.172:23048 (172.17.0.5:2222) [session: 01b12825] 
2016-05-02 11:07:21+0000 [cowrie.ssh.transport.HoneyPotSSHFactory] New connection: 183.3.202.172:60563 (172.17.0.5:2222) [session: ad64232b] 
2016-05-02 11:07:26+0000 [SSHService ssh-userauth on HoneyPotTransport,23,183.3.202.172] login attempt [root/[email protected]] failed 
2016-05-02 11:07:27+0000 [SSHService ssh-userauth on HoneyPotTransport,23,183.3.202.172] login attempt [root/123456] succeeded 
2016-05-02 11:07:33+0000 [cowrie.ssh.transport.HoneyPotSSHFactory] New connection: 183.3.202.172:53653 (172.17.0.5:2222) [session: 9c48415b] 
2016-05-02 11:07:41+0000 [SSHService ssh-userauth on HoneyPotTransport,26,183.3.202.172] login attempt [root/[email protected]] failed 
2016-05-02 11:07:47+0000 [SSHService ssh-userauth on HoneyPotTransport,26,183.3.202.172] login attempt [root/123456] succeeded 
2016-05-02 11:12:25+0000 [cowrie.ssh.transport.HoneyPotSSHFactory] New connection: 183.3.202.172:18942 (172.17.0.5:2222) [session: a4dc4901] 
2016-05-02 11:12:34+0000 [SSHService ssh-userauth on HoneyPotTransport,27,183.3.202.172] login attempt [root/[email protected]] failed 
2016-05-02 11:12:36+0000 [SSHService ssh-userauth on HoneyPotTransport,27,183.3.202.172] login attempt [root/123456] succeeded 
2016-05-02 11:32:40+0000 [cowrie.ssh.transport.HoneyPotSSHFactory] New connection: 183.3.202.172:40091 (172.17.0.5:2222) [session: aeb36234] 
2016-05-02 11:32:43+0000 [cowrie.ssh.transport.HoneyPotSSHFactory] New connection: 183.3.202.172:53505 (172.17.0.5:2222) [session: 9022c831] 
2016-05-02 11:32:48+0000 [cowrie.ssh.transport.HoneyPotSSHFactory] New connection: 183.3.202.172:15131 (172.17.0.5:2222) [session: cf62fb9a] 
2016-05-02 11:32:48+0000 [cowrie.ssh.transport.HoneyPotSSHFactory] New connection: 183.3.202.172:15853 (172.17.0.5:2222) [session: f2f6c254] 
2016-05-02 11:32:50+0000 [SSHService ssh-userauth on HoneyPotTransport,28,183.3.202.172] login attempt [root/[email protected]] failed 
2016-05-02 11:32:52+0000 [SSHService ssh-userauth on HoneyPotTransport,28,183.3.202.172] login attempt [root/123456] succeeded 
2016-05-02 11:32:55+0000 [SSHService ssh-userauth on HoneyPotTransport,29,183.3.202.172] login attempt [root/[email protected]] failed 
2016-05-02 11:32:55+0000 [SSHService ssh-userauth on HoneyPotTransport,30,183.3.202.172] login attempt [root/[email protected]] failed 
2016-05-02 11:32:56+0000 [SSHService ssh-userauth on HoneyPotTransport,30,183.3.202.172] login attempt [root/123456] succeeded 
2016-05-02 11:32:57+0000 [SSHService ssh-userauth on HoneyPotTransport,31,183.3.202.172] login attempt [root/[email protected]] failed 
2016-05-02 11:32:59+0000 [SSHService ssh-userauth on HoneyPotTransport,31,183.3.202.172] login attempt [root/123456] succeeded 

Deshalb ist die ausgegeben werden soll, wie in den ersten beiden Zeilen folgt

Port,Status,AttemptsOnPort,ConnectionsOnIP,Malicious 
    15853,failed,4,(total no of times the IP using this port is seen in log, even if it used other ports) 
    15853,succeeded,4,18 
+1

Es scheint, dass Sie einen Zähler für IP für jeden gesehen hinzufügen müssen: Benutzer, Status.Sie würden also einen Hash mit diesen Ebenen hinzufügen, mit einem Zähler, $ by_ip {$ ip} {$ usr} {$ status} ++ '. Sie fügen dieses Recht neben dem $ rept {$ port} {$ usr} {$ status} ++ 'in der nächsten Zeile hinzu. Dies kann die bereits aufgezeichnete $ IP verwenden, ich sehe nicht, warum Sie sie erneut aus der Zeile "letzter Versuch" holen müssen (muss dieselbe sein, nein?). Vergessen Sie nicht, diesen neuen Hash "my% by_ip" zu deklarieren. Ich kann dies posten, aber probiere es selbst aus und melde dich zurück. So wie Sie es jetzt haben, zählt IP für jeden Port, Benutzer, Status - alles, die Pauschale. – zdim

+0

@zdim nicht sicher, ob ich es richtig gemacht habe, fügte ich den Hash genau unter dem '$ rept {$ port} {$ usr} {$ status} ++' und hier drucke ich: 'print" Port, Status, AttampOnPort, AttemptsOnIP, Malicious \ n "; foreach meine $ ip (Sortierschlüssel% by_ip) { foreach meine $ port (Sortierschlüssel% rep) { foreach meine $ usr (Sortierschlüssel% {$ rept {$ port}}) { foreach meine $ stat (sort Schlüssel% {$ rept {$ port} {$ usr}}) { if ($ portne "") { print "$ port, $ stat, $ rept {$ port} {$ usr} {$ stat}, $ by_ip {$ ip} {$ usr} {$ stat} \ n $ } } } } } ' – firepro20

+0

@zdim das ist die [output] (http://pastebin.com/XDLbmBAK) Ich bekomme – firepro20

Antwort

1

Dieser Code druckt einen Bericht im folgenden Format. Entfernen Sie das Feld (IP), wenn dies unerwünscht ist.

 
Port,Status,AttemptOnPort,(IP),ConnectionsOnIP 

Eine solche Zeile wird für jeden Benutzer gedruckt. ConnectionsOnIP ist jedoch die Gesamtzahl dieser IP für alle Benutzer und Ports gesehen. Der Code druckt auch einen separaten Bericht über IPs allein. Siehe Kommentare zu verwandten Fragen.

use strict; 
use warnings; 

my $file = 'logfile.txt'; 
open my $fh_in, '<', $file; 

# Assemble results for required output in data structure: 
# %rept = { 
# $port => { 
#  $ip => { 
#   $usr => { 
#    $status => $freq 
#   }, 
#  }, 
# }, 
# }; 
# Auxiliary: %ip_tot = { $ip => { $status => $freq } } 

my (%rept, %ip_tot); 
my ($ip, $port); 

while (my $line = <$fh_in>) 
{ 
    if ($line =~ /New connection/) { 
     ($ip, $port) = $line =~ /New connection:\s+([^:]+):(\d+)/; 
     next; 
    } 
    elsif (!$ip or !$port) { next } # First lines come before New connection 

    my ($usr, $status) = $line =~ m/login attempt\s+\[([^\]]+)\]\s+(\w+)/; 
    if ($usr and $status) { 
     $rept{$port}{$ip}{$usr}{$status}++; 
     $ip_tot{$ip}{$status}++; 
    } 
    else { warn "Line with an unexpected format:\n$line" } 
} 

print "Port,Status,AttemptOnPort,(IP),ConnectionsOnIP\n"; 
foreach my $port (sort keys %rept) { 
    foreach my $ip (sort keys %{$rept{$port}}) { 
     foreach my $usr (sort keys %{$rept{$port}{$ip}}) { 
      foreach my $stat (sort keys %{$rept{$port}{$ip}{$usr}}) { 
       print "$port,$stat,$rept{$port}{$ip}{$usr}{$stat}"; 
       print "$,(ip),$ip_tot{$ip}{$stat}\n"; 
      } 
     } 
    } 
} 

print "\n"; 
print "IP,Status,Occurences\n"; 
foreach my $ip (sort keys %ip_tot) { 
    foreach my $stat (sort keys %{$ip_tot{$ip}}) { 
     print "$ip,$stat,$ip_tot{$ip}{$stat}\n"; 
    } 
} 

Mit der mitgelieferten Eingabe als logfile.txt dieser druckt

 
Port,Status,AttemptOnPort,(IP),ConnectionsOnIP 
15853,failed,4,(183.3.202.172),12 
15853,succeeded,3,(183.3.202.172),11 
18693,failed,1,(183.3.202.172),12 
18942,failed,1,(183.3.202.172),12 
18942,succeeded,1,(183.3.202.172),11 
31130,succeeded,1,(183.3.202.172),11 
46321,failed,1,(183.3.202.172),12 
46321,succeeded,1,(183.3.202.172),11 
47417,failed,3,(183.3.202.172),12 
47417,succeeded,3,(183.3.202.172),11 
53653,failed,1,(183.3.202.172),12 
53653,succeeded,1,(183.3.202.172),11 
60563,failed,1,(183.3.202.172),12 
60563,succeeded,1,(183.3.202.172),11 

IP,Status,Occurences 
183.3.202.172,failed,12 
183.3.202.172,succeeded,11 

Regex Erklärung. Dies ist ein gültiger Code mit freundlicher Genehmigung von /x. Die \s+ werden in Kommentaren ignoriert.

my ($usr, $status) = $line =~ m/ 
    login\ attempt \s+   # literal, serves as a 'post' to help matching 
    \[       # literal [ within which our pattern is 
     (      # start capture 
      [^\]]+    # any char which is not ], 1 or more times 
     )      # end of capture 
    \] \s+      # closing literal ] 
    (\w+)      # next capture: any 'word' char, 1 or more times 
/x; 

Im Herzen dafür ist die negierte Zeichenklasse, [ ^\] ]. Es heißt: Entsprechen Sie einem beliebigen Zeichen ([...]), das ist nicht (^) eine Klammer (\]), die escaped (\) muss, um das literale Zeichen zu bedeuten. Die + dahinter bedeutet one-or-more mal. Zum Beispiel

my $str = 'a5_".-]B1'; 
if ($str =~ m/([^\]]+)/) { say "Got: $1" } 

Diese Drucke Got: a5_".-. Alles bis auf die erste ] ist abgestimmt (und erfasst). Dies ist eine Möglichkeit, eine nicht gierige Übereinstimmung anzugeben, die bis das erste Auftreten des angegebenen Zeichens geht. Beachten Sie, dass etwas wie .+] alles bis zum letzten übereinstimmen würde, es ist gierig.

Siehe Regular Expressions Tutorial. Suche SO nach bestimmten Fragen, auch nach Mini-Tutorials.