The Libebox Intrusion Detection Library |
Libebox library (toolkit) allows the application programmer to easily capture, classify and detect anomalies in network traffic.
It allows a programmer to capture all protocols and pass that information into user designed functions,
for easy proc
essing and detection of errors and attempts to evade, interrupt and or intrude into netwok systems.
Most complex network programs can be rewritten with libebox with ease and simplicity.
There are a myriad of functions for detection and for parsing and displaying captured information.
And gives the programmer the functionality to override/replace/add to any protocol decoder
Libebox-Traffic Phases:
START_UP | PKT_PHASE | ALL_PHASE | ETHER_PHASE | IPV4_PHASE | TCP_PHASE | UDP_PHASE | PPPOE_PHASE | IPV4_FRAG_PHASE | IPV6_PHASE | ARP_PHASE | IPX_PHASE | MPLS_PHASE | Q8021Q_PHASE | JUMBO_PHASE | ISOCLNS_PHASE | EAP_PHASE | PPP_PHASE | SLOW_PHASE | CDP_PHASE | LOOP_PHASE | PPP_ENCAP_PHASE | IEEE802_PHASE | CHDLC_PHASE | FDDI_PHASE | TOKEN_PHASE | SLL_PHASE | ARCNET_PHASE | ARCNET_LNX_PHASE | LANE_PHASE | CIP_PHASE | SL_PHASE | SL_B_PHASE | FR_PHASE | SUNATM_PHASE | PRISIM_PHASE | IEE802_11_RADIO_PHASE | ENCAP_PHASE | ATM_PHASE | AP1394_PHASE | IPFC_PHASE | SCTP_PHASE | IGRP_PHASE | EGP_PHASE | OSPF4_PHASE | OSPF6_PHASE | IGMP_PHASE | RSVP_PHASE | GRE_PHASE | MOBILE_PHASE | VRRP_PHASE | VLAN_PHASE | RAWPKT_PHASE |
RAWIP_PHASE | I4L_PHASE | ICMP4_PHASE | STP_PHASE | PIM_PHASE | AH_PHASE | IPCOMP_PHASE | ESP_PHASE | DCCP_PHASE | UDP6_PHASE | MOBL_PHASE | IP6_ROUTE_PHASE | IP6_FRAG_PHASE | ICMP6_PHASE | TCP6_PHASE | STREAM_PHASE | EBOX_S5_PHASE | SNORT_S5_PHASE |
» Libebox is distrubuted under the GNU license.
» An Incomplete (and slighlty out of date) Man-Page. Updated Documentaion to follow soon.
» Example Of Writing engine module for libebox.
» Example Of Writing parser module for libebox.
» Libebox was designed and is maintained by Garrick Hermitt-Barrett.
I can be reached here |
Libebox supports modules {engines and parsers} that can be written and later loaded by an application.
» Currently distributed modules:
Engines:
engines/libpkttimer.so | packet timer engine |
engines/libsnipcopy.so | load snort ip copy util |
engines/libstats.so | simple stats engine |
engines/libfr.so | frame relay engine |
engines/libap1394.so | apple ap1394 engine |
engines/libarcnet.so | arcnet engine |
engines/libatm.so | atm engine |
engines/libcip.so | cip engine |
engines/libenc.so | enc engine |
engines/libipfc.so | ipfc engine |
engines/libsunatm.so | sunatm engine |
engines/libsl.so | sl engine |
engines/libdccp.so | dccp engine |
engines/libipv4frag.so | ipv4 frag engine |
engines/libfingeros.so | finger os engine -- tcp only |
engines/libscan.so | simple scan engine |
engines/libaltbuffer.so | altbuffer storage |
engines/libstream5e.so | snort stream5e engine uses ParserPkt |
engines/libipv6frag.so | ipv6 frag engine |
engines/libconficker.so | load conficker detection utility |
engines/snort/libsn_stream5.so | snort stream5 engine uses a cropped SnortPacket |
engines/snort/libsn_ftptelnet.so | snort ftptelnet engine |
engines/snort/libsn_searchapi.so | snort search api |
engines/snort/libsn_arpspoof.so | snort arpspoof engine |
engines/snort/libsn_frag3.so | snort frag3 engine |
engines/snort/libsn_sfpscan.so | snort sf portscan engine |
engines/snort/libsn_bo.so | snort bo engine |
engines/snort/libsn_rpc.so | snort rpc engine |
engines/snort/libsn_http1.so | snort simple http engine |
engines/snort/libsn_ssh.so | snort ssh engine |
engines/snort/libsn_smtp.so | snort smtp engine |
engines/snort/libsn_dns.so | snort dns engine |
engines/snort/libsn_dcerpc.so | snort dcerpc engine |
Parsers: ** These are only distributed to test the api ** they provide no other relevant functionality
parsers/libether_psr.so | ethernet parser |
parsers/libipv4_psr.so | ipv4 parser |
parsers/libsearchtest_psr.so | snort search api test |
» Latest Stable Version: 2.0.1-rc3
» Libebox 2.0.1 supported protocols/detectioin modes
Basic warn types: {Class}
IDS_WARN_ETH
IDS_WARN_IP
IDS_WARN_IP6
IDS_WARN_IP6_OPT
IDS_WARN_IP6_FRAG
IDS_WARN_ICMP6
IDS_WARN_TCP
IDS_WARN_UDP
IDS_WARN_SCAN
IDS_WARN_OSPF
IDS_WARN_OSPF6
IDS_WARN_RT6
IDS_WARN_IPCOMP
IDS_WARN_AH
IDS_WARN_ESP
IDS_WARN_IGRP
IDS_WARN_IGMP
IDS_WARN_EGP
IDS_WARN_GRE
IDS_WARN_MOBILE
IDS_WARN_VRRP
IDS_WARN_SCTP
IDS_WARN_PIM
IDS_WARN_IPX
IDS_WARN_VLAN
IDS_WARN_PPPoE
IDS_WARN_ARP
IDS_WARN_ATMARP
IDS_WARN_IEEE_802
IDS_WARN_MOBILITY
IDS_WARN_RSVP
IDS_WARN_MPLS
IDS_WARN_TCPen6
IDS_WARN_UDPen6
IDS_WARN_ICMP
IDS_WARN_TOKEN
IDS_WARN_FDDI
IDS_WARN_TCPSTREAM
IDS_WARN_CDP
IDS_WARN_STP
IDS_WARN_ISOCLNS
IDS_WARN_CHDLC
IDS_WARN_ARCNET
IDS_WARN_ARCNET_LINUX
IDS_WARN_80211_RADIO
IDS_WARN_PRISM
IDS_WARN_FIREWIRE
IDS_WARN_CIP
IDS_WARN_FR
IDS_WARN_LANE
IDS_WARN_IPFC
IDS_WARN_SLIP
IDS_WARN_SUNATM
IDS_WARN_ENC
IDS_WARN_LLC
IDS_WARN_ATM
IDS_WARN_SLOW
IDS_WARN_SNAP
IDS_WARN_SMB
IDS_WARN_DCCP
IDS_WARN_RPC
IDS_WARN_SSH
IDS_WARN_DVMRP
Basic warn types: {Errors}:
IDS_WARN_UNDEFINED
IDS_WARN_ETH_HDR_LEN
IDS_WARN_IP_OVERSIZED
IDS_WARN_IP_TSERROR
IDS_WARN_TRUNCATED_IP
IDS_WARN_IP_OPTS
IDS_WARN_IP_OPTS_TRUNC
IDS_WARN_IP_INVLIST
IDS_WARN_IP_OVERLAP
IDS_WARN_IP_HDR
IDS_WARN_IP_SRR
IDS_WARN_IP_MAX_PORTS
IDS_WARN_IP6_HDRLEN
IDS_WARN_IP6_LEN
IDS_WARN_IP6_SAMEIP
IDS_WARN_IP6_HBHOPT
IDS_WARN_IP6_DSTOPT
IDS_WARN_IP6_SOPT_DECODE
IDS_WARN_IP6_OPTS_DECODE
IDS_WARN_IP6_OVERSIZED_PKT
IDS_WARN_IP6_FRAG_OFF
IDS_WARN_IP6_FRAG_HDRERROR
IDS_WARN_IP6_FRAG_ROUNDED_ERROR
IDS_WARN_IP6_FRAG_NOTFRAG
IDS_WARN_ICMP6_HDRLEN
IDS_WARN_ICMP6_HDR
IDS_WARN_ICMP6_OPTS
IDS_WARN_ICMP6_CSUM
IDS_WARN_ICMP6_RRENUM
IDS_WARN_ICMP6_V2MEMB
IDS_WARN_ICMP6_NIINFO
IDS_WARN_TCP_TOOMUCH
IDS_WARN_TCP_HDR
IDS_WARN_TCP_BIGQUEUE
IDS_WARN_TCP_BADFLAGS
IDS_WARN_TCP_EXPR_TCPOPTS
IDS_WARN_TCP_OBSL_TCPOPTS
IDS_WARN_TCP_BAD_OPTS_TTCP
IDS_WARN_TCP_BAD_TCPOPTS
IDS_WARN_TCP_BAD_SACK_OPTS
IDS_WARN_OSPF_LEN
IDS_WARN_OSPF_HDR
IDS_WARN_OSPF6_LEN
IDS_WARN_OSPF6_HDR
IDS_WARN_RT6_HDR
IDS_WARN_IPCOMP_HDR
IDS_WARN_AH_HDR
IDS_WARN_ESP_HDR
IDS_WARN_IGRP_HDR
IDS_WARN_EGP_VER
IDS_WARN_EGP_HDR
IDS_WARN_IGMP_HDR
IDS_WARN_IGMP_SUM
IDS_WARN_GRE_HDR
IDS_WARN_GRE_UNKNOW_VER
IDS_WARN_GRE_VER0_ERROR
IDS_WARN_GRE_VER1_ERROR
IDS_WARN_MOBILE_CSUM
IDS_WARN_MOBILE_SIZE
IDS_WARN_VRRP_CSUM
IDS_WARN_VRRP_HDR
IDS_WARN_SCTP_LEN
IDS_WARN_SCTP_HDR
IDS_WARN_PIM_HDR
IDS_WARN_PIM_LEN
IDS_WARN_IPX_HDR
IDS_WARN_VLAN_HDR
IDS_WARN_VLAN_LEN
IDS_WARN_PPPoE_HDR
IDS_WARN_ARP_HDR
IDS_WARN_ARP_HDR_LEN
IDS_WARN_ARP_REQUEST
IDS_WARN_ARP_MISMATCH_S
IDS_WARN_ARP_MISMATCH_D
IDS_WARN_ARP_OVERWRITE
IDS_WARN_ATMARP_HDR
IDS_WARN_ATMARP_LEN
IDS_WARN_IEEE_802_LEN
IDS_WARN_IEEE_802_HDR
IDS_WARN_IEEE_802_DATA_LEN
IDS_WARN_MOBILITY_HDR
IDS_WARN_MOBILITY_OPTS
IDS_WARN_RSVP_VER
IDS_WARN_RSVP_COM_HDR
IDS_WARN_RSVP_HDR
IDS_WARN_SCAN_DETECT
IDS_WARN_SCAN_DETECTV6
IDS_WARN_UDP_HDR_LEN
IDS_WARN_UDP_HDR_TOO_SMALL
IDS_WARN_UDP_SMALL_ULEN
IDS_WARN_UDP_HDR_LEN_ULEN
IDS_WARN_UDP_HDR_CHKSUM
IDS_WARN_BO_TRAFFIC
IDS_WARN_MPLS_HDR
IDS_WARN_TCPen6_HDR
IDS_WARN_UDPen6_HDR
IDS_WARN_UDPen6_SUM
IDS_WARN_ICMP_HDR
IDS_WARN_TOKEN_HDR
IDS_WARN_TOKEN_SNAP
IDS_WARN_FDDI_HDR
IDS_WARN_STREAM_EVASIVE_RETRANS
IDS_WARN_STREAM_WINDOW_VIOLATION
IDS_WARN_STREAM_DATA_ON_SYNPKT
IDS_WARN_STREAM_EVASION_ATTEMPT
IDS_WARN_STREAM_STEALTHNMAP_FINGERPRINT
IDS_WARN_STREAM_STEALTHACTIVITY
IDS_WARN_STREAM_STEALTH_FULL_XMAS
IDS_WARN_STREAM_STEALTH_SAPU
IDS_WARN_STREAM_STEALTH_FINS
IDS_WARN_STREAM_SYN_FIN_SCAN
IDS_WARN_STREAM_NULL_SCAN
IDS_WARN_NMAP_XMAS_SCAN
IDS_WARN_STEALTH_VECNA_SCAN
IDS_WARN_EVASIVE_RESET
IDS_WARN_STREAM_TTL_EVASION
IDS_WARN_STREAM_PAWS_ID
IDS_WARN_STREAM_HIJACKING
IDS_WARN_STREAM_INVALID_OFFSET
IDS_WARN_STREAM_LARGE_OFFSET
IDS_WARN_STREAM_IP4_SAMEIP
IDS_WARN_STREAM_INVALID_DATA_LENGTH
IDS_WARN_STREAM_INVALID_CKSUM
IDS_WARN_STREAM_WINDOW_SCALE_ERR_RFC1323
IDS_WARN_STREAM_POSSIBLE_TROJAN
IDS_WARN_STREAM_OVERLAP_LIMIT
IDS_WARN_STREAM_FORWARD_OVERLAP
IDS_WARN_HTTP_LARGE_METH
IDS_WARN_HTTP_MISS_URI
IDS_WARN_HTTP_DOUBLE_ENC
IDS_WARN_HTTP_ILLEGAL_HEX
IDS_WARN_HTTP_OVERLONG_CHAR
IDS_WARN_TCP_NO_ACK
IDS_WARN_STREAM_ZERO_TIMESTAMP
IDS_WARN_STREAM_EVASIVE_RETRANS_DATAFAST
IDS_WARN_SMTP_PKT
IDS_WARN_SMTP_XLINK2
IDS_WARN_CDP_HEADER
IDS_WARN_STP_HEADER_LEN
IDS_WARN_STP_VERSION_ERROR
IDS_WARN_STP_UNK_VERSION
IDS_WARN_STP_PKT_LENGTH
IDS_WARN_ISOCLNS_LENGTH_ERROR
IDS_WARN_CHDLC_SLARP_HEADER
IDS_WARN_FRAG3_IPOPTIONS
IDS_WARN_FRAG3_ANOMALY_BADSIZE
IDS_WARN_FRAG3_TEARDROP
IDS_WARN_FRAG3_SHORTFRAG
IDS_WARN_ANOMALY_OVERSIZE
IDS_WARN_ANOMALY_ZERO
IDS_WARN_ANOMALY_BADSIZE_LG
IDS_WARN_FRAG3_ANOMALY_OVERLAP
IDS_WARN_ARCNET_HEADER_LEN
IDS_WARN_ARCNET_NEWHEADER_LEN
IDS_WARN_ARCNET_LINUX_HEADER_LEN
IDS_WARN_ARCNET_LINUX_NEWHEADER_LEN
IDS_WARN_80211_RADIO_HDRLEN
IDS_WARN_80211_RADIO_CAPLEN
IDS_WARN_80211_RADIO_TRUNC
IDS_WARN_PRISM_CAPLEN
IDS_WARN_PRISM_HDRLEN
IDS_WARN_FIREWIRE_HDRLEN
IDS_WARN_CIP_TRUNC
IDS_WARN_FR_HEADER
IDS_WARN_FR_Q933
IDS_WARN_LANE_HEADER
IDS_WARN_IPFC_HEADERLEN
IDS_WARN_SLIP_HEADER
IDS_WARN_SUNATM_HDR
IDS_WARN_ENC_HEADER
IDS_WARN_LLC_HEADER
IDS_WARN_ATM_HEADER
IDS_WARN_ATM_TRUNC
IDS_WARN_ATM_TRUNC_MSG
IDS_WARN_ATM_TRUNC_CALLREF
IDS_WARN_SLOW_LENGTH
IDS_WARN_SNAP_LENGTH
IDS_WARN_SMB_LENGTH
IDS_WARN_DCCP_HEADER_LENGTH
IDS_WARN_DCCP_TRUNCATED_LENGTH
IDS_WARN_DCCP_IP_CHKSUM
IDS_WARN_DCCP_IP6_CHKSUM
IDS_WARN_DCCP_ZERO_TIMESTAMP
IDS_WARN_DCCP_TRUNC_OPTS
IDS_WARN_RPC_TRAFFIC
IDS_WARN_RPC_MUL_RECORD
IDS_WARN_RPC_LFRAGSIZE
IDS_WARN_RPC_INCSEG
IDS_WARN_SSH_EVENT_CRC32
IDS_WARN_SSH_EVENT_GOBBLES
IDS_WARN_SSH_EVENT_SECURECRT
IDS_WARN_SSH_EVENT_PROTOMISMATCH
IDS_WARN_SSH_EVENT_PAYLOAD_SIZE
IDS_WARN_SSH_EVENT_WRONG_DIR
IDS_WARN_SSH_EVENT_VERSION
IDS_WARN_USER_CALL_BADNET
IDS_WARN_USER_CALLUP
IDS_WARN_DVMRP_HDR
IDS_WARN_DVMRP_PROBE
IDS_WARN_DVMRP_REPORT
IDS_WARN_GRE_TRUNC_LENGTH
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <fcntl.h> #ifdef WIN32 #include "..\src\win-config.h" #endif #ifndef WIN32 #include <strings.h> #include <sys/socket.h> #endif #ifndef WIN32 #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/ip.h> #include <netinet/tcp.h> #include <netinet/udp.h> #include <netinet/ip_icmp.h> #include <arpa/inet.h> #endif #include "ids_ebox.h" #include "ebox_scan.h" #include "ebox_var.h" #include "snort/sfsnprintfappend.h" #ifndef u_int8_t # define u_int8_t unsigned char #endif #ifndef u_int32_t # define u_int32_t u_int #endif #define IP6 1 #ifdef IP6 #include "../src/ip6.h" #include "../src/icmp6.h" #endif #define int_ntoa(x) inet_ntoa(*((struct in_addr *)&x)) extern void PrintEboxModules(short); char *ids_state_names[] = { "CLOSED", "LISTEN", "SYN_RCVD", "SYN_SENT", "ESTABLISHED", "CLOSE_WAIT", "LAST_ACK", "FIN_WAIT_1", "CLOSING", "FIN_WAIT_2", "TIME_WAIT"}; #define MAX_ETHER 20 #define SN_IPLEN 46 void my_syslog( ParserPkt *pkt ) { char esrc[MAX_ETHER]; char edst[MAX_ETHER]; char epro[8]; char sIP[SN_IPLEN], dIP[SN_IPLEN]; char scanaddr[SN_IPLEN]; char buffer[1024]; ulScanHost *sdata = NULL; char *scan_proto = NULL; int i; if(!pkt) return; if(!pkt->ehdr) return; memset(esrc, 0, MAX_ETHER); memset(edst, 0, MAX_ETHER); memset(epro, 0, 8); memset(sIP, 0, SN_IPLEN); memset(dIP, 0, SN_IPLEN); memset(buffer, 0, 1024); LogInfo("my_syslog:\n"); /* Get the ethernet src and destination address and eth proto type strings*/ EthAddrString((u_int8_t *)pkt->ehdr->ether_shost,esrc); EthAddrString((u_int8_t *)pkt->ehdr->ether_dhost,edst); EthProtoString(pkt->ehdr->ether_type,epro); if( pkt->cap.ned->estring ) { LogInfo("[t.%d,c.%d] Alert: %s\n", pkt->cap.ned->type,pkt->cap.ned->code,pkt->cap.ned->estring); } else { LogInfo("[t.%d,c.%d] Alert: Undefined Alert, no alert string\n", pkt->cap.ned->type,pkt->cap.ned->code); } if( pkt->L1->isv4 ) { ebox_ntop(AF_INET,&(pkt->cap.v4_addr).saddr, sIP, SN_IPLEN); ebox_ntop(AF_INET,&(pkt->cap.v4_addr).daddr, dIP, SN_IPLEN); LogInfo("logv4. epro(%s) %s_%s.%d -> %s_%s.%d\n", epro,esrc,sIP,pkt->cap.sp,edst,dIP,pkt->cap.dp); } else if( pkt->L1->isv6 ) { ebox_ntop(AF_INET6, &(pkt->cap.v6_addr).saddr, sIP, SN_IPLEN); ebox_ntop(AF_INET6, &(pkt->cap.v6_addr).daddr, dIP, SN_IPLEN); LogInfo("logv6. epro(%s) %s_%s.%d -> %s_%s.%d\n", epro,esrc,sIP,pkt->cap.sp,edst,dIP,pkt->cap.dp); } else { LogInfo("log(udef): type.%p\n",pkt); } if( pkt->cap.ned->code == IDS_WARN_SCAN ) { memset(scanaddr, 0, SN_IPLEN); LogInfo("Scan alert sent \n"); sdata = (ulScanHost *)pkt->cap.ned->mdata; if(sdata) { if(pkt->cap.ned->wbtype == -2 ) { scan_proto = GetProtoName(pkt->ip4h->ip_p); sprintf( buffer + strlen(buffer), "%s scan from %s Scanned ports: ", scan_proto, int_ntoa(sdata->addr.saddr)); for( i = 0; i < sdata->n_packets; i++) sprintf(buffer + strlen(buffer),":%hu,",sdata->PORTLIST[i]); sprintf(buffer + strlen(buffer), " [SType:(%d) %s] ",sdata->oc_flag,sdata->scan_type); LogInfo("%s\n",buffer); } else if(pkt->cap.ned->wbtype == -6 ) { scan_proto = GetProtoName(pkt->ip6h->ip6_nxt); sprintf( buffer + strlen(buffer),"%s Scan from %s Scanned ports: ", scan_proto, ebox_ntop( AF_INET6,&sdata->addr6.saddr,scanaddr,SN_IPLEN)); for( i = 0; i < sdata->n_packets; i++) sprintf(buffer+strlen(buffer),":%hu,",sdata->PORTLIST[i]); sprintf(buffer + strlen(buffer), " [SType:(%d) %s] ",sdata->oc_flag,sdata->scan_type); LogInfo("%s\n",buffer); } } } } void udp_callback(ParserPkt *bp) { LogInfo("udp packet "); } #define STD_BUF 1024 void ip_callback(ParserPkt *ep) { char buffer[8192]; char sIP[IDS_IPLEN]; char dIP[IDS_IPLEN]; char *flow[2],*proto; int i,sp,dp; memset(buffer, 0, 8192); flow[0] = CLIENT_ID; flow[1] = SERVER_ID; ebox_ntop(AF_INET,&(a_packet)->ip_src, sIP, IDS_IPLEN); ebox_ntop(AF_INET,&(a_packet)->ip_dst, dIP, IDS_IPLEN); sp = GetSrcPort((u_int8_t*)a_packet); dp = GetDstPort((u_int8_t*)a_packet); switch( a_packet->ip_p ) { case IPPROTO_ICMP: proto = "icmp."; break; case IPPROTO_UDP: proto = "udp."; break; case IPPROTO_TCP: proto = "tcp."; break; case IPPROTO_IGMP: proto = "igmp."; break; case IPPROTO_IGRP: proto = "igrp."; break; default: proto = "undef."; break; } LogInfo("v4IP [%s]\n",proto); LogInfo("[Sender:%s] %s.%d => %s.%d\n", flow[ll->flow_data.direction],sIP,sp,dIP,dp); if( ll->ip_opts_count ) { LogInfo("Ip opts: "); for(i=0; i < ll->ip_opts_count; i++ ) { LogInfo("%s",ll->ip_opts[i].data); } } sp = GetSrcPort((u_int8_t*)a_packet); dp = GetDstPort((u_int8_t*)a_packet); DumpPacket_Hex_Ascii_Buffer("\n",(u_char *)a_packet,(u_int)len,buffer); LogInfo("%s\n",buffer); } void sniff_callback3(ParserPkt *bp) { LogInfo("snoop_stream5_hook \n"); } void sniff_callback2(ParserPkt *bp) { struct ip *iph; u_int8_t *payload; struct tcphdr *tcph; STREAM *hs; char *state; LogInfo("tcpstream callback\n"); if( bp->conn->v4orv6 == 1 ) LogInfo(" .v4 "); else if( bp->conn->v4orv6 == 2) LogInfo(" .v6 "); else LogInfo(" (what).2T "); if(bp->conn->v4orv6 == 1 ) { if( bp->conn->flow == 0 ) // packet for server { LogInfo("[S@]%s -->\n\t\t%s %s-%s\n", GetTupleConDataV4(bp->conn->addr,1),bp->conn->snd_machine_string, TCP_STATES[bp->conn->server.state],ids_state_names[(int)bp->conn->ids_state]); } else { LogInfo("[C@]%s -->\n\t\t%s %s-%s\n", //packet for client GetTupleConDataV4(bp->conn->addr,0),bp->conn->rcv_machine_string, TCP_STATES[bp->conn->client.state],ids_state_names[(int)bp->conn->ids_state]); } } if( bp->conn->flow == 0 ) hs = &bp->conn->server; // packet for server else hs = &bp->conn->client; // packet for client state = ids_state_names[(int)bp->conn->ids_state]; iph = (struct ip *)hs->opkt; payload = hs->data; tcph = (struct tcphdr *)payload; if(bp->L1 != NULL){ LogInfo("Have L1 data "); /* write our ip opts string if any */ if( bp->L1->isv4 ) LogInfo(" v4 L1 data\n"); else if ( bp->L1->isv6 ) LogInfo(" v6 L1 data\n"); } else { LogInfo("Do Not Have L1 data\n"); } if( bp->L1->flow_data.direction == 0 ) /* server packet */ { LogInfo("From server"); } else // bp->L1->flow_data.direction >= 1/* client packet */ { LogInfo("From client"); } #ifdef HARD_WAY if( bp->conn->flow == 0){ /* from server */ if( bp->conn->v4orv6 == 1 ) LogInfo("src(%u.%d) dst(%u.%d) ",bp->conn->addr.saddr,bp->conn->addr.source, bp->conn->addr.daddr,bp->conn->addr.dest); } else { if( bp->conn->v4orv6 == 1 ) LogInfo("src(%u.%d) dst(%u.%d) ",bp->conn->addr.daddr,bp->conn->addr.dest, bp->conn->addr.saddr,bp->conn->addr.source); } #endif } void icmp6_callback(ParserPkt *pp) { LogInfo("6icmp\n"); } void route6_callback(ParserPkt *pp) { if( (pp->cap.flags & 0x00006000) != 0x00006000 ) { LogInfo("route6 raw\n"); } else { LogInfo("route6 reassembled\n"); } } int main(int argc, char *argv[]) { /* dont use memory api */ ids_params.MemoryApiInitialize = NULL; #if 0 //ids_params.MemoryApiInitialize(); //ids_params.use_bget_mem_functions = 0; //ids_params.HaveMemHandler = 0; #endif #ifdef WIN32 /* On win32 Gianluca Varenni states: it's not only a matter of (un)supported network cards (being them wireless or wired). It's also a matter of network card drivers. Some cards are supported (and by supported I mean that they work in promiscuous mode) with any version of their drivers, some others work only with some particular versions of their drivers (and maybe on some Windows flavors, only). try to capture in non-promiscuous mode */ ids_params.promisc = 0; #else ids_params.promisc = 1; #endif ids_params.n_tcp_streams = 1; /* collect tcp streams */ ids_params.tcp_useBothCollectionMethods = 0; stream_params.tcp_collect_state = 0; /* syn_rcvd, 4established */ stream_params.alert_replies_to_trojan_sweep = 1; stream_params.random_data_flush_points = 0; stream_params.alert_tcp_state = 1; stream_params.flush_base = 256; stream_params.flush_style = "default"; //"random";//"large_window"; /* turn off secondary scan detection */ stream_params.use_ebox_scan = 0; /* turn off secondary syslog scan alerts */ stream_params.stream_scan_alerts = 0; stream_params.watch_ports = (u_char *)strdup("all"); /* stream_params.watch_ports = strdup("21 22 80 53 100"); */ /* do no assemble server pkts */ stream_params.assemble_server = 1; stream_params.assemble_client = 1; /* change prune method for stream cap */ stream_params.prune_type = 1; ids_params.process_data_flow = 1; ids_params.debug_ebox = 0; /* debug ebox code */ ids_params.debug_Level |= 0x00000000; /* debug ebox code */ //ids_params.debug_Level |= (0x00004000|0x00000100); /* debug ebox code */ /* read from dump file */ /* ids_params.filename = "/path/to/some/tcpdump_file"; /** * ids_params.os_match_modes = 0x00000000; //no os match * ids_params.os_match_modes |= FP_MODE_RST; //only reset * ids_params.os_match_modes |= (FP_MODE_ACK|FP_MODE_RST|FP_MODE_SYNACK); */ ids_params.os_match_modes =(FP_MODE_SYN|FP_MODE_SYNACK|FP_MODE_RST|FP_MODE_ACK); ids_params.do_os_match = 1; ids_params.display_os_match_params = 0; /* suppress sylog logging */ ids_params.suppress_syslog = 1; /* override ebox sylog code with your own */ ids_params.syslog = (void *)my_syslog; /* On win32 you can specify the device by a digit or a proper device name where "1" is the "\Device\NPF_GenericDialupAdapter" and all other adapters adapter "++1" upwards to adapter limit. so to point to the second device you can use ids_params.device = "2"; or ids_params.device = "\\Device\\NPF_{4095CE7F-305D-49C2-ADBA-1D85C082F7EF}"; and so on ids_params.device = "3"; if you have two adapters on you system */ ids_params.device = "hme0"; /* fxp0,qfe0, etc.. check your system */ /* change prune method for flow cap */ ids_params.flow_prune_type = 1; ids_params.module_list = strdup("snoop_modules.conf"); ids_params.module_logdir = strdup("/tmp/"); ids_params.passdata_before_processing = 0; ids_params.passdata_after_processing = 1; /* initialize ebox component */ if(!ebox_init() ) { LogInfo("%s\n", EBOX_ERROR_BUFF); exit (1); } /* register user defined functions */ EBOX_REG_USERCODE( IPR_PROC_TYPE, ip_callback); EBOX_REG_USERCODE( UDP_PROC_TYPE, udp_callback); EBOX_REG_USERCODE( TCP_STREAM_PROC_TYPE, sniff_callback2); EBOX_REG_USERCODE( SNORT_S5_STREAM_PROC_TYPE, sniff_callback3); EBOX_REG_USERCODE( ICMP6_PROC_TYPE, icmp6_callback); EBOX_REG_USERCODE( IP6_RT_PROC_TYPE, route6_callback); /* * EBOX_REG_USERCODE( IPF_PROC_TYPE, ipf_callback); * EBOX_REG_USERCODE( ICMP_PROC_TYPE, icmp_callback); * EBOX_REG_USERCODE( IGMP_PROC_TYPE, igmp_callback); */ EBOX_VIEW_USERCODE( IPR_PROC_TYPE ); EBOX_VIEW_USERCODE( UDP_PROC_TYPE ); /* list modules we are using */ PrintEboxModules(0); PrintEboxModules(1); /* start pkt collection */ ebox_run(); /* should never get here, unless reading from dump log */ return 0; }
At this time we do not have a utility to automatically make your engine project 'like apache apxs'.
So the way to do it is by hand or by adding your project under the src/modules/engines/ directory
modify Makfile.am and either re-run buildconf-generic or do
autoconf;
automake;
./configure --whatever-opts
Example Engine Module
#ifdef HAVE_CONFIG_H #include "config.h" #endif #include "ebox_internal.h" #include "eboxmodule.h" #include "phase.h" #include "stats.h" /* module meta information */ #define MAJOR_VERSION 1 #define MINOR_VERSION 4 #define BUILD_VERSION 3 #define DETECT_NAME "PKT_ENGINE_SOMETHING" #define TYPE_ENGINE 0 ModuleEngineData *_dpd; ENGINE_LINKAGE int InitializeEngine(ModuleEngineData *ded, char *eargs) { if( !ded) { fprintf(stderr,"ModuleEngine Data not supplied\n"); return -1; } /* set to module engine data */ _dpd = ded; if( ded->version < MODULE_DATA_VERSION) { fprintf(stderr,"Module DataVersion dose not match engine DataVersion\n"); return -1; } return 0; } ENGINE_LINKAGE int LibVersion(ModulePluginData *dpm) { dpm->type = MOD_ENGINE; dpm->major = MAJOR_VERSION; dpm->minor = MINOR_VERSION; dpm->build = BUILD_VERSION; /* where we want to be calld */ dpm->anchor[0] = IPV4_PHASE; /* reflect the number of times though the ebox we want to be called */ dpm->num_anchor = 1; /* specify engine dependaincies */ dpm->amt_eng_deps = 0; /* specify parser dependaincies */ dpm->amt_psr_deps = 0; /* module name */ dpm->modName = DETECT_NAME; return 0; } ENGINE_LINKAGE int EboxEngineRun(ModuleEngineData *ed, ParserPkt *p ) { if(!p || !ed) return 0; //do something return 0; } ENGINE_LINKAGE int EboxEngineStop(ModuleEngineData *ed ) { return 0; } #ifdef WIN32 /** * do nothing during dll init/end just here to stop win32 from * complaining */ BOOL WINAPI DllMain( HINSTANCE hinstDLL, // handle to DLL module DWORD fdwReason, // reason for calling function LPVOID lpReserved ) // reserved { // Perform actions based on the reason for calling. switch( fdwReason ) { case DLL_PROCESS_ATTACH: // Initialize once for each new process. // Return FALSE to fail DLL load. break; case DLL_THREAD_ATTACH: // Do thread-specific initialization. break; case DLL_THREAD_DETACH: // Do thread-specific cleanup. break; case DLL_PROCESS_DETACH: // Perform any necessary cleanup. break; } return TRUE; // Successful DLL_PROCESS_ATTACH. } #endif /* Variables to check type of InitializeEngine and LibVersion */ ENGINE_LINKAGE InitEngineLibFunc initEngineFunc = &InitializeEngine; ENGINE_LINKAGE ModuleVersionFunc libVersionFunc = &LibVersion;
At this time we do not have a utility to automatically make your engine project 'like apache apxs'.
So the way to do it is by hand or by adding your project under the src/modules/parsers/ directory
modify Makfile.am and either re-run buildconf-generic or do
autoconf;
automake;
./configure --whatever-opts
Example Parser Module
#ifdef HAVE_CONFIG_H #include "config.h" #endif #include "ebox_internal.h" #include "listutils.h" #include "eboxmodule.h" #include "phase.h" #include "export.h" #define MAJOR_VERSION 1 #define MINOR_VERSION 4 #define BUILD_VERSION 3 #define DETECT_NAME "GNRC_PARSER" #define TYPE_PARSER 1 ENGINE_LINKAGE int InitializeParser(ModuleParserData *mpd, char *pargs) { return 0; } ENGINE_LINKAGE int LibVersion(ModulePluginData *dpm) { dpm->type = MOD_PARSER; dpm->major = MAJOR_VERSION; dpm->minor = MINOR_VERSION; dpm->build = BUILD_VERSION; /* where we want to be calld */ dpm->anchor[0] = IPV4_PHASE; /* reflect the number of time though the ebox we want to be called */ dpm->num_anchor = 1; dpm->modName = DETECT_NAME; /* specify engine dependaincies */ dpm->amt_eng_deps = 0; /* specify parser dependaincies */ dpm->amt_psr_deps = 0; return 0; } ENGINE_LINKAGE int EboxParserRun(ModuleParserData *mpd, ParserPkt *ebd ) { if(!mpd || !ebd) return 0; //do something return 0; } ENGINE_LINKAGE int EboxParserStop(ModuleParserData *mpd ) { return 0; } #ifdef WIN32 /** * do nothing during dll init/end just here to stop win32 from * complaining */ BOOL WINAPI DllMain( HINSTANCE hinstDLL, // handle to DLL module DWORD fdwReason, // reason for calling function LPVOID lpReserved ) // reserved { // Perform actions based on the reason for calling. switch( fdwReason ) { case DLL_PROCESS_ATTACH: // Initialize once for each new process. // Return FALSE to fail DLL load. break; case DLL_THREAD_ATTACH: // Do thread-specific initialization. break; case DLL_THREAD_DETACH: // Do thread-specific cleanup. break; case DLL_PROCESS_DETACH: // Perform any necessary cleanup. break; } return TRUE; // Successful DLL_PROCESS_ATTACH. } #endif /* Variables to check type of InitializeParser and LibVersion */ ENGINE_LINKAGE InitParserLibFunc initParserFunc = &InitializeParser; ENGINE_LINKAGE ModuleVersionFunc libVersionFunc = &LibVersion;
Introduction to Library Functions LIBEBOX(3) NAME libebox - network intrusion detection system E-box library SYNOPSIS #include <ebox_core_vars.h> #include <ids_ebox.h> #include <ids_misc.h> #include <ebox_var.h> extern struct ebox_prm ids_params; extern struct snort_prm snort_params; extern char ebox_warn[]; extern char EBOX_ERROR_BUFF[]; extern char TCP_STATES[]; extern char EboxCurrScanType; #define SBOX_VER_MAJOR 2 #define SBOX_VER_MINOR 0 /* amount of mem allocated by EboxAlloc et al */ u_int32_t ebox_memory_usage; int ebox_init( void); int EBOX_REG_USERCODE( int , void (*)); void EBOX_UNREGISTER_CODE( int , void (*)); void EBOX_VIEW_USERCODE( int PROC_TYPE); void EBOX_PKT_BASEHANDLER( u_char *, struct pcap_pkthdr *, u_char *); void ebox_run( void); void ebox_discard( TCPSTREAM *, int); int ebox_getfd(void); int ebox_dispatch(int); int ebox_next(void); void ebox_exit(void); char * GetTupleConDataV4(struct tuple4 addr, int dir); char * GetTupleConDataV6(struct tuple6 addr, int dir); void SetAddressByFlowId( TCPSTREAM *, int *, int *, char *, char *); inline int GetSrcPort( u_int8_t *); inline int GetDstPort( u_int8_t *); inline int GetSrcPortV6(u_int8_t *); inline int GetDstPortV6(u_int8_t *); TCPSTREAM * Getv4Session(struct ip *, u_int16_t , u_int16_t); TCPSTREAM * Getv6Session(struct ip6_hdr *, u_int16_t, u_int16_t); inline void StopCollectStream( TCPSTREAM *); inline void StopCollectHalfStream(TCPSTREAM *, int); char * lookup_link(u_int16_t mss, u_int8_t txt); void EthProtoString( u_short, char *); void EthAddrString( u_char *, char *); const char * ebox_ntop(int , const void *, char *, int); int ebox_pton(int , const char *, void *); u_short ip_fast_csum(u_char *, int); u_short ip_compute_csum(u_char *, int); u_short ids_tcp_check(struct tcphdr *, int, u_int, u_int); u_short ids_udp_check(void *, int, u_int, u_int); u_short in_cksum(const u_short *, register u_int , int); u_short ip_check_ext(register u_short *, register int , int); unsigned short in_chksum_icmp( unsigned short * w, int blen); int osi_cksum(const u_int8_t *tptr, u_int len); void * EboxAlloc(unsigned long); void EboxFree(void *, int); int EboxRespondInit(char *); void EboxRespondShutDown(void); void ebox_killtcp(TCPSTREAM *); void ebox_sendicmpv4_unreach(u_int, u_int, u_int32_t, u_int32_t, struct ip *, u_char *, int); int EboxContinuationCheck(char *); void FreeStringToks(char **, int); char ** SplitString(char *, char *, int , int *, char); void DumpPacket_Hex_Ascii(char *, u_char *, u_int); void DumpPacket_Hex_Ascii_Offset(char *, u_char *, u_int , u_int ); void DumpPacket_Hex_Offset(char *, u_char *, u_int,u_int); void DumpPacket_Hex(char *, u_char *, u_int); void DumpPacket_Hex_Buffer(char *,u_char *,u_int,char *); void DumpPacket_Hex_Offset_Buffer(char *,u_char *,u_int,u_int,char *); void DumpPacket_Hex_Ascii_Buffer(char *,u_char *,u_int, char *); void DumpPacket_Hex_Ascii_Offset_Buffer(char *,u_char *,u_int,u_int,char *); DESCRIPTION libebox provides the functionality of a network intrusion detection system (NIDS) E-box component. This ebox was inspired by libnids(3), snort, tcpdump(1), pcap(3). It currently performs: 1. IP defragmentation (ipfrags.c,snortfrag3.c) 2. TCP stream reassembly (v4 and v6 tcp ) 3. TCP port scan detection ( ebox_v4/v6 scan detect, snort portscan snort portscan2 snort sfportscan ) 4. Data Flow Processing (eboxflow.c) 5. Provides processing and warnings for the following: WARN_ETH_HDR_LEN, WARN_IP_OVERSIZED, WARN_IP_TSERROR, WARN_TRUNCATED_IP, WARN_IP_OPTS, WARN_IP_OPTS_TRUNC, WARN_IP_INVLIST, WARN_IP_OVERLAP, WARN_IP_HDR, WARN_IP_SRR, WARN_IP6_HDRLE, WARN_IP6_LEN, WARN_IP6_SAMEIP, WARN_IP6_HBHOPT, WARN_IP6_DSTOPT, WARN_IP6_SOPT_DECODE, WARN_IP6_OPTS_DECODE, WARN_IP6_FRAG_OFF, WARN_ICMP6_HDRLEN, WARN_ICMP6_HDR, WARN_ICMP6_LEN, WARN_ICMP6_CSUM, WARN_ICMP6_TOOBIG, WARN_ICMP6_PRAMERR, WARN_ICMP6_TEXCEED, WARN_ICMP6_UNRCH, WARN_TCP_TOOMUCH, WARN_TCP_HDR, WARN_TCP_BIGQUEUE, WARN_TCP_BADFLAGS, WARN_TCP_EXPR_TCPOPTS, WARN_TCP_OBSL_TCPOPTS, WARN_TCP_BAD_OPTS_TTCP, WARN_TCP_BAD_TCPOPTS, WARN_TCP_BAD_SACK_OPTS, WARN_OSPF_LEN, WARN_OSPF_HDR, WARN_OSPF6_LEN, WARN_OSPF6_HDR, WARN_RT6_HDR, WARN_IPCOMP_HDR, WARN_AH_HDR, WARN_ESP_HDR, WARN_IGRP_HDR, WARN_EGP_VER, WARN_EGP_HDR, WARN_IGMP_HDR, WARN_IGMP_SUM, WARN_GRE_HDR, WARN_GRE_TRUNC_LENGTH, WARN_GRE_UNKNOW_VER, WARN_GRE_VER0_ERROR, WARN_GRE_VER1_ERROR, WARN_MO BILE_CSUM, WARN_MOBILE_SIZE, WARN_VRRP_CSUM, WARN_VRRP_HDR, WARN_SCTP_LEN, WARN_SCTP_HDR, WARN_PIM_HDR, WARN_PIM_LEN, WARN_IPX_HDR, WARN_VLAN_HDR, WARN_VLAN_LEN, WARN_PPPoE_HDR, WARN_ARP_HDR, WARN_ARP_HDR_LEN, WARN_ATMARP_HDR, WARN_ATMARP_LEN, WARN_IEEE_802_LEN, WARN_IEEE_802_HDR, WARN_IEEE_802_DATA_LEN, WARN_MOBILITY_HDR, WARN_MOBILITY_OPTS, WARN_RSVP_VER, WARN_RSVP_COM_HDR, WARN_RSVP_HDR, WARN_SCAN_DETECT, WARN_SCAN_DETECTV6,WARN_UDP_HDR, WARN_MPLS_HDR, WARN_TCPen6_HDR, WARN_UDPen6_HDR, WARN_ICMP_HDR, WARN_TOKEN_HDR, WARN_TOKEN_SNAP, WARN_FDDI_HDR, WARN_STREAM_EVASIVE_RETRANS, WARN_STREAM_WINDOW_VIOLATION, WARN_STREAM_DATA_ON_SYNPKT, WARN_STREAM_EVASION_ATTEMPT , WARN_STREAM_STEALTHNMAP_FINGERPRINT, WARN_STREAM_STEALTHACTIVITY, WARN_STREAM_STEALTH_FULL_XMAS, WARN_STREAM_STEALTH_SAPU, WARN_STREAM_STEALTH_FINS, WARN_STREAM_SYN_FIN_SCAN, WARN_STREAM_NULL_SCAN, WARN_NMAP_XMAS_SCAN, WARN_STEALTH_VECNA_SCAN, WARN_EVASIVE_RESET, WARN_STREAM_TTL_EVASION, WARN_STREAM_PAWS_ID, WARN_STREAM_HIJACKING, WARN_STREAM_INVALID_OFFSET, WARN_STREAM_LARGE_OFFSET, WARN_STREAM_IP4_SAMEIP, WARN_STREAM_INVALID_DATA_LENGTH, WARN_STREAM_INVALID_CKSUM, WARN_STREAM_WINDOW_SCALE_ERR_RFC1323, WARN_STREAM_POSSIBLE_TROJAN, WARN_STREAM_OVERLAP_LIMIT, WARN_STREAM_FOWARD_OVERLAP, WARN_TCP_NO_ACK, WARN_CDP_HEADER, WARN_STP_HEADER_LEN, WARN_STP_VERSION_ERROR, WARN_ISOCLNS_LENGTH_ERROR, WARN_CHDLC_SLARP_HEADER, WARN_FRAG3_IPOPTIONS, WARN_FRAG3_ANOMALY_BADSIZE, WARN_FRAG3_TEARDROP, WARN_FRAG3_SHORTFRAG, WARN_ANOMALY_OVERSIZE, WARN_ANOMALY_ZERO, WARN_ANOMALY_BADSIZE_LG, WARN_FRAG3_ANOMALY_OVERLAP, WARN_USER_CALL_BADNET, WARN_USER_CALLUP ROUTINES void ebox_init () initializes the application for sniffing, based on the values set in the global variable ids_params, declared as follows: struct ebox_prm { u_int32_t n_tcp_streams; u_int32_t n_hosts; char *device; char *filename; void (*syslog)( ParserPkt *); int syslog_level; u_int32_t scan_num_hosts; u_int32_t scan_delay; u_int32_t scan_num_ports; void * (*MemGet)(unsigned long ); void (*MemDel)(void * ); u_int8_t HaveMemHandler; void (*no_mem)(char *); int (*ip_filter)(void *,...); int default_snaplen; char *pcap_filter; u_int8_t promisc; u_int8_t tcpopt_experiment; u_int8_t tcpopt_obsolete; u_int8_t tcpopt_decode; u_int8_t tcpopt_ttcp; u_int8_t ospf_check_all_data; u_int8_t check_ip6_opts; u_int8_t warnSCAN; u_int8_t initResponse; u_int8_t suppress_syslog; u_int8_t suppress_bad_packets; u_int8_t tcp_useBothCollectionMethods; u_int8_t do_os_match; u_int8_t display_os_match_params; u_int32_t os_match_modes; u_int8_t process_data_flow; u_int8_t use_utc; pcap_t *pcap_hand; u_int8_t passdata_before_processing; u_int8_t passdata_after_processing; u_int8_t debug_ebox; u_int8_t debug_Level; }; The members of this structure are: n_tcp_streams If non-zero then we do v4/v6 stream assembly Default value: 1024 n_hosts Size of the hash table used for storing IP defragmenta- tion information. Default value: 256 filename It this variable is set, libebox will call pcap_open_offline with this variable as the argument (instead of pcap_open_live()). Default value: NULL device Interface to monitor. Default value: NULL (in which case an appropriate device is determined automati- cally). If this variable is assigned value all, libebox will attempt to capture packets on all interfaces (which works on Linux only) sk_buff_size Size of struct sk_buff (used for queuing packets), which should be set to match the value on the hosts being monitored. Default value: 168 dev_addon Number of bytes in struct sk_buff reserved for link- layer information. Default value: -1 (in which case an appropriate offset if determined automatically based on link-layer type) syslog Syslog callback function, used to report unusual condi- tions, such as port scan attempts, invalid TCP header flags, etc. Default value: syslog (which logs messages via syslog(3) without regard for message rate per second or free disk space) syslog_level Log level used by ebox syslog for reporting events via syslog(3). Default value: LOG_ALERT scan_num_hosts Size of hash table used for storing portscan informa- tion (the maximum number portscans that will be detected simultaneously). If set to 0, portscan detec- tion will be disabled. Default value: 256 scan_num_ports Minimum number of ports that must be scanned from the same source host before it is identifed as a portscan. Default value: 10 scan_delay Maximum delay (in milliseconds) between connections to different ports for them to be identified as part of a portscan. Default value: 3000 void * (*MemGet)(unsigned long); memory handler get sub (your mem handler get routine must only take one arg) void (*MemDel)(void *); memory handler free sub (your mem handler free routine must only take one arg) int HaveMemHandler; are we useing memory handler subs no_mem Out-of-memory callback function, used to terminate the calling process gracefully. ip_filter IP filtering callback function, used to selectively discard IP packets, inspected after reassembly. If the function returns a non-zero value, the packet is pro- cessed; otherwise, it is discarded. Default value: ebox_ip_filter (which always returns 1) default_snaplen; just in case, you need to set it default(16384) pcap_filter pcap(3) filter string applied to the link-layer (raw, unassembled) packets. Note: filters like ``tcp dst port 23'' will NOT correctly handle appropriately fragmented traffic, e.g. 8-byte IP fragments; one should add "or (ip[6:2] & 0x1fff != 0)" at the end of the filter to process reassembled packets. Default value: NULL promisc If non-zero, libebox will set the interface(s) it listens on to promiscuous mode. Default value: 1 tcpopt_experiment alert on experimental opts tcpopt_obsolete alert on obsolete opts tcpopt_decode alert on crummy opts tcpopt_ttcp ospf_check_all_data check_ip6_opts warnSCAN 1 when a scan is in progress initResponse init response code suppress_syslog default (0) suppress any alerts suppress_bad_packets default (1) suprress alerted packets from futher pro- cessing tcp_useBothCollectionMethods default 1 do_os_match default 1, should we try to guess at os'es display_os_match_params default 0, could use info to build new finger print signatures os_match_modes def SYN possible SYN+ACK,RST,RST+ACK,ACK process_data_flow if we want flow stats per conn use_utc use UTC passdata_before_processing : passdata to user code passdata_after_processing : passdata to user code debug_ebox [0|1] display debug default(0). output only if compiled with --enable-debug debug_Level what code to debug default(0x00000000). only if com- piled with --enable-debug pcap_hand It this variable is set, libebox will call neither pcap_open_live nor pcap_open_offline, but will use a pre-opened PCAP descriptor; use this with EBOX_PKT_BASEHANDLER() in order to interactively feed packets to libebox. Default value: NULL Stream code intializer arguments struct stream_prm { u_int32_t stream_cap_memory_limit; /*default(8M)*/ u_int8_t tcp_collect_state; /* SYN_RCVD,SYN_SENT,ESTABILSHED etc*/ u_int8_t assemble_client; /* default (1) */ u_int8_t assemble_server; /* default (1) */ u_int8_t stream_scan_alerts; /* default (0) */ u_int8_t alert_tcp_state; /* default (1) */ u_int8_t alert_tcp_evade; /* default (1) */ u_int8_t alert_ttl_evade; /* default (1) */ u_int8_t alert_ttl_max; /* default (1) */ u_int8_t alert_stream_evasion; /* default (1) */ u_int8_t stream_cap_def_mode; /* default (1) normal ops mode */ u_int8_t use_ebox_scan; /*override def scan mode default(0)*/ u_int stream_time_out_value; /* def(30), when to cull stream data */ u_int8_t inspect_mac_addrs; /* default (1) */ u_int8_t inspect_server_side_mac; /* default (1) */ u_int8_t inspect_client_side_mac; /* default (1) */ u_int null_flushed_packets; /* default (0) */ u_int flush_data_diff_size; /* default (500) */ u_int8_t random_data_flush_points; /* default (0) */ u_int8_t alert_replies_to_trojan_sweep; /* default 0 */ u_int8_t server_inspect_limit; /* default 4 */ u_char *watch_ports; /* ports we want to get data on */ u_int overlap_limit; /* limit of packet overlaps we permit */ char *flush_style; u_int flush_seed; u_int flush_base; u_int flush_range; u_int8_t assemble_method; /* 0, favor old , 1 favor new*/ }; stream_cap_memory_limit additional Tcp Stream Cap Vars default(8M),(if < 16000K, lol, then set2MB)) tcp_collect_state SYN_RCVD,SYN_SENT,ESTABILSHED etc assemble_client default (1) assemble_server default (1) stream_scan_alerts default (0) alert_tcp_state default (1) alert_tcp_evade default (1) alert_ttl_evade default (1) alert_ttl_max default (1) alert_stream_evasion default (1) stream_cap_def_mode default (1) normal ops mode use_ebox_scan override def scan mode default(0) stream_time_out_value def(30), when to cull stream data inspect_mac_addrs default (1) inspect_server_side_mac default (1) inspect_client_side_mac default (1) null_flushed_packets default (0) flush_data_diff_size default (500) random_data_flush_points default (0) alert_replies_to_trojan_sweep default 0 server_inspect_limit default -1 unlimited watch_ports ports we want to get data on overlap_limit limit of packet overlaps we permit flush_style flush_seed flush_base flush_range assemble_method 0, forward stream search, 1 reverse search ebox_init() Returns 1 on success, 0 on failure (in which case EBOX_ERROR_BUFF contains an appropriate error message). int EBOX_REG_USERCODE( int code_type, void *mycode); Register your code with the ebox code_type as define by one of the following int types. ETH_PROC_TYPE,IPF_PROC_TYPE,IPR_PROC_TYPE,UDP_PROC_TYPE ARP_PROC_TYPE,PPPoe_PROC_TYPE,VLAN_PROC_TYPE,IPX_PROC_TYPE IP6_PROC_TYPE,IP6F_PROC_TYPE,ICMP6_PROC_TYPE,IP6_RT_PROC_TYPE ICMP_PROC_TYPE,TCP_PROC_TYPE,TCP_STREAM_PROC_TYPE,OSPF_PROC_TYPE OSPF6_PROC_TYPE,ESP_PROC_TYPE,SCTP_PROC_TYPE,AH_PROC_TYPE IPCOMP_PROC_TYPE,IGRP_PROC_TYPE,EGP_PROC_TYPE,IGMP_PROC_TYPE GRE_PROC_TYPE,MOBILE_PROC_TYPE,VRRP_PROC_TYPE,PIM_PROC_TYPE IEEE_80211_PROC_TYPE,MOBILITY_PROC_TYPE,RSVP_PROC_TYPE,MPLS_PROC_TYPE TCP6_PROC_TYPE,UDP6_PROC_TYPE,TOKEN_PROC_TYPE,FDDI_PROC_TYPE STP_PROC_TYPE,SLL_PROC_TYPE,RAWPKT_PROC_TYPE,RAWIPP_PROC_TYPE I4L_Cisco_PROC_TYPE,NULL_PROC_TYPE,ISOCLNS_PROC_TYPE,CDP_PROC_TYPE CHDLC_PROC_TYPE And mycode pointing to your code to run. Registering a user-defined callback function to process TCP streams vali-dated and reassembled by libebox. The TCPSTREAM structure is defined as follows: typedef struct _TCPSTREAM { struct tuple4 addr; /* v4 addr if */ struct tuple6 addr6; /* v6 addr if */ char ids_state; /* RESET,DATA,EST,CLOSED,etc */ u_int8_t v4orv6; /* is this v4 or v6 */ u_int32_t hash_index; /* index into hash table */ u_int32_t read; /* data size avail for reading now */ u_int32_t s_time; /* when caught */ u_int32_t l_time; /* when last updated */ u_int32_t sflags; /* session state flags */ u_int32_t isn_s; /* initial seq no for server */ u_int32_t isn_c; /* initial seq no for client */ u_int8_t flow; /* direction that data is being sent from */ u_int8_t preserve_stream; /*keep stream up to(programmer) to delete*/ u_int32_t data_flush_point; /*random flush point value for stream data */ u_int8_t stop_collect_srv; u_int8_t stop_queue_srv; u_int8_t stop_collect_cli; u_int8_t stop_queue_cli; u_int8_t syn_s_flags; /* what options sent with syn, if we caught the session from begining, not applicable on midstream, unless conn dose another TWH */ u_int16_t o_window_scale; /* changes during TWH, after that point it is the orig server win scale factor if any syn opt sent */ u_int8_t *snd_machine_string; /* identify os,else use default string*/ u_int8_t *rcv_machine_string; /* identify os,else use default string*/ EthHeader imac_c; /* original mac for server */ EthHeader imac_s; /* original mac for client */ u_int8_t *ipPkt; /* ip4orip6 raw pkt,represents the current sender pkt*/ u_int8_t *tcpPkt; /* tcp raw pkt,represents the current sender pkt*/ /* client and server halves of the stream */ STREAM client; STREAM server; } TCPSTREAM; /* VALID IDS STATES (for stream processing) */ #define IDS_INVALID_STATE 0 /* should never see */ #define IDS_SYN_DATA 1 /* a syn pkt just came in */ #define IDS_JUST_EST 2 /* just established connection*/ #define IDS_DATA 3 /* n/a unused*/ #define IDS_CLOSE 4 /* n/a unused*/ #define IDS_RESET 5 /* n/a unused*/ #define IDS_TIMED_OUT 6 /* n/a unused*/ #define IDS_PKT_REBUILT 7 /* stream rebuilt pkt data */ #define IDS_DATA_ON_UNEST 8 /* n/a unused*/ #define IDS_EXITING 9 /* n/a unused*/ The members of the tuple4 || tuple6 structure identify a unique TCP connection: void EBOX_UNREGISTER_CODE( int code_type, void *mycode); where code_type is one of codes supplied in above section. And mycode pointing to your code that was registered. void EBOX_VIEW_USERCODE( int PROC_TYPE); used to view the code(s) attached to a SBOX_NODE by EBOX_REG_USERCODE(), i.e the amount of usercode registered to a certain processor void EBOX_PKT_BASEHANDLER( u_char *, struct pcap_pkthdr u_char *); may be used by an application already running a capture with libpcap, in order to pass frames to libebox interactively (frame per frame) instead of having libebox itself do the capture. void ebox_run( void); starts the packet-driven application, reading packets in an endless loop, and invoking registered callback functions to handle new data as it arrives. This function does not return. void ebox_discard( TCPSTREAM *, int); (deprecated) int ebox_getfd(void); may be used by an application sleeping in select(2) to snoop for a socket file descriptor present in the read fd_set. Returns the file descriptor on success, -1 on failure (in which case nids_errbuf contains an appropriate error mes- sage). int ebox_dispatch(int); attempts to process cnt packets before returning, with a cnt of -1 understood as all packets available in one pcap buffer, or all packets in a file when reading offline. On success, returns the count of packets processed, which may be zero upon EOF (offline read) or upon hitting pcap_timeout (if supported by your platform). On failure, returns -1, putting an appropriate error message in nids_errbuf. int ebox_next(void); process the next available packet before returning. Returns 1 on success, 0 if no packet was processed, setting nids_effbuf appropriately if an error prevented packet pro- cessing. void ebox_exit(void); close ebox processors GetTupleConDataV4(struct tuple4 addr, int dir); string representaion of connection src.port/dst.port params GetTupleConDataV6(struct tuple6 addr, int dir); string representaion of connection src.port/dst.port params void SetAddressByFlowId( TCPSTREAM *, int *, int *, char *, char *); for streams set the address by the current flow of data int GetSrcPort( u_int8_t *); get the src port from an ip v4 packet int GetDstPort( u_int8_t *); get the dst port from an ip v4 packet int GetSrcPortV6(u_int8_t *); get the src port from an ip v6 packet int GetDstPortV6(u_int8_t *); get the dst port from an ip v6 packet TCPSTREAM * Getv4Session(struct ip *, u_int16_t , u_int16_t); so top level code can pull up a session copy if it exsits user must free TCPSTREAM object when finished using it TCPSTREAM * Getv6Session(struct ip6_hdr *, u_int16_t, u_int16_t); so top level code can pull up a session copy if it exsits user must free TCPSTREAM object when finished using it StopCollectStream( TCPSTREAM *); stop collection on a desired stream StopCollectHalfStream(TCPSTREAM *, int); stop collection on a desired half stream lookup_link(u_int16_t mss, u_int8_t txt); look up a link information based on mss of the connection EthProtoString( u_short, char *); Get the ethernet proto in string form EthAddrString( u_char *, char *); Get the ethernet addr in string form ebox_ntop(int , const void *, char our ntop/pton functions, thanks Paul Vixie, 1996. ebox_pton(int , const char *, void our ntop/pton functions, thanks Paul Vixie, 1996. ip_fast_csum(u_char *, int); ip checksums ip_compute_csum(u_char *, int); ip checksums ids_tcp_check(struct tcphdr *, int, u_int, u_int); tcp checksums ids_udp_check(void *, int, u_int, u_int); udp checksums in_cksum(const u_short *, register u_int , checksums ip_check_ext(register u_short *, register int , checksums in_chksum_icmp( unsigned short * w, int icmp checksums osi_cksum(const u_int8_t *tptr, u_int len); osi checksums EboxAlloc(unsigned long); our memory alloc funtion returns (void *) EboxFree(void *, int); our free memory funtion EboxRespondInit(char *); for terminating tcp connections, sending icmp responses EboxRespondShutDown(void); for shutting down term socket ebox_killtcp(TCPSTREAM *); tears down the specified TCP connection with symmetric RST packets between client and server. ebox_sendicmpv4_unreach(u_int,u_int,u_int32_t,u_int32_t, struct ip *,u_char *,int); send icmp unreach Common string utilities EboxContinuationCheck(char *); FreeStringToks(char **, int); Common string utilities char **SplitString(char *, char *, int Packet Dump Utilities void DumpPacket_Hex_Ascii(char *, u_char *, u_int); dump packet in hex and ascii void DumpPacket_Hex_Ascii_Offset(char *, u_char *, u_int, u_int); dump packet in hex and ascii void DumpPacket_Hex(char *, u_char *, u_int); dumpacket in hex (default offset=0) void DumpPacket_Hex_Offset(char *, u_char *, u_int,u_int); dumpacket in hex with an offset void DumpPacket_Hex_Buffer(char *,u_char *,u_int,char *); dumpacket in hex to a user void DumpPacket_Hex_Offset_Buffer(char *,u_char *,u_int,u_int,char *); dumpacket in hex to a user void DumpPacket_Hex_Ascii_Buffer(char *,u_char *,u_int, char *); dumpacket in hex and ascii to void DumpPacket_Hex_Ascii_Offset_Buffer(char *,u_char *,u_int,u_int,char *); dumpacket in hex and ascii to CODE_PROC CALLBACK ARGS This details the arguments that will be passed to the code registered with the ebox If your function dose not have the right arg mathching the correct code box the errors will occour. (more likley a core dump) ETH_PROC_NODE => (user_code)( ParserPkt * ); CDP_PROC_NODE => (user_code)( ParserPkt * ); SLL_PROC_NODE => (user_code)( ParserPkt * ); STP_PROC_NODE => (user_code)( ParserPkt * ); IEEE_80211_PROC_NOD => (user_code)( ParserPkt * ); IPX_PROC_NODE => (user_code)( ParserPkt * ); VLAN_PROC_NODE => (user_code)( ParserPkt * ); PPPoe_PROC_NODE => (user_code)( ParserPkt * ); CHDLC_PROC_NODE => (user_code)( ParserPkt * ); ARP_PROC_NODE => (user_code)( ParserPkt * ); IPF_PROC_NODE => (user_code)( ParserPkt * ); IPR_PROC_NODE => (user_code)( ParserPkt * ); RSVP_PROC_NODE => (user_code)( ParserPkt * ); PIM_PROC_NODE => (user_code)( ParserPkt * ); VRRP_PROC_NODE => (user_code)( ParserPkt * ); MOBILE_PROC_NODE => (user_code)( ParserPkt * ); GRE_PROC_NODE => (user_code)( ParserPkt * ); IGMP_PROC_NODE => (user_code)( ParserPkt * ); EGP_PROC_NODE => (user_code)( ParserPkt * ); IGRP_PROC_NODE => (user_code)( ParserPkt * ); UDP_PROC_NODE => (user_code)( ParserPkt * ); AH_PROC_NODE => (user_code)( ParserPkt * ); IPCOMP_PROC_NODE => (user_code)( ParserPkt * ); ESP_PROC_NODE => (user_code)( ParserPkt * ); MPLS_PROC_NODE => (user_code)( ParserPkt * ); NULL_PROC_NODE => (user_code)( ParserPkt * ); RAWPKT_PROC_NODE => (user_code)( ParserPkt * ); RAWIPP_PROC_NODE => (user_code)( ParserPkt * ); I4L_Cisco_PROC_NODE => (user_code)( ParserPkt * ); ISOCLNS_PROC_NODE => (user_code)( ParserPkt * ); IP6_PROC_NODE => (user_code)( ParserPkt * ); TCP6_PROC_NODE => (user_code)( ParserPkt * ); UDP6_PROC_NODE => (user_code)( ParserPkt * ); MOBILITY_PROC_NODE => (user_code)( ParserPkt * ); ICMP6_PROC_NODE => (user_code)( ParserPkt * ); IP6_RT_PROC_NODE => (user_code)( ParserPkt * ); IP6F_PROC_NODE => (user_code)( ParserPkt * ); TOKEN_PROC_NODE => (user_code)( ParserPkt * ); FDDI_PROC_NODE => (user_code)( ParserPkt * ); OSPF_PROC_NODE => (user_code)( ParserPkt * ); OSPF6_PROC_NODE => (user_code)( ParserPkt * ); DCCP_PROC_NODE => (user_code)( ParserPkt * ); SEE ALSO pcap(3), libnids(3), snort(3), libnet(3) pcre(3) AUTHOR Garrick Hermitt-Barrett http://www.enssoft.org