Changeset 1211
- Timestamp:
- 08/16/08 13:52:44 (4 months ago)
- Files:
-
- fwknop/trunk/CREDITS (modified) (1 diff)
- fwknop/trunk/ChangeLog (modified) (1 diff)
- fwknop/trunk/fwknopd (modified) (10 diffs)
- fwknop/trunk/test/fwknop_test.pl (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
fwknop/trunk/CREDITS
r1210 r1211 233 233 the GPG_NO_OPTIONS variable in the access.conf file for the fwknopd 234 234 daemon. 235 - Reported lots of 'Premature end of base64 data' and 'Premature padding 236 of base64 data' warning messages. A fix was applied to fwknopd to apply 237 more rigorous checks for base64 encoded characters, and either of the 238 two messages above will result in the packet data being discarded before 239 it is sent through any decryption function. fwknop/trunk/ChangeLog
r1210 r1211 33 33 option in the default options file was causing SPA packets to exceed 34 34 1500 bytes when encrypted with a 2048-bit GnuPG key. 35 - Bugfix for 'Premature end of base64 data' and 'Premature padding of 36 base64 data' warning messages from MIME::Base64 errors. Now fwknopd 37 applies more rigorous checks for base64 encoded characters, and either 38 of these two messages above will result in the packet data being 39 discarded before it is sent through any decryption function. Mike 40 Holzmann reported this issue. 35 41 36 42 fwknop-1.9.6 (07/18/2008): fwknop/trunk/fwknopd
r1210 r1211 499 499 } 500 500 501 ### check to make sure the packet data only contains base64 encoded 502 ### characters (see RFC 3548 for why the following negated character 503 ### class checks for all non-base64 encoded characters). 504 if ($transport_data =~ /[^\x30-\x39\x41-\x5a\x61-\x7a\x2b\x2f\x3d]/) { 505 if ($debug) { 506 print STDERR localtime() . " [+] Packet contains non-base64 ", 507 "encoded characters, skipping.\n"; 508 &check_packet_limit(); 509 } 510 return; 511 } 512 501 513 ### see if this packet is worthy of being granted access through 502 514 ### the firewall … … 671 683 } 672 684 685 &check_packet_limit(); 686 return; 687 } 688 689 sub check_packet_limit() { 673 690 ### see if we need to exit if the packet limit (set with -C on the 674 691 ### command line) has been reached 675 if ($packet_limit) { 676 $packet_ctr++; 677 if ($packet_ctr >= $packet_limit) { 678 &logr('[+]', "packet limit ($packet_limit) reached, exiting.", 679 $NO_MAIL); 680 exit 0; 681 } 682 } 683 692 return unless $packet_limit; 693 694 $packet_ctr++; 695 if ($packet_ctr >= $packet_limit) { 696 &logr('[+]', "packet limit ($packet_limit) reached, exiting.", 697 $NO_MAIL); 698 exit 0; 699 } 684 700 return; 685 701 } … … 1220 1236 ### see if we need to exit if the packet limit (set with -C on the 1221 1237 ### command line) has been reached 1222 if ($packet_limit) { 1223 $packet_ctr++; 1224 if ($packet_ctr >= $packet_limit) { 1225 &logr('[+]', "packet limit ($packet_limit) reached, " . 1226 "exiting.", $NO_MAIL); 1227 exit 0; 1228 } 1229 } 1238 &check_packet_limit(); 1239 1230 1240 $rv = 1; 1231 1241 last; … … 1986 1996 ### see if we need to exit if the packet limit (set with -C on the 1987 1997 ### command line) has been reached 1988 if ($packet_limit) { 1989 $packet_ctr++; 1990 if ($packet_ctr >= $packet_limit) { 1991 &logr('[+]', "packet limit ($packet_limit) reached, " . 1992 "exiting.", $NO_MAIL); 1993 exit 0; 1994 } 1995 } 1998 &check_packet_limit(); 1996 1999 1997 2000 if ($os_fprint_only) { … … 2238 2241 my $pid; 2239 2242 my $decrypted_msg = ''; 2243 my $base64_decoded_msg = ''; 2240 2244 my $found_sig = 0; 2241 2245 my $gpg_sign_id = ''; … … 2255 2259 } 2256 2260 2261 ### base64 decode the packet 2262 $base64_decoded_msg = decode_base64($msg); 2263 2264 ### continue only if decode_base64() had no "Premature end of base64 data" 2265 ### errors - we want to minimize code that executes against suspicious 2266 ### packet data 2267 if ($warn_msg =~ /Premature\s+end/i 2268 or $warn_msg =~ /Premature\s+padding/i) { 2269 if ($debug) { 2270 print STDERR localtime() . " [-] $warn_msg"; 2271 } 2272 return $decrypt_rv, $decrypted_msg, $gpg_sign_id; 2273 } 2274 2275 ### look for the 0x8502 GnuPG prefix 2276 unless ($base64_decoded_msg =~ /^\x85\x02/) { 2277 if ($debug) { 2278 print STDERR localtime() . " [-] base64-decoded data does not begin ", 2279 "with 0x8502\n"; 2280 } 2281 return $decrypt_rv, $decrypted_msg, $gpg_sign_id; 2282 } 2283 2257 2284 print STDERR localtime() . " [+] Attempting GnuPG decrypt...\n" if $debug; 2258 2285 if ($debug and $verbose) { 2259 2286 print STDERR localtime() . " Decrypting raw data (hex dump):\n"; 2260 &hex_dump( decode_base64($msg));2287 &hex_dump($base64_decoded_msg); 2261 2288 } 2262 2289 … … 2316 2343 close $pw; 2317 2344 2318 print $input decode_base64($msg);2345 print $input $base64_decoded_msg; 2319 2346 close $input; 2320 2347 … … 2370 2397 my $decrypted_msg = ''; 2371 2398 my $decrypt_rv = 0; 2399 my $base64_decoded_msg = ''; 2372 2400 2373 2401 unless ($msg =~ /^U2FsdGVkX1/) { … … 2387 2415 } 2388 2416 2417 ### base64 decode the packet 2418 $base64_decoded_msg = decode_base64($msg); 2419 2420 ### continue only if decode_base64() had no "Premature end of base64 data" 2421 ### errors - we want to minimize code that executes against suspicious 2422 ### packet data 2423 if ($warn_msg =~ /Premature\s+end/i 2424 or $warn_msg =~ /Premature\s+padding/i) { 2425 if ($debug) { 2426 print STDERR localtime() . " [-] $warn_msg"; 2427 } 2428 return $decrypt_rv, $decrypted_msg; 2429 } 2430 2431 ### look for the Salted__ prefix 2432 unless ($base64_decoded_msg =~ /^Salted__/) { 2433 if ($debug) { 2434 print STDERR localtime() . " [-] base64-decoded data does not ", 2435 "begin with 'Salted__'\n"; 2436 } 2437 return $decrypt_rv, $decrypted_msg; 2438 } 2439 2389 2440 print STDERR localtime() . " [+] Attempting Rijndael decrypt...\n" if $debug; 2390 2441 2391 2442 if ($debug and $verbose) { 2392 2443 print STDERR localtime() . " Decrypting raw data (hex dump):\n"; 2393 &hex_dump( decode_base64($msg));2444 &hex_dump($base64_decoded_msg); 2394 2445 } 2395 2446 … … 2399 2450 }); 2400 2451 eval { 2401 $decrypted_msg = $cipher->decrypt( decode_base64($msg));2452 $decrypted_msg = $cipher->decrypt($base64_decoded_msg); 2402 2453 }; 2403 2454 if ($debug and $verbose) { fwknop/trunk/test/fwknop_test.pl
r1209 r1211 5 5 # File: fwknop_test.pl 6 6 # 7 # Purpose: This program provides a test ing infrastructure for the fwknop8 # Single PacketAuthorization client and server.7 # Purpose: This program provides a test suite for the fwknop Single Packet 8 # Authorization client and server. 9 9 # 10 10 # Author: Michael Rash (mbr@cipherdyne.org) … … 240 240 &test_driver("(Replay attacks, broken data) $NUM_RAND random packets", 241 241 \&packet_randomness); 242 242 243 &test_driver('(Replay attacks, broken data) Truncated SPA packet', 243 244 \&truncated_SPA_packet); … … 251 252 &test_driver('(Replay attacks, broken data) Sniffing broken SPA packet', 252 253 \&bogus_SPA_sniff_decrypt); 254 &test_driver('(Replay attacks, broken data) Firewall rules do not exist', 255 \&fw_rules_removed); 256 &stop_fwknopd_quiet('(Replay attacks, broken data)'); 257 258 &test_driver('(Replay attacks, broken data) non-base64 SPA packet', 259 \&non_base64_SPA_packet); 260 &test_driver('(Replay attacks, broken data) Sniffing non-base64 SPA packet', 261 \&non_base64_SPA_sniff_decrypt); 253 262 &test_driver('(Replay attacks, broken data) Firewall rules do not exist', 254 263 \&fw_rules_removed); … … 2367 2376 sub truncated_SPA_packet() { 2368 2377 my $rv = &get_access_packet($default_fwknop_args, $NO_QUIET); 2369 ### chop off the last 10 chars 2370 $cache_encrypted_spa_packet =~ s|.{10}$||; 2378 ### chop off the last 11 chars 2379 $cache_encrypted_spa_packet =~ s|.{11}$||; 2380 return $rv; 2381 } 2382 2383 sub non_base64_SPA_packet() { 2384 my $rv = &get_access_packet($default_fwknop_args, $NO_QUIET); 2385 ### introduce one non-base64 encoded character "@" at the 11th position 2386 $cache_encrypted_spa_packet =~ s|(.{10}).|$1@|; 2371 2387 return $rv; 2372 2388 } … … 2393 2409 ### ANY (# 1 in access.conf) 2394 2410 $found_err = 1; 2395 last; 2396 return &print_errors("[-] Key mis-match"); 2411 last; 2397 2412 } elsif (/\[\-\]\s+Decrypted.*not\s+conform/i) { 2398 2413 ### [-] Decrypted message does not conform to a valid SPA packet 2399 return &print_errors("[-] Invalid SPA packet");2400 2414 $found_err = 1; 2401 last; 2415 last; 2402 2416 } 2403 2417 } … … 2407 2421 } else { 2408 2422 return &print_errors("[*] fwknopd accepted truncated SPA packet"); 2423 } 2424 } 2425 return &print_errors("[-] Sniff alarm ($sniff_alarm seconds) expired"); 2426 } 2427 2428 sub non_base64_SPA_sniff_decrypt() { 2429 2430 if (&run_fwknopd($cache_encrypted_spa_packet, 2431 $default_fwknop_conf, $default_access_conf)) { 2432 2433 ### now that fwknopd has exited, see if the SPA packet was valid 2434 my $found_err = 0; 2435 open SE, "< $current_test_file" 2436 or die "[*] Could not open $current_test_file: $!"; 2437 while (<SE>) { 2438 if (/Packet\s+contains\s+non-base64\s+encoded\s+characters/) { 2439 $found_err = 1; 2440 last; 2441 } 2442 } 2443 close SE; 2444 if ($found_err) { 2445 return 1; 2446 } else { 2447 return &print_errors("[*] fwknopd accepted non-base64 encoded SPA packet"); 2409 2448 } 2410 2449 }
