added icmp type/code blurb

This commit is contained in:
Michael Rash 2012-10-11 23:40:04 -04:00
parent 67f5d1f1e9
commit e4751d1c20
10 changed files with 77 additions and 7 deletions

View File

@ -23,6 +23,11 @@ fwknop-2.0.4 (09/20/2012):
against libfko in the local directory (if it exists) so that it doesn't
have to have libfko completely installed in /usr/lib/. This allows the
test suite to run FKO tests without installing libfko.
- [client] Added --icmp-type and --icmp-code arguments so the user can
control the icmp type/code combination for spoofed SPA packets ('-P
icmp') mode.
- [client] Updated default TTL value to 64 for spoofed SPA packets. This
closer to more OS default TTL values than the previous 255.
fwknop-2.0.3 (09/03/2012):
- [server] Fernando Arnaboldi from IOActive found several DoS/code

View File

@ -49,6 +49,8 @@ enum {
GPG_SIGNER_KEY,
GPG_HOME_DIR,
GPG_AGENT,
SPA_ICMP_TYPE,
SPA_ICMP_CODE,
NOOP /* Just to be a marker for the end */
};
@ -78,6 +80,8 @@ static struct option cmd_opts[] =
{"get-key", 1, NULL, 'G'},
{"help", 0, NULL, 'h'},
{"http-proxy", 1, NULL, 'H'},
{"icmp-type", 1, NULL, SPA_ICMP_TYPE },
{"icmp-code", 1, NULL, SPA_ICMP_CODE },
{"last-cmd", 0, NULL, 'l'},
{"nat-access", 1, NULL, 'N'},
{"named-config", 1, NULL, 'n'},

View File

@ -29,6 +29,7 @@
******************************************************************************
*/
#include "fwknop_common.h"
#include "netinet_common.h"
#include "config_init.h"
#include "cmd_opts.h"
#include "utils.h"
@ -644,6 +645,8 @@ set_defaults(fko_cli_options_t *options)
options->spa_dst_port = FKO_DEFAULT_PORT;
options->fw_timeout = -1;
options->spa_icmp_type = ICMP_ECHOREPLY; /* only used in '-P icmp' mode */
options->spa_icmp_code = 0; /* only used in '-P icmp' mode */
return;
}
@ -733,6 +736,22 @@ config_init(fko_cli_options_t *options, int argc, char **argv)
options->spa_proto = FKO_PROTO_HTTP;
strlcpy(options->http_proxy, optarg, MAX_PATH_LEN);
break;
case SPA_ICMP_TYPE:
options->spa_icmp_type = atoi(optarg);
if (options->spa_icmp_type < 0 || options->spa_icmp_type > MAX_ICMP_TYPE)
{
fprintf(stderr, "Unrecognized icmp type value: %s\n", optarg);
exit(EXIT_FAILURE);
}
break;
case SPA_ICMP_CODE:
options->spa_icmp_code = atoi(optarg);
if (options->spa_icmp_code < 0 || options->spa_icmp_code > MAX_ICMP_CODE)
{
fprintf(stderr, "Unrecognized icmp code value: %s\n", optarg);
exit(EXIT_FAILURE);
}
break;
case 'l':
options->run_last_command = 1;
break;

View File

@ -117,6 +117,9 @@ typedef struct fko_cli_options
unsigned int spa_dst_port;
unsigned int spa_src_port; /* only used with --source-port */
int spa_icmp_type; /* only used in '-P icmp' mode */
int spa_icmp_code; /* only used in '-P icmp' mode */
unsigned int digest_type;
/* Various command-line flags */

View File

