Skip to content

Commit

Permalink
Added source port and protocol to digest tracking
Browse files Browse the repository at this point in the history
Added the source port and protocol fields to valid SPA packets in the digest
cache.  This can help to discover replay trends.  The format of the digest
file cache is now:

<digest> <proto> <src_ip> <src_port> <dst_ip> <dst_port> <time>
  • Loading branch information
mrash committed Aug 14, 2011
1 parent 6982a72 commit 941a4aa
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 16 deletions.
4 changes: 3 additions & 1 deletion server/fwknopd_common.h
Expand Up @@ -417,9 +417,11 @@ typedef struct acc_stanza
typedef struct spa_pkt_info typedef struct spa_pkt_info
{ {
unsigned int packet_data_len; unsigned int packet_data_len;
unsigned int packet_proto;
unsigned int packet_src_ip; unsigned int packet_src_ip;
unsigned int packet_dst_ip; unsigned int packet_dst_ip;
unsigned short packet_dest_port; unsigned short packet_src_port;
unsigned short packet_dst_port;
unsigned char packet_data[MAX_SPA_PACKET_LEN+1]; unsigned char packet_data[MAX_SPA_PACKET_LEN+1];
} spa_pkt_info_t; } spa_pkt_info_t;


Expand Down
27 changes: 16 additions & 11 deletions server/process_packet.c
Expand Up @@ -53,11 +53,12 @@ process_packet(unsigned char *args, const struct pcap_pkthdr *packet_header,


unsigned int ip_hdr_words; unsigned int ip_hdr_words;


unsigned char proto;
unsigned int src_ip; unsigned int src_ip;
unsigned int dst_ip; unsigned int dst_ip;


unsigned short src_port; unsigned short src_port;
unsigned short dest_port; unsigned short dst_port;


unsigned short eth_type; unsigned short eth_type;


Expand Down Expand Up @@ -136,27 +137,29 @@ process_packet(unsigned char *args, const struct pcap_pkthdr *packet_header,
src_ip = iph_p->saddr; src_ip = iph_p->saddr;
dst_ip = iph_p->daddr; dst_ip = iph_p->daddr;


if (iph_p->protocol == IPPROTO_TCP) proto = iph_p->protocol;

if (proto == IPPROTO_TCP)
{ {
/* Process TCP packet /* Process TCP packet
*/ */
tcph_p = (struct tcphdr*)((unsigned char*)iph_p + (ip_hdr_words << 2)); tcph_p = (struct tcphdr*)((unsigned char*)iph_p + (ip_hdr_words << 2));


src_port = ntohs(tcph_p->source); src_port = ntohs(tcph_p->source);
dest_port = ntohs(tcph_p->dest); dst_port = ntohs(tcph_p->dest);


pkt_data = ((unsigned char*)(tcph_p+1))+((tcph_p->doff)<<2)-sizeof(struct tcphdr); pkt_data = ((unsigned char*)(tcph_p+1))+((tcph_p->doff)<<2)-sizeof(struct tcphdr);


pkt_data_len = (pkt_end-(unsigned char*)iph_p)-(pkt_data-(unsigned char*)iph_p); pkt_data_len = (pkt_end-(unsigned char*)iph_p)-(pkt_data-(unsigned char*)iph_p);
} }
else if (iph_p->protocol == IPPROTO_UDP) else if (proto == IPPROTO_UDP)
{ {
/* Process UDP packet /* Process UDP packet
*/ */
udph_p = (struct udphdr*)((unsigned char*)iph_p + (ip_hdr_words << 2)); udph_p = (struct udphdr*)((unsigned char*)iph_p + (ip_hdr_words << 2));


src_port = ntohs(udph_p->source); src_port = ntohs(udph_p->source);
dest_port = ntohs(udph_p->dest); dst_port = ntohs(udph_p->dest);


pkt_data = ((unsigned char*)(udph_p + 1)); pkt_data = ((unsigned char*)(udph_p + 1));
pkt_data_len = (pkt_end-(unsigned char*)iph_p)-(pkt_data-(unsigned char*)iph_p); pkt_data_len = (pkt_end-(unsigned char*)iph_p)-(pkt_data-(unsigned char*)iph_p);
Expand All @@ -180,10 +183,12 @@ process_packet(unsigned char *args, const struct pcap_pkthdr *packet_header,
/* Put the data in our 1-entry queue. /* Put the data in our 1-entry queue.
*/ */
strlcpy((char *)opts->spa_pkt.packet_data, (char *)pkt_data, pkt_data_len+1); strlcpy((char *)opts->spa_pkt.packet_data, (char *)pkt_data, pkt_data_len+1);
opts->spa_pkt.packet_data_len = pkt_data_len; opts->spa_pkt.packet_data_len = pkt_data_len;
opts->spa_pkt.packet_src_ip = src_ip; opts->spa_pkt.packet_proto = proto;
opts->spa_pkt.packet_dst_ip = dst_ip; opts->spa_pkt.packet_src_ip = src_ip;
opts->spa_pkt.packet_dest_port = dest_port; opts->spa_pkt.packet_dst_ip = dst_ip;
opts->spa_pkt.packet_src_port = src_port;
opts->spa_pkt.packet_dst_port = dst_port;


return; return;
} }
Expand Down
38 changes: 34 additions & 4 deletions server/replay_cache.c
Expand Up @@ -277,7 +277,9 @@ replay_check_file_cache(fko_srv_options_t *opts, fko_ctx_t ctx)
{ {
char *digest = NULL; char *digest = NULL;
char src_ip[INET_ADDRSTRLEN+1] = {0}; char src_ip[INET_ADDRSTRLEN+1] = {0};
char orig_src_ip[INET_ADDRSTRLEN+1] = {0};
char dst_ip[INET_ADDRSTRLEN+1] = {0}; char dst_ip[INET_ADDRSTRLEN+1] = {0};
char created[18];
int res = 0, digest_len = 0; int res = 0, digest_len = 0;
FILE *digest_file_cache_ptr = NULL; FILE *digest_file_cache_ptr = NULL;


Expand All @@ -300,8 +302,27 @@ replay_check_file_cache(fko_srv_options_t *opts, fko_ctx_t ctx)
digest_list_ptr != NULL; digest_list_ptr != NULL;
digest_list_ptr = digest_list_ptr->next) { digest_list_ptr = digest_list_ptr->next) {
if (strncmp(digest_list_ptr->cache_info.digest, digest, digest_len) == 0) { if (strncmp(digest_list_ptr->cache_info.digest, digest, digest_len) == 0) {

/* Convert the IPs to a human readable form
*/
inet_ntop(AF_INET, &(opts->spa_pkt.packet_src_ip),
src_ip, INET_ADDRSTRLEN);
inet_ntop(AF_INET, &(opts->spa_pkt.packet_src_ip),
orig_src_ip, INET_ADDRSTRLEN);

strftime(created, 18, "%D %H:%M:%S",
localtime(&(digest_list_ptr->cache_info.created)));

/* Detected a replay attack - bail /* Detected a replay attack - bail
*/ */
log_msg(LOG_WARNING,
"Replay detected from source IP: %s\n"
" Original source IP: %s\n"
" Entry created: %s\n",
src_ip,
orig_src_ip,
created
);
return(SPA_MSG_REPLAY); return(SPA_MSG_REPLAY);
} }
} }
Expand All @@ -326,8 +347,11 @@ replay_check_file_cache(fko_srv_options_t *opts, fko_ctx_t ctx)
} }


strlcpy(digest_elm->cache_info.digest, digest, digest_len+1); strlcpy(digest_elm->cache_info.digest, digest, digest_len+1);
digest_elm->cache_info.src_ip = opts->spa_pkt.packet_src_ip; digest_elm->cache_info.proto = opts->spa_pkt.packet_proto;
digest_elm->cache_info.dst_ip = opts->spa_pkt.packet_dst_ip; digest_elm->cache_info.src_ip = opts->spa_pkt.packet_src_ip;
digest_elm->cache_info.dst_ip = opts->spa_pkt.packet_dst_ip;
digest_elm->cache_info.src_port = opts->spa_pkt.packet_src_port;
digest_elm->cache_info.dst_port = opts->spa_pkt.packet_dst_port;
digest_elm->cache_info.created = time(NULL); digest_elm->cache_info.created = time(NULL);


/* First, add the digest at the head of the in-memory list /* First, add the digest at the head of the in-memory list
Expand All @@ -348,8 +372,14 @@ replay_check_file_cache(fko_srv_options_t *opts, fko_ctx_t ctx)
src_ip, INET_ADDRSTRLEN); src_ip, INET_ADDRSTRLEN);
inet_ntop(AF_INET, &(digest_elm->cache_info.dst_ip), inet_ntop(AF_INET, &(digest_elm->cache_info.dst_ip),
dst_ip, INET_ADDRSTRLEN); dst_ip, INET_ADDRSTRLEN);
fprintf(digest_file_cache_ptr, "%s %s %s %d\n", fprintf(digest_file_cache_ptr, "%s %d %s %d %s %d %d\n",
digest, src_ip, dst_ip, (int) digest_elm->cache_info.created); digest,
digest_elm->cache_info.proto,
src_ip,
(int) digest_elm->cache_info.src_port,
dst_ip,
digest_elm->cache_info.dst_port,
(int) digest_elm->cache_info.created);


fclose(digest_file_cache_ptr); fclose(digest_file_cache_ptr);


Expand Down
3 changes: 3 additions & 0 deletions server/replay_cache.h
Expand Up @@ -40,6 +40,9 @@ typedef struct digest_cache_info {
#if USE_FILE_CACHE #if USE_FILE_CACHE
char *digest; char *digest;
unsigned int dst_ip; unsigned int dst_ip;
unsigned short src_port;
unsigned short dst_port;
unsigned char proto;
#else #else
time_t first_replay; time_t first_replay;
time_t last_replay; time_t last_replay;
Expand Down

0 comments on commit 941a4aa

Please sign in to comment.