├── LICENSE.md ├── README.md ├── accttime.pl ├── dumpdns.pl ├── extract-http.pl ├── icmpxtract.pl ├── immutable.py ├── ip-as-geo.pl ├── le-hex-to-ip.py ├── linux-pkgs.sh ├── plaso-datefix.py ├── pngrep.pl ├── sigs.pl ├── sigs.py ├── tcp-honeypot.service └── tln_parse.py /LICENSE.md: -------------------------------------------------------------------------------- 1 | This software is distrbuted under the BSD License 2 | 3 | Copyright (c) 2005-2023, Jim Clausing. All other rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted 6 | provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions 9 | and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of 11 | conditions and the following disclaimer in the documentation and/or other materials provided 12 | with the distribution. 13 | 3. The names of any contributors may NOT be used to endorse or promote products derived from this 14 | software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY JIM CLAUSING ''AS IS'' AND ANY EXPRESS OR 17 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 19 | SHALL AT&T INTELLECTUAL PROPERTY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 | OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 25 | DAMAGE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # scripts 2 | My collection of scripts that I've written over the years as a SANS Internet Storm Center Handler 3 | 4 | ## Requirements 5 | 6 | + **pngrep.pl** currently requires an old version of NetPacket (v0.43.2), I need to fix it to work 7 | with the current version (and will accept pull requests that fix it :-) ). 8 | + **sigs.py** requires pysha3 (can be installed with pip) or Python <= 3.6 9 | 10 | ## Notes 11 | + **mac-robber.py** has been moved to 12 | + **pngrep.pl** is no longer maintained now that there is a version of ngrep that can do IPv6 on github 13 | (see ) 14 | -------------------------------------------------------------------------------- /accttime.pl: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/perl 2 | # 3 | # $RCSfile: accttime.pl,v $ 4 | # $Revision: 1.3 $ 5 | # Author: Jim Clausing 6 | # $Date: 2002/11/21 19:55:03 $ 7 | # 8 | # Purpose: Take time-machine format lastcomm output and 9 | # present it in a format similar to what mactime 10 | # does with MACTimes from the body file. 11 | # 12 | # Switches & arguments: 13 | # -h - usage message 14 | # -n - numeric uid/gid 15 | # -d - debug 16 | # -f file - acct/pacct file to use, otherwise stdin 17 | # -g grpfile - alternate group file to use (default /etc/group) 18 | # -p pwdfile - alternat passwd file to use (default /etc/passwd) 19 | # -u user - select records of a particular user (use numeric with -n) 20 | # time [time2] - optional start and end time to search 21 | # 22 | # $Log: accttime.pl,v $ 23 | # Revision 1.3 2002/11/21 19:55:03 jac 24 | # Fix a typo, add logic to give numeric uid/gid if there 25 | # is no corresponding entry in /etc/passwd or /etc/group 26 | # 27 | # Revision 1.2 2002/09/15 20:40:38 jac 28 | # Put RCS stuff in headers 29 | # 30 | # 31 | use POSIX qw(strftime); 32 | use Getopt::Std; 33 | use Date::Manip; 34 | require "pass.cache.pl"; 35 | 36 | $debug = 0; 37 | $usage = " usage: $0 [-hnd] [-f file] [-g grpfile] [-p pwdfile] [-u user] [time [time2]]\n"; 38 | 39 | getopts('f:g:hdnp:u:') || die ; 40 | die $usage if ($opt_h||$#ARGV>1); 41 | 42 | $debug = 1 if ($opt_d); 43 | select(STDOUT); $|=1; 44 | 45 | $PASSWD = ($opt_p?$opt_p:"/etc/passwd"); 46 | $GROUP = ($opt_g?$opt_g:"/etc/group"); 47 | 48 | if (!$opt_n) { 49 | &'load_passwd_info(0,$PASSWD); 50 | &'load_group_info(0,$GROUP); 51 | } 52 | 53 | if ($opt_f) { 54 | close(STDIN); 55 | open(STDIN,"$opt_f"); 56 | } 57 | 58 | $time_one = shift @ARGV if ($#ARGV>=0); 59 | $time_two = shift @ARGV if ($#ARGV>=0); 60 | 61 | $time_one = &ParseDate($time_one); 62 | $time_two = &ParseDate($time_two); 63 | 64 | if (defined($time_one)) { 65 | $start_seconds = &UnixDate($time_one,"%s"); 66 | } else { 67 | $start_seconds = 0; 68 | } 69 | if (defined($time_two)) { 70 | $end_seconds = &UnixDate($time_two,"%s"); 71 | } else { 72 | $end_seconds = time(); 73 | } 74 | 75 | for $i ( 0..2 ) { 76 | $junk = ; 77 | } 78 | 79 | @names = split /\|/,$junk; 80 | push @names,"end_time"; 81 | 82 | while () { 83 | $k++; 84 | print "." if ($k%20 == 0 && $opt_d); 85 | $newrec = {}; 86 | @vals = split /\|/; 87 | for $i ( 0 .. $#vals ) { 88 | $newrec->{$names[$i]} = $vals[$i]; 89 | } 90 | if ($opt_u) { 91 | $flag = 0; 92 | $flag = 1 if ($opt_n && ($opt_u == $newrec->{uid})); 93 | $flag = 1 if (!$opt_n && ($opt_u eq $uid2names{$newrec->{uid}})); 94 | next if !$flag; 95 | } 96 | 97 | $newrec->{end_time} = int($newrec->{start_time} 98 | +$newrec->{elapsed_time}); 99 | $newrec->{pseudoid} = substr($newrec->{start_time},-7,7) 100 | . '-' . base62($#{$starts{$newrec->{start_time}}} + 1); 101 | push @records, $newrec; 102 | push @{$starts{$newrec->{start_time}}}, $newrec; 103 | push @{$ends{$newrec->{end_time}}}, $newrec; 104 | $time_exists{$newrec->{start_time}} = 1; 105 | $time_exists{$newrec->{end_time}} = 1; 106 | } 107 | 108 | @list = sort( keys %starts ); 109 | for $i ( sort keys %time_exists ) { 110 | next if $i < $start_seconds; 111 | exit if $i > $end_seconds; 112 | $date_string = strftime("%Y-%m-%d %H:%M:%S",localtime($i)); 113 | if (defined($starts{$i})) { 114 | for $j ( 0..$#{$starts{$i}} ) { 115 | $r = \@{$starts{$i}}; 116 | $c = ($r->[$j]->{elapsed_time}<1.0)?'>':' '; 117 | if (!$opt_n) { 118 | printf "%-21s <%s %-8s %-8s %-16s %-6s %8.2f (%-8s)\n", 119 | $date_string,$c, 120 | (defined($uid2names{$r->[$j]->{uid}})?$uid2names{$r->[$j]->{uid}}:$r->[$j]->{uid}), 121 | (defined($gid2names{$r->[$j]->{gid}})?$gid2names{$r->[$j]->{gid}}:$r->[$j]->{gid}), 122 | $r->[$j]->{command}, 123 | $r->[$j]->{tty},$r->[$j]->{elapsed_time},$r->[$j]->{pseudoid}; 124 | } else { 125 | printf "%-21s <%s %-8d %-8d %-16s %-6s %8.2f (%-8s)\n", 126 | $date_string,$c,$r->[$j]->{uid}, 127 | $r->[$j]->{gid}, $r->[$j]->{command}, 128 | $r->[$j]->{tty},$r->[$j]->{elapsed_time},$r->[$j]->{pseudoid}; 129 | } 130 | $date_string = " "; 131 | } 132 | } 133 | if (defined($ends{$i})) { 134 | for $j ( 0..$#{$ends{$i}} ) { 135 | $r = \@{$ends{$i}}; 136 | next if ($r->[$j]->{elapsed_time} < 1.0); 137 | if (!$opt_n) { 138 | printf "%-21s > %-8s %-8s %-16s %-6s %8.2f (%-8s)\n", 139 | $date_string, 140 | (defined($uid2names{$r->[$j]->{uid}})?$uid2names{$r->[$j]->{uid}}:$r->[$j]->{uid}), 141 | (defined($gid2names{$r->[$j]->{gid}})?$gid2names{$r->[$j]->{gid}}:$r->[$j]->{gid}), 142 | $r->[$j]->{command}, 143 | $r->[$j]->{tty},$r->[$j]->{elapsed_time},$r->[$j]->{pseudoid}; 144 | } else { 145 | printf "%-21s > %-8d %-8d %-16s %-6s %8.2f (%-8s)\n", 146 | $date_string,$r->[$j]->{uid}, 147 | $r->[$j]->{gid}, $r->[$j]->{command}, 148 | $r->[$j]->{tty},$r->[$j]->{elapsed_time},$r->[$j]->{pseudoid}; 149 | } 150 | $date_string = " "; 151 | } 152 | } 153 | } 154 | 155 | sub base62 { 156 | my @parm = @_; 157 | if ($parm[0] <= 9) { 158 | $rc = $parm[0]; 159 | } elsif ($parm[0] > 9 && $parm[0] <= 35) { 160 | $rc = chr(ord('a') + $parm[0] - 10); 161 | } else { 162 | $rc = chr(ord('A') + $parm[0] - 36); 163 | } 164 | return $rc 165 | } 166 | -------------------------------------------------------------------------------- /dumpdns.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # 3 | # 4 | # Author: Jim Clausing 5 | # Date: 2013-11-18 6 | # Version: 1.5.1 7 | # 8 | # Purpose: Report on all DNS queries and responses from network traffic. 9 | # 10 | # Updates: (v1.4) added support for queries over IPv6 11 | # (v1.5) now handles routing, hop-by-hop and destination IPv6 extension headers 12 | # as a result, now requires a minimum of perl 5.10 13 | # (v1.5.1) fix typo, add some error correction 14 | 15 | require 5.010; 16 | 17 | use Data::Dumper; 18 | use Getopt::Std; 19 | use Net::Pcap; 20 | use IO::Socket::INET6; 21 | use NetPacket::Ethernet qw(:strip :types); 22 | use NetPacket::IP 0.43.2 qw(:strip :protos :versions); 23 | use NetPacket::IPv6 qw(:strip :protos :versions); 24 | use NetPacket::TCP qw(:strip); 25 | use NetPacket::UDP qw(:strip); 26 | use Net::DNS::Packet; 27 | use Net::DNS::Header; 28 | use Net::DNS::RR; 29 | use Net::IP qw(:PROC); 30 | use POSIX qw(strftime); 31 | 32 | my %opts; 33 | my $version = '1.5.1'; 34 | getopts('qahHti:r:s:V',\%opts); 35 | die "$0 v$version (c) Jim Clausing, 2009-2013\n" if ($opts{V}); 36 | usage() unless $opts{i} || $opts{r}; 37 | usage() if (($opts{i} && $opts{r}) || $opts{h}); 38 | 39 | my $err; 40 | my $pcap; 41 | my $filter; 42 | my $filter_str = '((ip proto 17) or (ip proto 6) or (ip6 protochain 17) or (ip6 protochain 6)) and port 53'; 43 | my $sep = ($opts{s}?$opts{s}:'|'); 44 | 45 | if ($opts{i}) { 46 | $pcap = Net::Pcap::open_live($opts{i}, 1500, 0, 1000, \$err); 47 | } else { 48 | $pcap = Net::Pcap::open_offline($opts{r}, \$err); 49 | } 50 | 51 | if ($opts{H}) { 52 | print "time"; 53 | print $sep; 54 | print "src ip"; 55 | print $sep; 56 | print "dst ip"; 57 | print $sep; 58 | print "qname"; 59 | print $sep; 60 | print "type"; 61 | print $sep; 62 | print "ttl"; 63 | print $sep; 64 | print "rcode"; 65 | print $sep; 66 | print "q/r flag"; 67 | print $sep; 68 | print "answer\n"; 69 | } 70 | 71 | die if (Net::Pcap::compile($pcap, \$filter, $filter_str, 0, 0)); 72 | Net::Pcap::setfilter($pcap, $filter); 73 | Net::Pcap::loop($pcap, -1, \&process_pkt, undef); 74 | exit(0); 75 | 76 | sub process_pkt { 77 | my ($user_data, $pcap_hdr, $pkt) = @_; 78 | 79 | my $rec = parse_pkt($pkt); 80 | return unless $rec; 81 | 82 | return if ($opts{a} && !$opts{q} && $rec->{qr} == 0); 83 | return if ($opts{q} && !$opts{a} && $rec->{qr} == 1); 84 | if (!$opts{t}) { 85 | $rec->{time} = sprintf "%s.%06d", 86 | strftime("%Y-%m-%d-%H:%M:%S", gmtime($pcap_hdr->{tv_sec})), 87 | $pcap_hdr->{tv_usec}; 88 | } else { 89 | $rec->{time} = sprintf "%d.%06d", $pcap_hdr->{tv_sec}, $pcap_hdr->{tv_usec}; 90 | } 91 | 92 | if($rec->{qr} == 1) { 93 | for (my $i = 0; $i < $rec->{ancount}; $i ++) { 94 | my ($name, $type, $ttl, $str) = split (/\^/, @{$rec->{ans}}[$i]); 95 | print $rec->{time}; 96 | print $sep; 97 | print $rec->{src_ip}; 98 | print $sep; 99 | print $rec->{dst_ip}; 100 | print $sep; 101 | print $name; 102 | print $sep; 103 | print $type; 104 | print $sep; 105 | print $ttl; 106 | print $sep; 107 | print $rec->{rcode}; 108 | print $sep; 109 | print $rec->{qr}; 110 | print $sep; 111 | $str =~ s/;.*$//mg if ($type eq 'SOA'); 112 | $str =~ s/\s+/ /g if ($type eq 'SOA'); 113 | if ($type eq "AAAA") { 114 | print ip_compress_address($str,6),"\n"; 115 | } else { 116 | print $str,"\n"; 117 | } 118 | } 119 | 120 | if ($rec->{ancount} == 0) { 121 | my ($name,$type,$str) = split(/\^/, pop(@{$rec->{question}})); 122 | print $rec->{time}; 123 | print $sep; 124 | print $rec->{src_ip}; 125 | print $sep; 126 | print $rec->{dst_ip}; 127 | print $sep; 128 | print $name; 129 | print $sep; 130 | print $type; 131 | print $sep; 132 | print "-"; 133 | print $sep; 134 | print $rec->{rcode}; 135 | print $sep; 136 | print $rec->{qr}; 137 | print $sep; 138 | print "\n"; 139 | } 140 | } else { 141 | my ($name,$type,$str) = split(/\^/, pop(@{$rec->{question}})); 142 | print $rec->{time}; 143 | print $sep; 144 | print $rec->{src_ip}; 145 | print $sep; 146 | print $rec->{dst_ip}; 147 | print $sep; 148 | print $name; 149 | print $sep; 150 | print $type; 151 | print $sep; 152 | print "-"; 153 | print $sep; 154 | print $rec->{rcode}; 155 | print $sep; 156 | print $rec->{qr}; 157 | print $sep; 158 | print "\n"; 159 | } 160 | } 161 | 162 | sub parse_pkt { 163 | my $pkt = shift; 164 | my $rec; 165 | my $len; 166 | my @seg_list; 167 | my $dns; 168 | my $ip_obj = NetPacket::IP->decode(eth_strip($pkt)); 169 | if ($ip_obj->{ver} == IP_VERSION_IPv4) { 170 | return unless ($ip_obj->{proto} == IP_PROTO_UDP || $ip_obj->{proto} == IP_PROTO_TCP); 171 | $rec->{src_ip} = $ip_obj->{src_ip}; 172 | $rec->{dst_ip} = $ip_obj->{dest_ip}; 173 | 174 | if ($ip_obj->{proto} == IP_PROTO_UDP) { 175 | my $udp_obj = NetPacket::UDP->decode($ip_obj->{data}); 176 | return unless $udp_obj; 177 | $rec->{src_port} = $udp_obj->{src_port}; 178 | $rec->{dst_port} = $udp_obj->{dest_port}; 179 | return unless ($udp_obj->{data}); 180 | $dns = Net::DNS::Packet->new(\$udp_obj->{data}); 181 | } else { 182 | my $tcp_obj = NetPacket::TCP->decode($ip_obj->{data}); 183 | return unless $tcp_obj; 184 | $rec->{src_port} = $tcp_obj->{src_port}; 185 | $rec->{dst_port} = $tcp_obj->{dest_port}; 186 | return unless ($tcp_obj->{data}); 187 | $dns = Net::DNS::Packet->new(\$tcp_obj->{data}); 188 | } 189 | 190 | unless ($dns) { 191 | warn "Net::DNS::Packet->new: $!"; 192 | return; 193 | } 194 | } elsif ($ip_obj->{ver} == IP_VERSION_IPv6) { 195 | $ip_obj = NetPacket::IPv6->decode(eth_strip($pkt)); 196 | $rec->{src_ip} = $ip_obj->{src_ip}; 197 | $rec->{dst_ip} = $ip_obj->{dest_ip}; 198 | 199 | while ($ip_obj->{nxt} ~~ [0,43,60]) { 200 | if ($ip_obj->{nxt} == 43) { 201 | @seg_list = (); 202 | $rec->{seg_list} = (); 203 | ($len,$rec->{seg_type},$rec->{seg_left}) = unpack('C3',substr($ip_obj->{data},1,3)); 204 | for (my $i = 0; $i < $len/2; $i++) { 205 | my @ip = unpack('N4',substr($ip_obj->{data},16*($i)+8,16)); 206 | my $ip_str = NetPacket::IPv6::int_to_hexstr(@ip); 207 | push @{$rec->{seg_list}},$ip_str; 208 | } 209 | #$rec->{seg_list} = @seg_list; 210 | } 211 | ($ip_obj->{nxt},$len) = unpack('C2',substr($ip_obj->{data},0,2)); 212 | $ip_obj->{data} = substr($ip_obj->{data},8*($len+1)); 213 | } 214 | 215 | if ($ip_obj->{nxt} == IP_PROTO_UDP) { 216 | my $udp_obj = NetPacket::UDP->decode($ip_obj->{data}); 217 | return unless $udp_obj; 218 | $rec->{src_port} = $udp_obj->{src_port}; 219 | $rec->{dst_port} = $udp_obj->{dest_port}; 220 | return unless ($udp_obj->{data}); 221 | $dns = Net::DNS::Packet->new(\$udp_obj->{data}); 222 | } else { 223 | my $tcp_obj = NetPacket::TCP->decode($ip_obj->{data}); 224 | return unless $tcp_obj; 225 | $rec->{src_port} = $tcp_obj->{src_port}; 226 | $rec->{dst_port} = $tcp_obj->{dest_port}; 227 | return unless ($tcp_obj->{data}); 228 | $dns = Net::DNS::Packet->new(\$tcp_obj->{data}); 229 | } 230 | 231 | unless ($dns) { 232 | warn "Net::DNS::Packet->new: $!"; 233 | return; 234 | } 235 | } else { 236 | warn "Invalid IP version in packet, continuing..."; 237 | return; 238 | } 239 | 240 | my $header = $dns->header; 241 | $rec->{id} = $header->id; 242 | $rec->{qr} = $header->qr; 243 | $rec->{opcode} = $header->opcode; 244 | $rec->{rcode} = $header->rcode; 245 | $rec->{aa} = $header->aa; 246 | $rec->{tc} = $header->tc; 247 | $rec->{rd} = $header->rd; 248 | $rec->{ra} = $header->ra; 249 | $rec->{ad} = $header->ad; 250 | $rec->{qdcount} = $header->qdcount; 251 | $rec->{ancount} = $header->ancount; 252 | $rec->{nscount} = $header->nscount; 253 | $rec->{adcount} = $header->adcount; 254 | 255 | if ($dns->question) { 256 | foreach my $rr ($dns->question) { 257 | push(@{$rec->{question}}, $rr->qname . '^' . $rr->qtype . '^' . $rr->string); 258 | } 259 | } 260 | if ($dns->answer) { 261 | foreach my $rr ($dns->answer) { 262 | push(@{$rec->{ans}}, $rr->name . '^' . $rr->type . '^' . $rr->ttl . '^' . $rr->rdatastr); 263 | } 264 | } 265 | if ($dns->authority) { 266 | foreach my $rr ($dns->authority) { 267 | if (defined $rec->{auth}) { 268 | push(@{$rec->{auth}}, $rr->rdatastr); 269 | } 270 | } 271 | } 272 | if ($dns->additional) { 273 | foreach my $rr ($dns->additional) { 274 | if (defined $rec->{addl}) { 275 | push(@{$rec->{addl}}, $rr->rdatastr); 276 | } 277 | } 278 | } 279 | return $rec; 280 | } 281 | 282 | sub usage { 283 | print STDERR " 284 | $0 [ -i ifname | -r filename ] [ -s sep ] [ -q ] [ -a ] [ -h ] [ -H ] [ -t ] 285 | 286 | \t-h\t\tthis message 287 | \t-i ifname\tinterface on which to listen for live capture 288 | \t-r filename\tpcap file from which to extract DNS data 289 | \t-s sep\t\tseparator in the output (default: |) 290 | \t-q\t\tqueries only 291 | \t-a\t\tanswers only 292 | \t-H\t\tinclude header line 293 | \t-t\t\tuse unix timestamps for time 294 | "; 295 | exit 1; 296 | } 297 | -------------------------------------------------------------------------------- /extract-http.pl: -------------------------------------------------------------------------------- 1 | #!/usr/local/bin/perl 2 | # 3 | # Author: Jim Clausing 4 | # Date: 2006-05-31 5 | # Purpose: Take an input file which consists of the 6 | # server->client side of an HTTP connection 7 | # and extract the contents into a file. This 8 | # input file can be generated using tcpflow, 9 | # tcptrace or ethereal. I personally like 10 | # tcptrace since it will tell you if packets 11 | # are missing and what the name of the file 12 | # was that it was trying to download. 13 | # 14 | # Example: 15 | # $ tcpdump -s 0 -w foo.pcap host umn.sourceforge.net 16 | # ... 17 | # $ wget http://umn.sourceforge.net/sourceforge/srm/srm-1.2.8.tar.gz 18 | # ... 19 | # 20 | # $ tcptrace -xhttp -r foo.pcap 21 | # mod_http: Capturing HTTP traffic (port 80) 22 | # 1 arg remaining, starting with 'foo.pcap' 23 | # Ostermann's tcptrace -- version 6.6.7 -- Thu Nov 4, 2004 24 | # 25 | # 113 packets seen, 113 TCP packets traced 26 | # elapsed wallclock time: 0:00:00.010641, 10619 pkts/sec analyzed 27 | # trace file elapsed time: 0:00:00.455470 28 | # TCP connection info: 29 | # 1: my.machine:60477 - torpor.mirror.umn.edu:80 (a2b) 48> 65< (complete) 30 | # Http module output: 31 | # my.machine:60477 ==> torpor.mirror.umn.edu:80 (a2b) 32 | # Server Syn Time: Wed May 31 12:58:57.301102 2006 (1149094737.301) 33 | # Client Syn Time: Wed May 31 12:58:57.253209 2006 (1149094737.253) 34 | # Server Fin Time: Wed May 31 12:58:57.670698 2006 (1149094737.671) 35 | # Client Fin Time: Wed May 31 12:58:57.671034 2006 (1149094737.671) 36 | # GET /sourceforge/srm/srm-1.2.8.tar.gz HTTP/1.0 37 | # Response Code: 200 (OK) 38 | # Request Length: 140 39 | # Reply Length: 88328 40 | # Content Length: 88067 41 | # Content Type : application/x-gzip 42 | # Time request sent: Wed May 31 12:58:57.301592 2006 (1149094737.302) 43 | # Time reply started: Wed May 31 12:58:57.374448 2006 (1149094737.374) 44 | # Time reply ACKed: Wed May 31 12:58:57.671034 2006 (1149094737.671) 45 | # Elapsed time: 73 ms (request to first byte sent) 46 | # Elapsed time: 369 ms (request to content ACKed) 47 | # 48 | # $ extract-http.pl -f foo.tar.gz b2a_contents.dat 49 | # $ md5sum foo.tar.gz srm-1.2.8.tar.gz 50 | # 66ba49b1864a7c69763210dbc3efee33 foo.tar.gz 51 | # 66ba49b1864a7c69763210dbc3efee33 srm-1.2.8.tar.gz 52 | # 53 | 54 | use Getopt::Std; 55 | use HTTP::Response; 56 | 57 | getopts('hf:'); 58 | 59 | die " 60 | 61 | Usage: $0 [-h] [-f outfile] [infile] 62 | -h this message 63 | -f outfile extract contents into outfile (default: stdout) 64 | infile if no input file given, uses stdin 65 | 66 | " if ($opt_h); 67 | 68 | while (<>) { 69 | $str .= $_; 70 | } 71 | 72 | $r = HTTP::Response->parse($str); 73 | 74 | if ($opt_f) { 75 | close STDOUT; 76 | open STDOUT, ">$opt_f"; 77 | } 78 | 79 | print $r->content; 80 | -------------------------------------------------------------------------------- /icmpxtract.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # 3 | # Name: icmpxtract.pl 4 | # Author: Jim Cluaisng 5 | # Version: 1.1 6 | # Date: 2011-08-22 7 | # 8 | # Notes: This version doesn't handle out of order packets, 9 | # duplicates, or IPv6 that will be rectified in v1.1 10 | # 11 | # Updates: (1.1) Added IPv6 support, handles out of order 12 | # packets now, in case of duplicates we use 13 | # the last one. Any holes are ignored 14 | 15 | require 5.010; 16 | 17 | use Data::Dumper; 18 | use Getopt::Std; 19 | use Net::Pcap; 20 | use IO::Socket::INET6; 21 | use NetPacket::Ethernet qw(:strip :types); 22 | use NetPacket::IP 0.43.2 qw(:strip :protos :versions); 23 | use NetPacket::IPv6 qw(:strip :protos :versions); 24 | #use NetPacket::TCP qw(:strip); 25 | #use NetPacket::UDP qw(:strip); 26 | use NetPacket::ICMP qw(:ALL); 27 | use NetPacket::ICMPv6 qw(:strip); 28 | #use Net::IP qw(:PROC); 29 | use POSIX qw(strftime); 30 | use Digest::MD5 qw(md5_hex); 31 | use Digest::SHA qw(sha256_hex); 32 | 33 | my %buffers; 34 | my $filter_str = 'icmp or icmp6'; 35 | my $version='1.1'; 36 | 37 | getopts('hVd:f:o:',\%opts); 38 | die "$0 v$version (c) Jim Clausing, 2011\n" if ($opts{V}); 39 | usage() unless $opts{d} || $opts{f}; 40 | usage() if (($opts{d} && $opts{f}) || $opts{h}); 41 | usage() if $#ARGV > 0; 42 | 43 | chdir($opts{d}) if defined ($opts{d}); 44 | 45 | if ($#ARGV == 0) { 46 | $filter_str .= ' and (' . shift @ARGV; 47 | $filter_str .= ')'; 48 | # $filter_str = shift @ARGV; 49 | } 50 | 51 | 52 | if ($opts{d}) { 53 | $pcap = Net::Pcap::open_live($opts{d}, 1600, 0, 1000, \$err); 54 | } else { 55 | $pcap = Net::Pcap::open_offline($opts{f}, \$err); 56 | } 57 | 58 | 59 | die if (Net::Pcap::compile($pcap, \$filter, $filter_str, 0, 0)); 60 | Net::Pcap::setfilter($pcap, $filter); 61 | Net::Pcap::loop($pcap, -1, \&process_pkt, undef); 62 | foreach $file (keys %buffers) { 63 | my $tmp = ''; 64 | open OUT,">$file"; 65 | for ($i = 0; $i < $#{$buffers{$file}}; $i++) { 66 | $tmp .= $buffers{$file}[$i] if (defined $buffers{$file}[$i] && length($buffers{$file}[$i]) > 0); 67 | } 68 | print OUT $tmp; 69 | close OUT; 70 | $size = length $tmp; 71 | $md5 = md5_hex($tmp); 72 | $sha256 = sha256_hex($tmp); 73 | print "File: $file\n size: $size\n MD5: $md5\n SHA256: $sha256\n"; 74 | } 75 | exit(0); 76 | 77 | sub process_pkt { 78 | my ($user_data, $pcap_hdr, $pkt) = @_; 79 | 80 | my $proto; 81 | my $rec = parse_pkt($pkt); 82 | my $filename; 83 | return unless $rec; 84 | $_ = $rec->{data}; 85 | 86 | #print Dumper ($rec); 87 | $filename = sprintf("%s-%s-0x%02x%02x-0x%04x.raw", $rec->{src_ip},$rec->{dst_ip},$rec->{type},$rec->{code},$rec->{id}); 88 | #open OUT,">>$filename"; 89 | #print OUT $rec->{data}; 90 | #close OUT; 91 | #print $filename,"\n"; 92 | $buffers{$filename}[$rec->{seq}] = $rec->{data}; 93 | return 94 | 95 | } 96 | 97 | sub parse_pkt { 98 | my $pkt = shift; 99 | my $rec; 100 | my $dns; 101 | my $packet; 102 | my $eth_obj = NetPacket::Ethernet->decode($pkt); 103 | if ($eth_obj->{type} == ETH_TYPE_IP || $eth_obj->{type} == ETH_TYPE_IPv6 || $eth_obj->{type} == ETH_TYPE_ARP) { 104 | $packet = eth_strip($pkt); 105 | } else { 106 | $packet = $pkt; 107 | } 108 | my $ip_obj = NetPacket::IP->decode($packet); 109 | if ($ip_obj->{ver} == IP_VERSION_IPv4) { 110 | $rec->{src_ip} = $ip_obj->{src_ip}; 111 | $rec->{dst_ip} = $ip_obj->{dest_ip}; 112 | $rec->{proto} = $ip_obj->{proto}; 113 | 114 | if ($ip_obj->{proto} == IP_PROTO_UDP) { 115 | # my $udp_obj = NetPacket::UDP->decode($ip_obj->{data}); 116 | # return unless $udp_obj; 117 | # $rec->{src_port} = $udp_obj->{src_port}; 118 | # $rec->{dst_port} = $udp_obj->{dest_port}; 119 | # return unless ($udp_obj->{data}); 120 | # $rec->{data} = $udp_obj->{data}; 121 | } elsif ($ip_obj->{proto} == IP_PROTO_TCP) { 122 | # my $tcp_obj = NetPacket::TCP->decode($ip_obj->{data}); 123 | # return unless $tcp_obj; 124 | # $rec->{src_port} = $tcp_obj->{src_port}; 125 | # $rec->{dst_port} = $tcp_obj->{dest_port}; 126 | # return unless ($tcp_obj->{data}); 127 | # $rec->{data} = $tcp_obj->{data}; 128 | } elsif ($ip_obj->{proto} == IP_PROTO_ICMP) { 129 | my $icmp_obj = NetPacket::ICMP->decode($ip_obj->{data}); 130 | return unless $icmp_obj; 131 | $rec->{type} = $icmp_obj->{type}; 132 | $rec->{code} = $icmp_obj->{code}; 133 | return unless ($icmp_obj->{data}); 134 | if ($rec->{type} == ICMP_ECHO || $rec->{type} == ICMP_ECHOREPLY) { 135 | $rec->{id} = unpack('S>',substr($icmp_obj->{data},0,2)); 136 | $rec->{seq} = unpack('S',substr($icmp_obj->{data},2,2)); 137 | $rec->{data} = substr($icmp_obj->{data},4); 138 | } else { 139 | $rec->{data} = $icmp_obj->{data}; 140 | } 141 | } 142 | 143 | } elsif ($ip_obj->{ver} == IP_VERSION_IPv6) { 144 | $ip_obj = NetPacket::IPv6->decode($packet); 145 | $rec->{src_ip} = $ip_obj->{src_ip}; 146 | $rec->{dst_ip} = $ip_obj->{dest_ip}; 147 | $rec->{proto} = $ip_obj->{nxt}; 148 | 149 | while ($ip_obj->{nxt} ~~ [0,43,60]) { 150 | if ($ip_obj->{nxt} == 43) { 151 | @seg_list = (); 152 | $rec->{seg_list} = (); 153 | ($len,$rec->{seg_type},$rec->{seg_left}) = unpack('C3',substr($ip_obj->{data},1,3)); 154 | for (my $i = 0; $i < $len/2; $i++) { 155 | my @ip = unpack('N4',substr($ip_obj->{data},16*($i)+8,16)); 156 | my $ip_str = NetPacket::IPv6::int_to_hexstr(@ip); 157 | push @{$rec->{seg_list}},$ip_str; 158 | } 159 | #$rec->{seg_list} = @seg_list; 160 | } 161 | ($ip_obj->{nxt},$len) = unpack('C2',substr($ip_obj->{data},0,2)); 162 | $ip_obj->{data} = substr($ip_obj->{data},8*($len+1)); 163 | } 164 | if ($ip_obj->{nxt} == IP_PROTO_ICMPV6) { 165 | my $icmpv6_obj = NetPacket::ICMPv6->decode($ip_obj->{data}); 166 | return unless $icmpv6_obj; 167 | $rec->{type} = $icmpv6_obj->{type}; 168 | $rec->{code} = $icmpv6_obj->{code}; 169 | return unless ($icmpv6_obj->{data}); 170 | $rec->{data} = $icmpv6_obj->{data}; 171 | if ($rec->{type} == ICMPV6_ECHO_REQUEST || $rec->{type} == ICMPV6_ECHO_REPLY) { 172 | $rec->{id} = $icmpv6_obj->{id}; 173 | $rec->{seq} = $icmpv6_obj->{seq}; 174 | $rec->{data} = $icmpv6_obj->{data}; 175 | } 176 | } else { 177 | $rec->{data} = $ip_obj->{data}; 178 | } 179 | } 180 | return $rec; 181 | } 182 | 183 | sub usage { 184 | print STDERR " 185 | $0 [ -d ifname | -f ] [ -o ] [ -h ] [] 186 | 187 | \t\tthis will be and-ed with 'icmp[icmptype]=icmp-echo' 188 | \t-h\t\tthis message 189 | \t-d ifname\tinterface on which to listen for live capture 190 | \t-f \tpcap file from which to look for data 191 | \t-o \tpcap file from which to look for data 192 | \t-V\t\tprint Version 193 | "; 194 | exit 1; 195 | } 196 | 197 | -------------------------------------------------------------------------------- /immutable.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Author: Jim Clausing 4 | # 5 | 6 | import os 7 | import subprocess 8 | import argparse 9 | import shutil 10 | import sys 11 | 12 | __version_info__ = (0, 1, 0) 13 | __version__ = ".".join(map(str, __version_info__)) 14 | 15 | def check_lsattr_exists(): 16 | if not shutil.which('lsattr'): 17 | print("Error: 'lsattr' command not found. Please ensure it is installed and available in your PATH.") 18 | sys.exit(1) 19 | 20 | def is_immutable(file_path): 21 | try: 22 | # Run the lsattr command and capture the output 23 | result = subprocess.run(['lsattr', file_path], capture_output=True, text=True, check=True) 24 | # The immutable attribute is represented by an 'i' 25 | return 'i' in result.stdout.split()[0] 26 | except subprocess.CalledProcessError: 27 | # If lsattr fails, we assume the file is not immutable 28 | return False 29 | 30 | def search_immutable_files(directory, recursive, follow_symlinks): 31 | immutable_files = [] 32 | if recursive: 33 | for root, _, files in os.walk(directory): 34 | for file in files: 35 | file_path = os.path.join(root, file) 36 | if is_immutable(file_path): 37 | immutable_files.append(file_path) 38 | else: 39 | for item in os.listdir(directory): 40 | file_path = os.path.join(directory, item) 41 | if os.path.isfile(file_path) or (follow_symlinks and os.path.islink(file_path)): 42 | if is_immutable(file_path): 43 | immutable_files.append(file_path) 44 | return immutable_files 45 | 46 | def main(): 47 | check_lsattr_exists() 48 | 49 | parser = argparse.ArgumentParser(description="Search for immutable files.") 50 | parser.add_argument('paths', metavar='PATH', type=str, nargs='+', help='Path to file or directory') 51 | parser.add_argument('-r', '--recursive', action='store_true', help='Recursively search directories') 52 | parser.add_argument('-f', '--fullpath', action='store_true', help='Print full path rather than relative') 53 | parser.add_argument('-l', '--follow-symlinks', action='store_true', help='Follow symbolic links') 54 | args = parser.parse_args() 55 | 56 | immutable_files = [] 57 | 58 | for path in args.paths: 59 | if args.fullpath: 60 | path = os.path.abspath(path) 61 | if os.path.isfile(path) or (args.follow_symlinks and os.path.islink(path)): 62 | if is_immutable(path): 63 | immutable_files.append(path) 64 | elif os.path.isdir(path): 65 | immutable_files.extend(search_immutable_files(path, args.recursive, args.follow_symlinks)) 66 | else: 67 | print(f"Path '{path}' is neither a file nor a directory.") 68 | 69 | if immutable_files: 70 | for file in immutable_files: 71 | print(file) 72 | 73 | if __name__ == "__main__": 74 | main() 75 | -------------------------------------------------------------------------------- /ip-as-geo.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # 3 | # Name: ip-as-geo.pl 4 | # Version: 1.6 5 | # Date: 2014-01-14 6 | # Author: Jim Clausing 7 | # Inputs: IP address 8 | # Outputs: IP 9 | # CIDR range(s) assigned to 10 | # 2-letter country code where IP located 11 | # long country name where IP is located 12 | # AS number 13 | # BGP prefix 14 | # Organization AS assigned to 15 | # 16 | # Changes: Modified to handle IPv6 addresses (2009-08-11) 17 | # Requires modified Net::Abuse::Utils and 18 | # Net::Whois::IANA 19 | # 20 | # Handle multiple IPs either on command line 21 | # or via STDIN 22 | # 23 | # Clean up an issue with trailing white space 24 | # 25 | # Fix issue with IPs that aren't in cymru whois 26 | # 27 | # Fix AutoLoader warning messages in 5.14 and later 28 | # 29 | 30 | use strict; 31 | use warnings; 32 | use AutoLoader qw/AUTOLOAD/; 33 | 34 | use Getopt::Std; 35 | 36 | use Net::Abuse::Utils qw( :all ); 37 | use Net::Whois::IANA; 38 | use Net::CIDR; 39 | use Net::IP qw(:PROC); 40 | use Geography::Countries qw (country); 41 | 42 | my %opt; 43 | my $ip; 44 | my $cidr_out; 45 | my $country; 46 | my $country_long; 47 | my @asn; 48 | my $asn_desc; 49 | 50 | getopts('hHn',\%opt) || &usage(); 51 | 52 | &usage() if $opt{'h'}; 53 | 54 | chomp(@ARGV = ) unless @ARGV; 55 | if ($opt{H}) { 56 | format STDOUT_TOP = 57 | IP addr | CIDR/inetnum |CC|Country (long)| ASN | BGP Prefix | Owner 58 | ----------------|-----------------------------------|--|--------------|-----|-------------------|------------------------------ 59 | . 60 | format STDOUT = 61 | @|||||||||||||| | @|||||||||||||||||||||||||||||||| |@<|@<<<<<<<<<<<<<|@>>>>|@||||||||||||||||| |@<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 62 | $ip, $cidr_out, $country, $country_long, $asn[0], $asn[1], $asn_desc 63 | . 64 | $==255; 65 | } 66 | 67 | while ($ip = shift(@ARGV)) { 68 | $ip=~s/\s+$//; 69 | my $iana = new Net::Whois::IANA; 70 | 71 | if (!ip_is_ipv4($ip) && !ip_is_ipv6($ip)) { 72 | warn "$ip doesn't look like an IP.\n"; 73 | exit; 74 | } 75 | 76 | $iana->whois_query(-ip=>$ip); 77 | 78 | @asn = get_asn_info($ip); 79 | if ($#asn > 0) { 80 | $asn_desc = get_as_description($asn[0]) || ''; 81 | } else { 82 | $asn[0] = $asn[1] = $asn_desc = ''; 83 | } 84 | 85 | #my $cidr = $iana->cidr(); 86 | # 87 | # for some reason $iana->cidr() wasn't returning the CIDR, so we'll do it ourselves 88 | # 89 | my $net = $iana->inetnum(); 90 | my @cidr = Net::CIDR::range2cidr($net) if !$opt{'n'}; 91 | 92 | if ( $opt{'n'} ) { 93 | $cidr_out = $net; 94 | } elsif ( $#cidr == 0 ) { 95 | $cidr_out = $cidr[0]; 96 | } elsif ( $#cidr < 2 ) { 97 | $cidr_out = join(',',@cidr); 98 | } else { 99 | # it just looks too crowded if the netrange requires 3 or more CIDR blocks to describe 100 | $cidr_out = $net; 101 | } 102 | 103 | $country = get_ip_country($ip); 104 | if (defined $country) { 105 | $country_long = country($country) || ''; 106 | } else { 107 | $country = $country_long = '' 108 | } 109 | 110 | if ( !$opt{'H'} ) { 111 | print "$ip|$cidr_out|$country|$country_long|$asn[0]|$asn[1]|$asn_desc\n"; 112 | } else { 113 | write; 114 | } 115 | } 116 | 117 | exit 0; 118 | 119 | sub usage() { 120 | print "$0 [-h][-n] 121 | 122 | -h print this message 123 | -n print IP range, rather than CIDR(s) 124 | -H print headers for each column 125 | 126 | "; 127 | exit; 128 | } 129 | -------------------------------------------------------------------------------- /le-hex-to-ip.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | __description__ = ('Program to convert little-endian hex (as found in /proc//net/tcp[6], etc.) to IPv4 or IPv6 ' 4 | 'addresses') 5 | __author__ = 'Jim Clausing' 6 | __version__ = '1.3.1' 7 | __date__ = '2024-10-07' 8 | 9 | import argparse 10 | import os 11 | import socket 12 | import struct 13 | import sys 14 | 15 | 16 | def ipconvert(hexstr): 17 | if len(hexstr) == 8: 18 | addr_long = int(hexstr, 16) 19 | return socket.inet_ntop(socket.AF_INET, struct.pack(" 0 else ("-",)): 29 | line = lines.rstrip("\n").split(",") 30 | date = line[0] 31 | if date == "date": 32 | print("datestamp," + ",".join(line[3:])) 33 | continue 34 | time = line[1] 35 | tz = line[2] 36 | rest = ",".join(line[3:]) 37 | parts = date.split("/") 38 | datestamp = parts[2] + "-" + parts[0] + "-" + parts[1] + "T" + time + " " + tz 39 | print(datestamp + "," + rest) 40 | -------------------------------------------------------------------------------- /pngrep.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # 3 | # 4 | # Author: Jim Clausing 5 | # Date: 2011-08-31 6 | # Version: 1.4 7 | # 8 | # Purpose: create ngrep workalike (well, similar) in perl 9 | # 10 | # Updates: (v1.1) add IPv6 support 11 | # (v1.2) handle routing, hop-by-hop, and dest option headers 12 | # now requires minimum of perl 5.10 due to use of ~~ operator 13 | # (v1.3) fix typo 14 | # (v1.4) add capability to write to pcap file 15 | # 16 | # Now that there is a version of ngrep that can handle IPv6 on github 17 | # this script is no longer maintained 18 | # 19 | 20 | use 5.010; 21 | 22 | use Data::Dumper; 23 | use Getopt::Std; 24 | use Net::Pcap; 25 | use IO::Socket::INET6; 26 | use NetPacket::Ethernet qw(:strip :types); 27 | use NetPacket::IP 0.43.2 qw(:strip :protos :versions); 28 | use NetPacket::IPv6 qw(:strip :protos :versions); 29 | use NetPacket::TCP qw(:strip); 30 | use NetPacket::UDP qw(:strip); 31 | use NetPacket::ICMP qw(:strip); 32 | use NetPacket::ICMPv6 qw(:strip); 33 | use Net::IP qw(:PROC); 34 | use POSIX qw(strftime); 35 | 36 | use vars qw($Matches); 37 | 38 | my %opts; 39 | my $version = "1.4"; 40 | my $err; 41 | my $pcap; 42 | my $dumper; 43 | my $filter; 44 | #my $filter_str = 'not host 4.5.6.1 and src host 4.5.6.7'; 45 | my $filter_str = ''; 46 | my $match_pattern = "[[:print:]]{4,}"; 47 | my $match_code = ''; 48 | 49 | getopts('htuivVWd:r:s:w:',\%opts); 50 | die "$0 v$version (c) Jim Clausing, 2009-2011\n" if ($opts{V}); 51 | usage() unless $opts{d} || $opts{r}; 52 | usage() if (($opts{d} && $opts{r}) || ($opts{u} && $opts{w}) || $opts{h}); 53 | usage() if $#ARGV > 1; 54 | 55 | if ($#ARGV >= 0) { 56 | $match_pattern = shift @ARGV; 57 | if ($#ARGV == 0) { 58 | # $filter_str .= ' and (' . shift @ARGV; 59 | # $filter_str .= ')'; 60 | $filter_str = shift @ARGV; 61 | } 62 | } 63 | 64 | $match_pattern =~ s(/)(\\)g; 65 | $match_code .= "\$Matches += " 66 | . ($opts{v}?'!':'') . "/" 67 | . ($opts{W}?'\b':'') . "$match_pattern" 68 | . ($opts{W}?'\b':'') . "/" 69 | . ($opts{i}?'i':'') . ";"; 70 | 71 | my $matcher = eval "sub { $match_code }"; 72 | 73 | if ($opts{d}) { 74 | $pcap = Net::Pcap::open_live($opts{d}, 1600, 0, 1000, \$err); 75 | } else { 76 | $pcap = Net::Pcap::open_offline($opts{r}, \$err); 77 | } 78 | 79 | 80 | die if (Net::Pcap::compile($pcap, \$filter, $filter_str, 0, 0)); 81 | Net::Pcap::setfilter($pcap, $filter); 82 | $dumper = Net::Pcap::pcap_dump_open($pcap, $opts{w}) if ($opts{w}); 83 | Net::Pcap::loop($pcap, -1, \&process_pkt, undef); 84 | Net::Pcap::pcap_dump_close($dumper) if ($opts{w}); 85 | exit(0); 86 | 87 | sub process_pkt { 88 | my ($user_data, $pcap_hdr, $pkt) = @_; 89 | 90 | my $proto; 91 | my $rec = parse_pkt($pkt); 92 | return unless $rec; 93 | $Matches = 0; 94 | $_ = $rec->{data}; 95 | &{$matcher}(); 96 | return unless $Matches; 97 | 98 | if ($opts{w}) { 99 | Net::Pcap::pcap_dump($dumper,$pcap_hdr,$pkt); 100 | } else { 101 | if (!$opts{t}) { 102 | $rec->{time} = sprintf "%s.%06d", 103 | strftime("%Y-%m-%d-%H:%M:%S", gmtime($pcap_hdr->{tv_sec})), 104 | $pcap_hdr->{tv_usec}; 105 | } else { 106 | $rec->{time} = sprintf "%d.%06d", $pcap_hdr->{tv_sec}, $pcap_hdr->{tv_usec}; 107 | } 108 | 109 | #print Dumper ($rec); 110 | if ($rec->{proto} == IP_PROTO_TCP) { 111 | $proto = "T"; 112 | } elsif ($rec->{proto} == IP_PROTO_UDP) { 113 | $proto = "U"; 114 | } elsif ($rec->{proto} == IP_PROTO_ICMP) { 115 | $proto = "I"; 116 | } elsif ($rec->{proto} == IP_PROTO_ICMPV6) { 117 | $proto = "I6"; 118 | } else { 119 | $proto = $rec->{proto}; 120 | } 121 | if ($rec->{proto} == IP_PROTO_TCP || $rec->{proto} == IP_PROTO_UDP) { 122 | print "$rec->{time} $proto $rec->{src_ip}:$rec->{src_port} -> $rec->{dst_ip}:$rec->{dst_port} "; 123 | } elsif ($rec->{proto} == IP_PROTO_ICMP || $rec->{proto} == IP_PROTO_ICMPV6) { 124 | print "$rec->{time} $proto $rec->{src_ip} -> $rec->{dst_ip} ($rec->{type}/$rec->{code}) "; 125 | } else { 126 | print "$rec->{time} $proto $rec->{src_ip} -> $rec->{dst_ip} "; 127 | } 128 | my $data = $rec->{data}; 129 | $data =~ s/\r\n$//; 130 | if ($opts{u}) { 131 | $data =~ s/([^[:alnum:][:space:]\._-])/sprintf("%%%02x",ord $1)/ge; 132 | $data =~ s/([\r\n])/sprintf("%%%02x",ord $1)/ge; 133 | } else { 134 | $data =~ s/([^[:print:][:space:]_-])/'.'/ge; 135 | } 136 | print $data; 137 | print "\n"; 138 | } 139 | 140 | } 141 | 142 | sub parse_pkt { 143 | my $pkt = shift; 144 | my $rec; 145 | my $len; 146 | my @seg_list; 147 | my $packet; 148 | my $eth_obj = NetPacket::Ethernet->decode($pkt); 149 | if ($eth_obj->{type} == ETH_TYPE_IP || $eth_obj->{type} == ETH_TYPE_IPv6 || $eth_obj->{type} == ETH_TYPE_ARP) { 150 | $packet = eth_strip($pkt); 151 | } else { 152 | $packet = $pkt; 153 | } 154 | my $ip_obj = NetPacket::IP->decode($packet); 155 | if ($ip_obj->{ver} == IP_VERSION_IPv4) { 156 | $rec->{src_ip} = $ip_obj->{src_ip}; 157 | $rec->{dst_ip} = $ip_obj->{dest_ip}; 158 | $rec->{proto} = $ip_obj->{proto}; 159 | 160 | if ($ip_obj->{proto} == IP_PROTO_UDP) { 161 | my $udp_obj = NetPacket::UDP->decode($ip_obj->{data}); 162 | return unless $udp_obj; 163 | $rec->{src_port} = $udp_obj->{src_port}; 164 | $rec->{dst_port} = $udp_obj->{dest_port}; 165 | return unless ($udp_obj->{data}); 166 | $rec->{data} = $udp_obj->{data}; 167 | } elsif ($ip_obj->{proto} == IP_PROTO_TCP) { 168 | my $tcp_obj = NetPacket::TCP->decode($ip_obj->{data}); 169 | return unless $tcp_obj; 170 | $rec->{src_port} = $tcp_obj->{src_port}; 171 | $rec->{dst_port} = $tcp_obj->{dest_port}; 172 | return unless ($tcp_obj->{data}); 173 | $rec->{data} = $tcp_obj->{data}; 174 | } elsif ($ip_obj->{proto} == IP_PROTO_ICMP) { 175 | my $icmp_obj = NetPacket::ICMP->decode($ip_obj->{data}); 176 | return unless $icmp_obj; 177 | $rec->{type} = $icmp_obj->{type}; 178 | $rec->{code} = $icmp_obj->{code}; 179 | return unless ($icmp_obj->{data}); 180 | $rec->{data} = $icmp_obj->{data}; 181 | } 182 | 183 | } elsif ($ip_obj->{ver} == IP_VERSION_IPv6) { 184 | # } else { 185 | $ip_obj = NetPacket::IPv6->decode($packet); 186 | $rec->{src_ip} = $ip_obj->{src_ip}; 187 | $rec->{dst_ip} = $ip_obj->{dest_ip}; 188 | $rec->{proto} = $ip_obj->{nxt}; 189 | 190 | while ($ip_obj->{nxt} ~~ [0,43,60]) { 191 | if ($ip_obj->{nxt} == 43) { 192 | @seg_list = (); 193 | $rec->{seg_list} = (); 194 | ($len,$rec->{seg_type},$rec->{seg_left}) = unpack('C3',substr($ip_obj->{data},1,3)); 195 | for (my $i = 0; $i < $len/2; $i++) { 196 | my @ip = unpack('N4',substr($ip_obj->{data},16*($i)+8,16)); 197 | my $ip_str = NetPacket::IPv6::int_to_hexstr(@ip); 198 | push @{$rec->{seg_list}},$ip_str; 199 | } 200 | #$rec->{seg_list} = @seg_list; 201 | } 202 | ($ip_obj->{nxt},$len) = unpack('C2',substr($ip_obj->{data},0,2)); 203 | $ip_obj->{data} = substr($ip_obj->{data},8*($len+1)); 204 | } 205 | if ($ip_obj->{nxt} == IP_PROTO_UDP) { 206 | my $udp_obj = NetPacket::UDP->decode($ip_obj->{data}); 207 | return unless $udp_obj; 208 | $rec->{src_port} = $udp_obj->{src_port}; 209 | $rec->{dst_port} = $udp_obj->{dest_port}; 210 | return unless ($udp_obj->{data}); 211 | $rec->{data} = $udp_obj->{data}; 212 | } elsif ($ip_obj->{nxt} == IP_PROTO_TCP) { 213 | my $tcp_obj = NetPacket::TCP->decode($ip_obj->{data}); 214 | return unless $tcp_obj; 215 | $rec->{src_port} = $tcp_obj->{src_port}; 216 | $rec->{dst_port} = $tcp_obj->{dest_port}; 217 | return unless ($tcp_obj->{data}); 218 | $rec->{data} = $tcp_obj->{data}; 219 | } elsif ($ip_obj->{nxt} == IP_PROTO_ICMPV6) { 220 | my $icmpv6_obj = NetPacket::ICMPv6->decode($ip_obj->{data}); 221 | return unless $icmpv6_obj; 222 | $rec->{type} = $icmpv6_obj->{type}; 223 | $rec->{code} = $icmpv6_obj->{code}; 224 | return unless ($icmpv6_obj->{data}); 225 | $rec->{data} = $icmpv6_obj->{data}; 226 | } else { 227 | $rec->{data} = $ip_obj->{data}; 228 | } 229 | } 230 | return $rec; 231 | } 232 | 233 | sub usage { 234 | print STDERR " 235 | $0 [ -hituvVW ] [ -d ifname | -r filename ] [ -w filename ] [ -s snaplen ] 236 | 237 | \t\tthe pattern to search for (if omitted behaves like strings(1)) 238 | \t-h\t\tthis message 239 | \t-d ifname\tinterface on which to listen for live capture 240 | \t-r filename\tpcap file from which to look for data 241 | \t-w filename\tpcap file to which matching data is written 242 | \t-s snaplen\tset bpf snaplen (default: 1500) 243 | \t-t\t\tuse unix timestamps for time (defaults to ISO-ish dates) 244 | \t-u\t\tUnicode encode non-printable or special characters (not valid with -w) 245 | \t-i\t\tcase insensitive 246 | \t-v\t\tinvert search (print packets not matching pattern) 247 | \t-W\t\tword match 248 | \t-V\t\tprint Version 249 | "; 250 | exit 1; 251 | } 252 | -------------------------------------------------------------------------------- /sigs.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | # 3 | # Author: Jim Clausing 4 | # Date: 2016-10-17 5 | # 6 | # Calculate hashes of files 7 | # 8 | 9 | use Digest::MD5; 10 | #use Digest::SHA1; 11 | #use Digest::SHA256; 12 | use Digest::SHA; 13 | use Getopt::Std; 14 | use Digest::SHA3; 15 | 16 | $VERSION = '1.4.0'; 17 | $i = getopts('ams235V'); 18 | 19 | die "Usage: $0 [-a][-m][-s][-M][-S][-2][-5][-V][-h] file... 20 | -a All (MD5, SHA1, SHA256, SHA512, SHA3-256) (default if no other options) 21 | -m Only MD5 signature (md5sum equiv output) 22 | -s Only SHA1 signature (sha1sum equiv output) 23 | -2 Only SHA256 signature 24 | -3 Only SHA3-256 signature 25 | -5 Only SHA512 signature (note: base64 encoded rather than hex) 26 | -V print version 27 | -h This message\n" if (defined($i) && $opt_h) || ($#ARGV==-1 && !$opt_V); 28 | die "$0 v$VERSION\nCopyright (c) 2005-2016 Jim Clausing\nIssue $0 -h for more information\n" if $opt_V; 29 | exit if $#ARGV == -1; 30 | 31 | $opt_a = 1 if (!$opt_a && !$opt_m && !$opt_s && !$opt_2 && !$opt_5 && !$opt_3); 32 | if ($opt_a) { 33 | $num_sigs = 100 34 | } else { 35 | $num_sigs = $opt_m + $opt_s + $opt_2 + $opt_5 + $opt_3; 36 | } 37 | 38 | while ($ARGV[0]) { 39 | $ARGV[0] =~ /^([-\/\@\w.]+)$/; 40 | $arg = $1; 41 | $ctx1 = Digest::MD5->new; 42 | $ctx2 = Digest::SHA->new(1); 43 | $ctx3 = Digest::SHA->new(256); 44 | $ctx4 = Digest::SHA->new(512); 45 | $ctx5 = Digest::SHA->new(512); 46 | $ctx6 = Digest::SHA3->new(256); 47 | open (FILE1, $arg); 48 | open (FILE2, $arg); 49 | open (FILE3, $arg); 50 | open (FILE4, $arg); 51 | open (FILE5, $arg); 52 | open (FILE6, $arg); 53 | binmode(FILE1); 54 | binmode(FILE2); 55 | binmode(FILE3); 56 | binmode(FILE4); 57 | binmode(FILE5); 58 | binmode(FILE6); 59 | $ctx1->addfile(*FILE1); 60 | $ctx2->addfile(*FILE2); 61 | $ctx3->addfile(*FILE3); 62 | $ctx4->addfile(*FILE4); 63 | $ctx5->addfile(*FILE5); 64 | $ctx6->addfile(*FILE6); 65 | $dig1 = $ctx1->hexdigest; 66 | $dig2 = $ctx2->hexdigest; 67 | $dig3 = $ctx3->hexdigest; 68 | $dig4 = $ctx4->hexdigest; 69 | $dig5 = $ctx5->b64digest; 70 | while (length($dig5) % 4) { 71 | $dig5 .= '='; 72 | } 73 | # Probably want to change this to b64digest if we change from SHA3-256 to SHA3-512 74 | $dig6 = $ctx6->hexdigest; 75 | # or if we change it to SHA3-512 but keep hexdigest, uncomment the following 76 | # while (length($dig6) % 4) { 77 | # $dig6 .= '='; 78 | # } 79 | close(FILE1); 80 | close(FILE2); 81 | close(FILE3); 82 | close(FILE4); 83 | close(FILE5); 84 | close(FILE6); 85 | $pre1 = ($num_sigs>1?"MD5: ":""); 86 | $pre2 = ($num_sigs>1?"SHA1: ":""); 87 | $pre3 = ($num_sigs>1?"SHA256: ":""); 88 | $pre5 = ($num_sigs>1?"SHA512: ":""); 89 | $pre6 = ($num_sigs>1?"SHA3-256: ":""); 90 | if ($opt_a) { 91 | print "$arg:\n"; 92 | print " MD5: $dig1\n"; 93 | print " SHA1: $dig2\n"; 94 | print " SHA256: $dig3\n"; 95 | # for ($i=0; $i<8; $i++) { 96 | # push (@line, substr($dig3,$i*8,8)); 97 | # } 98 | # @line = split(/ /,$dig3); 99 | # $dig3a = join(' ',@line[0..3]); 100 | # $dig3b = join(' ',@line[4..7]); 101 | # print " SHA256: $dig3a\n $dig3b\n"; 102 | @line = (); 103 | for ($i=0; $i<8; $i++) { 104 | push (@line, substr($dig4,$i*16,16)); 105 | } 106 | # @line = split(/ /,$dig4); 107 | $dig4a = join(' ',@line[0..3]); 108 | $dig4b = join(' ',@line[4..7]); 109 | print " SHA512: $dig4a\n $dig4b\n"; 110 | print " SHA512: $dig5\n"; 111 | print " SHA3-256: $dig6\n"; 112 | } else { 113 | print "$pre1$dig1\t$arg\n" if $opt_m; 114 | print "$pre2$dig2\t$arg\n" if $opt_s; 115 | print "$pre3$dig3\t$arg\n" if $opt_2; 116 | print "$pre5$dig5\t$arg\n" if $opt_5; 117 | print "$pre6$dig6\t$arg\n" if $opt_3; 118 | } 119 | shift; 120 | } 121 | -------------------------------------------------------------------------------- /sigs.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Rewrite of my perl sigs script in python. 4 | # Calculate hashes of files 5 | # 6 | # Author: Jim Clausing 7 | # Date: 2025-02-16 8 | # Version: 1.7.0 9 | 10 | from __future__ import print_function 11 | import sys 12 | import os 13 | import io 14 | import argparse 15 | 16 | if sys.version_info < (3, 6): 17 | import sha3 18 | 19 | import hashlib 20 | import base64 21 | import contextlib 22 | import codecs 23 | 24 | __version_info__ = (1, 7, 0) 25 | __version__ = ".".join(map(str, __version_info__)) 26 | 27 | @contextlib.contextmanager 28 | def smart_open(filename=None): 29 | if filename and filename != "-": 30 | fh = open(filename, "rb") 31 | else: 32 | fh = sys.stdin.buffer 33 | 34 | try: 35 | yield fh 36 | finally: 37 | if fh is not sys.stdin: 38 | fh.close() 39 | 40 | 41 | def print_header(): 42 | if args.md5 or args.all: 43 | sys.stdout.write("md5|") 44 | if args.sha1 or args.all: 45 | sys.stdout.write("sha1|") 46 | if args.sha256 or args.all: 47 | sys.stdout.write("sha256|") 48 | if args.sha512 or args.all: 49 | sys.stdout.write("sha512|") 50 | if args.sha3_224 or args.all: 51 | sys.stdout.write("sha3-224|") 52 | if args.sha3 or args.all: 53 | sys.stdout.write("sha3-384|") 54 | print("filename") 55 | 56 | def hash_file(fname): 57 | global md5, sha1, sha256, sha3_224, sha3, sha512 58 | md5 = hashlib.md5() 59 | sha1 = hashlib.sha1() 60 | sha256 = hashlib.sha256() 61 | sha3 = hashlib.sha3_384() 62 | sha3_224 = hashlib.sha3_224() 63 | sha512 = hashlib.sha512() 64 | if fname == "-" or os.access(str(fname), os.R_OK): 65 | with smart_open(fname) as f: 66 | for block in iter(lambda: f.read(args.block), b""): 67 | if args.md5 or args.all: 68 | md5.update(block) 69 | if args.sha1 or args.all: 70 | sha1.update(block) 71 | if args.sha256 or args.all: 72 | sha256.update(block) 73 | if args.sha3_224 or args.all: 74 | sha3_224.update(block) 75 | if args.sha3 or args.all: 76 | sha3.update(block) 77 | if args.sha512 or args.all: 78 | sha512.update(block) 79 | 80 | def print_hashes(fname): 81 | if fname == "-" or os.access(str(fname), os.R_OK): 82 | if hashcnt == 1: 83 | if args.md5: 84 | print(md5.hexdigest() + " " + (fname if fname != "-" else "")) 85 | elif args.sha1: 86 | print(sha1.hexdigest() + " " + (fname if fname != "-" else "")) 87 | elif args.sha256: 88 | print(sha256.hexdigest() + " " + (fname if fname != "-" else "")) 89 | elif args.sha512: 90 | print(codecs.decode(base64.b64encode(sha512.digest())) + " " + (fname if fname != "-" else "")) 91 | elif args.sha3_224: 92 | print(sha3_224.hexdigest() + " " + (fname if fname != "-" else "")) 93 | elif args.sha3: 94 | print(sha3.hexdigest() + " " + (fname if fname != "-" else "")) 95 | elif args.psv: 96 | if args.md5 or args.all: 97 | sys.stdout.write(md5.hexdigest() + "|") 98 | if args.sha1 or args.all: 99 | sys.stdout.write(sha1.hexdigest() + "|") 100 | if args.sha256 or args.all: 101 | sys.stdout.write(sha256.hexdigest() + "|") 102 | if args.sha512 or args.all: 103 | sys.stdout.write(codecs.decode(base64.b64encode(sha512.digest())) + "|") 104 | if args.sha3_224 or args.all: 105 | sys.stdout.write(sha3_224.hexdigest() + "|") 106 | if args.sha3 or args.all: 107 | sys.stdout.write(sha3.hexdigest() + "|") 108 | print(fname) 109 | else: 110 | if fname != "-": 111 | print(fname + ":") 112 | if args.md5 or args.all: 113 | print(" MD5: " + md5.hexdigest()) 114 | if args.sha1 or args.all: 115 | print(" SHA1: " + sha1.hexdigest()) 116 | if args.sha256 or args.all: 117 | print(" SHA256: " + sha256.hexdigest()) 118 | if args.sha512 or args.all: 119 | print(" SHA512: " + codecs.decode(base64.b64encode(sha512.digest()))) 120 | if args.sha3_224 or args.all: 121 | print(" SHA3-224: " + sha3_224.hexdigest()) 122 | if args.sha3 or args.all: 123 | print(" SHA3-384: " + sha3.hexdigest()) 124 | else: 125 | if hashcnt == 1: 126 | if args.md5: 127 | print("(Permission Problem)" + " " + fname) 128 | elif args.sha1: 129 | print("(Permission Problem)" + " " + fname) 130 | elif args.sha256: 131 | print("(Permission Problem)" + " " + fname) 132 | elif args.sha512: 133 | print("(Permission Problem)" + " " + fname) 134 | elif args.sha3_224: 135 | print("(Permission Problem)" + " " + fname) 136 | elif args.sha3: 137 | print("(Permission Problem)" + " " + fname) 138 | elif args.psv: 139 | if args.md5 or args.all: 140 | sys.stdout.write("(Permission Problem)" + "|") 141 | if args.sha1 or args.all: 142 | sys.stdout.write("(Permission Problem)" + "|") 143 | if args.sha256 or args.all: 144 | sys.stdout.write("(Permission Problem)" + "|") 145 | if args.sha512 or args.all: 146 | sys.stdout.write("(Permission Problem)" + "|") 147 | if args.sha3_224 or args.all: 148 | sys.stdout.write("(Permission Problem)" + "|") 149 | if args.sha3 or args.all: 150 | sys.stdout.write("(Permission Problem)" + "|") 151 | print(fname) 152 | else: 153 | print(fname + ":") 154 | if args.md5 or args.all: 155 | print(" MD5: " + "(Permission Problem)") 156 | if args.sha1 or args.all: 157 | print(" SHA1: " + "(Permission Problem)") 158 | if args.sha256 or args.all: 159 | print(" SHA256: " + "(Permission Problem)") 160 | if args.sha512 or args.all: 161 | print(" SHA512: " + "(Permission Problem)") 162 | if args.sha3_224 or args.all: 163 | print(" SHA3-224: " + "(Permission Problem)") 164 | if args.sha3 or args.all: 165 | print(" SHA3-384: " + "(Permission Problem)") 166 | 167 | def count_hashes(): 168 | global hashcnt 169 | hashcnt = 0 170 | if args.all: 171 | hashcnt = 6 172 | if args.md5: 173 | hashcnt += 1 174 | if args.sha1: 175 | hashcnt += 1 176 | if args.sha256: 177 | hashcnt += 1 178 | if args.sha3: 179 | hashcnt += 1 180 | if args.sha3_224: 181 | hashcnt += 1 182 | if args.sha512: 183 | hashcnt += 1 184 | 185 | def check_hashes(): 186 | failures = 0 187 | for path in args.files: 188 | if os.path.isfile(path) or path == "-": 189 | with smart_open(path) as f: 190 | for line in f: 191 | line = line.decode('utf-8') 192 | line = line.strip('\n') 193 | parts = str(line).split(" ") 194 | if len(parts[0]) == 32: 195 | args.md5 = True 196 | elif len(parts[0]) == 40: 197 | args.sha1 = True 198 | elif len(parts[0]) == 64: 199 | args.sha256 = True 200 | elif len(parts[0]) == 96: 201 | args.sha3 = True 202 | elif len(parts[0]) == 56: 203 | args.sha3_224 = True 204 | elif len(parts[0]) == 88: 205 | args.sha512 = True 206 | count_hashes() 207 | if os.path.isfile(parts[1]): 208 | hash_file(parts[1]) 209 | else: 210 | print(parts[1], ": File not found") 211 | break 212 | if len(parts[0]) == 32: 213 | if args.md5 and (parts[0] == md5.hexdigest()): 214 | print (parts[1] + ": OK") 215 | else: 216 | print (parts[1] + ": FAILED") 217 | failures += 1 218 | if len(parts[0]) == 40: 219 | if args.sha1 and (parts[0] == sha1.hexdigest()): 220 | print (parts[1] + ": OK") 221 | else: 222 | print (parts[1] + ": FAILED") 223 | failures += 1 224 | if len(parts[0]) == 64: 225 | if args.sha256 and (parts[0] == sha256.hexdigest()): 226 | print (parts[1] + ": OK") 227 | else: 228 | print (parts[1] + ": FAILED") 229 | failures += 1 230 | if len(parts[0]) == 96: 231 | if args.sha3 and (parts[0] == sha3.hexdigest()): 232 | print (parts[1] + ": OK") 233 | else: 234 | print (parts[1] + ": FAILED") 235 | failures += 1 236 | if len(parts[0]) == 56: 237 | if args.sha3_224 and (parts[0] == sha3_224.hexdigest()): 238 | print (parts[1] + ": OK") 239 | else: 240 | print (parts[1] + ": FAILED") 241 | failures += 1 242 | if len(parts[0]) == 88: 243 | if args.sha512 and (parts[0] == codecs.decode(base64.b64encode(sha512.digest()))): 244 | print (parts[1] + ": OK") 245 | else: 246 | print (parts[1] + ": FAILED") 247 | failures += 1 248 | if failures > 0: 249 | print (sys.argv[0] + ": WARNING: " + str(failures) + " checksums did not match") 250 | sys.exit(255) 251 | 252 | 253 | if __name__ == "__main__": 254 | # define switches and commandline arguments 255 | parser = argparse.ArgumentParser(description="Calculate hashes") 256 | parser.add_argument("files", metavar="FILE", nargs="*", default="-", help="files to hash") 257 | parser.add_argument( 258 | "-V", "--version", action="version", help="print version number", version="%(prog)s v" + __version__ 259 | ) 260 | parser.add_argument( 261 | "-r", "--recursive", action="store_true", help="recursive mode. All subdirectories are traversed" 262 | ) 263 | parser.add_argument( 264 | "-a", 265 | "--all", 266 | action="store_true", 267 | help="All (MD5, SHA1, SHA256, SHA512, and SHA3-384), default if no other options chosen", 268 | default="true", 269 | ) 270 | parser.add_argument("-m", "--md5", action="store_true", help="MD5 signature (md5sum equivalent output)") 271 | parser.add_argument("-s", "--sha1", action="store_true", help="SHA1 signature (sha1sum equivalent output)") 272 | parser.add_argument( 273 | "-2", "--sha256", action="store_true", help="SHA2 (aka SHA2-256) signature (sha256sum equivalent output)" 274 | ) 275 | parser.add_argument("-3", "--sha3", action="store_true", help="SHA3-384 signature") 276 | parser.add_argument("-t", "--sha3_224", action="store_true", help="SHA3-224 signature") 277 | parser.add_argument( 278 | "-5", 279 | "--sha512", 280 | action="store_true", 281 | help="SHA512 (aka SHA2-512) signature (note: base64 encoded rather than hex)", 282 | ) 283 | parser.add_argument("-f", "--fullpath", action="store_true", help="print full path rather than relative") 284 | parser.add_argument( 285 | "-B", "--block", metavar="blk", type=int, default=65536, help="block size to read file, default = 65536" 286 | ) 287 | parser.add_argument("-c", "--check", action="store_true", help="read sums from FILE and check them") 288 | #parser.add_argument("-b", "--base", action="store_true", help="match only basename, only valid with -c") 289 | parser.add_argument("-p", "--psv", action="store_true", help="write output as pipe separated values") 290 | args = parser.parse_args() 291 | 292 | # if any hash switches are specified turn -a off 293 | if args.md5 or args.sha1 or args.sha256 or args.sha3 or args.sha3_224 or args.sha512 or args.check: 294 | args.all = False 295 | #if args.base and not args.check: 296 | # print("-b not valid without -c") 297 | # sys.exit(255) 298 | 299 | if args.psv: 300 | print_header() 301 | 302 | if args.check: 303 | check_hashes() 304 | sys.exit(0) 305 | 306 | # count whether a non-zero number of hashes are specified (affects output format) 307 | count_hashes() 308 | 309 | # process commandline arguments 310 | for path in args.files: 311 | if os.path.isdir(os.path.abspath(path)) and args.recursive: 312 | if args.fullpath: 313 | path = os.path.abspath(path) 314 | for root, directories, filenames in os.walk(path): 315 | for filename in filenames: 316 | fname = os.path.join(root, filename) 317 | if os.path.isfile(fname): 318 | hash_file(fname) 319 | print_hashes(fname) 320 | else: 321 | if os.path.isfile(path) or path == "-": 322 | hash_file(path) 323 | print_hashes(path) 324 | 325 | sys.exit(0) 326 | -------------------------------------------------------------------------------- /tcp-honeypot.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=tcp-honeypot service 3 | After=network.target 4 | 5 | [Service] 6 | ExecStart=/usr/local/bin/tcp-honeypot-3.py 7 | KillMode=process 8 | Restart=on-failure 9 | RestartSec=95s 10 | 11 | [Install] 12 | WantedBy=multi-user.target 13 | -------------------------------------------------------------------------------- /tln_parse.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Description: parse.exe wasn't cutting it for me and wasn't doing much, so 4 | # I figured I'd replace it with a python script 5 | # 6 | # Author: Jim Clausing 7 | # Date: 2021-01-07 8 | # 9 | 10 | import sys 11 | import os 12 | import argparse 13 | from datetime import * 14 | from time import * 15 | import contextlib 16 | import codecs 17 | import chardet 18 | 19 | __version_info__ = (0, 1, 1) 20 | __version__ = ".".join(map(str, __version_info__)) 21 | 22 | 23 | @contextlib.contextmanager 24 | def smart_open(filename=None): 25 | # KAPE made the TLN file a UTF-16-LE file, this detects that and sets encoding accordingly 26 | if filename and filename != "-": 27 | fh = open(filename, "r") 28 | rawdata = open(filename, "rb").read() 29 | result = chardet.detect(rawdata) 30 | charenc = result["encoding"] 31 | fh.close() 32 | fh = open(filename, "r", encoding=charenc) 33 | else: 34 | fh = sys.stdin 35 | 36 | try: 37 | yield fh 38 | finally: 39 | if fh is not sys.stdin: 40 | fh.close() 41 | 42 | 43 | def parse_line(line): 44 | line = line.rstrip() 45 | i = line.find(",") 46 | if i <= 0: 47 | l = line.split("|") 48 | l[0] = datetime.utcfromtimestamp(int(l[0])).strftime("%Y-%m-%d %H:%M:%S") 49 | print(",".join(l)) 50 | 51 | 52 | if __name__ == "__main__": 53 | parser = argparse.ArgumentParser(description="Parse/Transform TLN files") 54 | parser.add_argument("files", metavar="FILE", nargs="*", default="-", help="TLN file") 55 | 56 | args = parser.parse_args() 57 | 58 | for path in args.files: 59 | with smart_open(path) as f: 60 | for line in f: 61 | parse_line(line) 62 | 63 | sys.exit(0) 64 | --------------------------------------------------------------------------------