@ -257,7 +257,7 @@ send_spa_packet_tcp_raw(const char *spa_data, const int sd_len,
/* The value here does not matter */
iph->id = random() & 0xffff;
iph->frag_off = 0;
iph->ttl = 255;
iph->ttl = RAW_SPA_TTL;
iph->protocol = IPPROTO_TCP;
iph->check = 0;
iph->saddr = saddr->sin_addr.s_addr;
@ -370,7 +370,7 @@ send_spa_packet_udp_raw(const char *spa_data, const int sd_len,
/* The value here does not matter */
iph->id = random() & 0xffff;
iph->frag_off = 0;
iph->ttl = 255;
iph->ttl = RAW_SPA_TTL;
iph->protocol = IPPROTO_UDP;
iph->check = 0;
iph->saddr = saddr->sin_addr.s_addr;
@ -469,7 +469,7 @@ send_spa_packet_icmp(const char *spa_data, const int sd_len,
/* The value here does not matter */
iph->id = random() & 0xffff;
iph->frag_off = 0;
iph->ttl = 255;
iph->ttl = RAW_SPA_TTL;
iph->protocol = IPPROTO_ICMP;
iph->check = 0;
iph->saddr = saddr->sin_addr.s_addr;
@ -477,10 +477,16 @@ send_spa_packet_icmp(const char *spa_data, const int sd_len,
/* Now the ICMP header values.
*/
icmph->type = ICMP_ECHOREPLY; /* Make it an echo reply */
icmph->code = 0;
icmph->type = options->spa_icmp_type;
icmph->code = options->spa_icmp_code;
icmph->checksum = 0;
if(icmph->type == ICMP_ECHO && icmph->code == 0)
{
icmph->un.echo.id = htons(random() & 0xffff);
icmph->un.echo.sequence = htons(1);
}
/* No we can compute our checksum.
*/
iph->check = chksum((unsigned short *)pkt_data, iph->tot_len);

View File

@ -104,6 +104,9 @@ enum {
#define MIN_HIGH_PORT 10000 /* sensible minimum for SPA dest port */
#define MAX_PORT 65535
#define MAX_SERVER_STR_LEN 50
#define MAX_ICMP_TYPE 40
#define MAX_ICMP_CODE 15
#define RAW_SPA_TTL 255
#define MAX_LINE_LEN 1024
#define MAX_PATH_LEN 1024

View File

@ -316,6 +316,14 @@ SPA OPTIONS
on the fwknopd server (*--spoof-src* mode requires that the *fwknop*
client is executed as root).
*--icmp-type*='<type>'::
In *-P icmp* mode, specify the ICMP type value that will be set in the
SPA packet ICMP header. The default is echo reply.
*--icmp-code*='<code>'::
In *-P icmp* mode, specify the ICMP code value that will be set in the
SPA packet ICMP header. The default is zero.
GPG-RELATED OPTIONS
-------------------

View File

@ -53,11 +53,11 @@ _rijndael_encrypt(fko_ctx_t ctx, const char *enc_key)
/* Make a bucket big enough to hold the enc msg + digest (plaintext)
* and populate it appropriately.
*/
plain = malloc(strlen(ctx->encoded_msg) + strlen(ctx->digest) + 2);
plain = malloc(strlen(ctx->encoded_msg) + strlen(ctx->digest) + 4);
if(plain == NULL)
return(FKO_ERROR_MEMORY_ALLOCATION);
snprintf(plain, strlen(ctx->encoded_msg) + strlen(ctx->digest) + 2,
snprintf(plain, strlen(ctx->encoded_msg) + strlen(ctx->digest) + 4,
"%s:%s", ctx->encoded_msg, ctx->digest);
/* Make a bucket for the encrypted version and populate it.

View File

@ -868,6 +868,21 @@ my @tests = (
'server_positive_output_matches' => [qr/SPA\sPacket\sfrom\sIP\:\s$spoof_ip\s/],
'fatal' => $NO
},
{
'category' => 'Rijndael SPA',
'subcategory' => 'client+server',
'detail' => "icmp type/code 8/0 spoof src IP ",
'err_msg' => "could not spoof source IP",
'function' => \&spa_cycle,
'cmdline' => "$default_client_args -P icmp --icmp-type 8 --icmp-code 0 -Q $spoof_ip",
'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
"$fwknopdCmd -c $cf{'icmp_pcap_filter'} -a $cf{'def_access'} " .
"-d $default_digest_file -p $default_pid_file $intf_str",
'fw_rule_created' => $NEW_RULE_REQUIRED,
'fw_rule_removed' => $NEW_RULE_REMOVED,
'server_positive_output_matches' => [qr/SPA\sPacket\sfrom\sIP\:\s$spoof_ip\s/],
'fatal' => $NO
},
### SPA over TCP (not really "single" packet auth since a TCP connection
### is established)

View File

@ -83,3 +83,10 @@
** [server] Add access variable to require particular IP's even when REQUIRE_SOURCE is used
The SOURCE variable only applies to the IP header. Add analogous filtering
for the allow IP that is encrypted within an SPA payload.
** [client] Add --icmp-type and --icmp-code args
For SPA packets sent over ICMP via raw socket, allow the user to specify
the ICMP type and code.
** [client] Fix 'Could not set destination IP.' in hostname resolution in '-P icmp' mode
It seems that hostname resolution is not working when SPA packets are
spoofed. Here is the command line to trigger the problem:
# fwknop -A tcp/22 -a 127.0.0.2 -D <host> --verbose --verbose -P icmp --icmp-type 8 --icmp-code 0 -Q 1.2.3.4