Started a test with opnsense, my other test is utilizing some Mikrotik’s with firewalling.

Will post my findings below .. hold on
Started a test with opnsense, my other test is utilizing some Mikrotik’s with firewalling.
Will post my findings below .. hold on
Observe. Hack. Make. also known as OHM, was an outdoor hacker conference that took place in the Netherlands from July 31 to August 4, 2013
Note to myself: Add more text to this lazy bastard!
Sound Firewall V2
See also
https://www.henriaanstoot.nl/2001/08/11/sound-firewall/
See also 2nd Firewall 2013 and Led Firewall
https://www.henriaanstoot.nl/2013/08/03/ohm-2013-hackerevent/
While partying @ HAL2001, a hackers event, Venom and I made a Soundfirewall.
We had a little DMZ, with our servers.
This was protected by a iptables firewall.
Our idea was to get a sound notification on every (interesting) network packet the firewall dropped.
So we made this: (At the bottom are the sound definitions.)
Example of the sound we heared whole day.
#use strict; # @(#) First Edit: Bas # @(#) Last Edit: Fash use POSIX ":sys_wait_h"; use vars qw(%Msg_Rec); $SIG{'TERM'} = $SIG{'HUP'} = 'goodbye'; $SIG{'CHLD'} = 'IGNORE'; ## Constants my $BELL = ""; my $MAILER = "/usr/sbin/sendmail"; my $WRITE = "/usr/bin/write"; $/ = " "; autoflush STDOUT; sub goodbye { $| = 0; close_pipe_if_open(); exit(0); } # # in_range($range, $number) # returns 1 if $number is inside $range, 0 if not # sub in_range { my $range = shift; my $num = shift; foreach my $f (split(/,/, $range)) { if ($f =~ /-/) { my ($low,$high) = split(/-/, $f); return 1 if ($low <= $num and $num <= $high); } elsif ($f == $num) { return 1; } } return 0; } # # inside_time_window($days,$hours) # returns 1 if inside window, 0 if outside window # sub inside_time_window { my $range = shift; my($days, $hours) = split(/:/, $range); my ($hr, $wday) = (localtime(time))[2,6]; if (($days eq '*' or in_range($days, $wday)) and ($hours eq '*' or in_range($hours, $hr))) { return 1; } else { return 0; } } print "\n*** swatch-3.0.1 (pid:6826) started at " . `/bin/date` . "\n"; use Date::Calc qw(:all); sub parse_dot { my $message = shift; my $dot_loc = shift; my @dot = (); my @ranges = split(/:/, $dot_loc); foreach my $range (0..$#ranges) { if ($ranges[$range] != -1) { my ($begin, $end) = split(/-/, $ranges[$range]); $dot[$range] = substr($message, $begin, ($end - $begin + 1)); } } return @dot; } my ($date_loc, $time_loc) = ("-1:0-2:4-5", "7-8:10-11:13-14"); my %months = ( Jan => 1, Feb => 2, Mar => 3, Apr => 4, May => 5, Jun => 6, Jul => 7, Aug => 8, Sep => 9, Oct => 10, Nov => 11, Dec => 12 ); # Returns an array of year, month, day, hours, minutes, and seconds. # sub YMDHMS { my $string = shift; my $year_today = (Today())[0]; my ($y, $m, $d) = parse_dot($string, $date_loc); my ($hrs, $mins, $secs) = parse_dot($string, $time_loc); if (length($y) eq 0) { $y = (Today())[0] }; return ($y, $months{$m}, $d, $hrs, $mins, $secs); } sub new_msg { my $use = shift; my $msg = shift; my $count = shift; my @delta = @_; my $delta; if ($delta[0] == 0) { $delta = sprintf("%d:%.2d:%.2d", $delta[1], $delta[2], $delta[3]); } else { $delta = sprintf("$delta[0] day%s %d:%.2d:%.2d", $delta[0] > 1 ? 's' : '', $delta[1], $delta[2], $delta[3]); } if ($use eq 'regex') { return "$count $msg regular expressions in $delta"; } else { return "$count in $delta: $msg"; } } # # Stores message information in # $Msg_Rec = ( # {<truncated message>|<pattern>} => { # dhms => [ array ], # days,hours,minutes,seconds # count => integer, sub throttle { my %opts = ( KEY => $_, CUT_MARKS => [ "0:16" ], # not used yet USE => 'message', @_ ); my $msg = $opts{'KEY'}; my $use = $opts{'USE'}; my @ymdhms = YMDHMS($msg); my $key; my @min_dhms_delta = split(/(\s+|:)/, $opts{'MIN_DELTA'}); foreach my $i (0..$#min_dhms_delta) { # strip out unwanted element splice (@min_dhms_delta, $i, 1) if ($min_dhms_delta[$i] eq ":"); } if ($use eq 'regex') { $key = $opts{'REGEX'}; } else { $key = substr($msg, 16); $key =~ s/\[\d+\]/[PID]/; } while ($#min_dhms_delta < 3) { unshift(@min_dhms_delta, 0); # make sure that the dhms array is full } if (exists $Msg_Rec{$key} and defined $Msg_Rec{$key}->{ymdhms}) { my $passed = 1; $Msg_Rec{$key}->{count}++; if ($ymdhms[1] > $Msg_Rec{$key}->{ymdhms}[1]) { $ymdhms[0]--; } my @delta_dhms = Delta_DHMS(@{$Msg_Rec{$key}->{ymdhms}}, @ymdhms); foreach my $i (0..$#min_dhms_delta) { $passed = 0 if ($delta_dhms[$i] < $min_dhms_delta[$i]); last unless ($delta_dhms[$i] == $min_dhms_delta[$i]); } if ($passed) { my $new = ''; $new = new_msg($use, $key, $Msg_Rec{$key}->{count}, @delta_dhms); $Msg_Rec{$key}->{ymdhms} = [ @ymdhms ]; $Msg_Rec{$key}->{count} = 1; return $new; } else { return ''; } } else { my $rec; $rec->{ymdhms} = [ @ymdhms ]; $Msg_Rec{$key} = $rec; return $msg; } } ## ## ACTION SUBROUTINES ## my %text_modes = ( "black" => "\033[30;1m", "red" => "\033[31;1m", "green" => "\033[32;1m", "yellow" => "\033[33;1m", "blue" => "\033[34;1m", "magenta" => "\033[35;1m", "cyan" => "\033[36;1m", "white" => "\033[37;1m", "black_h" => "\033[40;1m", "red_h" => "\033[41;1m", "green_h" => "\033[42;1m", "yellow_h" => "\033[43;1m", "blue_h" => "\033[44;1m", "magenta_h" => "\033[45;1m", "cyan_h" => "\033[46;1m", "white_h" => "\033[47;1m", "bold" => "\033[1m", "blink" => "\033[5m", "inverse" => "\033[7m", "normal" => "\033[0m", "underscore" => "\033[4m", ); sub echo { my %args = ( 'MODES' => [ 'normal' ], @_ ); return if (exists($args{'WHEN'}) and not inside_time_window($args{'WHEN'})); if ($args{'MODES'}[0] eq 'random') { my @mode_names = keys %text_modes; print $text_modes{$mode_names[rand $#mode_names]}; } else { foreach my $mode (@{$args{'MODES'}}) { print $text_modes{$mode}; } } print $args{'MESSAGE'}; print $text_modes{'normal'}; print "\n"; } # # ring_bell(args) -- send x number of control-G characters to the output. # sub ring_bell { my %args = ( 'RINGS' => 1, @_ ); my $sun_terminal = (`uname -s` eq 'SunOS\n'); return if exists($args{'WHEN'}) and not inside_time_window($args{'WHEN'}); my $bells = $args{'RINGS'}; for ( ; $bells > 0 ; $bells-- ) { print $BELL; sleep 1 if $sun_terminal; # SunOS needed this. Not sure about Solaris though } } # # exec_command(args) -- fork and execute a command # sub exec_command { my %args = (@_); my $exec_pid; my $command; if (exists $args{'COMMAND'}) { $command = $args{'COMMAND'}; } else { warn "$0: No command was specified in exec action.\n"; return; } return if exists($args{'WHEN'}) and not inside_time_window($args{'WHEN'}); EXECFORK: { if ($exec_pid = fork) { waitpid(-1, WNOHANG); return; } elsif (defined $exec_pid) { exec($command); } elsif ($! =~ /No more processes/) { # EAGAIN, supposedly recoverable fork error sleep 5; redo EXECFORK; } else { warn "$0: Can't fork to exec $command: $!\n"; } } return; } { my $pipe_is_open; my $current_command_name; # # send_message_to_pipe -- send text to a pipe. # # usage: &send_message_to_pipe($program_to_pipe_to_including_the_vertical_bar_symbol, # $message_to_send_to_the_pipe); # sub send_message_to_pipe { my %args = (@_); my $command; if (exists $args{'COMMAND'}) { $command = $args{'COMMAND'}; } else { warn "$0: No command was specified in pipe action.\n"; return; } return if exists($args{'WHEN'}) and not inside_time_window($args{'WHEN'}); # open a new pipe if necessary if ( !$pipe_is_open or $current_command_name ne $command ) { # first close an open pipe close(PIPE) if $pipe_is_open; $pipe_is_open = 0; open(PIPE, "| $command") or warn "$0: cannot open pipe to $command: $!\n" && return; PIPE->autoflush(1); $pipe_is_open = 1; $current_command_name = $command; } # send the text print PIPE "$args{'MESSAGE'}"; if (not exists $args{'KEEP_OPEN'}) { close(PIPE) if $pipe_is_open; $pipe_is_open = 0; } } # # close_pipe_if_open -- used at the end of a script to close a pipe # opened by &pipe_it(). # # usage: &close_pipe_if_open(); # sub close_pipe_if_open { if ($pipe_is_open) { close(PIPE); } } } # # send_email -- send some mail using $MAILER. # # usage: &send_email($addresses_to_mail_to); # sub send_email { my $login = (getpwuid($<))[0]; my %args = ( 'ADDRESSES' => $login, 'SUBJECT' => 'Message from Swatch', @_ ); return if exists($args{'WHEN'}) and not inside_time_window($args{'WHEN'}); my $addresses = $args{'ADDRESSES'}; $addresses =~ s/:/,/g; if ($MAILER eq '') { warn "ERROR: $0 cannot find a mail delivery program\n"; return; } open(MAIL, "| $MAILER $addresses") or warn "$0: cannot open pipe to $MAILER: $!\n" && return; print MAIL "To: $addresses\n"; print MAIL "Subject: $args{SUBJECT}\n\n"; print MAIL "$args{'MESSAGE'}\n"; close(MAIL); } # # write_message -- use $WRITE to send a message logged on users. # sub write_message { my %args = (@_); return if exists($args{'WHEN'}) and not inside_time_window($args{'WHEN'}); if ($WRITE eq '') { warn "ERROR: $0 cannot find the write(1) program\n"; return; } if (exists($args{'USERS'})) { foreach my $user (split(/:/, $args{'USERS'})) { send_message_to_pipe(COMMAND => "$WRITE $user 2>/dev/null", MESSAGE => "$args{'MESSAGE'}\n"); } } } use File::Tail; my $Filename = '/var/log/ulog/syslogemu.log'; my $File = File::Tail->new(name=>$Filename, maxinterval => 1, interval => 1); if (not defined $File) { die "/usr/local/bin/swatch: cannot read input \"$Filename\": $!\n"; } LOOP: while (defined($_=$File->read)) { chomp; my $sanitized_ = $_; @_ = split; # quote all special shell chars $sanitized_ =~ s/([;&\(\)\|\^><\$`'\\])/\\$1/g; my @sanitized_ = split(/\s+/, $sanitized_); if (/INVALID|REPEATED|INCOMPLETE:LOGIN/) { echo('MODES' => [ "bold", ], 'MESSAGE' => "$_", ); ring_bell('RINGS' => "3", ); next; } if (/(panic|halt)/) { echo('MESSAGE' => "$_", ); ring_bell(); next; } if (/Regents/) { echo('MODES' => [ "bold", ], 'MESSAGE' => "$_", ); ring_bell(); next; } if (/ipfw:.*Deny ICMP:8.0/) { echo('MODES' => [ "bold", ], 'MESSAGE' => "$_", ); exec_command('COMMAND' => "mpg123 -q /root/wavs/drip.wav &", ); next; } if (/ipfw:.*Deny TCP .*:6000/) { echo('MODES' => [ "bold", ], 'MESSAGE' => "$_", ); exec_command('COMMAND' => "mpg123 -q /root/wavs/camera.wav &", ); next; } if (/ipfw:.*Deny UDP .*:513/) { echo('MODES' => [ "bold", ], 'MESSAGE' => "$_", ); exec_command('COMMAND' => "mpg123 -q /root/wavs/flush.wav &", ); next; } if (/ipfw:.*Deny TCP .*:21/) { echo('MODES' => [ "bold", ], 'MESSAGE' => "$_", ); exec_command('COMMAND' => "mpg123 -q /root/wavs/vault.wav &", ); next; } if (/PROTO=TCP .*DPT=80/) { echo('MODES' => [ "bold", ], 'MESSAGE' => "$_", ); exec_command('COMMAND' => "mpg123 /root/wavs/tcp80.mp3 &", ); next; } if (/PROTO=TCP .*DPT=23/) { echo('MODES' => [ "bold", ], 'MESSAGE' => "$_", ); exec_command('COMMAND' => "mpg123 /root/wavs/tcp23.mp3 &", ); next; } if (/UDP .*=1300007/) { echo('MODES' => [ "bold", ], 'MESSAGE' => "$_", ); exec_command('COMMAND' => "mpg123 /root/wavs/udp137.mp3 &", ); next; } if (/PROTO=ICMP/) { echo('MODES' => [ "bold", ], 'MESSAGE' => "$_", ); exec_command('COMMAND' => "mpg123 /root/wavs/ping.mp3 &", ); next; } if (/.*/) { echo('MESSAGE' => "$_", ); next; } }
Above is a picture of a Box with leds which lightup when certain network packets are seen on the network.
It is connected to the parallel port of a PC (using port 0x3bc)
Makefile:
CC=gcc CCOPT=-O2 -I/usr/include/pcap LIBS=-lpcap all: netled netled: netled.c $(CC) $(CCOPT) -o netled netled.c $(LIBS)
netled.c code ( older version, i will upload a newer if found)
#include <stdio.h> #include <pcap.h> #include <netinet/in.h> #include <sys/io.h> #include <sys/time.h> #include <signal.h> #include "ether.h" #include "ethertype.h" #include "ip.h" #include "tcp.h" #define LP_PORT 0x3bc #define CAPLEN 64 #define DELAY 30000 char *program_name; static pcap_t *pd; const u_char *snapend; u_char leds = 0; int mode = 0; long packets; void do_leds() { mode ^= 1; if(!leds && mode) return; if(mode) { outb(leds, LP_PORT); leds = 0; } else { outb(0, LP_PORT); } } int do_tcp(register const u_char *bp) { register const struct tcphdr *tp; u_int16_t sport, dport; tp = (struct tcphdr *)bp; sport = ntohs(tp->th_sport); dport = ntohs(tp->th_dport); if (sport == 22 || dport == 22) { leds |= 8; } return; } int do_ip(register const u_char *bp, register u_int length) { register const struct ip *ip; register u_int hlen, len, len0, off; register const u_char *cp; ip = (const struct ip *)bp; if ((u_char *)(ip + 1) > snapend || length < sizeof (struct ip)) { return; } hlen = IP_HL(ip) * 4; if (hlen < sizeof (struct ip)) { fprintf(stderr, "bad-hlen %d\n", hlen); return; } len = ntohs(ip->ip_len); if (length < len) (void)printf("truncated-ip - %d bytes missing!", len - length); len -= hlen; len0 = len; off = ntohs(ip->ip_off); if ((off & 0x1fff) == 0) { cp = (const u_char *)ip + hlen; switch(ip->ip_p) { case IPPROTO_TCP: // fprintf(stderr, "TCP!\n"); leds |= 128; do_tcp(cp); break; case IPPROTO_UDP: // fprintf(stderr, "UDP!\n"); leds |= 64; break; case IPPROTO_ICMP: // fprintf(stderr, "ICMP!\n"); leds |= 32; break; default: fprintf(stderr, "HUH? [ip_proto: %i]\n", ip->ip_p); break; } } } void handler(u_char *user, const struct pcap_pkthdr *h, const u_char *p) { u_int caplen = h->caplen; u_int length = h->len; u_short ether_type; register const struct ether_header *ep; u_short extracted_ethertype; if (caplen < ETHER_HDRLEN) { printf("c: [%d] e: [%d]\n", caplen, ETHER_HDRLEN); return; } ep = (struct ether_header *)p; ether_type = ntohs(ep->ether_type); snapend = p + caplen; p += ETHER_HDRLEN; length -= ETHER_HDRLEN; if (ether_type > ETHERMTU) { switch (ether_type) { case ETHERTYPE_ARP: case ETHERTYPE_REVARP: // leds |= 8; // fprintf(stderr, "(R)ARP\n"); break; case ETHERTYPE_IP: // fprintf(stderr, "IP!\n"); do_ip(p, length); break; default: fprintf(stderr, "HUH? [et: %i]\n", ether_type); } } } int main(int argc, char *argv[]) { char *device; char ebuf[PCAP_ERRBUF_SIZE]; register char *cp; u_char *pcap_userdata; void *sig_old; struct itimerval timer_old, timer_new; if ((cp = (char *)strrchr(argv[0], '/')) != NULL) program_name = cp + 1; else program_name = argv[0]; if(ioperm(LP_PORT,3,1)) error("IOPEEEEERM!\n"); sig_old = signal(SIGALRM, do_leds); if (sig_old == SIG_ERR) error("SIGNAAAAAAAAAAAAAL!\n"); timer_new.it_value.tv_usec = DELAY; timer_new.it_value.tv_sec = 0; timer_new.it_interval.tv_usec = DELAY; timer_new.it_interval.tv_sec = 0; if(setitimer(ITIMER_REAL, &timer_new, &timer_old)) error("SETITIMEEEEEER!\n"); device = pcap_lookupdev(ebuf); if (device == NULL) error("%s", ebuf); pd = pcap_open_live(device, CAPLEN, 1, 1000, ebuf); if (pd == NULL) error("%s", ebuf); if (pcap_loop(pd, -1, handler, pcap_userdata) < 0) { (void)fprintf(stderr, "%s: pcap_loop: %s\n", program_name, pcap_geterr(pd)); exit(1); } return 0; }