Changeset 1658
- Timestamp:
- 11/12/06 16:40:29 (2 years ago)
- Files:
-
- psad/branches/sigdevel/psad (modified) (19 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
psad/branches/sigdevel/psad
r1656 r1658 1044 1044 ### sid matching, Netfilter logging prefixes and chains, etc.) 1045 1045 'fwsnort_sid' => 0, 1046 ' nf_chain'=> '',1047 ' nf_log_prefix'=> '',1046 'chain' => '', 1047 'log_prefix' => '', 1048 1048 'dshield_str' => '', 1049 1049 'syslog_host' => '', … … 1153 1153 $scan{$pkt{'src'}}{$pkt{'dst'}}{'absnum'}++; 1154 1154 $scan{$pkt{'src'}}{$pkt{'dst'}}{'chain'} 1155 {$pkt{' nf_chain'}}{$pkt{'intf'}}{$pkt{'proto'}}++;1155 {$pkt{'chain'}}{$pkt{'intf'}}{$pkt{'proto'}}++; 1156 1156 $curr_scan{$pkt{'src'}}{$pkt{'dst'}}{$pkt{'proto'}}{'pkts'}++; 1157 1157 $curr_scan{$pkt{'src'}}{$pkt{'dst'}} … … 1166 1166 {$pkt{'syslog_host'}} = '' if $pkt{'syslog_host'}; 1167 1167 1168 if ($pkt{' nf_log_prefix'}) {1168 if ($pkt{'log_prefix'}) { 1169 1169 ### see if the logging prefix matches the blocking 1170 1170 ### regex, and if not the IP will not be blocked … … 1174 1174 ### we require a match 1175 1175 if (not defined $auto_block_regex_match{$pkt{'src'}} 1176 and $pkt{' nf_log_prefix'} =~ /$config{'AUTO_BLOCK_REGEX'}/) {1176 and $pkt{'log_prefix'} =~ /$config{'AUTO_BLOCK_REGEX'}/) { 1177 1177 $auto_block_regex_match{$pkt{'src'}} = ''; 1178 1178 } 1179 1179 } 1180 1180 } else { 1181 $pkt{' nf_log_prefix'} = '*noprfx*';1181 $pkt{'log_prefix'} = '*noprfx*'; 1182 1182 } 1183 1183 1184 1184 ### keep track of Netfilter chain and logging prefix 1185 1185 $curr_scan{$pkt{'src'}}{$pkt{'dst'}}{$pkt{'proto'}}{'chain'} 1186 {$pkt{' nf_chain'}}{$pkt{'nf_log_prefix'}}++;1186 {$pkt{'chain'}}{$pkt{'log_prefix'}}++; 1187 1187 1188 1188 unless ($pkt{'proto'} eq 'icmp') { … … 1246 1246 ### found a snort sid in the packet log message 1247 1247 my $dl = &add_snort_sid($pkt{'src'}, $pkt{'dst'}, 1248 $pkt{' nf_chain'}, $pkt{'proto'}, $pkt{'fwsnort_sid'});1248 $pkt{'chain'}, $pkt{'proto'}, $pkt{'fwsnort_sid'}); 1249 1249 $curr_sids_dl{$pkt{'src'}} = $dl if $dl; 1250 1250 } else { … … 1303 1303 ### "kernel:" string is preceded by .*). 1304 1304 if ($pkt_str =~ /.*kernel:\s+(.*?)\s*IN=/) { 1305 $pkt_hr->{' nf_log_prefix'} = $1;1306 if ($pkt_hr->{' nf_log_prefix'} =~ /\S/) {1305 $pkt_hr->{'log_prefix'} = $1; 1306 if ($pkt_hr->{'log_prefix'} =~ /\S/) { 1307 1307 if ($config{'IGNORE_LOG_PREFIXES'} ne 'NONE') { 1308 return $PKT_IGNORE if $pkt_hr->{' nf_log_prefix'}1308 return $PKT_IGNORE if $pkt_hr->{'log_prefix'} 1309 1309 =~ m|$config{'IGNORE_LOG_PREFIXES'}|; 1310 1310 } 1311 $ipt_prefixes{$pkt_hr->{' nf_log_prefix'}}++;1311 $ipt_prefixes{$pkt_hr->{'log_prefix'}}++; 1312 1312 } 1313 1313 } … … 1571 1571 my $pkt_hr = shift; 1572 1572 1573 my $dl = 0; 1574 1573 1575 ### always run the IP protocol sigs 1574 1576 for my $proto ($pkt_hr->{'proto'}, 'ip') { … … 1636 1638 ### and sp/dp, so match any Snort 1637 1639 ### keywords 1638 &match_snort_keywords($pkt_hr,1640 my $dl_tmp = &match_snort_keywords($pkt_hr, 1639 1641 $dp_hr->{$dp_s}->{$dp_e}); 1642 1643 ### return maximal danger level from all 1644 ### signature matches 1645 $dl = $dl_tmp if $dl_tmp > $dl; 1640 1646 } 1641 1647 } … … 1646 1652 ### now we have the set of applicable icmp 1647 1653 ### signatures that match the sip/dip 1648 &match_snort_keywords($pkt_hr,1654 my $dl_tmp = &match_snort_keywords($pkt_hr, 1649 1655 $sig_search{$proto}{$src}{$dst}); 1650 1656 1651 } 1652 } 1653 } 1654 } 1655 return 0; 1657 ### return maximal danger level from all signature matches 1658 $dl = $dl_tmp if $dl_tmp > $dl; 1659 } 1660 } 1661 } 1662 } 1663 return $dl; 1656 1664 } 1657 1665 … … 1659 1667 my ($pkt_hr, $sigs_ids_hr) = @_; 1660 1668 1661 print ".......match_snort_keywords()\n"; 1669 print STDERR "[+] match_snort_keywords()\n" if $debug; 1670 1671 my $dl = 0; 1662 1672 1663 1673 ### see if all Snort keywords match the packet … … 1671 1681 ### values (at least for ipv4, see 1672 1682 ### linux/net/ipv4/netfilter/ipt_LOG.c) 1673 next SIG unless &match_snort_ip_keywords($pkt_hr, $sig_hr); 1683 my $dl_tmp = &match_snort_ip_keywords($pkt_hr, $sig_hr); 1684 next SIG unless $dl_tmp; 1685 1686 $dl = $dl_tmp if $dl_tmp > $dl; 1674 1687 1675 1688 if ($sig_hr->{'proto'} eq 'tcp') { 1676 1689 1677 &match_snort_tcp_keywords($pkt_hr, $sig_hr); 1678 1690 $dl_tmp = &match_snort_tcp_keywords($pkt_hr, $sig_hr); 1691 if ($dl_tmp) { 1692 $dl = $dl_tmp if $dl_tmp > $dl; 1693 1694 $scan{$pkt_hr->{'src'}}{$pkt_hr->{'dst'}}{'tcp'}{'curr_sig'} 1695 {$pkt_hr->{'sid'}}{$pkt_hr->{'chain'}}{'dp'} 1696 {$pkt_hr->{'dp'}}++; 1697 1698 $scan{$pkt_hr->{'src'}}{$pkt_hr->{'dst'}}{'tcp'}{'curr_sig'} 1699 {$pkt_hr->{'sid'}}{$pkt_hr->{'chain'}}{'flags'} 1700 {$pkt_hr->{'dp'}} = $pkt_hr->{'flags'}; 1701 1702 } 1679 1703 } elsif ($sig_hr->{'proto'} eq 'udp') { 1680 1704 1681 &match_snort_udp_keywords($pkt_hr, $sig_hr); 1682 1705 $dl_tmp = &match_snort_udp_keywords($pkt_hr, $sig_hr); 1706 if ($dl_tmp) { 1707 $dl = $dl_tmp if $dl_tmp > $dl; 1708 1709 $scan{$pkt_hr->{'src'}}{$pkt_hr->{'dst'}}{'udp'}{'curr_sig'} 1710 {$pkt_hr->{'sid'}}{$pkt_hr->{'chain'}}{'dp'} 1711 {$pkt_hr->{'dp'}}++; 1712 } 1683 1713 } elsif ($sig_hr->{'proto'} eq 'icmp') { 1684 1714 1685 &match_snort_icmp_keywords($pkt_hr, $sig_hr); 1686 } 1687 } 1688 1689 return; 1715 ### validate icmp type and code fields against the official values 1716 ### in RFC 792. See %inval_type_code for corresponding signature 1717 ### message text and danger levels. 1718 my $type_code_rv = &check_icmp_type($pkt_hr->{'itype'}, 1719 $pkt_hr->{'icode'}); 1720 if ($type_code_rv == 1) { ### bad type 1721 1722 $dl = 2 if $dl < 2; 1723 1724 $scan{$pkt_hr->{'src'}}{$pkt_hr->{'dst'}}{'icmp'} 1725 {'invalid_type'}{$pkt_hr->{'itype'}} 1726 {$pkt_hr->{'chain'}}{'pkts'}++; 1727 1728 } elsif ($type_code_rv == 2) { 1729 1730 $dl = 2 if $dl < 2; 1731 1732 $scan{$pkt_hr->{'src'}}{$pkt_hr->{'dst'}}{'icmp'} 1733 {'invalid_code'}{$pkt_hr->{'itype'}}{$pkt_hr->{'icode'}} 1734 {$pkt_hr->{'chain'}}{'pkts'}++; 1735 } 1736 $dl = $dl_tmp if $dl_tmp > $dl; 1737 1738 $dl_tmp = &match_snort_icmp_keywords($pkt_hr, $sig_hr); 1739 if ($dl_tmp) { 1740 $dl = $dl_tmp if $dl_tmp > $dl; 1741 1742 $scan{$pkt_hr->{'src'}}{$pkt_hr->{'dst'}}{'icmp'}{'curr_sig'} 1743 {$sid}{$pkt_hr->{'chain'}}{'pkts'}++; 1744 } 1745 } 1746 1747 } 1748 return $dl; 1690 1749 } 1691 1750 … … 1694 1753 1695 1754 if (defined $sig_hr->{'flags'}) { 1696 return unless $pkt_hr->{'flags'} eq $sig_hr->{'flags'};1697 } 1698 1699 return unless &check_sig_int_range(1755 return 0 unless $pkt_hr->{'flags'} eq $sig_hr->{'flags'}; 1756 } 1757 1758 return 0 unless &check_sig_int_range( 1700 1759 ($pkt_hr->{'ip_len'}-$IP_HEADER_LEN-$TCP_HEADER_LEN), 1701 1760 'dsize', $sig_hr 1702 1761 ); 1703 1762 1704 return unless &check_sig_int_range(1763 return 0 unless &check_sig_int_range( 1705 1764 ($pkt_hr->{'ip_len'}-$IP_HEADER_LEN-$TCP_HEADER_LEN), 1706 1765 'psad_dsize', $sig_hr 1707 1766 ); 1708 1767 1709 return unless &check_sig_int_range($pkt_hr->{'win'}, 'window', $sig_hr);1710 return unless &check_sig_int_range($pkt_hr->{'tcp_seq'}, 'seq', $sig_hr);1711 return unless &check_sig_int_range($pkt_hr->{'tcp_ack'}, 'ack', $sig_hr);1768 return 0 unless &check_sig_int_range($pkt_hr->{'win'}, 'window', $sig_hr); 1769 return 0 unless &check_sig_int_range($pkt_hr->{'tcp_seq'}, 'seq', $sig_hr); 1770 return 0 unless &check_sig_int_range($pkt_hr->{'tcp_ack'}, 'ack', $sig_hr); 1712 1771 1713 1772 ### matched the signature 1714 print "..... matched tcp keywords: $sig_hr->{'sid'} $sig_hr->{'psad_id'}\n"; 1715 return; 1773 if ($debug) { 1774 print STDERR "[+] packet matched matched tcp keywords for sid: ", 1775 "$sig_hr->{'sid'} (psad_id: $sig_hr->{'psad_id'})\n"; 1776 } 1777 return $sig_hr->{'dl'}; 1716 1778 } 1717 1779 … … 1719 1781 my ($pkt_hr, $sig_hr) = @_; 1720 1782 1721 return unless &check_sig_int_range(1783 return 0 unless &check_sig_int_range( 1722 1784 ($pkt_hr->{'udp_len'}-$UDP_HEADER_LEN), 1723 1785 'dsize', $sig_hr 1724 1786 ); 1725 1787 1726 return unless &check_sig_int_range(1788 return 0 unless &check_sig_int_range( 1727 1789 ($pkt_hr->{'udp_len'}-$UDP_HEADER_LEN), 1728 1790 'psad_dsize', $sig_hr … … 1730 1792 1731 1793 ### matched the signature 1732 print "..... matched udp keywords: $sig_hr->{'sid'} $sig_hr->{'psad_id'}\n"; 1733 return; 1794 if ($debug) { 1795 print STDERR "[+] packet matched udp keywords for sid: ", 1796 "$sig_hr->{'sid'} (psad_id: $sig_hr->{'psad_id'})\n"; 1797 } 1798 return $sig_hr->{'dl'}; 1734 1799 } 1735 1800 … … 1737 1802 my ($pkt_hr, $sig_hr) = @_; 1738 1803 1739 return unless &check_sig_int_range(1804 return 0 unless &check_sig_int_range( 1740 1805 ($pkt_hr->{'ip_len'}-$IP_HEADER_LEN-$ICMP_HEADER_LEN), 1741 1806 'dsize', $sig_hr 1742 1807 ); 1743 1808 1744 return unless &check_sig_int_range(1809 return 0 unless &check_sig_int_range( 1745 1810 ($pkt_hr->{'ip_len'}-$IP_HEADER_LEN-$ICMP_HEADER_LEN), 1746 1811 'psad_dsize', $sig_hr 1747 1812 ); 1748 1813 1749 return unless &check_sig_int_range($pkt_hr->{'itype'}, 'itype', $sig_hr);1750 return unless &check_sig_int_range($pkt_hr->{'icode'}, 'icode', $sig_hr);1751 return unless &check_sig_int_range($pkt_hr->{'icmp_seq'}, 'icmp_seq', $sig_hr);1752 return unless &check_sig_int_range($pkt_hr->{'icmp_id'}, 'icmp_id', $sig_hr);1814 return 0 unless &check_sig_int_range($pkt_hr->{'itype'}, 'itype', $sig_hr); 1815 return 0 unless &check_sig_int_range($pkt_hr->{'icode'}, 'icode', $sig_hr); 1816 return 0 unless &check_sig_int_range($pkt_hr->{'icmp_seq'}, 'icmp_seq', $sig_hr); 1817 return 0 unless &check_sig_int_range($pkt_hr->{'icmp_id'}, 'icmp_id', $sig_hr); 1753 1818 1754 1819 ### matched the signature 1755 print "..... matched icmp keywords: $sig_hr->{'sid'} $sig_hr->{'psad_id'}\n"; 1756 return; 1820 if ($debug) { 1821 print STDERR "[+] packet matched icmp keywords for sid: ", 1822 "$sig_hr->{'sid'} (psad_id: $sig_hr->{'psad_id'})\n"; 1823 } 1824 return $sig_hr->{'dl'}; 1757 1825 } 1758 1826 … … 1773 1841 if ($sig_hr->{'proto'} eq 'ip') { 1774 1842 ### signature match 1775 print "$sig_hr->{'sid'} sig proto: $sig_hr->{'proto'} packet proto: $pkt_hr->{'proto'}\n"; 1776 } 1777 1843 if ($debug) { 1844 print STDERR "[+] packet matched ip keywords for sid: ", 1845 "$sig_hr->{'sid'} (psad_id: $sig_hr->{'psad_id'})\n"; 1846 } 1847 return $sig_hr->{'dl'} 1848 } 1778 1849 return 1; 1779 1850 } … … 1812 1883 } 1813 1884 return 0; 1814 }1815 1816 1817 sub old_match_sigs() {1818 my ($src, $dst, $chain, $sp, $dp, $proto,1819 $flags, $len, $ttl, $type, $code, $id, $seq) = @_;1820 1821 my $dl = 0;1822 if ($proto eq 'tcp') {1823 for my $sid (keys %{$sigs{'tcp'}}) {1824 next unless defined $sigs{'tcp'}{$sid}{'flags'};1825 if (&check_port($sp, $dp, $sigs{'tcp'}{$sid})1826 and $flags eq $sigs{'tcp'}{$sid}{'flags'}1827 and &check_src($chain, $src, $sigs{'tcp'}{$sid}{'src'})1828 and &check_dst($chain, $dst, $sigs{'tcp'}{$sid}{'dst'})) {1829 ### future1830 # && &check_misc_fields($sid, $proto, $len, $ttl)) {1831 ### tripped a tcp signature1832 print STDERR "[+] match_sigs(): matched tcp $dp,$sp,$flags, ",1833 "sid: $sid\n" if $debug;1834 if ($dl < $sigs{$sid}{'dl'}) {1835 $dl = $sigs{$sid}{'dl'};1836 }1837 $scan{$src}{$dst}{$proto}{'curr_sig'}1838 {$sid}{$chain}{'dp'}{$dp}++;1839 $scan{$src}{$dst}{$proto}{'curr_sig'}1840 {$sid}{$chain}{'flags'}{$dp} = $flags;1841 }1842 }1843 } elsif ($proto eq 'udp') {1844 for my $sid (keys %{$sigs{'udp'}}) {1845 if (&check_src($chain, $src, $sigs{'udp'}{$sid}{'src'})1846 and &check_dst($chain, $dst, $sigs{'udp'}{$sid}{'dst'})1847 and &check_port($sp, $dp, $sigs{'udp'}{$sid})) {1848 # && &check_misc_fields($sid, $proto, $len, $ttl)) {1849 ### tripped a udp signature1850 print STDERR "[+] match_sigs(): matched udp $dp,$sp, ",1851 "sid: $sid\n" if $debug;1852 if ($dl < $sigs{$sid}{'dl'}) {1853 $dl = $sigs{$sid}{'dl'};1854 }1855 $scan{$src}{$dst}{$proto}{'curr_sig'}1856 {$sid}{$chain}{'dp'}{$dp}++;1857 }1858 }1859 } elsif ($proto eq 'icmp') {1860 ### check icmp type and code fields against the official values1861 ### in RFC 792. See %inval_type_code for corresponding signature1862 ### message text and danger levels.1863 my $type_code_rv = &check_icmp_type($type, $code);1864 if ($type_code_rv == 1) { ### bad type1865 if ($dl < 2) {1866 $dl = 2; ### FIXME: hard-coded as dl 2 for now.1867 }1868 $scan{$src}{$dst}{'icmp'}{'invalid_type'}1869 {$type}{$chain}{'pkts'}++;1870 } elsif ($type_code_rv == 2) {1871 if ($dl < 2) {1872 $dl = 2; ### FIXME: hard-coded as dl 2 for now.1873 }1874 $scan{$src}{$dst}{'icmp'}{'invalid_code'}1875 {$type}{$code}{$chain}{'pkts'}++;1876 }1877 for my $sid (keys %{$sigs{'icmp'}}) {1878 if (&check_src($chain, $src, $sigs{'icmp'}{$sid}{'src'})1879 and &check_dst($chain, $dst, $sigs{'icmp'}{$sid}{'dst'})1880 and &check_icmp_sig($sid, $ttl, $type, $code,1881 $id, $seq)) {1882 print STDERR "[+] match_sigs(): matched icmp sid: $sid\n"1883 if $debug;1884 if ($dl < $sigs{$sid}{'dl'}) {1885 $dl = $sigs{$sid}{'dl'};1886 }1887 $scan{$src}{$dst}{'icmp'}{'curr_sig'}1888 {$sid}{$chain}{'pkts'}++;1889 }1890 }1891 }1892 return $dl;1893 1885 } 1894 1886 … … 3267 3259 3268 3260 ### psad danger level 3261 $sig{'dl'} = 2; ### default danger level 3269 3262 if ($rule_options =~ /psad_dl:\s*(\d+)/) { 3270 3263 $sig{'dl'} = $1; 3271 } else {3272 die "[*] import_signatures(): could not find ",3273 qq|"psad_dl" on line: $line_num|;3274 3264 } 3275 3265 … … 4322 4312 if (defined $curr_scan_hr->{$src}->{$dst}->{'tcp'}->{'chain'}) { 4323 4313 &print_chains_and_prefixes( 4324 $curr_scan_hr->{$src}->{$dst}->{'tcp'}->{'chain'}, 4325 $fh 4314 $curr_scan_hr->{$src}->{$dst}->{'tcp'}->{'chain'}, $fh 4326 4315 ); 4327 4316 }
