Changeset 1165
- Timestamp:
- 07/03/08 19:06:27 (5 months ago)
- Files:
-
- fwknop/trunk/ChangeLog (modified) (1 diff)
- fwknop/trunk/fwknop (modified) (8 diffs)
- fwknop/trunk/fwknopd (modified) (3 diffs)
- fwknop/trunk/test/fwknop_test.pl (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
fwknop/trunk/ChangeLog
r1163 r1165 1 1 fwknop-1.9.6 (07//2008): 2 - SPA packets are base64-encoded by the fwknop client, and this encoding 3 pads data with '=' chars until the total length of the encoded data is a 4 multiple of four. This characteristic can be used within a Snort rule 5 to assist in the detection of SPA communications. The 1.9.6 release of 6 fwknop strips out these padding characters before the client sends an 7 SPA packet, and the fwknopd server adds them back in (to form a multiple 8 of four) before base64 decoding the packet data. This reduces the level 9 of identifying information in SPA packets and therefore makes it more 10 difficult to detect the usage of SPA for service access. For reference, 11 a Snort rule that would detect SPA packets via the trailing '=' chars 12 (previous to this release) would be: 13 14 alert udp any any -> any 62201 (msg:"fwknop SPA traffic"; \ 15 dsize:>150; pcre:"/==$/"; sid:20080001; rev:1;) 16 17 - According to the 'file' command (via it's 'magic') database, files that 18 are encrypted with GnuPG begin with 0x8502, and this is true for SPA 19 packets generated by fwknop (previous to this release). In 20 fwknop-1.9.6, the "hQ" prefix is removed by the fwknop client and added 21 back in by the fwknopd server if it doesn't exist. This measure is 22 another effort to make SPA packets more difficult to detect on the wire, 23 such as with the following Snort rule: 24 25 alert udp any any -> any 62201 (msg:"fwknop GnuPG encrypted SPA 26 traffic"; content:"hQ"; depth:2; dsize:>1000; sid:20080003; rev:1;) 27 2 28 - (Test suite): Added the ability to explicitly run major classes of tests 3 29 with two new command line arguments to the fwknop_test.pl script: fwknop/trunk/fwknop
r1163 r1165 103 103 my $knock_dst_pre_resolve = ''; 104 104 my $selected_random_nat_port = 0; 105 my $include_base64_trailing_equals = 0; 106 my $include_base64_gnupg_prefix = 0; 105 107 my $rand_port = 0; ### for SPA packet destination port 106 108 my $NAT_rand_port = 0; ### for randomized access based on … … 509 511 } 510 512 513 my $encrypted_msg = ''; 511 514 if ($gpg_signing_key or $gpg_default_key) { 512 return &pcap_GPG_encrypt_msg($msg); 513 } 514 return &pcap_Rijndael_encrypt_msg($msg); 515 $encrypted_msg = &pcap_GPG_encrypt_msg($msg); 516 } else { 517 $encrypted_msg = &pcap_Rijndael_encrypt_msg($msg); 518 } 519 520 unless ($include_base64_trailing_equals) { 521 print "[+] Stripping trailing equals chars from base64 encoding.\n" 522 if $debug; 523 $encrypted_msg =~ s/=*$//; 524 } 525 526 return $encrypted_msg; 515 527 } 516 528 … … 777 789 my $encoded_msg = encode_base64($ctext, ''); 778 790 791 if ($verbose and $debug) { 792 print "[+] base64-encoded message before stripping identifying chars:\n", 793 $encoded_msg, "\n"; 794 } 795 796 unless ($include_base64_gnupg_prefix) { 797 print "[+] Stripping encoded '0x8502' prefix (hQ) from ", 798 "outgoing encoded SPA packet.\n" if $debug; 799 $encoded_msg =~ s/^hQ//; 800 ### perl -MMIME::Base64 -e 'print encode_base64("\x85\x02\n")' 801 ### The 'magic' database (via the 'file') command identifies GnuPG 802 ### encrypted files as starting with 0x8502 803 } 804 779 805 print "[+] Encrypted message: $encoded_msg\n" if $debug; 780 806 return $encoded_msg; … … 784 810 my $msg = shift; 785 811 786 my $cipher = Crypt::CBC->new( 787 { 788 'key' => $enc_key, 789 'cipher' => $enc_alg, 790 } 791 ); 812 my $cipher = Crypt::CBC->new({ 813 'key' => $enc_key, 814 'cipher' => $enc_alg, 815 }); 792 816 793 817 my $encrypted_msg = $cipher->encrypt($msg); … … 800 824 801 825 my $encoded_msg = encode_base64($encrypted_msg, ''); 826 827 if ($verbose and $debug) { 828 print "[+] base64-encoded message before stripping identifying chars:\n", 829 $encoded_msg, "\n"; 830 } 802 831 803 832 ### Crypt::CBC adds the string "Salted__" to the beginning of the … … 809 838 ### string "U2FsdGVkX1" over UDP port 62201). 810 839 unless ($include_salted) { 811 print "[+] Stripping encoded Salted__prefix (U2FsdGVkX1) from ",840 print "[+] Stripping encoded 'Salted__' prefix (U2FsdGVkX1) from ", 812 841 "outgoing encoded SPA packet.\n" if $debug; 813 842 $encoded_msg =~ s/^U2FsdGVkX1//; ### encoded "Salted__" string … … 1510 1539 'Home-dir=s' => \$cmdl_homedir, 1511 1540 'Include-salted' => \$include_salted, 1541 'Include-equals' => \$include_base64_trailing_equals, 1512 1542 'Test-mode' => \$test_mode, 1513 1543 'LC_ALL=s' => \$locale, … … 1801 1831 PERMIT_CLIENT_TIMEOUT in access.conf on the 1802 1832 fwknopd server side). 1803 --I , --Include-salted- Include the encoded "Salted__" prefix; this1833 --Include-salted - Include the encoded "Salted__" prefix; this 1804 1834 is only necessary for older versions of the 1805 1835 fwknopd server (< 1.9.2). 1836 --Include-equals - Include the trailing "=" chars used by 1837 base64 encoding scheme; this is only 1838 necessary for older versions of the fwknopd 1839 server (< 1.9.6). 1840 --Include-gpg-prefix - Include the base64-encoded "hQ" prefix that 1841 GnuPG includes by default; this is only 1842 necessary for older versions of the fwknopd 1843 server (< 1.9.6). 1806 1844 --Save-dst - Save the command line args for this 1807 1845 invocation against the destination to the fwknop/trunk/fwknopd
r1163 r1165 2150 2150 my $gpg_sign_id = ''; 2151 2151 2152 my $equals_padding = &base64_equals_padding($msg); 2153 2154 if ($equals_padding) { 2155 print STDERR localtime() . " [+] Padding base64-encoded message ", 2156 "with '$equals_padding'.\n" if $debug; 2157 $msg .= $equals_padding; 2158 } 2159 2160 unless ($msg =~ /^hQ/) { 2161 print STDERR localtime() . " [+] Adding 'hQ' prefix to ", 2162 "base64-encoded message.\n" if $debug; 2163 $msg = 'hQ' . $msg; 2164 } 2165 2152 2166 print STDERR localtime() . " [+] Attempting GnuPG decrypt...\n" if $debug; 2153 2167 if ($debug and $verbose) { … … 2265 2279 unless ($msg =~ /^U2FsdGVkX1/) { 2266 2280 if ($debug) { 2267 print STDERR localtime() . " [+] Adding encoded Salted__prefix ",2281 print STDERR localtime() . " [+] Adding encoded 'Salted__' prefix ", 2268 2282 "(U2FsdGVkX1) to incoming encoded SPA packet.\n" 2269 2283 } 2270 2284 $msg = 'U2FsdGVkX1' . $msg; 2285 } 2286 2287 my $equals_padding = &base64_equals_padding($msg); 2288 2289 if ($equals_padding) { 2290 print STDERR localtime() . " [+] Padding base64-encoded message ", 2291 "with '$equals_padding'.\n" if $debug; 2292 $msg .= $equals_padding; 2271 2293 } 2272 2294 … … 4871 4893 } 4872 4894 4895 sub base64_equals_padding() { 4896 my $msg = shift; 4897 my $padding = ''; 4898 4899 ### base64 encoding pads encoded data to a multiple of four 4900 ### with '=' chars, but the fwknop client strips these out 4901 ### before sending to make it more difficult to detect SPA 4902 ### traffic 4903 my $remainder = 4 - length($msg) % 4; 4904 4905 unless ($remainder == 4) { 4906 $padding .= '='x$remainder; 4907 } 4908 return $padding; 4909 } 4910 4873 4911 sub null_func() { 4874 4912 return; fwknop/trunk/test/fwknop_test.pl
r1163 r1165 1476 1476 ### [-] Decrypted message does not conform to a valid SPA packet 1477 1477 return &print_errors("[-] Invalid SPA packet"); 1478 } elsif (/Unable\s+to\s+compile\s+packet\s+capture/) { 1479 return &print_errors("[-] Could not compile pcap filter, " . 1480 "upgrade libpcap?"); 1478 1481 } 1479 1482 } … … 2719 2722 $cache_encrypted_spa_packet = ''; 2720 2723 2724 my $found_packet_data = 0; 2725 2721 2726 open F, "< $current_test_file" 2722 2727 or die "[*] Could not open $current_test_file: $!"; … … 2726 2731 next; 2727 2732 } 2728 if (/^\s*\[\+\]\s+Encrypted\s+message:\s+(.*)/) { 2733 if (/^\s*\[\+\]\s+Packet\s+data:/) { 2734 $found_packet_data = 1; 2735 next; 2736 } 2737 if ($found_packet_data and /(\S+)/) { 2729 2738 $cache_encrypted_spa_packet = $1; 2739 $found_packet_data = 0; 2730 2740 next; 2731 2741 }
