#ifndef SANCP_H #include "sancp.h" #endif #include using namespace std; /************************************************************************** **SA Network Connection Profiler [sancp] - A TCP/IP statistical/collection tool * ************************************************************************ * * Copyright (C) 2003 John Curry * * * * This program is distributed under the terms of version 1.0 of the * * Q Public License. See LICENSE.QPL for further details. * * * * 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. * * * ***********************************************************************/ void usage() { cout << "\n" << "**************************************************************************\n" << "**Security Analyst Network Connection Profiler [sancp] - v " << VERSION <<"\n" << "** A TCP/IP statistics and pcap collection tool\n" << " * ************************************************************************\n" << " * * Copyright (C) 2003,2004 John Curry \n" << " * *\n" << " * * This program is distributed under the terms of version 1.0 of the\n" << " * * Q Public License. See LICENSE.QPL for further details.\n" << " * *\n" << " * * This program is distributed in the hope that it will be useful,\n" << " * * but WITHOUT ANY WARRANTY; without even the implied warranty of\n" << " * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" << " * *\n" << " * ***********************************************************************\n" << "\n" << "\n" << " About SANCP:\n" << " ------------\n" << "\n" << " Without specifying any options, SANCP (pronounced san-cee-pee) collects\n" << " all network traffic on the default pcap interface 'any' \n" << " SANCP creates three types of output files (pcap, realtime, and stats)\n" << " in the current directory. Filenames contain the interface (-i) and\n" << " timestamp, both are optional.\n" << " All three output types are optional see: -R -P -S cmdline options\n" << "\n" << "\n" << " pcap:\n" << " -----\n" << " We record all pcap data in tcpdump format, as it arrives.\n" << " Filename format: pcap..\n" << "\n" << " realtime:\n" << " ---------\n" << " We record a 'realtime' entry upon seeing the first \n" << " packet of each unique connection. The 'realtime' format is changable.\n" << " Filename format: realtime..\n" << "\n" << " stats:\n" << " -----\n" << " We record a 'stats' entry when a connection terminates or times out.\n" << " The 'stats' format is changable" << " Filename format: stats..\n" << "\n" << " debug_pcap_raw: (Fourth output for Debug mode)\n" << " ---------------\n" << " When the -A option is given, log all pcap data to a second pcap file\n" << " -before- any rule or packet manipulation occurs.\n" << " See: 'default debug_pcap_raw enable'\n" << " Filename format: debug_pcap_raw..\n" << "\n" << "\n" << " *Important Notes about how SANCP handles pcap files*\n" << "\n" << " SANCP may actively log to multiple files -at the same time-.\n" << " SANCP will log all pcap data (for a given connection)\n" << " is written to the same pcap file. SANCP does this by associating\n" << " each connection with the 'current' pcap output filehandle. \n" << " Pcap files will remain open until all connections associated with it\n" << " either terminate or timeout\n" << " SANCP will append pcap data to 'pre-existing' pcap files (ref: rule directive 'pcap filename')\n" << " However ,preexisting files need to have valid pcap headers since SANCP will only create \n" << " a pcap header for new/empty files.\n" << " When managing SANCP pcap files, always check to see if the file \n" << " is in use before handling it in a destructive manner. If you destroy a SANCP output\n" << " file, while actively in use, SANCP will not recreate the file on the disk for subsequent logging.\n" << " SANCP assumes files that it opens are always present.\n " << " This is done so that SANCP can write pcap data quickly.\n" << "\n" << " i.e. use a system command such as 'fuser' to check whether a process is using an output file.\n" << "\n" << "\n" << " HINT:\n" << " If write rules to define your normal traffic with 'realtimes=pass' set on each,\n" << " then all abnormal activity will be appear in the realtime log.\n" << "\n" << " HINT:\n" << " 'Tuning' sancp consists of running it, extracting new activity from realtime files,\n" << " creating rules to identify the normal activity and having sancp re-read the configuration file\n" << " (Using kill -HUP ).\n" << "\n" << " Command Line Options: (cmdline)\n" << " ---------------------\n" << "\n" << " -? or -h this help screen\n" << " -c specify the configuration/rules filename\n" << " -d specify the directory for output files\n" << " -i set the network device to listen on (default: 'any')\n" << " -g set a group identity\n" << " -u set a user identity\n" << " -r pcap file to read (overrides -i)\n" << " -B \"\" set a bpf expression (alternative to -F )\n" << " -D (daemon) forks, prints msgs to syslog only and overrides -C option\n" << " -K (console) enable additional printing of 'realtimes' to stdout (suppressed by option -D)\n" << " -F file containing a bpf filter expression, overrides (alternative to -B)\n" << " -H --human-readable write IP addresses in dotted notation and TCPflag fields in hex \n" << " -R Set default for realtime to 'pass' (default is 'log') disables realtime, but rules can override\n" << " -S Set default for stats to 'pass' (default is 'log') disables stats, but rules can override\n" << " -P Set default for pcap to 'pass' (default is 'log') disables pcap, but rules can override\n" << " -I or --enable_icmp_mixed record 'code' and 'type' fields for ICMP\n" << " to the fields 's_port' and 'd_port'.\n" << " note: affects how related icmp packets are correlated \n" << " -V display version\n" << " --shift (debug) force interpretation of packet starting at byte[2] \n" << " normally performed when reading from the 'any' interface\n" << " --strip-80211 strip 802.1Q headers from 802.1Q packets; used to \n" << " decode 802.1Q encapsulated packets - affects -A option, \n" << " --log-facility where facility can be 'LOCAL1' - 'LOCAL7'\n" << " The default log facility used by SANCP is LOG_DAEMON \n" << "\n" << " # Debug mode for pcap data logging\n" << " -A records ALL traffic frames to a pcap file named 'debug_pcap_raw'\n" << " (despite rules). Packets are logged here prior to decoding or handling. \n" << " Use -F or -B option to restrict what is collectedi.\n" << " Pcap data logged using this option is affected by the --strip-80211 cmdline option\n" << " The configuration file equivalent to this is 'default debug_pcap_raw enable'\n" << "\n" << "\n" << " Kill Signals:\n" << " -------------\n" << " \n" << " -HUP re-read rules configuration file and open new output files\n" << " (sets new used for new output files)\n" << " -USR1 print running configuration (with counters for rule matches)\n" << " -USR2 print -all ongoing- connections to stdout\n" << "\n" << " HINT:\n" << " Run sancp something like this to have access the kill signal output in daemon mode\n" << " sancp -D -H >> sancp.output & \n" << " This way you can view it 'cat sancp.output' and then clear it '> sancp.output'\n" << " and sancp will continue to output to this file as normal.\n" << "\n" << " Output Fields: for 'realtime' and 'stats' files\n" << " (Some realtime fields are naturally blank, i.e. counters)\n" << " --------------\n" << "\n" << " 1: 64bit sancp id: based on timeptr.tv_sec and timeptr.tv_usec\n" << " 2: 32bit start time: unix timestamp for first packet\n" << " 3: 32bit end time: unix timestamp for last packet\n" << " 4: 32bit erased time: unix timestamp for when connection was cleared from memory\n" << " 5: 16bit hw_proto: layer 2 protocol number\n" << " 6: 8bit proto: layer 3 protocol (if IP proto is layer 2)\n" << " 7: 32bit source address: dotted notation IP address\n" << " 8: 16bit source port: i.e. udp, tcp \n" << " also used for icmp 'type' (see: --enable_icmp_mixed)\n" << " 9: 32bit destination address: dotted notation IP address\n" << " 10: 16bit destination port: i.e. udp, tcp \n" << " also used for icmp 'code' (see: --enable_icmp_mixed)\n" << " 11: 32bit duration: seconds the connection remained active \n" << " (difference between start and end times)\n" << " 12: 16bit timeout: applicable timeout value for the connection\n" << " 13: 64bit source packets: packets received from source\n" << " 14: 64bit destination packets: packets received from destination\n" << " 15: 64bit source bytes: bytes received from source\n" << " 16: 64bit destination bytes: bytes received from destination\n" << " The next two fields contain 8bit values representing 8 possible TCP flags\n" << " cumulativeily seen from source and destination throughout the connection\n" << " 8Bit order is 12UAPRSF, where:\n" << " 1: Reserved bit 1 from source\n" << " 2: Reserved bit 2 from source\n" << " U: Urgent Pointer bit from source\n" << " A: ACK bit from source\n" << " P: Push bit from source\n" << " R: Reset bit from source\n" << " S: SYN bit from source\n" << " F: FIN bit from source\n" << "\n" << " 17: 8bit sflags: cumlative tcp flags from source (bit order: 12UAPRSF)\n" << " 18: 8bit dflags: cumlative tcp flags from dest (bit order: 12UAPRSF)\n" << "\n" << " The next field contains an 8bit value representing 6 possible TCP close session flags\n" << " from the source and destination. The first 2 significant bits are unused.)\n" << " 8Bit order is 00AARRFF/00DSDSDS, where:\n" << " DA: Close ACK seen from destination\n" << " SA: Close ACK seen from source\n" << " DR: Close Reset seen from destination\n" << " SR: Close Reset seen from source\n" << " DF: Close FIN seen from destination\n" << " SF: Close FIN seen from source\n" << " 19: 8bit closed flags (bit order: 00AARRFF/00DSDSDS)\n" << "\n" << " The next 8 fields contain p0F information gathered from initial TCP packet\n" << " 20: 16bit wss: window segment size (initial packet, tcp only)\n" << " 21: 8bit ttl: time to live (initial packet, tcp only)\n" #ifdef EXPERIMENTAL_TCPOPTIONS << " 22: 16bit mss: maximum segment size (initial packet, tcp only)\n" #else << " 22: 16bit mss: maximum segment size (initial packet, tcp only) need to re-compile with EXPERIMENTAL_TCPOPTIONS\n" #endif << " 23: Y/N df: don't fragment bit was set (initial packet, tcp only)\n" #ifdef EXPERIMENTAL_TCPOPTIONS << " 24: 8bit wscale: window scale (initial packet, tcp only)\n" << " 25: Y/N sack_ok: sack_ok flag was set (initial packet, tcp only)\n" << " 26: Y/N nop: 'no op' was seen (initial packet, tcp only)\n" #else << " 24: 8bit wscale: window scale (initial packet, tcp only) need to re-compile with EXPERIMENTAL_TCPOPTIONS\n" << " 25: Y/N sack_ok: sack_ok flag was set (initial packet, tcp only) need to re-compile with EXPERIMENTAL_TCPOPTIONS\n" << " 26: Y/N nop: 'no op' was seen (initial packet, tcp only) need to re-compile with EXPERIMENTAL_TCPOPTIONS\n" #endif << " 27: 16bit len: ip length (initial packet, tcp only)\n" << "\n" << " The next 8 fields contain p0F information gathered from second TCP packet\n" << " 28: 16bit wss2: window segment size (second packet, tcp only)\n" << " 29: 8bit ttl2: time to live (second packet, tcp only)\n" << " 30: 16bit mss2: maximum segment size (second packet, tcp only)\n" << " 31: Y/N df2: don't fragment bit was set (second packet, tcp only)\n" << " 32: 8bit wscale2: window scale (second packet, tcp only)\n" << " 33: Y/N sack_ok2: sack_ok flag was set (second packet, tcp only)\n" << " 34: Y/N nop2: 'no op' was seen (second packet, tcp only)\n" << " 35: 16bit len2: ip length (second packet, tcp only)\n" << "\n" << " The last 7 fields contain information about how we handled the connection\n" << " 36: 8bit reversed: did we reverse the ip addresses seen in the \n" << " initial packet? 0=no, 1=yes, 2=no(both ports were known),\n" << " 3=no(both ports were unknown)\n" << " 37: 8bit collect: what mode was used for collecting: \n" << " none, both, from_src, from_dst (0,1,2,3 respectively)\n" << " 38: 64bit collected: how much data did we collect \n" << " 39: 64bit limit: how much data were we limited to collecting\n" << " 40: 16bit tcplag value: seconds to wait for straggler packets, after the connection 'ends'\n" << " 41: Y/N pcap enabled: did we record data to a pcap file \n" << " (does not apply to data recorded using the -A option)\n" << " 42: Y/N realtime enabled: did we record the connection to a realtime file\n" << " 43: Y/N stats enabled: did we record the connection to a stats file \n" << " 44: 16bit hash value: used for tuning (developer's choice)\n" << " 45: 64bit total_bytes: useful for overall statistics\n" << " 46: 32bit rid: rule id assoc. w/ the network profile rule that this connection matched on ('0' is default)\n" << " 47: 8bit status: status assigned to this connection i.e. assigned by rule\n" << " 48: 16bit node: node/network interface/sancp instance associated this connection\n" << " i.e. assigned globally as a 'default' or, specifically, by a rule\n" << " 49: 17byte src-mac: source ethernet address in ascii format i.e. xx:xx:xx:xx:xx:xx \n" << " 50: 17byte dst_mac: destination ethernet address in ascii format i.e. xx:xx:xx:xx:xx:xx \n" << "\n" << "\n" << "\n" << " HINT:\n" << " Check fields 41-43 to see what kind of logging was performed on the connection at a glance\n" << " i.e. 'Was a realtime logged' (a.k.a 'have we seen this traffic before')\n" << " i.e. 'Did we collect any data' (a.k.a '')\n" << "\n" << "\n" << "\n" << "\n" << " Configuration and Rule Syntax: (one rule per line)\n" << " -----------------------------\n" << "\n" << "\n" << " The configuration file designates the characters: ',' and '=' as word separators\n" << " These four characters may be used liberally as rule-beautifying delimiters; they are treated spaces.\n" << "\n" << "\n" << " var syntax:\n" << " -----------------------:\n" << " Use vars to avoid having to use protocol numbers in rules i.e. var icmp 1\n" << " Vars are used to define 4 kinds of values: ethernet protocols, ip addresses, ip protocols, and ports\n" << " These values are present in the connection rules and the known_ports definition\n" << " These vars remain present when sancp prints the running configuration\n" << " Var 'names' should be unique nnd represent only one kind of value, else rule behavior is undefined \n" << " (generally, you may get parse errors or the running configuration output will appear incorrect.)\n" << " \n" << " Vars have valid value ranges depending on the kind of value they are to represent;\n" << " ethernet protocols: 0x0-0xFFFF (0-65535)\n" << " ip addresses: 0.0.0.0/255.255.255.255 (0.0.0.0/32)\n" << " ip protocols: 0x0-0xFF (0-255)\n" << " ports: 0x0-0xFFFF (0-65535)\n" << " Values outside these ranges may be trunicated or otherwise result in a rule error\n" << " You can represent all but 'dotted-ip' values in decimal, hex or octal.\n" << " One single range should be specified in a var. In the case of an IP address, you \n" << " will want to use a normal ipaddress/mask to represent a 'network range'\n" << " \n" << " var |]}>\n" << " Define for use in place of IP addresses in proceding rules\n" << "\n" << " 'default' syntax:\n" << " -----------------------:\n" << " default (defaults specified here override command line options\n" << " keywords:\n" << " pcap {log|pass}\n" << " realtime {log|pass}\n" << " stats {log|pass}\n" << " limit \n" << " timeout \n" << " tcplag \n" << " status \n" << " pcapfilter [ bpf expression ] (read only once at start-up)\n" << " strip-80211 { disable|enable }\n" << " node \n" << " debug_pcap_raw { disable|enable }\n" << "\n" << " known_port syntax:\n" << " -----------------------:\n" << " known_ports [] [{-}{,}{,...}] \n" << " Define a list of 'known tcp and/or udp server ports'\n" << " SANCP will use these lists to help 'resolve/guess' the direction of ambiguous tcp/udp connections\n" << " Lists should only be provided to help reduce the occurrance of logging 'reversed' connections.\n" << " And were going to make this one hurt... you have to specify '6' or '17' for the \n" << " Or just create and use vars for them i.e. 'var tcp 6','var udp 17'\n" << "\n" << " Short Example of using vars in conjuntion with known_ports:\n" << "\n" << " var tcp 6\n" << " var udp 17\n" << " var http 80\n" << " var https 443\n" << " var dns 53\n" << " known_ports udp dns\n" << " known_ports tcp dns,http,https\n" << "\n" << "\n" << " connection rule syntax:\n" << " -----------------------:\n" << "\n" << " A connection rule consists of two central parts:\n" << " 1) network connection profile \n" << " i.e. ether proto, ip address, ip proto and ports\n" << " 2) options\n" << " a) collection options\n" << " i.e. stats=pass, pcap=pass, realtime=pass, timeout=120 or limit=1500 \n" << " b) tagging options \n" << " i.e. status=16 rid=1112 node=2 \n" << "\n" << " [[-] [|}>] [|}>] [{tcp|udp|icmp|[-] }]\n" << " [{-[]}] [{-[]}] \n" << " { ignore | stats [{log|pass}] | realtime [{log|pass}] |\n" << " pcap [ {log|pass|rule|connection|{filename|tsfilename} []}\n" << " { logdst|logsrc } { timeout []|limit []|tcplag []|retro|status <0-255>|rid |node }\n" << "\n" << "\n" << " Description for connection options:\n" << " --------------------------------------\n" << "\n" << " timeout - set delay after last packet before expiring the connection \n" << " limit - set max bytes of pcap data to record per connection \n" << " realtime (option):\n" << " pass - do not log realtime for this traffic\n" << " log - log realtime for this traffic\n" << " stats (option): \n" << " pass - do not log statistics for this traffic\n" << " log - log statistics for this traffic\n" << " pcap (option): \n" << " pass - do not record pcap data\n" << " log - record pcap data to the default 'pcap' output file\n" << " rule - record pcap data to output file; filename derived from rule\n" << " connection - record pcap data to a output file; filename derived \n" << " from the connection\n" << " filename - record pcap data to a specific output \n" << " filename (names starting with '/' are considered absolute).\n" << " logsrc - only record pcap data from the source (default is both)\n" << " logdst - only record pcap data from the destination (default is both)\n" << " ignore - set realtime, stats, and pcap to 'pass' (ignores any logdst or logsrc options)\n" << " retro - apply this rule to -all- ongoing connections, not just new ones\n" << "\n" << " Description of 'tagging' options:\n" << " --------------------------------------\n" << "\n" << " status - status to be assigned to matching connections \n" << " rid - rule id (32bit) for this rule (assign to matching connections)\n" << " node - node id (8bit) number to assign to matching connections\n" << " the node id is formed from the notion that more than one network could be monitored\n" << " by one or more instances of sancp on the same system. Node id can be handy in rules\n" << " to help tag traffic as belonging to a certain network interface; i.e. consider '-i any'\n" << "\n" << "\n" << " NOTE: Malformed rules are reported to syslog and simply ignored\n" << "\n" << "\n" << "\n" << " Basic Examples:\n" << " ---------------\n" << "\n" << "\n" << " Notes:\n" << "\n" << " Below is a matrix outlining how the three different output types are used for four different modes of operation.\n" << "\n" << " Output Type Mode 1 Mode 2 Mode 3 Mode 4 Mode 5\n" << " ----------------------------------------------------- \n" << " pcap log log pass pass * \n" << " realtime log pass pass pass * \n" << " stats log log log pass * \n" << " debug_pcap_raw disable disable disable disable enable\n" << "\n" << " These modes can be obtained by setting their 'defaults' in the sancp.conf\n" << " or by providing the command line option: -P -S and -R to disable pcap, stats\n" << " and realtime, respectively \n" << "\n" << " IMPORTANT NOTE: the configuration file overides the cmdline options to ensure SANCP\n" << " can be controlled through configuration file changes (use: kill -HUP to re-read the config)\n" << "\n" << " Mode 1: Default Monitoring Mode: allow full access to 'realtime', 'stats' and 'pcap' data\n" << " Use a set of rules which define your network. Disable realtime for uninteresting traffic.\n" << " Use collection options to reduce collection effort on certain traffic\n" << " Use realtime entries as 'alerts' to notify you of new and interesting traffic\n" << " Modify rules real-time so sancp can stay current with your changing collection requirements\n" << " Use rule identifiers (rid)'s to mark connections as matching a different kinds (profiles) of traffic\n" << " Storing rules with rule id's in the same database allows for quick access to connections\n" << " of certain kinds of traffic\n" << "\n" << " Mode 2: Batch Analysis Mode: for (re)processing pcap files - realtime disabled\n" << " Use a set of rules to extract interesting traffic from large tcpdump files;\n" << " Create a 'pcap' file containing only traffic of interest.\n" << " Use the 'stats' file as an index to the data available in 'pcap' file.\n" << "\n" << " Mode 3: Connection Profiling Mode: (output only a stats log from a pcap file)\n" << " Rules may be needed to exclude certain IP traffic you don't care about.\n" << "\n" << " Mode 4: Pcap Split Mode: turns off all default output modes, uses rules to\n" << " control which files matching traffic should be written to.\n" << " Use the 'pcap filename ' rule option to specify an output file.\n" << " The 'pcap rule' option will create a filename based on/derived from the rule itself\n" << " i.e. -:-_-:-_-.\n" << " The 'pcap uniq' option will write to a pcap file whose filename is\n" << " based on/derived from the connection itself:\n" << " i.e. :_:-.\n" << "\n" << " Mode 5: Debug Pcap Raw Mode: additionally, records all traffic to a 'debug_pcap_raw' file\n" << " regardless of any rules. 80211 headers are still stripped, if configured to do so\n" << " This is enabled via command line (-A) or via config file (default debug_pcap_raw enable)\n" << " It can subsequently be disabled via config file (default debug_pcap_raw disable)\n" << "\n" << " **To use the configuration file to dynamically (re)configure sancp while running**\n" << " see: 'kill signals'\n" << "\n" << " -----------------------------\n" << " #\n" << " # Example sancp.conf file\n" << " #\n" << " # Define known_ports to help sancp determine connection direction\n" << " # for pre-existing udp and tcp connections (i.e. at startup)\n" << " # We set these only as we need them. They are used for half-open TCP connections\n" << " # (ie. if we missed the syn or syn-ack), and for all udp connections \n" << " # The 'reversed' field in the connection (profile) output will tell you if \n" << " # SANCP recorded the direction opposite that of the initial packet (i.e. '1').\n" << " #\n" << " # known_ports tcp 80,443\n" << " # known_ports udp 53\n" << "\n" << " # Override default logging for stats, pcap, and realtime \n" << " #\n" << " # ** The sancp configuration file can be re-loaded dynamically while running **\n" << " #\n" << " # Configure default mode for 'stats' logging\n" << " #\n" << " #default stats log # sets default mode to 'log stats' (*default mode)\n" << " # # use 'pass' to set default mode to 'do not log stats'\n" << " #\n" << " # Configure default mode for 'pcap' logging \n" << " #\n" << " #default pcap log # sets default mode to 'record pcap data' (*default mode)\n" << " # # use 'pass' to set default mode to 'do not record pcap data' \n" << " #\n" << " # Configure default mode for 'realtime' logging \n" << " #\n" << " #default realtime log # create a realtime when we record pcap data (*default mode)\n" << " # # use 'pass' set default to 'not create' realtime \n" << " # Note: You can add the 'realtime log' option to a rule to 'force' all matches to log a \n" << " # realtime regardless of whether we record pcap data\n" << " #\n" << " #default debug_pcap_raw disable # enable|disable debug pcap logging mode for online debugging\n" << " # # if set to 'enable' we will record packets to a 'debug_pcap_raw' file, regardless of rules \n" << " #\n" << " #default status 0 # sets default 8bit status (0-255) for all connections which do not match a rule, or where a status is not specified for a rule(default = 0)\n" << " #\n" << " # Define local vars (used for IP/MASK combinations only)\n" << " var HOME_NET 192.168.1.0/24\n" << " var ip 8\n" << "\n" << " #\n" << " # The following rule syntax is supported:\n" << " # Rule format:\n" << " # sip dip proto sp dp options\n" << " # any any any any any pcap none\n" << "\n" << " # Ignore outbound HTTP (ignore both pcap and stats)\n" << " ip HOME_NET any tcp any 80 pcap pass stats pass\n" << "\n" << " # Do not record ssh data\n" << " ip HOME_NET any tcp any 22 pcap pass\n" << "\n" << " # Streaming media can kill your logging so\n" << " # we ignore UDP > 1024 with few a exceptions\n" << " ip any HOME_NET udp any 1025-32769 pcap pass\n" << " ip any HOME_NET udp any 32781- pcap pass\n" << "\n" << " # Don't log ICMP at all (no stats, pcap, or realtime) \n" << " ip any any icmp any any ignore\n" << "\n" << " # Ignore incoming blaster scans\n" << " ip any HOME_NET tcp any 135 ignore\n" << "\n" << "\n"; }