Changeset 1655

Show
Ignore:
Timestamp:
11/12/06 14:11:14 (2 years ago)
Author:
mbr
Message:

bugfix for negative port and integer range matches, simplified calling convention for check_sig_int_range() to just pass in the signature hash key (from there the start, end, and negative keys are inferred)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • psad/branches/sigdevel/psad

    r1652 r1655  
    15951595                            ### normal match on the starting port value 
    15961596                            next SP_S unless $pkt_hr->{'sp'} >= $sp_s; 
    1597                         } else { 
    1598                             ### negative match on the starting port value 
    1599                             next SP_S unless $pkt_hr->{'sp'} < $sp_s; 
    16001597                        } 
    16011598 
     
    16071604                            } else { 
    16081605                                ### negative match on the ending port value 
    1609                                 next SP_E unless $pkt_hr->{'sp'} > $sp_e; 
     1606                                ### (note the "or" condition) 
     1607                                next SP_E unless ($pkt_hr->{'sp'} > $sp_e 
     1608                                    or $pkt_hr->{'sp'} < $sp_s); 
    16101609                            } 
    16111610 
     
    16181617                                if ($dp_type eq 'norm') { 
    16191618                                    next DP_S unless $pkt_hr->{'dp'} >= $dp_s; 
    1620                                 } else { 
    1621                                     next DP_S unless $pkt_hr->{'dp'} < $dp_s; 
    16221619                                } 
    16231620 
     
    16261623                                        next DP_E unless $pkt_hr->{'dp'} <= $dp_e; 
    16271624                                    } else { 
    1628                                         next DP_E unless $pkt_hr->{'dp'} > $dp_e; 
     1625                                        ### negative match on the ending port value 
     1626                                        ### (note the "or" condition) 
     1627                                        next DP_E unless ($pkt_hr->{'dp'} > $dp_e 
     1628                                            or $pkt_hr->{'dp'} < $dp_s); 
    16291629                                    } 
    16301630 
     
    17011701    } 
    17021702 
    1703     return unless &check_range_match('dsize', 
    1704             $pkt_hr->{'ip_len'}-$IP_HEADER_LEN-$TCP_HEADER_LEN, $sig_hr); 
    1705     return unless &check_range_match('psad_dsize', 
    1706             $pkt_hr->{'ip_len'}-$IP_HEADER_LEN-$TCP_HEADER_LEN, $sig_hr); 
    1707  
    1708     return unless &check_range_match('window', $pkt_hr->{'win'}, $sig_hr); 
    1709     return unless &check_range_match('seq', $pkt_hr->{'tcp_seq'}, $sig_hr); 
    1710     return unless &check_range_match('ack', $pkt_hr->{'tcp_ack'}, $sig_hr); 
     1703    return unless &check_sig_int_range( 
     1704            ($pkt_hr->{'ip_len'}-$IP_HEADER_LEN-$TCP_HEADER_LEN), 
     1705            'dsize', $sig_hr 
     1706    ); 
     1707 
     1708    return unless &check_sig_int_range( 
     1709            ($pkt_hr->{'ip_len'}-$IP_HEADER_LEN-$TCP_HEADER_LEN), 
     1710            'psad_dsize', $sig_hr 
     1711    ); 
     1712 
     1713    return unless &check_sig_int_range($pkt_hr->{'win'}, 'window', $sig_hr); 
     1714    return unless &check_sig_int_range($pkt_hr->{'tcp_seq'}, 'seq', $sig_hr); 
     1715    return unless &check_sig_int_range($pkt_hr->{'tcp_ack'}, 'ack', $sig_hr); 
    17111716 
    17121717    ### matched the signature 
     
    17181723    my ($pkt_hr, $sig_hr) = @_; 
    17191724 
    1720     return unless &check_range_match('dsize', 
    1721             $pkt_hr->{'udp_len'}-$UDP_HEADER_LEN, $sig_hr); 
    1722  
    1723     return unless &check_range_match('psad_dsize', 
    1724             $pkt_hr->{'udp_len'}-$UDP_HEADER_LEN, $sig_hr); 
     1725    return unless &check_sig_int_range( 
     1726            ($pkt_hr->{'udp_len'}-$UDP_HEADER_LEN), 
     1727            'dsize', $sig_hr 
     1728    ); 
     1729 
     1730    return unless &check_sig_int_range( 
     1731            ($pkt_hr->{'udp_len'}-$UDP_HEADER_LEN), 
     1732            'psad_dsize', $sig_hr 
     1733    ); 
    17251734 
    17261735    ### matched the signature 
     
    17321741    my ($pkt_hr, $sig_hr) = @_; 
    17331742 
    1734     return unless &check_range_match('dsize', 
    1735             $pkt_hr->{'ip_len'}-$IP_HEADER_LEN-$ICMP_HEADER_LEN, $sig_hr); 
    1736     return unless &check_range_match('psad_dsize', 
    1737             $pkt_hr->{'ip_len'}-$IP_HEADER_LEN-$ICMP_HEADER_LEN, $sig_hr); 
    1738     return unless &check_range_match('itype', $pkt_hr->{'itype'}, $sig_hr); 
    1739     return unless &check_range_match('icode', $pkt_hr->{'icode'}, $sig_hr); 
    1740     return unless &check_range_match('icmp_seq', $pkt_hr->{'icmp_seq'}, $sig_hr); 
    1741     return unless &check_range_match('icmp_id', $pkt_hr->{'icmp_id'}, $sig_hr); 
     1743    return unless &check_sig_int_range( 
     1744            ($pkt_hr->{'ip_len'}-$IP_HEADER_LEN-$ICMP_HEADER_LEN), 
     1745            'dsize', $sig_hr 
     1746    ); 
     1747 
     1748    return unless &check_sig_int_range( 
     1749            ($pkt_hr->{'ip_len'}-$IP_HEADER_LEN-$ICMP_HEADER_LEN), 
     1750            'psad_dsize', $sig_hr 
     1751    ); 
     1752 
     1753    return unless &check_sig_int_range($pkt_hr->{'itype'}, 'itype', $sig_hr); 
     1754    return unless &check_sig_int_range($pkt_hr->{'icode'}, 'icode', $sig_hr); 
     1755    return unless &check_sig_int_range($pkt_hr->{'icmp_seq'}, 'icmp_seq', $sig_hr); 
     1756    return unless &check_sig_int_range($pkt_hr->{'icmp_id'}, 'icmp_id', $sig_hr); 
    17421757 
    17431758    ### matched the signature 
     
    17491764    my ($pkt_hr, $sig_hr) = @_; 
    17501765 
    1751     return 0 unless &check_range_match('ttl', $pkt_hr->{'ttl'}, $sig_hr); 
    1752     return 0 unless &check_range_match('id', $pkt_hr->{'ip_id'}, $sig_hr); 
     1766    return 0 unless &check_sig_int_range($pkt_hr->{'ttl'}, 'ttl', $sig_hr); 
     1767    return 0 unless &check_sig_int_range($pkt_hr->{'ip_id'}, 'id', $sig_hr); 
    17531768 
    17541769    if ($pkt_hr->{'proto'} =~ m|\d|) { 
    1755         return 0 unless &check_range_match('ip_proto'
    1756             $pkt_hr->{'proto'}, $sig_hr); 
     1770        return 0 unless &check_sig_int_range($pkt_hr->{'proto'}
     1771                'ip_proto', $sig_hr); 
    17571772    } 
    17581773 
     
    17601775} 
    17611776 
    1762 sub check_range_match() { 
    1763     my ($keyword, $pkt_val, $sig_hr) = @_; 
     1777sub check_sig_int_range() { 
     1778    my ($pkt_val, $keyword, $sig_hr) = @_; 
    17641779 
    17651780    ### if the Snort signature does not have this keyword then 
     
    17681783 
    17691784    if ($sig_hr->{"${keyword}_neg"}) { 
    1770         return 0 if $pkt_val > $sig_hr->{"${keyword}_s"}; 
    1771         return 0 if $pkt_val < $sig_hr->{"${keyword}_e"}
     1785        return 0 if ($pkt_val <= $sig_hr->{"${keyword}_e"} 
     1786            and $pkt_val >= $sig_hr->{"${keyword}_s"})
    17721787    } else { 
     1788        ### normal match 
    17731789        return 0 if $pkt_val < $sig_hr->{"${keyword}_s"}; 
    17741790        return 0 if $pkt_val > $sig_hr->{"${keyword}_e"}; 
     
    31983214 
    31993215            ### assign the source and destination port ranges 
    3200             &build_sig_int_range(\%sig, 'sp', 'sp_s', 'sp_e', 
    3201                     'sp_neg', 1, 65535, $line_num); 
    3202             &build_sig_int_range(\%sig, 'dp', 'dp_s', 'dp_e', 
    3203                     'dp_neg', 1, 65535, $line_num); 
     3216            &build_sig_int_range(\%sig, 'sp', 1, 65535, $line_num); 
     3217            &build_sig_int_range(\%sig, 'dp', 1, 65535, $line_num); 
    32043218 
    32053219        } else { 
     
    32643278        if ($rule_options =~ /[\s;]psad_dsize:\s*(.+?)\s*;/i) { 
    32653279            $sig{'psad_dsize'} = $1; 
    3266             &build_sig_int_range(\%sig, 'psad_dsize', 'psad_dsize_s', 
    3267                     'psad_dsize_e', 'psad_dsize_neg', 1, 1514, $line_num); 
     3280            &build_sig_int_range(\%sig, 'psad_dsize', 1, 1514, $line_num); 
    32683281        } 
    32693282 
     
    32713284        if ($rule_options =~ /[\s;]dsize:\s*(.+?)\s*;/i) { 
    32723285            $sig{'dsize'} = $1; 
    3273             &build_sig_int_range(\%sig, 'dsize', 'dsize_s', 
    3274                     'dsize_e', 'dsize_neg', 1, 1514, $line_num); 
     3286            &build_sig_int_range(\%sig, 'dsize', 1, 1514, $line_num); 
    32753287        } 
    32763288 
     
    32783290        if ($rule_options =~ /[\s;]ttl:\s*(.+?)\s*;/i) { 
    32793291            $sig{'ttl'} = $1; 
    3280             &build_sig_int_range(\%sig, 'ttl', 'ttl_s', 'ttl_e', 
    3281                     'ttl_neg', 1, 255, $line_num); 
     3292            &build_sig_int_range(\%sig, 'ttl', 1, 255, $line_num); 
    32823293        } 
    32833294 
     
    32853296        if ($rule_options =~ /[\s;]id:\s*(.+?)\s*;/i) { 
    32863297            $sig{'id'} = $1; 
    3287             &build_sig_int_range(\%sig, 'id', 'id_s', 'id_e', 
    3288                     'id_neg', 1, 65535, $line_num); 
     3298            &build_sig_int_range(\%sig, 'id', 1, 65535, $line_num); 
    32893299        } 
    32903300 
     
    33283338            if ($rule_options =~ /[\s;]seq:\s*(.+?)\s*;/i) { 
    33293339                $sig{'seq'} = $1; 
    3330                 &build_sig_int_range(\%sig, 'seq', 
    3331                         'seq_s', 'seq_e', 'seq_neg', 1, 
     3340                &build_sig_int_range(\%sig, 'seq', 1, 
    33323341                        4294967296, $line_num); 
    33333342            } 
     
    33363345            if ($rule_options =~ /[\s;]ack:\s*(.+?)\s*;/i) { 
    33373346                $sig{'ack'} = $1; 
    3338                 &build_sig_int_range(\%sig, 'ack', 
    3339                         'ack_s', 'ack_e', 'ack_neg', 1, 
     3347                &build_sig_int_range(\%sig, 'ack', 1, 
    33403348                        4294967296, $line_num); 
    33413349            } 
     
    33443352            if ($rule_options =~ /[\s;]window:\s*(.+?)\s*;/i) { 
    33453353                $sig{'window'} = $1; 
    3346                 &build_sig_int_range(\%sig, 'window', 
    3347                         'window_s', 'window_e', 'window_neg', 1, 
     3354                &build_sig_int_range(\%sig, 'window', 1, 
    33483355                        65535, $line_num); 
    33493356            } 
     
    33553362            if ($rule_options =~ /[\s;]itype:\s*(.+?)\s*;/i) { 
    33563363                $sig{'itype'} = $1; 
    3357                 &build_sig_int_range(\%sig, 'itype', 
    3358                         'itype_s', 'itype_e', 'itype_neg', 1, 
     3364                &build_sig_int_range(\%sig, 'itype', 1, 
    33593365                        255, $line_num); 
    33603366            } 
    33613367            if ($rule_options =~ /[\s;]icode:\s*(.+?)\s*;/i) { 
    33623368                $sig{'icode'} = $1; 
    3363                 &build_sig_int_range(\%sig, 'icode', 
    3364                         'icode_s', 'icode_e', 'icode_neg', 1, 
     3369                &build_sig_int_range(\%sig, 'icode', 1, 
    33653370                        255, $line_num); 
    33663371            } 
     
    33683373                $sig{'icmp_seq'} = $1; 
    33693374                &build_sig_int_range(\%sig, 'icmp_seq', 
    3370                         'icmp_seq_s', 'icmp_seq_e', 'icmp_seq_neg', 
    33713375                        1, 255, $line_num); 
    33723376            } 
     
    33823386                $sig{'ip_proto'} = $1; 
    33833387                &build_sig_int_range(\%sig, 'ip_proto', 
    3384                         'ip_proto_s', 'ip_proto_e', 'ip_proto_neg', 
    33853388                        1, 255, $line_num); 
    33863389            } 
     
    34223425        print STDERR "[+] Main signatures hash:\n"; 
    34233426        print STDERR Dumper \%sig_search; 
     3427        print STDERR Dumper \%sigs; 
    34243428    } 
    34253429    &Psad::psyslog('psad', "imported $sig_ctr psad Snort signatures") 
     
    35143518 
    35153519sub build_sig_int_range() { 
    3516     my ($sig_hr, $field_key, $start_key, $end_key, $neg_key, 
    3517         $range_start, $range_end, $line_num) = @_; 
    3518  
    3519     my $val = $sig_hr->{$field_key}; 
     3520    my ($sig_hr, $keyword, $range_start, $range_end, $line_num) = @_; 
     3521 
     3522    my $start_key = "${keyword}_s"; 
     3523    my $end_key   = "${keyword}_e"; 
     3524    my $neg_key   = "${keyword}_neg"; 
     3525 
     3526    my $val = $sig_hr->{$keyword}; 
    35203527 
    35213528    ### resolve any embedded vars 
     
    35273534        if (defined $config{$sub_var}) { 
    35283535            $val =~ s|\$\w+|$config{$sub_var}|; 
    3529             $sig_hr->{$field_key} = $val; 
     3536            $sig_hr->{$keyword} = $val; 
    35303537        } else { 
    35313538            die qq|[*] import_signatures(): sub-var "$sub_var" at line: |, 
     
    35493556        $sig_hr->{$start_key} = $1; 
    35503557        $sig_hr->{$end_key}   = $2; 
     3558    } elsif ($val =~ m|^\s*\<=\s*(\d+)|) { 
     3559        $sig_hr->{$end_key} = $1; 
    35513560    } elsif ($val =~ m|^\s*\<\s*(\d+)|) { 
    35523561        $sig_hr->{$end_key} = $1-1; 
     3562    } elsif ($val =~ m|^\s*\>=\s*(\d+)|) { 
     3563        $sig_hr->{$start_key} = $1; 
    35533564    } elsif ($val =~ m|^\s*\>\s*(\d+)|) { 
    35543565        $sig_hr->{$start_key} = $1+1;