464 lines
16 KiB
C
464 lines
16 KiB
C
/*
|
|
* The IKE Scanner (ike-scan) is Copyright (C) 2003-2007 Roy Hills,
|
|
* NTA Monitor Ltd.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
* In addition, as a special exception, the copyright holders give
|
|
* permission to link the code of portions of this program with the
|
|
* OpenSSL library, and distribute linked combinations including the two.
|
|
*
|
|
* You must obey the GNU General Public License in all respects
|
|
* for all of the code used other than OpenSSL. If you modify
|
|
* file(s) with this exception, you may extend this exception to your
|
|
* version of the file(s), but you are not obligated to do so. If you
|
|
* do not wish to do so, delete this exception statement from your
|
|
* version.
|
|
*
|
|
* If this license is unacceptable to you, I may be willing to negotiate
|
|
* alternative licenses (contact ike-scan@nta-monitor.com).
|
|
*
|
|
* You are encouraged to send comments, improvements or suggestions to
|
|
* me at ike-scan@nta-monitor.com.
|
|
*
|
|
* $Id: ike-scan.h 9884 2007-01-14 19:05:39Z rsh $
|
|
*
|
|
* ike-scan.h -- Header file for IKE Scanner (ike-scan)
|
|
*
|
|
* Author: Roy Hills
|
|
* Date: 12 September 2002
|
|
*/
|
|
|
|
#ifndef IKE_SCAN_H
|
|
#define IKE_SCAN_H 1
|
|
|
|
/* Includes */
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#ifdef STDC_HEADERS
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <ctype.h>
|
|
#include <stdarg.h>
|
|
#include <errno.h>
|
|
#include <limits.h>
|
|
#else
|
|
#error This program requires the ANSI C Headers
|
|
#endif
|
|
|
|
#include <sys/types.h> /* FreeBSD needs explicit include for sys/types.h */
|
|
|
|
/* Integer types */
|
|
#ifdef HAVE_INTTYPES_H
|
|
#include <inttypes.h>
|
|
#else
|
|
#ifdef HAVE_STDINT_H
|
|
#include <stdint.h>
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef __CYGWIN__
|
|
#include <windows.h> /* Include windows.h if compiling under Cygwin */
|
|
#endif
|
|
|
|
#ifdef HAVE_UNISTD_H
|
|
#include <unistd.h>
|
|
#endif
|
|
|
|
#ifdef HAVE_NETDB_H
|
|
#include <netdb.h>
|
|
#endif
|
|
|
|
#ifdef HAVE_SYSLOG_H
|
|
#include <syslog.h>
|
|
#endif
|
|
|
|
#ifdef HAVE_GETOPT_H
|
|
#include <getopt.h>
|
|
#else
|
|
/* Include getopt.h for the sake of getopt_long.
|
|
We don't need the declaration of getopt, and it could conflict
|
|
with something from a system header file, so effectively nullify that. */
|
|
#define getopt getopt_loser
|
|
#include "getopt.h"
|
|
#undef getopt
|
|
#endif
|
|
|
|
#ifdef HAVE_NETINET_IN_H
|
|
#include <netinet/in.h>
|
|
#endif
|
|
|
|
#ifdef HAVE_NETINET_TCP_H
|
|
#include <netinet/tcp.h>
|
|
#endif
|
|
|
|
#ifdef TIME_WITH_SYS_TIME
|
|
# include <sys/time.h>
|
|
# include <time.h>
|
|
#else
|
|
# ifdef HAVE_SYS_TIME_H
|
|
# include <sys/time.h>
|
|
# else
|
|
# include <time.h>
|
|
# endif
|
|
#endif
|
|
|
|
#ifdef HAVE_SYS_SOCKET_H
|
|
#include <sys/socket.h> /* For struct sockaddr */
|
|
#endif
|
|
|
|
#ifdef HAVE_ARPA_INET_H
|
|
#include <arpa/inet.h>
|
|
#endif
|
|
|
|
#ifdef HAVE_SIGNAL_H
|
|
#include <signal.h> /* For TCP connect() timeout using alarm */
|
|
#endif
|
|
|
|
#ifdef HAVE_REGEX_H
|
|
#include <regex.h> /* Posix regular expression support */
|
|
#endif
|
|
|
|
#ifdef HAVE_SYS_STAT_H
|
|
#include <sys/stat.h>
|
|
#endif
|
|
|
|
#ifdef HAVE_FCNTL_H
|
|
#include <fcntl.h>
|
|
#endif
|
|
|
|
#ifdef HAVE_OPENSSL
|
|
#include <openssl/md5.h>
|
|
#include <openssl/sha.h>
|
|
#else
|
|
#include "md5.h"
|
|
#include "sha1.h"
|
|
#endif
|
|
|
|
#include "isakmp.h"
|
|
|
|
#include "ip.h"
|
|
#include "udp.h"
|
|
|
|
/* Defines */
|
|
|
|
#define MAXLINE 255 /* Max line length for input files */
|
|
#define MAXUDP 65507 /* Max UDP data size = 64k - 20 - 8 */
|
|
#define DEFAULT_SELECT_TIMEOUT 10 /* Default select timeout in ms */
|
|
#define DEFAULT_BACKOFF_FACTOR 1.5 /* Default timeout backoff factor */
|
|
#define DEFAULT_RETRY 3 /* Default number of retries */
|
|
#define DEFAULT_TIMEOUT 500 /* Default per-host timeout in ms */
|
|
#define DEFAULT_BANDWIDTH 56000 /* Default bandwidth in bits/sec */
|
|
#define DEFAULT_SOURCE_PORT 500 /* Default UDP source port */
|
|
#define DEFAULT_DEST_PORT 500 /* Default UDP destination port */
|
|
#define DEFAULT_NAT_T_SOURCE_PORT 4500 /* Default UDP src port with NAT-T */
|
|
#define DEFAULT_NAT_T_DEST_PORT 4500 /* Default UDP dest port with NAT-T */
|
|
#define DEFAULT_LIFETIME 28800 /* Default lifetime in seconds */
|
|
#define DEFAULT_LIFESIZE 0 /* Default lifesize in KB */
|
|
#define DEFAULT_AUTH_METHOD 1 /* Default authentication method */
|
|
#define DEFAULT_END_WAIT 60 /* Default time to wait at end in sec */
|
|
#define DEFAULT_PATTERN_FUZZ 500 /* Default pattern fuzz in ms */
|
|
#define DEFAULT_DH_GROUP 2 /* Default DH group for agg. mode */
|
|
#define DEFAULT_IDTYPE ID_USER_FQDN /* Default ID Type for agg. mode */
|
|
#define DEFAULT_EXCHANGE_TYPE ISAKMP_XCHG_IDPROT /* Main Mode */
|
|
#define DEFAULT_NONCE_LEN 20 /* Default Nonce length in bytes */
|
|
#define DEFAULT_HEADER_VERSION 0x10 /* Default ISAKMP header version */
|
|
#define DEFAULT_DOI ISAKMP_DOI_IPSEC /* Default SA DOI */
|
|
#define DEFAULT_SITUATION SIT_IDENTITY_ONLY /* Default SA Situation */
|
|
#define DEFAULT_PROTOCOL PROTO_ISAKMP /* Default Proposal Protocol */
|
|
#define DEFAULT_TRANS_ID KEY_IKE /* Default Transform ID */
|
|
#define DEFAULT_IKE_VERSION 1 /* Default IKE version */
|
|
#define SYSLOG 1 /* Use syslog if defined */
|
|
#define SYSLOG_FACILITY LOG_USER /* Syslog facility to use */
|
|
#define PATTERNS_FILE "ike-backoff-patterns" /* Backoff patterns filename */
|
|
#define VID_FILE "ike-vendor-ids" /* Vendor ID patterns filename */
|
|
#define REALLOC_COUNT 1000 /* Entries to realloc at once */
|
|
#define DEFAULT_TCP_CONNECT_TIMEOUT 10 /* TCP connect timeout in seconds */
|
|
#define TCP_PROTO_RAW 1 /* Raw IKE over TCP (Checkpoint) */
|
|
#define TCP_PROTO_ENCAP 2 /* Encapsulated IKE over TCP (cisco) */
|
|
#define PACKET_OVERHEAD 28 /* 20 bytes for IP hdr + 8 for UDP */
|
|
#define OPT_SPISIZE 256
|
|
#define OPT_HDRFLAGS 257
|
|
#define OPT_HDRMSGID 258
|
|
#define OPT_COOKIE 259
|
|
#define OPT_EXCHANGE 260
|
|
#define OPT_NEXTPAYLOAD 261
|
|
#define OPT_WRITEPKTTOFILE 262
|
|
#define OPT_RANDOMSEED 263
|
|
#define OPT_TIMESTAMP 264
|
|
#define OPT_SOURCEIP 265
|
|
#define OPT_SHOWNUM 266
|
|
#define OPT_NAT_T 267
|
|
#define OPT_RCOOKIE 268
|
|
#define OPT_READPKTFROMFILE 269
|
|
#undef DEBUG_TIMINGS /* Define to 1 to debug timing code */
|
|
/* #define WRITE_RECEIVED_IKE_PACKET "received-ike-packet.dat" */
|
|
|
|
/* Structures */
|
|
typedef struct time_list_ {
|
|
struct timeval time;
|
|
struct time_list_ *next;
|
|
} time_list;
|
|
|
|
typedef struct {
|
|
int id;
|
|
union {
|
|
void *ptr;
|
|
int val;
|
|
} un;
|
|
} misc_data;
|
|
|
|
typedef struct {
|
|
time_list *recv_times; /* List of receive times */
|
|
misc_data *extra; /* Extra data for this entry */
|
|
unsigned n; /* Ordinal number for this entry */
|
|
unsigned timeout; /* Timeout for this host */
|
|
uint32_t icookie[COOKIE_SIZE]; /* IKE Initiator cookie */
|
|
struct in_addr addr; /* Host IP address */
|
|
struct timeval last_send_time; /* Time when last packet sent to this addr */
|
|
unsigned short num_sent; /* Number of packets sent */
|
|
unsigned short num_recv; /* Number of packets received */
|
|
unsigned char live; /* Set when awaiting response */
|
|
} host_entry;
|
|
|
|
typedef struct pattern_entry_list_ {
|
|
struct timeval time;
|
|
unsigned fuzz;
|
|
struct pattern_entry_list_ *next;
|
|
} pattern_entry_list;
|
|
|
|
typedef struct pattern_list_ {
|
|
char *name; /* Name of this backoff pattern */
|
|
unsigned num_times; /* Number of time entries in this pattern */
|
|
pattern_entry_list *recv_times; /* Pointer to list of times */
|
|
struct pattern_list_ *next;
|
|
} pattern_list;
|
|
|
|
typedef struct vid_pattern_list_ {
|
|
char *name;
|
|
char *pattern; /* Text regular expression */
|
|
regex_t *regex; /* Compiled regular expression */
|
|
struct vid_pattern_list_ *next;
|
|
} vid_pattern_list;
|
|
|
|
typedef struct {
|
|
unsigned char *g_xr; /* Responder DH public value */
|
|
unsigned char *g_xi; /* Initiator DH public value */
|
|
unsigned char *cky_r; /* Responder cookie */
|
|
unsigned char *cky_i; /* Initiator cookie */
|
|
unsigned char *sai_b; /* Initiator SA payload */
|
|
unsigned char *idir_b; /* Responder ID payload */
|
|
unsigned char *ni_b; /* Initiator nonce */
|
|
unsigned char *nr_b; /* Responder nonce */
|
|
unsigned char *hash_r; /* Responder hash */
|
|
size_t g_xr_len;
|
|
size_t g_xi_len;
|
|
size_t cky_r_len;
|
|
size_t cky_i_len;
|
|
size_t sai_b_len;
|
|
size_t idir_b_len;
|
|
size_t ni_b_len;
|
|
size_t nr_b_len;
|
|
size_t hash_r_len;
|
|
} psk_crack;
|
|
|
|
typedef struct {
|
|
int id; /* IKE IDs are generally 8 or 16-bits */
|
|
const char *name;
|
|
} id_name_map;
|
|
|
|
typedef struct { /* Used for encapsulated IKE */
|
|
uint16_t source;
|
|
uint16_t dest;
|
|
uint16_t len;
|
|
uint16_t check;
|
|
} ike_udphdr;
|
|
|
|
/*
|
|
* If you change the ordering of the members in this struct, then you must
|
|
* also change the initialisation of ike_params in main() in ike-scan.c to
|
|
* conform to the new order.
|
|
*/
|
|
typedef struct { /* IKE Packet Parameters */
|
|
unsigned char *lifetime_data;
|
|
size_t lifetime_data_len;
|
|
unsigned char *lifesize_data;
|
|
size_t lifesize_data_len;
|
|
unsigned auth_method;
|
|
unsigned dhgroup;
|
|
unsigned idtype;
|
|
unsigned char *id_data;
|
|
size_t id_data_len;
|
|
int vendor_id_flag;
|
|
int trans_flag;
|
|
unsigned exchange_type;
|
|
int gss_id_flag;
|
|
unsigned char *gss_data;
|
|
size_t gss_data_len;
|
|
size_t nonce_data_len;
|
|
char *header_length;
|
|
unsigned char *cr_data;
|
|
size_t cr_data_len;
|
|
int header_version; /* ISAKMP Header Version */
|
|
unsigned doi; /* SA DOI */
|
|
unsigned situation; /* SA Situation */
|
|
unsigned protocol; /* Proposal protocol */
|
|
unsigned trans_id; /* Transform ID */
|
|
unsigned spi_size; /* Proposal SPI Size */
|
|
int hdr_flags; /* ISAKMP Header flags */
|
|
unsigned hdr_msgid; /* ISAKMP Header message id */
|
|
unsigned hdr_next_payload; /* Next payload in ISAKMP header */
|
|
int advanced_trans_flag;
|
|
int ike_version; /* IKE version */
|
|
unsigned char *rcookie_data; /* Responder cookie */
|
|
size_t rcookie_data_len;
|
|
} ike_packet_params;
|
|
|
|
/* Functions */
|
|
|
|
void err_sys(const char *, ...);
|
|
void warn_sys(const char *, ...);
|
|
void err_msg(const char *, ...);
|
|
void warn_msg(const char *, ...);
|
|
void info_syslog(const char *, ...);
|
|
void err_print(int, int, const char *, va_list);
|
|
void usage(int, int);
|
|
void add_host_pattern(const char *, unsigned, unsigned *, unsigned char *,
|
|
size_t);
|
|
void add_host(const char *, unsigned, unsigned *, unsigned char *,
|
|
size_t);
|
|
void send_packet(int, unsigned char *, size_t, host_entry *, unsigned, unsigned,
|
|
struct timeval *);
|
|
int recvfrom_wto(int, unsigned char *, size_t, struct sockaddr *, int);
|
|
void remove_host(host_entry **, unsigned *, unsigned);
|
|
void timeval_diff(const struct timeval *, const struct timeval *,
|
|
struct timeval *);
|
|
unsigned char *initialise_ike_packet(size_t *, ike_packet_params *);
|
|
host_entry *find_host_by_cookie(host_entry **, unsigned char *,
|
|
int, unsigned);
|
|
void display_packet(int, unsigned char *, host_entry *,
|
|
struct in_addr *, unsigned *, unsigned *, int, int);
|
|
void advance_cursor(unsigned, unsigned);
|
|
void dump_list(unsigned);
|
|
void dump_times(unsigned);
|
|
void add_recv_time(host_entry *, struct timeval *);
|
|
void load_backoff_patterns(const char *, unsigned);
|
|
void add_pattern(char *, unsigned);
|
|
void load_vid_patterns(const char *);
|
|
void add_vid_pattern(char *);
|
|
char **load_id_strings(char *);
|
|
char *match_pattern(host_entry *);
|
|
int times_close_enough(struct timeval *, struct timeval *, unsigned);
|
|
void dump_backoff(unsigned);
|
|
void dump_vid(void);
|
|
unsigned int hstr_i(const char *);
|
|
unsigned char* hex2data(const char *, size_t *);
|
|
unsigned char* hex_or_str(const char *, size_t *);
|
|
unsigned char* hex_or_num(const char *, size_t *);
|
|
unsigned char* make_isakmp_hdr(unsigned, unsigned, unsigned, int, int,
|
|
unsigned, unsigned char*, size_t);
|
|
unsigned char* make_sa(size_t *, unsigned, unsigned, unsigned, unsigned char *,
|
|
size_t);
|
|
unsigned char* make_sa2(size_t *, unsigned, unsigned char *, size_t);
|
|
unsigned char* make_prop(size_t *, unsigned, unsigned, unsigned, unsigned,
|
|
unsigned, unsigned char *, size_t);
|
|
unsigned char* add_prop(int, size_t *, unsigned, unsigned,
|
|
unsigned, unsigned char *, size_t);
|
|
unsigned char* make_trans_simple(size_t *, unsigned, unsigned, unsigned,
|
|
unsigned, unsigned, unsigned, unsigned,
|
|
unsigned char *, size_t, unsigned char *,
|
|
size_t, int, unsigned char *, size_t,
|
|
unsigned);
|
|
unsigned char* add_trans_simple(int, size_t *, unsigned, unsigned, unsigned,
|
|
unsigned, unsigned, unsigned char *, size_t,
|
|
unsigned char *, size_t, int, unsigned char *,
|
|
size_t, unsigned);
|
|
unsigned char* make_attr(size_t *, int, unsigned, size_t, unsigned, void *);
|
|
unsigned char* add_attr(int, size_t *, int, unsigned, size_t, unsigned,
|
|
void *);
|
|
unsigned char* make_vid(size_t *, unsigned, unsigned char *, size_t);
|
|
unsigned char* add_vid(int, size_t *, unsigned char *, size_t, unsigned);
|
|
unsigned char* make_ke(size_t *, unsigned, size_t);
|
|
unsigned char* make_ke2(size_t *, unsigned, unsigned, size_t);
|
|
unsigned char* make_nonce(size_t *, unsigned, size_t);
|
|
unsigned char* make_id(size_t *, unsigned, unsigned, unsigned char *, size_t);
|
|
unsigned char* make_cr(size_t *, unsigned, unsigned char *, size_t);
|
|
unsigned char* make_udphdr(size_t *, unsigned, unsigned, unsigned);
|
|
int Gettimeofday(struct timeval *);
|
|
void *Malloc(size_t);
|
|
void *Realloc(void *, size_t);
|
|
unsigned long int Strtoul(const char *, int);
|
|
void decode_trans_simple(const char *, unsigned *, unsigned *, unsigned *,
|
|
unsigned *, unsigned *);
|
|
unsigned char *decode_transform(const char *, size_t *);
|
|
unsigned char *skip_payload(unsigned char *, size_t *, unsigned *);
|
|
unsigned char *process_isakmp_hdr(unsigned char *, size_t *, unsigned *,
|
|
unsigned *, char **);
|
|
char *process_sa(unsigned char *, size_t, unsigned, int, int, char *);
|
|
char *process_sa2(unsigned char *, size_t, unsigned, int, int, char *);
|
|
char *process_attr(unsigned char **, size_t *);
|
|
char *process_transform2(unsigned char **, size_t *);
|
|
char *process_vid(unsigned char *, size_t, vid_pattern_list *);
|
|
char *process_notify(unsigned char *, size_t, int, int, char *);
|
|
char *process_notify2(unsigned char *, size_t, int, int, char *);
|
|
char *process_id(unsigned char *, size_t);
|
|
char *process_cert(unsigned char *, size_t, unsigned);
|
|
char *process_delete(unsigned char *, size_t);
|
|
char *process_notification(unsigned char *, size_t);
|
|
char *process_generic(unsigned char *, size_t, unsigned);
|
|
unsigned char *make_transform(size_t *, unsigned, unsigned, unsigned,
|
|
unsigned char *, size_t);
|
|
unsigned char* add_transform(int, size_t *, unsigned, unsigned char *, size_t);
|
|
unsigned char* make_transform2(size_t *, unsigned, unsigned, unsigned,
|
|
unsigned char *, size_t);
|
|
unsigned char* add_transform2(int, size_t *, unsigned, unsigned,
|
|
unsigned char *, size_t);
|
|
unsigned char *add_isakmp_payload(unsigned char *, size_t, unsigned char **);
|
|
void print_payload(unsigned char *cp, unsigned payload, int);
|
|
void add_psk_crack_payload(unsigned char *cp, unsigned, int);
|
|
void print_psk_crack_values(const char *);
|
|
unsigned char *clone_payload(const unsigned char *, size_t);
|
|
char *make_message(const char *, ...);
|
|
char *numstr(unsigned);
|
|
char *printable(const unsigned char*, size_t);
|
|
char *hexstring(const unsigned char*, size_t);
|
|
void print_times(void);
|
|
void sig_alarm(int);
|
|
const char *id_to_name(unsigned, const id_name_map[]);
|
|
int name_to_id(const char *, const id_name_map[]);
|
|
uint16_t in_cksum(uint16_t *, size_t);
|
|
uint8_t random_byte(void);
|
|
uint32_t random_ip(void);
|
|
int str_ccmp(const char *, const char *);
|
|
unsigned name_or_number(const char *, const id_name_map[]);
|
|
/* MT19937 prototypes */
|
|
void init_genrand(unsigned long);
|
|
void init_by_array(unsigned long[], int);
|
|
unsigned long genrand_int32(void);
|
|
long genrand_int31(void);
|
|
double genrand_real1(void);
|
|
double genrand_real2(void);
|
|
double genrand_real3(void);
|
|
double genrand_res53(void);
|
|
/* The following functions are just to prevent rcsid being optimised away */
|
|
void error_use_rcsid(void);
|
|
void isakmp_use_rcsid(void);
|
|
void wrappers_use_rcsid(void);
|
|
void utils_use_rcsid(void);
|
|
|
|
#endif /* IKE_SCAN_H */
|