From 9e0b0f918744f113cb5486863cd178ee0e2498a8 Mon Sep 17 00:00:00 2001 From: Vlad Grigorescu Date: Tue, 19 Nov 2013 20:20:36 -0500 Subject: [PATCH 001/136] Basic RADIUS support - checkpoint --- scripts/base/init-default.bro | 1 + scripts/base/protocols/radius/__load__.bro | 3 + scripts/base/protocols/radius/consts.bro | 537 ++++++++++++++++++ scripts/base/protocols/radius/dpd.sig | 7 + scripts/base/protocols/radius/main.bro | 142 +++++ scripts/base/utils/addrs.bro | 26 +- src/analyzer/protocol/CMakeLists.txt | 5 +- src/analyzer/protocol/radius/CMakeLists.txt | 11 + src/analyzer/protocol/radius/Plugin.cc | 11 + src/analyzer/protocol/radius/RADIUS.cc | 45 ++ src/analyzer/protocol/radius/RADIUS.h | 45 ++ src/analyzer/protocol/radius/events.bif | 23 + .../protocol/radius/radius-analyzer.pac | 23 + .../protocol/radius/radius-protocol.pac | 15 + src/analyzer/protocol/radius/radius.pac | 37 ++ 15 files changed, 928 insertions(+), 3 deletions(-) create mode 100644 scripts/base/protocols/radius/__load__.bro create mode 100644 scripts/base/protocols/radius/consts.bro create mode 100644 scripts/base/protocols/radius/dpd.sig create mode 100644 scripts/base/protocols/radius/main.bro create mode 100644 src/analyzer/protocol/radius/CMakeLists.txt create mode 100644 src/analyzer/protocol/radius/Plugin.cc create mode 100644 src/analyzer/protocol/radius/RADIUS.cc create mode 100644 src/analyzer/protocol/radius/RADIUS.h create mode 100644 src/analyzer/protocol/radius/events.bif create mode 100644 src/analyzer/protocol/radius/radius-analyzer.pac create mode 100644 src/analyzer/protocol/radius/radius-protocol.pac create mode 100644 src/analyzer/protocol/radius/radius.pac diff --git a/scripts/base/init-default.bro b/scripts/base/init-default.bro index d0120d930b..a732212335 100644 --- a/scripts/base/init-default.bro +++ b/scripts/base/init-default.bro @@ -47,6 +47,7 @@ @load base/protocols/irc @load base/protocols/modbus @load base/protocols/pop3 +@load base/protocols/radius @load base/protocols/smtp @load base/protocols/socks @load base/protocols/ssh diff --git a/scripts/base/protocols/radius/__load__.bro b/scripts/base/protocols/radius/__load__.bro new file mode 100644 index 0000000000..96bf67a57f --- /dev/null +++ b/scripts/base/protocols/radius/__load__.bro @@ -0,0 +1,3 @@ +# Generated by binpac_quickstart +@load ./main +#@load-sigs ./dpd.sig \ No newline at end of file diff --git a/scripts/base/protocols/radius/consts.bro b/scripts/base/protocols/radius/consts.bro new file mode 100644 index 0000000000..6231a25631 --- /dev/null +++ b/scripts/base/protocols/radius/consts.bro @@ -0,0 +1,537 @@ +module RADIUS; + +const msg_types: table[count] of string = { + [1] = "Access-Request", + [2] = "Access-Accept", + [3] = "Access-Reject", + [4] = "Accounting-Request", + [5] = "Accounting-Response", + [11] = "Access-Challenge", + [12] = "Status-Server", + [13] = "Status-Client", +} &default=function(i: count): string { return fmt("unknown-%d", i); }; + +const attr_types: table[count] of string = { + [1] = "User-Name", + [2] = "User-Password", + [3] = "CHAP-Password", + [4] = "NAS-IP-Address", + [5] = "NAS-Port", + [6] = "Service-Type", + [7] = "Framed-Protocol", + [8] = "Framed-IP-Address", + [9] = "Framed-IP-Netmask", + [10] = "Framed-Routing", + [11] = "Filter-Id", + [12] = "Framed-MTU", + [13] = "Framed-Compression", + [14] = "Login-IP-Host", + [15] = "Login-Service", + [16] = "Login-TCP-Port", + [18] = "Reply-Message", + [19] = "Callback-Number", + [20] = "Callback-Id", + [22] = "Framed-Route", + [23] = "Framed-IPX-Network", + [24] = "State", + [25] = "Class", + [26] = "Vendor-Specific", + [27] = "Session-Timeout", + [28] = "Idle-Timeout", + [29] = "Termination-Action", + [30] = "Called-Station-Id", + [31] = "Calling-Station-Id", + [32] = "NAS-Identifier", + [33] = "Proxy-State", + [34] = "Login-LAT-Service", + [35] = "Login-LAT-Node", + [36] = "Login-LAT-Group", + [37] = "Framed-AppleTalk-Link", + [38] = "Framed-AppleTalk-Network", + [39] = "Framed-AppleTalk-Zone", + [40] = "Acct-Status-Type", + [41] = "Acct-Delay-Time", + [42] = "Acct-Input-Octets", + [43] = "Acct-Output-Octets", + [44] = "Acct-Session-Id", + [45] = "Acct-Authentic", + [46] = "Acct-Session-Time", + [47] = "Acct-Input-Packets", + [48] = "Acct-Output-Packets", + [49] = "Acct-Terminate-Cause", + [50] = "Acct-Multi-Session-Id", + [51] = "Acct-Link-Count", + [52] = "Acct-Input-Gigawords", + [53] = "Acct-Output-Gigawords", + [55] = "Event-Timestamp", + [56] = "Egress-VLANID", + [57] = "Ingress-Filters", + [58] = "Egress-VLAN-Name", + [59] = "User-Priority-Table", + [60] = "CHAP-Challenge", + [61] = "NAS-Port-Type", + [62] = "Port-Limit", + [63] = "Login-LAT-Port", + [64] = "Tunnel-Type", + [65] = "Tunnel-Medium-Type", + [66] = "Tunnel-Client-EndPoint", + [67] = "Tunnel-Server-EndPoint", + [68] = "Acct-Tunnel-Connection", + [69] = "Tunnel-Password", + [70] = "ARAP-Password", + [71] = "ARAP-Features", + [72] = "ARAP-Zone-Access", + [73] = "ARAP-Security", + [74] = "ARAP-Security-Data", + [75] = "Password-Retry", + [76] = "Prompt", + [77] = "Connect-Info", + [78] = "Configuration-Token", + [79] = "EAP-Message", + [80] = "Message Authenticator", + [81] = "Tunnel-Private-Group-ID", + [82] = "Tunnel-Assignment-ID", + [83] = "Tunnel-Preference", + [84] = "ARAP-Challenge-Response", + [85] = "Acct-Interim-Interval", + [86] = "Acct-Tunnel-Packets-Lost", + [87] = "NAS-Port-Id", + [88] = "Framed-Pool", + [89] = "CUI", + [90] = "Tunnel-Client-Auth-ID", + [91] = "Tunnel-Server-Auth-ID", + [92] = "NAS-Filter-Rule", + [94] = "Originating-Line-Info", + [95] = "NAS-IPv6-Address", + [96] = "Framed-Interface-Id", + [97] = "Framed-IPv6-Prefix", + [98] = "Login-IPv6-Host", + [99] = "Framed-IPv6-Route", + [100] = "Framed-IPv6-Pool", + [101] = "Error-Cause", + [102] = "EAP-Key-Name", + [103] = "Digest-Response", + [104] = "Digest-Realm", + [105] = "Digest-Nonce", + [106] = "Digest-Response-Auth", + [107] = "Digest-Nextnonce", + [108] = "Digest-Method", + [109] = "Digest-URI", + [110] = "Digest-Qop", + [111] = "Digest-Algorithm", + [112] = "Digest-Entity-Body-Hash", + [113] = "Digest-CNonce", + [114] = "Digest-Nonce-Count", + [115] = "Digest-Username", + [116] = "Digest-Opaque", + [117] = "Digest-Auth-Param", + [118] = "Digest-AKA-Auts", + [119] = "Digest-Domain", + [120] = "Digest-Stale", + [121] = "Digest-HA1", + [122] = "SIP-AOR", + [123] = "Delegated-IPv6-Prefix", + [124] = "MIP6-Feature-Vector", + [125] = "MIP6-Home-Link-Prefix", + [126] = "Operator-Name", + [127] = "Location-Information", + [128] = "Location-Data", + [129] = "Basic-Location-Policy-Rules", + [130] = "Extended-Location-Policy-Rules", + [131] = "Location-Capable", + [132] = "Requested-Location-Info", + [133] = "Framed-Management-Protocol", + [134] = "Management-Transport-Protection", + [135] = "Management-Policy-Id", + [136] = "Management-Privilege-Level", + [137] = "PKM-SS-Cert", + [138] = "PKM-CA-Cert", + [139] = "PKM-Config-Settings", + [140] = "PKM-Cryptosuite-List", + [141] = "PKM-SAID", + [142] = "PKM-SA-Descriptor", + [143] = "PKM-Auth-Key", + [144] = "DS-Lite-Tunnel-Name", + [145] = "Mobile-Node-Identifier", + [146] = "Service-Selection", + [147] = "PMIP6-Home-LMA-IPv6-Address", + [148] = "PMIP6-Visited-LMA-IPv6-Address", + [149] = "PMIP6-Home-LMA-IPv4-Address", + [150] = "PMIP6-Visited-LMA-IPv4-Address", + [151] = "PMIP6-Home-HN-Prefix", + [152] = "PMIP6-Visited-HN-Prefix", + [153] = "PMIP6-Home-Interface-ID", + [154] = "PMIP6-Visited-Interface-ID", + [155] = "PMIP6-Home-IPv4-HoA", + [156] = "PMIP6-Visited-IPv4-HoA", + [157] = "PMIP6-Home-DHCP4-Server-Address", + [158] = "PMIP6-Visited-DHCP4-Server-Address", + [159] = "PMIP6-Home-DHCP6-Server-Address", + [160] = "PMIP6-Visited-DHCP6-Server-Address", + [161] = "PMIP6-Home-IPv4-Gateway", + [162] = "PMIP6-Visited-IPv4-Gateway", + [163] = "EAP-Lower-Layer", + [164] = "GSS-Acceptor-Service-Name", + [165] = "GSS-Acceptor-Host-Name", + [166] = "GSS-Acceptor-Service-Specifics", + [167] = "GSS-Acceptor-Realm-Name", + [168] = "Framed-IPv6-Address", + [169] = "DNS-Server-IPv6-Address", + [170] = "Route-IPv6-Information", + [171] = "Delegated-IPv6-Prefix-Pool", + [172] = "Stateful-IPv6-Address-Pool", + [173] = "IPv6-6rd-Configuration" +} &default=function(i: count): string { return fmt("unknown-%d", i); }; + +const nas_port_types: table[count] of string = { + [0] = "Async", + [1] = "Sync", + [2] = "ISDN Sync", + [3] = "ISDN Async V.120", + [4] = "ISDN Async V.110", + [5] = "Virtual", + [6] = "PIAFS", + [7] = "HDLC Clear Channel", + [8] = "X.25", + [9] = "X.75", + [10] = "G.3 Fax", + [11] = "SDSL - Symmetric DSL", + [12] = "ADSL-CAP - Asymmetric DSL, Carrierless Amplitude Phase Modulation", + [13] = "ADSL-DMT - Asymmetric DSL, Discrete Multi-Tone", + [14] = "IDSL - ISDN Digital Subscriber Line", + [15] = "Ethernet", + [16] = "xDSL - Digital Subscriber Line of unknown type", + [17] = "Cable", + [18] = "Wireless - Other", + [19] = "Wireless - IEEE 802.11" +} &default=function(i: count): string { return fmt("unknown-%d", i); }; + +const service_types: table[count] of string = { + [1] = "Login", + [2] = "Framed", + [3] = "Callback Login", + [4] = "Callback Framed", + [5] = "Outbound", + [6] = "Administrative", + [7] = "NAS Prompt", + [8] = "Authenticate Only", + [9] = "Callback NAS Prompt", + [10] = "Call Check", + [11] = "Callback Administrative", +} &default=function(i: count): string { return fmt("unknown-%d", i); }; + +const framed_protocol_types: table[count] of string = { + [1] = "PPP", + [2] = "SLIP", + [3] = "AppleTalk Remote Access Protocol (ARAP)", + [4] = "Gandalf proprietary SingleLink/MultiLink protocol", + [5] = "Xylogics proprietary IPX/SLIP", + [6] = "X.75 Synchronous" +} &default=function(i: count): string { return fmt("unknown-%d", i); }; + +const vendor_9_types: table[count] of string = { + [1] = "Cisco-AVPair", + [2] = "Cisco-NAS-Port", + [3] = "Cisco-Fax-Account-Id-Origin", + [4] = "Cisco-Fax-Msg-Id", + [5] = "Cisco-Fax-Pages", + [6] = "Cisco-Fax-Coverpage-Flag", + [7] = "Cisco-Fax-Modem-Time", + [8] = "Cisco-Fax-Connect-Speed", + [9] = "Cisco-Fax-Recipient-Count", + [10] = "Cisco-Fax-Process-Abort-Flag", + [11] = "Cisco-Fax-Dsn-Address", + [12] = "Cisco-Fax-Dsn-Flag", + [13] = "Cisco-Fax-Mdn-Address", + [14] = "Cisco-Fax-Mdn-Flag", + [15] = "Cisco-Fax-Auth-Status", + [16] = "Cisco-Email-Server-Address", + [17] = "Cisco-Email-Server-Ack-Flag", + [18] = "Cisco-Gateway-Id", + [19] = "Cisco-Call-Type", + [20] = "Cisco-Port-Used", + [21] = "Cisco-Abort-Cause", + [23] = "Cisco-h323-remote-address", + [24] = "Cisco-h323-conf-id", + [25] = "Cisco-h323-setup-time", + [26] = "Cisco-h323-call-origin", + [27] = "Cisco-h323-call-type", + [28] = "Cisco-h323-connect-time", + [29] = "Cisco-h323-disconnect-time", + [30] = "Cisco-h323-disconnect-cause", + [31] = "Cisco-h323-voice-quality", + [33] = "Cisco-h323-gw-id", + [35] = "Cisco-h323-incoming-conn-id", + [37] = "Cisco-Policy-Up", + [38] = "Cisco-Policy-Down", + [100] = "Cisco-sip-conf-id", + [101] = "Cisco-h323-credit-amount", + [102] = "Cisco-h323-credit-time", + [103] = "Cisco-h323-return-code", + [104] = "Cisco-h323-prompt-id", + [105] = "Cisco-h323-day-and-time", + [106] = "Cisco-h323-redirect-number", + [107] = "Cisco-h323-preferred-lang", + [108] = "Cisco-h323-redirect-ip-addr", + [109] = "Cisco-h323-billing-model", + [110] = "Cisco-h323-currency", + [111] = "Cisco-subscriber", + [112] = "Cisco-gw-rxd-cdn", + [113] = "Cisco-gw-final-xlated-cdn", + [114] = "Cisco-remote-media-address", + [115] = "Cisco-release-source", + [116] = "Cisco-gw-rxd-cgn", + [117] = "Cisco-gw-final-xlated-cgn", + [141] = "Cisco-call-id", + [142] = "Cisco-session-protocol", + [143] = "Cisco-method", + [144] = "Cisco-prev-hop-via", + [145] = "Cisco-prev-hop-ip", + [146] = "Cisco-incoming-req-uri", + [147] = "Cisco-outgoing-req-uri", + [148] = "Cisco-next-hop-ip", + [149] = "Cisco-next-hop-dn", + [150] = "Cisco-sip-hdr", + [187] = "Cisco-Multilink-ID", + [188] = "Cisco-Num-In-Multilink", + [190] = "Cisco-Pre-Input-Octets", + [191] = "Cisco-Pre-Output-Octets", + [192] = "Cisco-Pre-Input-Packets", + [193] = "Cisco-Pre-Output-Packets", + [194] = "Cisco-Maximum-Time", + [195] = "Cisco-Disconnect-Cause", + [197] = "Cisco-Data-Rate", + [198] = "Cisco-PreSession-Time", + [208] = "Cisco-PW-Lifetime", + [209] = "Cisco-IP-Direct", + [210] = "Cisco-PPP-VJ-Slot-Comp", + [212] = "Cisco-PPP-Async-Map", + [217] = "Cisco-IP-Pool-Definition", + [218] = "Cisco-Assign-IP-Pool", + [228] = "Cisco-Route-IP", + [233] = "Cisco-Link-Compression", + [234] = "Cisco-Target-Util", + [235] = "Cisco-Maximum-Channels", + [242] = "Cisco-Data-Filter", + [243] = "Cisco-Call-Filter", + [244] = "Cisco-Idle-Limit", + [249] = "Cisco-Subscriber-Password", + [250] = "Cisco-Account-Info", + [251] = "Cisco-Service-Info", + [252] = "Cisco-Command-Code", + [253] = "Cisco-Xmit-Rate" +} &default=function(i: count): string { return fmt("Cisco-unknown-%d", i); }; + +const vendor_255_types: table[count] of string = { + [1] = "CVPN5000-Tunnel-Throughput", + [2] = "CVPN5000-Client-Assigned-IP", + [3] = "CVPN5000-Client-Real-IP", + [4] = "CVPN5000-VPN-GroupInfo", + [5] = "CVPN5000-VPN-Password", + [6] = "CVPN5000-Echo", + [7] = "CVPN5000-Client-Assigned-IPX" +} &default=function(i: count): string { return fmt("CVPN5000-unknown-%d", i); }; + +const vendor_311_types: table[count] of string = { + [1] = "MS-CHAP-Response", + [2] = "MS-CHAP-Error", + [3] = "MS-CHAP-CPW-1", + [4] = "MS-CHAP-CPW-2", + [5] = "MS-CHAP-LM-Enc-PW", + [6] = "MS-CHAP-NT-Enc-PW", + [7] = "MS-MPPE-Encryption-Policy", + [8] = "MS-MPPE-Encryption-Types", + [9] = "MS-RAS-Vendor", + [10] = "MS-CHAP-Domain", + [11] = "MS-CHAP-Challenge", + [12] = "MS-CHAP-MPPE-Keys", + [13] = "MS-BAP-Usage", + [14] = "MS-Link-Utilization-Threshold", + [15] = "MS-Link-Drop-Time-Limit", + [16] = "MS-MPPE-Send-Key", + [17] = "MS-MPPE-Recv-Key", + [18] = "MS-RAS-Version", + [19] = "MS-Old-ARAP-Password", + [20] = "MS-New-ARAP-Password", + [21] = "MS-ARAP-PW-Change-Reason", + [22] = "MS-Filter", + [23] = "MS-Acct-Auth-Type", + [24] = "MS-Acct-EAP-Type", + [25] = "MS-CHAP2-Response", + [26] = "MS-CHAP2-Success", + [27] = "MS-CHAP2-CPW", + [28] = "MS-Primary-DNS-Server", + [29] = "MS-Secondary-DNS-Server", + [30] = "MS-Primary-NBNS-Server", + [31] = "MS-Secondary-NBNS-Server", + [34] = "MS-RAS-Client-Name", + [35] = "MS-RAS-Client-Version", + [36] = "MS-Quarantine-IPFilter", + [37] = "MS-Quarantine-Session-Timeout", + [40] = "MS-User-Security-Identity", + [41] = "MS-Identity-Type", + [42] = "MS-Service-Class", + [44] = "MS-Quarantine-User-Class", + [45] = "MS-Quarantine-State", + [46] = "MS-Quarantine-Grace-Time", + [47] = "MS-Network-Access-Server-Type", + [48] = "MS-AFW-Zone", + [49] = "MS-AFW-Protection-Level", + [50] = "MS-Machine-Name", + [51] = "MS-IPv6-Filter", + [52] = "MS-IPv4-Remediation-Servers", + [53] = "MS-IPv6-Remediation-Servers", + [54] = "MS-RNAP-Not-Quarantine-Capable", + [55] = "MS-Quarantine-SOH", + [56] = "MS-RAS-Correlation", + [57] = "MS-Extended-Quarantine-State", + [58] = "MS-HCAP-User-Groups", + [59] = "MS-HCAP-Location-Group-Name", + [60] = "MS-HCAP-User-Name", + [61] = "MS-User-IPv4-Address", + [62] = "MS-User-IPv6-Address", + [63] = "MS-TSG-Device-Redirection" +} &default=function(i: count): string { return fmt("MS-unknown-%d", i); }; + +const vendor_3076_types: table[count] of string = { + [1] = "CVPN3000-Access-Hours", + [2] = "CVPN3000-Simultaneous-Logins", + [3] = "CVPN3000-Min-Password-Length", + [4] = "CVPN3000-Allow-Alpha-Only-Passwords", + [5] = "CVPN3000-Primary-DNS", + [6] = "CVPN3000-Secondary-DNS", + [7] = "CVPN3000-Primary-WINS", + [8] = "CVPN3000-Secondary-WINS", + [9] = "CVPN3000-SEP-Card-Assignment", + [10] = "CVPN3000-Priority-On-SEP", + [11] = "CVPN3000-Tunneling-Protocols", + [12] = "CVPN3000-IPSec-Sec-Association", + [13] = "CVPN3000-IPSec-Authentication", + [15] = "CVPN3000-IPSec-Banner1", + [16] = "CVPN3000-IPSec-Allow-Passwd-Store", + [17] = "CVPN3000-Use-Client-Address", + [18] = "CVPN3000-PPTP-Min-Auth-Protocol", + [19] = "CVPN3000-L2TP-Min-Auth-Protocol", + [20] = "CVPN3000-PPTP-Encryption", + [21] = "CVPN3000-L2TP-Encryption", + [22] = "CVPN3000-Auth-Server-Type", + [23] = "CVPN3000-Auth-Server-Password", + [24] = "CVPN3000-Request-Auth-Vector", + [25] = "CVPN3000-IPSec-LTL-Keepalives", + [26] = "CVPN3000-IPSec-Group-Name", + [27] = "CVPN3000-IPSec-Split-Tunnel-List", + [28] = "CVPN3000-IPSec-Default-Domain", + [29] = "CVPN3000-IPSec-Split-DNS-Names", + [30] = "CVPN3000-IPSec-Tunnel-Type", + [31] = "CVPN3000-IPSec-Mode-Config", + [32] = "CVPN3000-Auth-Server-Priority", + [33] = "CVPN3000-IPSec-User-Group-Lock", + [34] = "CVPN3000-IPSec-Over-UDP", + [35] = "CVPN3000-IPSec-Over-UDP-Port", + [36] = "CVPN3000-IPSec-Banner2", + [37] = "CVPN3000-PPTP-MPPC-Compression", + [38] = "CVPN3000-L2TP-MPPC-Compression", + [39] = "CVPN3000-IPSec-IP-Compression", + [40] = "CVPN3000-IPSec-IKE-Peer-ID-Check", + [41] = "CVPN3000-IKE-Keep-Alives", + [42] = "CVPN3000-IPSec-Auth-On-Rekey", + [45] = "CVPN3000-Reqrd-Client-Fw-Vendor-Code", + [46] = "CVPN3000-Reqrd-Client-Fw-Product-Code", + [47] = "CVPN3000-Reqrd-Client-Fw-Description", + [48] = "CVPN3000-Require-HW-Client-Auth", + [49] = "CVPN3000-Require-Individual-User-Auth", + [50] = "CVPN3000-Authd-User-Idle-Timeout", + [51] = "CVPN3000-Cisco-IP-Phone-Bypass", + [52] = "CVPN3000-User-Auth-Server-Name", + [53] = "CVPN3000-User-Auth-Server-Port", + [54] = "CVPN3000-User-Auth-Server-Secret", + [55] = "CVPN3000-IPSec-Split-Tunneling-Policy", + [56] = "CVPN3000-IPSec-Reqrd-Client-Fw-Cap", + [57] = "CVPN3000-IPSec-Client-Fw-Filter-Name", + [58] = "CVPN3000-IPSec-Client-Fw-Filter-Opt", + [59] = "CVPN3000-IPSec-Backup-Servers", + [60] = "CVPN3000-IPSec-Backup-Server-List", + [61] = "CVPN3000-DHCP-Network-Scope", + [62] = "CVPN3000-MS-Client-Icpt-DHCP-Conf-Msg", + [63] = "CVPN3000-MS-Client-Subnet-Mask", + [64] = "CVPN3000-Allow-Network-Extension-Mode", + [65] = "CVPN3000-IPSec-Authorization-Type", + [66] = "CVPN3000-IPSec-Authorization-Required", + [67] = "CVPN3000-IPSec-DN-Field", + [68] = "CVPN3000-IPSec-Confidence-Level", + [69] = "CVPN3000-WebVPN-Content-Filter", + [70] = "CVPN3000-WebVPN-Enable-functions", + [74] = "CVPN3000-WebVPN-Exchange-Addr", + [75] = "CVPN3000-LEAP-Bypass", + [78] = "CVPN3000-WebVPN-Exchange-NETBIOS-name", + [79] = "CVPN3000-Port-Forwarding-Name", + [80] = "CVPN3000-IE-Proxy-Server", + [81] = "CVPN3000-IE-Proxy-Server-Policy", + [82] = "CVPN3000-IE-Proxy-Exception-List", + [83] = "CVPN3000-IE-Proxy-Bypass-Local", + [84] = "CVPN3000-IKE-Keepalive-Retry-Interval", + [88] = "CVPN3000-Perfect-Forward-Secrecy-Enable", + [89] = "CVPN3000-NAC-Enable", + [90] = "CVPN3000-NAC-Status-Query-Timer", + [91] = "CVPN3000-NAC-Revalidation-Timer", + [92] = "CVPN3000-NAC-Default-ACL", + [93] = "CVPN3000-WebVPN-URL-Entry-Enable", + [94] = "CVPN3000-WebVPN-File-Access-Enable", + [95] = "CVPN3000-WebVPN-File-Svr-Entry-Enable", + [96] = "CVPN3000-WebVPN-File-Svr-Brwsing-Enable", + [97] = "CVPN3000-WebVPN-Port-Forwarding-Enable", + [98] = "CVPN3000-WebVPN-Outlook-Exch-Proxy-Enb", + [99] = "CVPN3000-WebVPN-Port-Fwding-HTTP-Proxy", + [100] = "CVPN3000-WebVPN-Auto-Applet-Downld-Enb", + [101] = "CVPN3000-WebVPN-Citrix-Metaframe-Enable", + [102] = "CVPN3000-WebVPN-Apply-ACL", + [103] = "CVPN3000-WebVPN-SSL-VPN-Client-Enable", + [104] = "CVPN3000-WebVPN-SSL-VPN-Client-Required", + [105] = "CVPN3000-WebVPN-SSL-VPN-Client-Keep-Ins", + [128] = "CVPN3000-Partition-Primary-DHCP", + [129] = "CVPN3000-Partition-Secondary-DHCP", + [131] = "CVPN3000-Partition-Premise-Router", + [132] = "CVPN3000-Partition-Max-Sessions", + [133] = "CVPN3000-Partition-Mobile-IP-Key", + [134] = "CVPN3000-Partition-Mobile-IP-Address", + [135] = "CVPN3000-Partition-Mobile-IP-SPI", + [136] = "CVPN3000-Strip-Realm", + [137] = "CVPN3000-Group-Name" +} &default=function(i: count): string { return fmt("CPNV3000-unknown-%d", i); }; + +const vendor_14823_types: table[count] of string = { + [1] = "Aruba-User-Role", + [2] = "Aruba-User-Vlan", + [3] = "Aruba-Priv-Admin-User", + [4] = "Aruba-Admin-Role", + [5] = "Aruba-Essid-Name", + [6] = "Aruba-Location-Id", + [7] = "Aruba-Port-Identifier", + [8] = "Aruba-MMS-User-Template", + [9] = "Aruba-Named-User-Vlan", + [10] = "Aruba-AP-Group", + [11] = "Aruba-Framed-IPv6-Address", + [12] = "Aruba-Device-Type", + [13] = "Aruba-AP-Name", + [14] = "Aruba-No-DHCP-Fingerprint", + [15] = "Aruba-Mdps-Device-Udid", + [16] = "Aruba-Mdps-Device-Imei", + [17] = "Aruba-Mdps-Device-Iccid", + [18] = "Aruba-Mdps-Max-Devices", + [19] = "Aruba-Mdps-Device-Name", + [20] = "Aruba-Mdps-Device-Product", + [21] = "Aruba-Mdps-Device-Version", + [22] = "Aruba-Mdps-Device-Serial", + [23] = "Aruba-CPPM-Role", + [24] = "Aruba-AirGroup-User-Name", + [25] = "Aruba-AirGroup-Shared-User", + [26] = "Aruba-AirGroup-Shared-Role", + [27] = "Aruba-AirGroup-Device-Type", + [28] = "Aruba-Auth-Survivability", + [29] = "Aruba-AS-User-Name", + [30] = "Aruba-AS-Credential-Hash", + [31] = "Aruba-WorkSpace-App-Name", + [32] = "Aruba-Mdps-Provisioning-Settings", + [33] = "Aruba-Mdps-Device-Profile" +} &default=function(i: count): string { return fmt("Aruba-unknown-%d", i); }; + diff --git a/scripts/base/protocols/radius/dpd.sig b/scripts/base/protocols/radius/dpd.sig new file mode 100644 index 0000000000..d32ba49771 --- /dev/null +++ b/scripts/base/protocols/radius/dpd.sig @@ -0,0 +1,7 @@ +# Generated by binpac_quickstart + +signature dpd_radius { + ip-proto == udp + # TODO: payload /^RADIUS/ + enable "radius" +} \ No newline at end of file diff --git a/scripts/base/protocols/radius/main.bro b/scripts/base/protocols/radius/main.bro new file mode 100644 index 0000000000..0d239dcb64 --- /dev/null +++ b/scripts/base/protocols/radius/main.bro @@ -0,0 +1,142 @@ +##! Implements base functionality for RADIUS analysis. Generates the radius.log file. + +# Generated by binpac_quickstart + +module RADIUS; + +@load ./consts.bro + +export { + redef enum Log::ID += { LOG }; + + type Info: record { + ## Timestamp for when the event happened. + ts: time &log; + ## Unique ID for the connection. + uid: string &log; + ## The connection's 4-tuple of endpoint addresses/ports. + id: conn_id &log; + msg_type: string &log; + }; + + ## Event that can be handled to access the RADIUS record as it is sent on + ## to the loggin framework. + global log_radius: event(rec: Info); +} + +const ports = { 1812/udp }; + +event bro_init() &priority=5 + { + Log::create_stream(RADIUS::LOG, [$columns=Info, $ev=log_radius]); + Analyzer::register_for_ports(Analyzer::ANALYZER_RADIUS, ports); + } + +event radius_message(c: connection, msg_type: count, trans_id: count) + { + local info: Info; + info$ts = network_time(); + info$uid = c$uid; + info$id = c$id; + info$msg_type = msg_types[msg_type]; + + Log::write(RADIUS::LOG, info); + } + +event radius_attribute(c: connection, attr_type: count, trans_id: count, value: string) + { + switch ( attr_types[attr_type] ) { +# case "Calling-Station-Id": +# tmp = normalize_mac(value); +# if ( tmp != "" ) +# print cat(attr_types[attr_type], " ", tmp); +# else +# print cat(attr_types[attr_type], " ", value); +# break; +# case "Called-Station-Id": +# fallthrough; + + ## Strings: + case "Reply-Message": + fallthrough; + case "User-Name": + print cat(attr_types[attr_type], ": ", value); + break; + + ## IPs: + + case "Framed-IP-Address": + fallthrough; + case "Framed-IP-Netmask": + fallthrough; + case "NAS-IP-Address": + print cat(attr_types[attr_type], ": ", count_to_v4_addr(bytestring_to_count(value))); + break; + + ## Counts: + + case "Framed-MTU": + fallthrough; + case "NAS-Port": + fallthrough; + case "Session-Timeout": + print cat(attr_types[attr_type], ": ", bytestring_to_count(value)); + break; + + ## Other: + + case "NAS-Port-Type": + print cat(attr_types[attr_type], ": ", nas_port_types[bytestring_to_count(value)]); + break; + case "Service-Type": + print cat(attr_types[attr_type], ": ", service_types[bytestring_to_count(value)]); + break; + case "Framed-Protocol": + print cat(attr_types[attr_type], ": ", framed_protocol_types[bytestring_to_count(value)]); + break; + case "Vendor-Specific": + switch(bytestring_to_count(sub_bytes(value, 0, 4))) { + case 9: + # Cisco IOS/PIX 6.0 + print cat(vendor_9_types[bytestring_to_count(sub_bytes(value, 5, 1))], ": ", sub_bytes(value, 7, 128)); + break; + case 255: + # Cisco VPN 5000 + print cat(vendor_255_types[bytestring_to_count(sub_bytes(value, 5, 1))], ": ", sub_bytes(value, 7, 128)); + break; + case 311: + # Microsoft + print cat(vendor_311_types[bytestring_to_count(sub_bytes(value, 5, 1))], ": ", sub_bytes(value, 7, 128)); + break; + case 3076: + # Cisco VPN 3000 + print cat(vendor_3076_types[bytestring_to_count(sub_bytes(value, 5, 1))], ": ", sub_bytes(value, 7, 128)); + break; + case 14823: + # Aruba + print cat(vendor_14823_types[bytestring_to_count(sub_bytes(value, 5, 1))], ": ", sub_bytes(value, 7, 128)); + break; + default: + print cat("Unknown vendor: ", bytestring_to_count(sub_bytes(value, 0, 4))); + break; + } + break; + default: + print cat(attr_types[attr_type], ": ", value); + break; + } + } + +# Called-Station-Id: +# Calling-Station-Id: +# Class: +# NAS-Identifier: +# State: +# Vendor-Specific: +# unknown-185: +# unknown-66: +# unknown-77: +# unknown-79: +# unknown-80: +# unknown-87: +# unknown-95: \ No newline at end of file diff --git a/scripts/base/utils/addrs.bro b/scripts/base/utils/addrs.bro index e2031e3efa..54ef62695a 100644 --- a/scripts/base/utils/addrs.bro +++ b/scripts/base/utils/addrs.bro @@ -1,4 +1,4 @@ -##! Functions for parsing and manipulating IP addresses. +##! Functions for parsing and manipulating IP and MAC addresses. # Regular expressions for matching IP addresses in strings. const ipv4_addr_regex = /[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}/; @@ -119,3 +119,27 @@ function addr_to_uri(a: addr): string else return fmt("[%s]", a); } + +## Given a string, extracts the hex digits and returns a MAC address in the +## format: 00:a0:32:d7:81:8f. If the string doesn't contain 12 or 16 hex digits, +## an empty string is returned. +## +## a: the string to normalize +## +## Returns: a normalized MAC address, or an empty string in the case of an error. +function normalize_mac(a: string): string + { + local result = to_lower(gsub(a, /[^A-Fa-f0-9]/, "")); + local octets: string_vec; + if ( |result| == 12 ) + { + octets = str_split(result, vector(2, 4, 6, 8, 10)); + return fmt("%s:%s:%s:%s:%s:%s", octets[1], octets[2], octets[3], octets[4], octets[5], octets[6]); + } + if ( |result| == 16 ) + { + octets = str_split(result, vector(2, 4, 6, 8, 10, 12, 14)); + return fmt("%s:%s:%s:%s:%s:%s:%s:%s", octets[1], octets[2], octets[3], octets[4], octets[5], octets[6], octets[7], octets[8]); + } + return ""; + } \ No newline at end of file diff --git a/src/analyzer/protocol/CMakeLists.txt b/src/analyzer/protocol/CMakeLists.txt index fc63aa4b66..a7bb43a470 100644 --- a/src/analyzer/protocol/CMakeLists.txt +++ b/src/analyzer/protocol/CMakeLists.txt @@ -19,14 +19,15 @@ add_subdirectory(ident) add_subdirectory(interconn) add_subdirectory(irc) add_subdirectory(login) -add_subdirectory(modbus) add_subdirectory(mime) +add_subdirectory(modbus) add_subdirectory(ncp) -add_subdirectory(netflow) add_subdirectory(netbios) +add_subdirectory(netflow) add_subdirectory(ntp) add_subdirectory(pia) add_subdirectory(pop3) +add_subdirectory(radius) add_subdirectory(rpc) add_subdirectory(smb) add_subdirectory(smtp) diff --git a/src/analyzer/protocol/radius/CMakeLists.txt b/src/analyzer/protocol/radius/CMakeLists.txt new file mode 100644 index 0000000000..2d1cd0e024 --- /dev/null +++ b/src/analyzer/protocol/radius/CMakeLists.txt @@ -0,0 +1,11 @@ +# Generated by binpac_quickstart + +include(BroPlugin) + +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +bro_plugin_begin(Bro RADIUS) + bro_plugin_cc(RADIUS.cc Plugin.cc) + bro_plugin_bif(events.bif) + bro_plugin_pac(radius.pac radius-analyzer.pac radius-protocol.pac) +bro_plugin_end() \ No newline at end of file diff --git a/src/analyzer/protocol/radius/Plugin.cc b/src/analyzer/protocol/radius/Plugin.cc new file mode 100644 index 0000000000..22780c13c5 --- /dev/null +++ b/src/analyzer/protocol/radius/Plugin.cc @@ -0,0 +1,11 @@ +// Generated by binpac_quickstart + +#include "plugin/Plugin.h" + +#include "RADIUS.h" + +BRO_PLUGIN_BEGIN(Bro, RADIUS) + BRO_PLUGIN_DESCRIPTION("RADIUS analyzer"); + BRO_PLUGIN_ANALYZER("RADIUS", RADIUS::RADIUS_Analyzer); + BRO_PLUGIN_BIF_FILE(events); +BRO_PLUGIN_END \ No newline at end of file diff --git a/src/analyzer/protocol/radius/RADIUS.cc b/src/analyzer/protocol/radius/RADIUS.cc new file mode 100644 index 0000000000..e88bd40083 --- /dev/null +++ b/src/analyzer/protocol/radius/RADIUS.cc @@ -0,0 +1,45 @@ +// Generated by binpac_quickstart + +#include "RADIUS.h" + +#include "Reporter.h" + +#include "events.bif.h" + +using namespace analyzer::RADIUS; + +RADIUS_Analyzer::RADIUS_Analyzer(Connection* c) + +: analyzer::Analyzer("RADIUS", c) + + { + interp = new binpac::RADIUS::RADIUS_Conn(this); + + } + +RADIUS_Analyzer::~RADIUS_Analyzer() + { + delete interp; + } + +void RADIUS_Analyzer::Done() + { + + Analyzer::Done(); + + } + +void RADIUS_Analyzer::DeliverPacket(int len, const u_char* data, + bool orig, int seq, const IP_Hdr* ip, int caplen) + { + Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); + + try + { + interp->NewData(orig, data, data + len); + } + catch ( const binpac::Exception& e ) + { + ProtocolViolation(fmt("Binpac exception: %s", e.c_msg())); + } + } diff --git a/src/analyzer/protocol/radius/RADIUS.h b/src/analyzer/protocol/radius/RADIUS.h new file mode 100644 index 0000000000..85f8f197a6 --- /dev/null +++ b/src/analyzer/protocol/radius/RADIUS.h @@ -0,0 +1,45 @@ +// Generated by binpac_quickstart + +#ifndef ANALYZER_PROTOCOL_RADIUS_RADIUS_H +#define ANALYZER_PROTOCOL_RADIUS_RADIUS_H + +#include "events.bif.h" + + +#include "analyzer/protocol/udp/UDP.h" + +#include "radius_pac.h" + +namespace analyzer { namespace RADIUS { + +class RADIUS_Analyzer + +: public analyzer::Analyzer { + +public: + RADIUS_Analyzer(Connection* conn); + virtual ~RADIUS_Analyzer(); + + // Overriden from Analyzer. + virtual void Done(); + + virtual void DeliverPacket(int len, const u_char* data, bool orig, + int seq, const IP_Hdr* ip, int caplen); + + + static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) + { return new RADIUS_Analyzer(conn); } + + static bool Available() + { + return ( radius_message ); + } + +protected: + binpac::RADIUS::RADIUS_Conn* interp; + +}; + +} } // namespace analyzer::* + +#endif diff --git a/src/analyzer/protocol/radius/events.bif b/src/analyzer/protocol/radius/events.bif new file mode 100644 index 0000000000..4ef93a8ca7 --- /dev/null +++ b/src/analyzer/protocol/radius/events.bif @@ -0,0 +1,23 @@ +# Generated by binpac_quickstart + +## Generated for RADIUS messages +## +## See `Wikipedia `__ for more information about RADIUS +## +## c: The connection +## msg_type: The value of the code field (1 == Access-Request, 2 == Access-Accept, etc.) +## trans_id: The RADIUS transaction identifier +## authenticator: The value of the authenticator field +## +event radius_message%(c: connection, msg_type: count, trans_id: count%); + +## Generated for each RADIUS attribute +## +## See `Wikipedia `__ for more information about RADIUS +## +## c: The connection +## attr_type: The value of the code field (1 == User-Name, 2 == User-Password, etc.) +## trans_id: The RADIUS transaction identifier +## authenticator: The value of the authenticator field +## +event radius_attribute%(c: connection, attr_type: count, trans_id: count, value: string%); \ No newline at end of file diff --git a/src/analyzer/protocol/radius/radius-analyzer.pac b/src/analyzer/protocol/radius/radius-analyzer.pac new file mode 100644 index 0000000000..9739970880 --- /dev/null +++ b/src/analyzer/protocol/radius/radius-analyzer.pac @@ -0,0 +1,23 @@ +# Generated by binpac_quickstart + +refine flow RADIUS_Flow += { + function proc_radius_message(code: uint8, trans_id: uint8): bool + %{ + BifEvent::generate_radius_message(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), code, trans_id); + return true; + %} + + function proc_radius_attribute(code: uint8, trans_id: uint8, value: bytestring): bool + %{ + BifEvent::generate_radius_attribute(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), code, trans_id, bytestring_to_val(value)); + return true; + %} +}; + +refine typeattr RADIUS_PDU += &let { + proc: bool = $context.flow.proc_radius_message(code, trans_id); +}; + +refine typeattr RADIUS_Attribute += &let { + proc: bool = $context.flow.proc_radius_attribute(code, trans_id, value); +}; \ No newline at end of file diff --git a/src/analyzer/protocol/radius/radius-protocol.pac b/src/analyzer/protocol/radius/radius-protocol.pac new file mode 100644 index 0000000000..27d96bb3f6 --- /dev/null +++ b/src/analyzer/protocol/radius/radius-protocol.pac @@ -0,0 +1,15 @@ +# Generated by binpac_quickstart + +type RADIUS_PDU(is_orig: bool) = record { + code: uint8; + trans_id: uint8; + length: uint16; + authenticator: bytestring &length=16; + attributes: RADIUS_Attribute(trans_id)[] &until($input.length() == 0); +} &byteorder=bigendian; + +type RADIUS_Attribute(trans_id: uint8) = record { + code: uint8; + length: uint8; + value: bytestring &length=length-2; +}; \ No newline at end of file diff --git a/src/analyzer/protocol/radius/radius.pac b/src/analyzer/protocol/radius/radius.pac new file mode 100644 index 0000000000..a4c3e7dd5c --- /dev/null +++ b/src/analyzer/protocol/radius/radius.pac @@ -0,0 +1,37 @@ +# Generated by binpac_quickstart + +# Analyzer for RADIUS +# - radius-protocol.pac: describes the RADIUS protocol messages +# - radius-analyzer.pac: describes the RADIUS analyzer code + +%include binpac.pac +%include bro.pac + +%extern{ + #include "events.bif.h" +%} + +analyzer RADIUS withcontext { + connection: RADIUS_Conn; + flow: RADIUS_Flow; +}; + +# Our connection consists of two flows, one in each direction. +connection RADIUS_Conn(bro_analyzer: BroAnalyzer) { + upflow = RADIUS_Flow(true); + downflow = RADIUS_Flow(false); +}; + +%include radius-protocol.pac + +# Now we define the flow: +flow RADIUS_Flow(is_orig: bool) { + # There are two options here: flowunit or datagram. + # flowunit = RADIUS_PDU(is_orig) withcontext(connection, this); + datagram = RADIUS_PDU(is_orig) withcontext(connection, this); + # Using flowunit will cause the anlayzer to buffer incremental input. + # This is needed for &oneline and &length. If you don't need this, you'll + # get better performance with datagram. +}; + +%include radius-analyzer.pac \ No newline at end of file From f3c0d17541a56a844f532a111118344882e39a2f Mon Sep 17 00:00:00 2001 From: Vlad Grigorescu Date: Tue, 10 Dec 2013 22:09:16 -0500 Subject: [PATCH 002/136] Basic RADIUS functionality implemented. --- scripts/base/init-bare.bro | 17 + scripts/base/protocols/radius/__load__.bro | 1 - scripts/base/protocols/radius/consts.bro | 306 ------------------ scripts/base/protocols/radius/dpd.sig | 7 - scripts/base/protocols/radius/main.bro | 190 +++++------ src/analyzer/protocol/radius/events.bif | 9 +- .../protocol/radius/radius-analyzer.pac | 39 ++- 7 files changed, 140 insertions(+), 429 deletions(-) delete mode 100644 scripts/base/protocols/radius/dpd.sig diff --git a/scripts/base/init-bare.bro b/scripts/base/init-bare.bro index 9f8c9f42ac..d956cf6a2d 100644 --- a/scripts/base/init-bare.bro +++ b/scripts/base/init-bare.bro @@ -2762,6 +2762,23 @@ export { name: string &optional; } &log; } +module RADIUS; + +export { + type RADIUS::AttributeList: vector of string; + type RADIUS::Attributes: table[count] of RADIUS::AttributeList; + + type RADIUS::Message: record { + ## The type of message (Access-Request, Access-Accept, etc.) + code : count; + ## The transaction ID + trans_id : count; + ## The "authenticator" string + authenticator : string; + ## Any attributes + attributes : RADIUS::Attributes &optional; + }; +} module GLOBAL; @load base/bif/event.bif diff --git a/scripts/base/protocols/radius/__load__.bro b/scripts/base/protocols/radius/__load__.bro index 96bf67a57f..fb802a40a5 100644 --- a/scripts/base/protocols/radius/__load__.bro +++ b/scripts/base/protocols/radius/__load__.bro @@ -1,3 +1,2 @@ # Generated by binpac_quickstart @load ./main -#@load-sigs ./dpd.sig \ No newline at end of file diff --git a/scripts/base/protocols/radius/consts.bro b/scripts/base/protocols/radius/consts.bro index 6231a25631..d9c78f58ad 100644 --- a/scripts/base/protocols/radius/consts.bro +++ b/scripts/base/protocols/radius/consts.bro @@ -229,309 +229,3 @@ const framed_protocol_types: table[count] of string = { [6] = "X.75 Synchronous" } &default=function(i: count): string { return fmt("unknown-%d", i); }; -const vendor_9_types: table[count] of string = { - [1] = "Cisco-AVPair", - [2] = "Cisco-NAS-Port", - [3] = "Cisco-Fax-Account-Id-Origin", - [4] = "Cisco-Fax-Msg-Id", - [5] = "Cisco-Fax-Pages", - [6] = "Cisco-Fax-Coverpage-Flag", - [7] = "Cisco-Fax-Modem-Time", - [8] = "Cisco-Fax-Connect-Speed", - [9] = "Cisco-Fax-Recipient-Count", - [10] = "Cisco-Fax-Process-Abort-Flag", - [11] = "Cisco-Fax-Dsn-Address", - [12] = "Cisco-Fax-Dsn-Flag", - [13] = "Cisco-Fax-Mdn-Address", - [14] = "Cisco-Fax-Mdn-Flag", - [15] = "Cisco-Fax-Auth-Status", - [16] = "Cisco-Email-Server-Address", - [17] = "Cisco-Email-Server-Ack-Flag", - [18] = "Cisco-Gateway-Id", - [19] = "Cisco-Call-Type", - [20] = "Cisco-Port-Used", - [21] = "Cisco-Abort-Cause", - [23] = "Cisco-h323-remote-address", - [24] = "Cisco-h323-conf-id", - [25] = "Cisco-h323-setup-time", - [26] = "Cisco-h323-call-origin", - [27] = "Cisco-h323-call-type", - [28] = "Cisco-h323-connect-time", - [29] = "Cisco-h323-disconnect-time", - [30] = "Cisco-h323-disconnect-cause", - [31] = "Cisco-h323-voice-quality", - [33] = "Cisco-h323-gw-id", - [35] = "Cisco-h323-incoming-conn-id", - [37] = "Cisco-Policy-Up", - [38] = "Cisco-Policy-Down", - [100] = "Cisco-sip-conf-id", - [101] = "Cisco-h323-credit-amount", - [102] = "Cisco-h323-credit-time", - [103] = "Cisco-h323-return-code", - [104] = "Cisco-h323-prompt-id", - [105] = "Cisco-h323-day-and-time", - [106] = "Cisco-h323-redirect-number", - [107] = "Cisco-h323-preferred-lang", - [108] = "Cisco-h323-redirect-ip-addr", - [109] = "Cisco-h323-billing-model", - [110] = "Cisco-h323-currency", - [111] = "Cisco-subscriber", - [112] = "Cisco-gw-rxd-cdn", - [113] = "Cisco-gw-final-xlated-cdn", - [114] = "Cisco-remote-media-address", - [115] = "Cisco-release-source", - [116] = "Cisco-gw-rxd-cgn", - [117] = "Cisco-gw-final-xlated-cgn", - [141] = "Cisco-call-id", - [142] = "Cisco-session-protocol", - [143] = "Cisco-method", - [144] = "Cisco-prev-hop-via", - [145] = "Cisco-prev-hop-ip", - [146] = "Cisco-incoming-req-uri", - [147] = "Cisco-outgoing-req-uri", - [148] = "Cisco-next-hop-ip", - [149] = "Cisco-next-hop-dn", - [150] = "Cisco-sip-hdr", - [187] = "Cisco-Multilink-ID", - [188] = "Cisco-Num-In-Multilink", - [190] = "Cisco-Pre-Input-Octets", - [191] = "Cisco-Pre-Output-Octets", - [192] = "Cisco-Pre-Input-Packets", - [193] = "Cisco-Pre-Output-Packets", - [194] = "Cisco-Maximum-Time", - [195] = "Cisco-Disconnect-Cause", - [197] = "Cisco-Data-Rate", - [198] = "Cisco-PreSession-Time", - [208] = "Cisco-PW-Lifetime", - [209] = "Cisco-IP-Direct", - [210] = "Cisco-PPP-VJ-Slot-Comp", - [212] = "Cisco-PPP-Async-Map", - [217] = "Cisco-IP-Pool-Definition", - [218] = "Cisco-Assign-IP-Pool", - [228] = "Cisco-Route-IP", - [233] = "Cisco-Link-Compression", - [234] = "Cisco-Target-Util", - [235] = "Cisco-Maximum-Channels", - [242] = "Cisco-Data-Filter", - [243] = "Cisco-Call-Filter", - [244] = "Cisco-Idle-Limit", - [249] = "Cisco-Subscriber-Password", - [250] = "Cisco-Account-Info", - [251] = "Cisco-Service-Info", - [252] = "Cisco-Command-Code", - [253] = "Cisco-Xmit-Rate" -} &default=function(i: count): string { return fmt("Cisco-unknown-%d", i); }; - -const vendor_255_types: table[count] of string = { - [1] = "CVPN5000-Tunnel-Throughput", - [2] = "CVPN5000-Client-Assigned-IP", - [3] = "CVPN5000-Client-Real-IP", - [4] = "CVPN5000-VPN-GroupInfo", - [5] = "CVPN5000-VPN-Password", - [6] = "CVPN5000-Echo", - [7] = "CVPN5000-Client-Assigned-IPX" -} &default=function(i: count): string { return fmt("CVPN5000-unknown-%d", i); }; - -const vendor_311_types: table[count] of string = { - [1] = "MS-CHAP-Response", - [2] = "MS-CHAP-Error", - [3] = "MS-CHAP-CPW-1", - [4] = "MS-CHAP-CPW-2", - [5] = "MS-CHAP-LM-Enc-PW", - [6] = "MS-CHAP-NT-Enc-PW", - [7] = "MS-MPPE-Encryption-Policy", - [8] = "MS-MPPE-Encryption-Types", - [9] = "MS-RAS-Vendor", - [10] = "MS-CHAP-Domain", - [11] = "MS-CHAP-Challenge", - [12] = "MS-CHAP-MPPE-Keys", - [13] = "MS-BAP-Usage", - [14] = "MS-Link-Utilization-Threshold", - [15] = "MS-Link-Drop-Time-Limit", - [16] = "MS-MPPE-Send-Key", - [17] = "MS-MPPE-Recv-Key", - [18] = "MS-RAS-Version", - [19] = "MS-Old-ARAP-Password", - [20] = "MS-New-ARAP-Password", - [21] = "MS-ARAP-PW-Change-Reason", - [22] = "MS-Filter", - [23] = "MS-Acct-Auth-Type", - [24] = "MS-Acct-EAP-Type", - [25] = "MS-CHAP2-Response", - [26] = "MS-CHAP2-Success", - [27] = "MS-CHAP2-CPW", - [28] = "MS-Primary-DNS-Server", - [29] = "MS-Secondary-DNS-Server", - [30] = "MS-Primary-NBNS-Server", - [31] = "MS-Secondary-NBNS-Server", - [34] = "MS-RAS-Client-Name", - [35] = "MS-RAS-Client-Version", - [36] = "MS-Quarantine-IPFilter", - [37] = "MS-Quarantine-Session-Timeout", - [40] = "MS-User-Security-Identity", - [41] = "MS-Identity-Type", - [42] = "MS-Service-Class", - [44] = "MS-Quarantine-User-Class", - [45] = "MS-Quarantine-State", - [46] = "MS-Quarantine-Grace-Time", - [47] = "MS-Network-Access-Server-Type", - [48] = "MS-AFW-Zone", - [49] = "MS-AFW-Protection-Level", - [50] = "MS-Machine-Name", - [51] = "MS-IPv6-Filter", - [52] = "MS-IPv4-Remediation-Servers", - [53] = "MS-IPv6-Remediation-Servers", - [54] = "MS-RNAP-Not-Quarantine-Capable", - [55] = "MS-Quarantine-SOH", - [56] = "MS-RAS-Correlation", - [57] = "MS-Extended-Quarantine-State", - [58] = "MS-HCAP-User-Groups", - [59] = "MS-HCAP-Location-Group-Name", - [60] = "MS-HCAP-User-Name", - [61] = "MS-User-IPv4-Address", - [62] = "MS-User-IPv6-Address", - [63] = "MS-TSG-Device-Redirection" -} &default=function(i: count): string { return fmt("MS-unknown-%d", i); }; - -const vendor_3076_types: table[count] of string = { - [1] = "CVPN3000-Access-Hours", - [2] = "CVPN3000-Simultaneous-Logins", - [3] = "CVPN3000-Min-Password-Length", - [4] = "CVPN3000-Allow-Alpha-Only-Passwords", - [5] = "CVPN3000-Primary-DNS", - [6] = "CVPN3000-Secondary-DNS", - [7] = "CVPN3000-Primary-WINS", - [8] = "CVPN3000-Secondary-WINS", - [9] = "CVPN3000-SEP-Card-Assignment", - [10] = "CVPN3000-Priority-On-SEP", - [11] = "CVPN3000-Tunneling-Protocols", - [12] = "CVPN3000-IPSec-Sec-Association", - [13] = "CVPN3000-IPSec-Authentication", - [15] = "CVPN3000-IPSec-Banner1", - [16] = "CVPN3000-IPSec-Allow-Passwd-Store", - [17] = "CVPN3000-Use-Client-Address", - [18] = "CVPN3000-PPTP-Min-Auth-Protocol", - [19] = "CVPN3000-L2TP-Min-Auth-Protocol", - [20] = "CVPN3000-PPTP-Encryption", - [21] = "CVPN3000-L2TP-Encryption", - [22] = "CVPN3000-Auth-Server-Type", - [23] = "CVPN3000-Auth-Server-Password", - [24] = "CVPN3000-Request-Auth-Vector", - [25] = "CVPN3000-IPSec-LTL-Keepalives", - [26] = "CVPN3000-IPSec-Group-Name", - [27] = "CVPN3000-IPSec-Split-Tunnel-List", - [28] = "CVPN3000-IPSec-Default-Domain", - [29] = "CVPN3000-IPSec-Split-DNS-Names", - [30] = "CVPN3000-IPSec-Tunnel-Type", - [31] = "CVPN3000-IPSec-Mode-Config", - [32] = "CVPN3000-Auth-Server-Priority", - [33] = "CVPN3000-IPSec-User-Group-Lock", - [34] = "CVPN3000-IPSec-Over-UDP", - [35] = "CVPN3000-IPSec-Over-UDP-Port", - [36] = "CVPN3000-IPSec-Banner2", - [37] = "CVPN3000-PPTP-MPPC-Compression", - [38] = "CVPN3000-L2TP-MPPC-Compression", - [39] = "CVPN3000-IPSec-IP-Compression", - [40] = "CVPN3000-IPSec-IKE-Peer-ID-Check", - [41] = "CVPN3000-IKE-Keep-Alives", - [42] = "CVPN3000-IPSec-Auth-On-Rekey", - [45] = "CVPN3000-Reqrd-Client-Fw-Vendor-Code", - [46] = "CVPN3000-Reqrd-Client-Fw-Product-Code", - [47] = "CVPN3000-Reqrd-Client-Fw-Description", - [48] = "CVPN3000-Require-HW-Client-Auth", - [49] = "CVPN3000-Require-Individual-User-Auth", - [50] = "CVPN3000-Authd-User-Idle-Timeout", - [51] = "CVPN3000-Cisco-IP-Phone-Bypass", - [52] = "CVPN3000-User-Auth-Server-Name", - [53] = "CVPN3000-User-Auth-Server-Port", - [54] = "CVPN3000-User-Auth-Server-Secret", - [55] = "CVPN3000-IPSec-Split-Tunneling-Policy", - [56] = "CVPN3000-IPSec-Reqrd-Client-Fw-Cap", - [57] = "CVPN3000-IPSec-Client-Fw-Filter-Name", - [58] = "CVPN3000-IPSec-Client-Fw-Filter-Opt", - [59] = "CVPN3000-IPSec-Backup-Servers", - [60] = "CVPN3000-IPSec-Backup-Server-List", - [61] = "CVPN3000-DHCP-Network-Scope", - [62] = "CVPN3000-MS-Client-Icpt-DHCP-Conf-Msg", - [63] = "CVPN3000-MS-Client-Subnet-Mask", - [64] = "CVPN3000-Allow-Network-Extension-Mode", - [65] = "CVPN3000-IPSec-Authorization-Type", - [66] = "CVPN3000-IPSec-Authorization-Required", - [67] = "CVPN3000-IPSec-DN-Field", - [68] = "CVPN3000-IPSec-Confidence-Level", - [69] = "CVPN3000-WebVPN-Content-Filter", - [70] = "CVPN3000-WebVPN-Enable-functions", - [74] = "CVPN3000-WebVPN-Exchange-Addr", - [75] = "CVPN3000-LEAP-Bypass", - [78] = "CVPN3000-WebVPN-Exchange-NETBIOS-name", - [79] = "CVPN3000-Port-Forwarding-Name", - [80] = "CVPN3000-IE-Proxy-Server", - [81] = "CVPN3000-IE-Proxy-Server-Policy", - [82] = "CVPN3000-IE-Proxy-Exception-List", - [83] = "CVPN3000-IE-Proxy-Bypass-Local", - [84] = "CVPN3000-IKE-Keepalive-Retry-Interval", - [88] = "CVPN3000-Perfect-Forward-Secrecy-Enable", - [89] = "CVPN3000-NAC-Enable", - [90] = "CVPN3000-NAC-Status-Query-Timer", - [91] = "CVPN3000-NAC-Revalidation-Timer", - [92] = "CVPN3000-NAC-Default-ACL", - [93] = "CVPN3000-WebVPN-URL-Entry-Enable", - [94] = "CVPN3000-WebVPN-File-Access-Enable", - [95] = "CVPN3000-WebVPN-File-Svr-Entry-Enable", - [96] = "CVPN3000-WebVPN-File-Svr-Brwsing-Enable", - [97] = "CVPN3000-WebVPN-Port-Forwarding-Enable", - [98] = "CVPN3000-WebVPN-Outlook-Exch-Proxy-Enb", - [99] = "CVPN3000-WebVPN-Port-Fwding-HTTP-Proxy", - [100] = "CVPN3000-WebVPN-Auto-Applet-Downld-Enb", - [101] = "CVPN3000-WebVPN-Citrix-Metaframe-Enable", - [102] = "CVPN3000-WebVPN-Apply-ACL", - [103] = "CVPN3000-WebVPN-SSL-VPN-Client-Enable", - [104] = "CVPN3000-WebVPN-SSL-VPN-Client-Required", - [105] = "CVPN3000-WebVPN-SSL-VPN-Client-Keep-Ins", - [128] = "CVPN3000-Partition-Primary-DHCP", - [129] = "CVPN3000-Partition-Secondary-DHCP", - [131] = "CVPN3000-Partition-Premise-Router", - [132] = "CVPN3000-Partition-Max-Sessions", - [133] = "CVPN3000-Partition-Mobile-IP-Key", - [134] = "CVPN3000-Partition-Mobile-IP-Address", - [135] = "CVPN3000-Partition-Mobile-IP-SPI", - [136] = "CVPN3000-Strip-Realm", - [137] = "CVPN3000-Group-Name" -} &default=function(i: count): string { return fmt("CPNV3000-unknown-%d", i); }; - -const vendor_14823_types: table[count] of string = { - [1] = "Aruba-User-Role", - [2] = "Aruba-User-Vlan", - [3] = "Aruba-Priv-Admin-User", - [4] = "Aruba-Admin-Role", - [5] = "Aruba-Essid-Name", - [6] = "Aruba-Location-Id", - [7] = "Aruba-Port-Identifier", - [8] = "Aruba-MMS-User-Template", - [9] = "Aruba-Named-User-Vlan", - [10] = "Aruba-AP-Group", - [11] = "Aruba-Framed-IPv6-Address", - [12] = "Aruba-Device-Type", - [13] = "Aruba-AP-Name", - [14] = "Aruba-No-DHCP-Fingerprint", - [15] = "Aruba-Mdps-Device-Udid", - [16] = "Aruba-Mdps-Device-Imei", - [17] = "Aruba-Mdps-Device-Iccid", - [18] = "Aruba-Mdps-Max-Devices", - [19] = "Aruba-Mdps-Device-Name", - [20] = "Aruba-Mdps-Device-Product", - [21] = "Aruba-Mdps-Device-Version", - [22] = "Aruba-Mdps-Device-Serial", - [23] = "Aruba-CPPM-Role", - [24] = "Aruba-AirGroup-User-Name", - [25] = "Aruba-AirGroup-Shared-User", - [26] = "Aruba-AirGroup-Shared-Role", - [27] = "Aruba-AirGroup-Device-Type", - [28] = "Aruba-Auth-Survivability", - [29] = "Aruba-AS-User-Name", - [30] = "Aruba-AS-Credential-Hash", - [31] = "Aruba-WorkSpace-App-Name", - [32] = "Aruba-Mdps-Provisioning-Settings", - [33] = "Aruba-Mdps-Device-Profile" -} &default=function(i: count): string { return fmt("Aruba-unknown-%d", i); }; - diff --git a/scripts/base/protocols/radius/dpd.sig b/scripts/base/protocols/radius/dpd.sig deleted file mode 100644 index d32ba49771..0000000000 --- a/scripts/base/protocols/radius/dpd.sig +++ /dev/null @@ -1,7 +0,0 @@ -# Generated by binpac_quickstart - -signature dpd_radius { - ip-proto == udp - # TODO: payload /^RADIUS/ - enable "radius" -} \ No newline at end of file diff --git a/scripts/base/protocols/radius/main.bro b/scripts/base/protocols/radius/main.bro index 0d239dcb64..0b73ecc257 100644 --- a/scripts/base/protocols/radius/main.bro +++ b/scripts/base/protocols/radius/main.bro @@ -11,19 +11,51 @@ export { type Info: record { ## Timestamp for when the event happened. - ts: time &log; + ts : time &log; ## Unique ID for the connection. - uid: string &log; + uid : string &log; ## The connection's 4-tuple of endpoint addresses/ports. - id: conn_id &log; - msg_type: string &log; + id : conn_id &log; + ## The username, if present + username : string &log &optional; + ## MAC address, if present + mac : string &log &optional; + ## Remote IP address, if present + remote_ip : addr &log &optional; + ## Connect info, if present + connect_info : string &log &optional; + ## Successful or failed authentication + result : string &log &optional; + ## Whether this has already been logged and can be ignored + logged : bool &optional; + }; + ## The amount of time we wait for an authentication response before + ## expiring it. + const expiration_interval = 10secs &redef; + + ## Logs an authentication attempt if we didn't see a response in time + ## + ## t: A table of Info records. + ## + ## idx: The index of the connection$radius table corresponding to the + ## radius authentication about to expire. + ## + ## Returns: 0secs, which when this function is used as an + ## :bro:attr:`&expire_func`, indicates to remove the element at + ## *idx* immediately. + global expire: function(t: table[count] of Info, idx: count): interval; + ## Event that can be handled to access the RADIUS record as it is sent on ## to the loggin framework. global log_radius: event(rec: Info); } +redef record connection += { + radius: table[count] of Info &optional &write_expire=expiration_interval &expire_func=expire; +}; + const ports = { 1812/udp }; event bro_init() &priority=5 @@ -32,111 +64,57 @@ event bro_init() &priority=5 Analyzer::register_for_ports(Analyzer::ANALYZER_RADIUS, ports); } -event radius_message(c: connection, msg_type: count, trans_id: count) +event radius_message(c: connection, result: RADIUS::Message) { local info: Info; - info$ts = network_time(); - info$uid = c$uid; - info$id = c$id; - info$msg_type = msg_types[msg_type]; - - Log::write(RADIUS::LOG, info); - } - -event radius_attribute(c: connection, attr_type: count, trans_id: count, value: string) - { - switch ( attr_types[attr_type] ) { -# case "Calling-Station-Id": -# tmp = normalize_mac(value); -# if ( tmp != "" ) -# print cat(attr_types[attr_type], " ", tmp); -# else -# print cat(attr_types[attr_type], " ", value); -# break; -# case "Called-Station-Id": -# fallthrough; - - ## Strings: - case "Reply-Message": - fallthrough; - case "User-Name": - print cat(attr_types[attr_type], ": ", value); - break; - - ## IPs: - - case "Framed-IP-Address": - fallthrough; - case "Framed-IP-Netmask": - fallthrough; - case "NAS-IP-Address": - print cat(attr_types[attr_type], ": ", count_to_v4_addr(bytestring_to_count(value))); - break; - - ## Counts: - - case "Framed-MTU": - fallthrough; - case "NAS-Port": - fallthrough; - case "Session-Timeout": - print cat(attr_types[attr_type], ": ", bytestring_to_count(value)); - break; - - ## Other: - - case "NAS-Port-Type": - print cat(attr_types[attr_type], ": ", nas_port_types[bytestring_to_count(value)]); - break; - case "Service-Type": - print cat(attr_types[attr_type], ": ", service_types[bytestring_to_count(value)]); - break; - case "Framed-Protocol": - print cat(attr_types[attr_type], ": ", framed_protocol_types[bytestring_to_count(value)]); - break; - case "Vendor-Specific": - switch(bytestring_to_count(sub_bytes(value, 0, 4))) { - case 9: - # Cisco IOS/PIX 6.0 - print cat(vendor_9_types[bytestring_to_count(sub_bytes(value, 5, 1))], ": ", sub_bytes(value, 7, 128)); - break; - case 255: - # Cisco VPN 5000 - print cat(vendor_255_types[bytestring_to_count(sub_bytes(value, 5, 1))], ": ", sub_bytes(value, 7, 128)); - break; - case 311: - # Microsoft - print cat(vendor_311_types[bytestring_to_count(sub_bytes(value, 5, 1))], ": ", sub_bytes(value, 7, 128)); - break; - case 3076: - # Cisco VPN 3000 - print cat(vendor_3076_types[bytestring_to_count(sub_bytes(value, 5, 1))], ": ", sub_bytes(value, 7, 128)); - break; - case 14823: - # Aruba - print cat(vendor_14823_types[bytestring_to_count(sub_bytes(value, 5, 1))], ": ", sub_bytes(value, 7, 128)); - break; - default: - print cat("Unknown vendor: ", bytestring_to_count(sub_bytes(value, 0, 4))); - break; + if ( c?$radius && result$trans_id in c$radius ) + info = c$radius[result$trans_id]; + else + { + c$radius = table(); + info$ts = network_time(); + info$uid = c$uid; + info$id = c$id; } - break; - default: - print cat(attr_types[attr_type], ": ", value); - break; + + switch ( result$code ) { + case 1: + # Acess-Request + if ( result?$attributes ) { + # User-Name + if ( !info?$username && 1 in result$attributes ) + info$username = result$attributes[1][0]; + # Calling-Station-Id (we expect this to be a MAC) + if ( !info?$mac && 31 in result$attributes ) + info$mac = normalize_mac(result$attributes[31][0]); + # Tunnel-Client-EndPoint (useful for VPNs) + if ( !info?$remote_ip && 66 in result$attributes ) + info$remote_ip = to_addr(result$attributes[66][0]); + # Connect-Info + if ( !info?$connect_info && 77 in result$attributes ) + info$connect_info = result$attributes[77][0]; + } + break; + case 2: + # Access-Accept + info$result = "success"; + break; + case 3: + # Access-Reject + info$result = "failed"; + break; } + if ( info?$result && !info?$logged ) + { + info$logged = T; + Log::write(RADIUS::LOG, info); + } + c$radius[result$trans_id] = info; } -# Called-Station-Id: -# Calling-Station-Id: -# Class: -# NAS-Identifier: -# State: -# Vendor-Specific: -# unknown-185: -# unknown-66: -# unknown-77: -# unknown-79: -# unknown-80: -# unknown-87: -# unknown-95: \ No newline at end of file + +function expire(t: table[count] of Info, idx: count): interval + { + t[idx]$result = "unknown"; + return 0secs; + } \ No newline at end of file diff --git a/src/analyzer/protocol/radius/events.bif b/src/analyzer/protocol/radius/events.bif index 4ef93a8ca7..8885c2c6e6 100644 --- a/src/analyzer/protocol/radius/events.bif +++ b/src/analyzer/protocol/radius/events.bif @@ -9,7 +9,7 @@ ## trans_id: The RADIUS transaction identifier ## authenticator: The value of the authenticator field ## -event radius_message%(c: connection, msg_type: count, trans_id: count%); +event radius_message%(c: connection, result: RADIUS::Message%); ## Generated for each RADIUS attribute ## @@ -17,7 +17,10 @@ event radius_message%(c: connection, msg_type: count, trans_id: count%); ## ## c: The connection ## attr_type: The value of the code field (1 == User-Name, 2 == User-Password, etc.) -## trans_id: The RADIUS transaction identifier ## authenticator: The value of the authenticator field ## -event radius_attribute%(c: connection, attr_type: count, trans_id: count, value: string%); \ No newline at end of file +event radius_attribute%(c: connection, attr_type: count, value: string%); + +type RADIUS::AttributeList: vector; +type RADIUS::Attributes: table; +type RADIUS::Message: record; diff --git a/src/analyzer/protocol/radius/radius-analyzer.pac b/src/analyzer/protocol/radius/radius-analyzer.pac index 9739970880..7f0239de1f 100644 --- a/src/analyzer/protocol/radius/radius-analyzer.pac +++ b/src/analyzer/protocol/radius/radius-analyzer.pac @@ -1,23 +1,50 @@ # Generated by binpac_quickstart refine flow RADIUS_Flow += { - function proc_radius_message(code: uint8, trans_id: uint8): bool + function proc_radius_message(msg: RADIUS_PDU): bool %{ - BifEvent::generate_radius_message(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), code, trans_id); + connection()->bro_analyzer()->ProtocolConfirmation(); + + if ( !radius_message ) return false; + + RecordVal* result = new RecordVal(BifType::Record::RADIUS::Message); + result->Assign(0, new Val(${msg.code}, TYPE_COUNT)); + result->Assign(1, new Val(${msg.trans_id}, TYPE_COUNT)); + result->Assign(2, bytestring_to_val(${msg.authenticator})); + + TableVal* Attributes = new TableVal(BifType::Table::RADIUS::Attributes); + + for ( uint i = 0; i < ${msg.attributes}->size(); ++i ) { + // Do we already have a vector of attributes for this type? + VectorVal* current = (VectorVal*) Attributes->Lookup(new Val(${msg.attributes[i].code}, TYPE_COUNT)); + if ( current ) + current->Assign((uint) current->Size(), bytestring_to_val(${msg.attributes[i].value})); + else { + VectorVal* AttributeList = new VectorVal(BifType::Vector::RADIUS::AttributeList); + AttributeList->Assign((uint) 0, bytestring_to_val(${msg.attributes[i].value})); + Attributes->Assign(new Val(${msg.attributes[i].code}, TYPE_COUNT), AttributeList); + } + + } + if ( ${msg.attributes}->size() ) + result->Assign(3, Attributes); + BifEvent::generate_radius_message(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), result); return true; %} - function proc_radius_attribute(code: uint8, trans_id: uint8, value: bytestring): bool + function proc_radius_attribute(attr: RADIUS_Attribute): bool %{ - BifEvent::generate_radius_attribute(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), code, trans_id, bytestring_to_val(value)); + if ( !radius_attribute ) return false; + + BifEvent::generate_radius_attribute(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), ${attr.code}, bytestring_to_val(${attr.value})); return true; %} }; refine typeattr RADIUS_PDU += &let { - proc: bool = $context.flow.proc_radius_message(code, trans_id); + proc: bool = $context.flow.proc_radius_message(this); }; refine typeattr RADIUS_Attribute += &let { - proc: bool = $context.flow.proc_radius_attribute(code, trans_id, value); + proc: bool = $context.flow.proc_radius_attribute(this); }; \ No newline at end of file From 8688c764a0c831c896595073abbe16777ed67b41 Mon Sep 17 00:00:00 2001 From: Vlad Grigorescu Date: Fri, 13 Dec 2013 15:04:43 -0500 Subject: [PATCH 003/136] Fix a couple memleaks. --- .../protocol/radius/radius-analyzer.pac | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/analyzer/protocol/radius/radius-analyzer.pac b/src/analyzer/protocol/radius/radius-analyzer.pac index 7f0239de1f..f64d5ff105 100644 --- a/src/analyzer/protocol/radius/radius-analyzer.pac +++ b/src/analyzer/protocol/radius/radius-analyzer.pac @@ -12,22 +12,27 @@ refine flow RADIUS_Flow += { result->Assign(1, new Val(${msg.trans_id}, TYPE_COUNT)); result->Assign(2, bytestring_to_val(${msg.authenticator})); - TableVal* Attributes = new TableVal(BifType::Table::RADIUS::Attributes); - - for ( uint i = 0; i < ${msg.attributes}->size(); ++i ) { - // Do we already have a vector of attributes for this type? - VectorVal* current = (VectorVal*) Attributes->Lookup(new Val(${msg.attributes[i].code}, TYPE_COUNT)); - if ( current ) - current->Assign((uint) current->Size(), bytestring_to_val(${msg.attributes[i].value})); - else { - VectorVal* AttributeList = new VectorVal(BifType::Vector::RADIUS::AttributeList); - AttributeList->Assign((uint) 0, bytestring_to_val(${msg.attributes[i].value})); - Attributes->Assign(new Val(${msg.attributes[i].code}, TYPE_COUNT), AttributeList); - } - - } if ( ${msg.attributes}->size() ) + { + TableVal* Attributes = new TableVal(BifType::Table::RADIUS::Attributes); + + for ( uint i = 0; i < ${msg.attributes}->size(); ++i ) { + Val* index = new Val(${msg.attributes[i].code}, TYPE_COUNT); + + // Do we already have a vector of attributes for this type? + VectorVal* current = (VectorVal*) Attributes->Lookup(index); + if ( current ) + current->Assign((uint) current->Size(), bytestring_to_val(${msg.attributes[i].value})); + else { + VectorVal* AttributeList = new VectorVal(BifType::Vector::RADIUS::AttributeList); + AttributeList->Assign((uint) 0, bytestring_to_val(${msg.attributes[i].value})); + Attributes->Assign(index, AttributeList); + } + + Unref(index); + } result->Assign(3, Attributes); + } BifEvent::generate_radius_message(connection()->bro_analyzer(), connection()->bro_analyzer()->Conn(), result); return true; %} From ffd4711a41ba0e9ea0f8cfd3097aadbe68912eb4 Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Tue, 8 Apr 2014 07:41:08 -0700 Subject: [PATCH 004/136] Throw new event for heartbeat messages. Not tested. --- src/analyzer/protocol/ssl/events.bif | 2 ++ src/analyzer/protocol/ssl/ssl-analyzer.pac | 17 +++++++++++++++++ src/analyzer/protocol/ssl/ssl-defs.pac | 1 + src/analyzer/protocol/ssl/ssl-protocol.pac | 11 +++++++++++ 4 files changed, 31 insertions(+) diff --git a/src/analyzer/protocol/ssl/events.bif b/src/analyzer/protocol/ssl/events.bif index 054d9c672f..c85e911ee8 100644 --- a/src/analyzer/protocol/ssl/events.bif +++ b/src/analyzer/protocol/ssl/events.bif @@ -138,3 +138,5 @@ event ssl_alert%(c: connection, is_orig: bool, level: count, desc: count%); ## .. bro:see:: ssl_client_hello ssl_established ssl_extension ssl_server_hello ## ssl_alert event ssl_session_ticket_handshake%(c: connection, ticket_lifetime_hint: count, ticket: string%); + +event ssl_heartbeat%(c: connection, length: count%); diff --git a/src/analyzer/protocol/ssl/ssl-analyzer.pac b/src/analyzer/protocol/ssl/ssl-analyzer.pac index 49104fa549..e6ea1628a1 100644 --- a/src/analyzer/protocol/ssl/ssl-analyzer.pac +++ b/src/analyzer/protocol/ssl/ssl-analyzer.pac @@ -306,6 +306,10 @@ refine connection SSL_Conn += { function proc_ciphertext_record(rec : SSLRecord) : bool %{ + if ( ${rec.content_type} == HEARTBEAT ) + BifEvent::generate_ssl_heartbeat(bro_analyzer(), + bro_analyzer()->Conn(), ${rec.length}); + if ( state_ == STATE_TRACK_LOST ) bro_analyzer()->ProtocolViolation(fmt("unexpected ciphertext record from %s in state %s", orig_label(${rec.is_orig}).c_str(), @@ -320,6 +324,15 @@ refine connection SSL_Conn += { return true; %} + + function proc_heartbeat(rec : SSLRecord) : bool + %{ + BifEvent::generate_ssl_heartbeat(bro_analyzer(), + bro_analyzer()->Conn(), ${rec.length}); + + return true; + %} + }; refine typeattr ChangeCipherSpec += &let { @@ -339,6 +352,10 @@ refine typeattr ApplicationData += &let { proc : bool = $context.connection.proc_application_data(rec); }; +refine typeattr Heartbeat += &let { + proc : bool = $context.connection.proc_heartbeat(rec); +}; + refine typeattr ClientHello += &let { proc : bool = $context.connection.proc_client_hello(rec, client_version, gmt_unix_time, random_bytes, diff --git a/src/analyzer/protocol/ssl/ssl-defs.pac b/src/analyzer/protocol/ssl/ssl-defs.pac index c35fc56e85..23fa7abce5 100644 --- a/src/analyzer/protocol/ssl/ssl-defs.pac +++ b/src/analyzer/protocol/ssl/ssl-defs.pac @@ -12,6 +12,7 @@ enum ContentType { ALERT = 21, HANDSHAKE = 22, APPLICATION_DATA = 23, + HEARTBEAT = 24, V2_ERROR = 300, V2_CLIENT_HELLO = 301, V2_CLIENT_MASTER_KEY = 302, diff --git a/src/analyzer/protocol/ssl/ssl-protocol.pac b/src/analyzer/protocol/ssl/ssl-protocol.pac index 9368122eaa..c12130abf8 100644 --- a/src/analyzer/protocol/ssl/ssl-protocol.pac +++ b/src/analyzer/protocol/ssl/ssl-protocol.pac @@ -63,6 +63,7 @@ type PlaintextRecord(rec: SSLRecord) = case rec.content_type of { CHANGE_CIPHER_SPEC -> ch_cipher : ChangeCipherSpec(rec); ALERT -> alert : Alert(rec); HANDSHAKE -> handshake : Handshake(rec); + HEARTBEAT -> heartbeat: Heartbeat(rec); APPLICATION_DATA -> app_data : ApplicationData(rec); V2_ERROR -> v2_error : V2Error(rec); V2_CLIENT_HELLO -> v2_client_hello : V2ClientHello(rec); @@ -225,6 +226,16 @@ type ApplicationData(rec: SSLRecord) = record { data : bytestring &restofdata &transient; }; +###################################################################### +# V3 Heartbeat +###################################################################### + +# Heartbeats should basically always be encrypted, so we should not +# reach this point. +type Heartbeat(rec: SSLRecord) = record { + data : bytestring &restofdata &transient; +}; + ###################################################################### # Handshake Protocol (7.4.) ###################################################################### From 902d52e261069addbf6647537b1a5db9a171f79d Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Tue, 8 Apr 2014 08:43:38 -0700 Subject: [PATCH 005/136] add is_orig to heartbeat event --- src/analyzer/protocol/ssl/events.bif | 2 +- src/analyzer/protocol/ssl/ssl-analyzer.pac | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/analyzer/protocol/ssl/events.bif b/src/analyzer/protocol/ssl/events.bif index c85e911ee8..3f780bdd60 100644 --- a/src/analyzer/protocol/ssl/events.bif +++ b/src/analyzer/protocol/ssl/events.bif @@ -139,4 +139,4 @@ event ssl_alert%(c: connection, is_orig: bool, level: count, desc: count%); ## ssl_alert event ssl_session_ticket_handshake%(c: connection, ticket_lifetime_hint: count, ticket: string%); -event ssl_heartbeat%(c: connection, length: count%); +event ssl_heartbeat%(c: connection, is_orig: bool, length: count%); diff --git a/src/analyzer/protocol/ssl/ssl-analyzer.pac b/src/analyzer/protocol/ssl/ssl-analyzer.pac index e6ea1628a1..1730ce8ce5 100644 --- a/src/analyzer/protocol/ssl/ssl-analyzer.pac +++ b/src/analyzer/protocol/ssl/ssl-analyzer.pac @@ -308,7 +308,7 @@ refine connection SSL_Conn += { %{ if ( ${rec.content_type} == HEARTBEAT ) BifEvent::generate_ssl_heartbeat(bro_analyzer(), - bro_analyzer()->Conn(), ${rec.length}); + bro_analyzer()->Conn(), ${rec.is_orig}, ${rec.length}); if ( state_ == STATE_TRACK_LOST ) bro_analyzer()->ProtocolViolation(fmt("unexpected ciphertext record from %s in state %s", @@ -328,7 +328,7 @@ refine connection SSL_Conn += { function proc_heartbeat(rec : SSLRecord) : bool %{ BifEvent::generate_ssl_heartbeat(bro_analyzer(), - bro_analyzer()->Conn(), ${rec.length}); + bro_analyzer()->Conn(), ${rec.is_orig}, ${rec.length}); return true; %} From 018735a5744d8a82bbd7cee48fd828b4018d257f Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Tue, 8 Apr 2014 09:49:00 -0700 Subject: [PATCH 006/136] default to TLS when not being able to determine version --- src/analyzer/protocol/ssl/ssl-protocol.pac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/analyzer/protocol/ssl/ssl-protocol.pac b/src/analyzer/protocol/ssl/ssl-protocol.pac index c12130abf8..944f081060 100644 --- a/src/analyzer/protocol/ssl/ssl-protocol.pac +++ b/src/analyzer/protocol/ssl/ssl-protocol.pac @@ -39,13 +39,13 @@ type SSLRecord(is_orig: bool) = record { $context.connection.determine_ssl_version(head0, head1, head2); content_type : int = case version of { - UNKNOWN_VERSION -> 0; + # UNKNOWN_VERSION -> 0; assume tls on unknown version SSLv20 -> head2+300; default -> head0; }; length : int = case version of { - UNKNOWN_VERSION -> 0; + # UNKNOWN_VERSION -> 0; assume tls on unknown version SSLv20 -> (((head0 & 0x7f) << 8) | head1) - 3; default -> (head3 << 8) | head4; }; From 335a30b08f10ecc6243182d71f786ac104f31897 Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Tue, 8 Apr 2014 11:03:12 -0700 Subject: [PATCH 007/136] detect and alert on simple case of heartbleed --- scripts/policy/protocols/ssl/heartbleed.bro | 44 +++++++++++++++++++++ src/analyzer/protocol/ssl/events.bif | 4 +- src/analyzer/protocol/ssl/ssl-analyzer.pac | 8 ++-- src/analyzer/protocol/ssl/ssl-protocol.pac | 4 +- 4 files changed, 53 insertions(+), 7 deletions(-) create mode 100644 scripts/policy/protocols/ssl/heartbleed.bro diff --git a/scripts/policy/protocols/ssl/heartbleed.bro b/scripts/policy/protocols/ssl/heartbleed.bro new file mode 100644 index 0000000000..b3f81034b0 --- /dev/null +++ b/scripts/policy/protocols/ssl/heartbleed.bro @@ -0,0 +1,44 @@ +module Heartbleed; + +redef record SSL::Info += { +# last_originator_heartbeat_request_size: count &optional; +# originator_heartbeats: count &default=0; +# responder_heartbeats: count &default=0; + heartbleed_detected: bool &default=F; + }; + +export { + redef enum Notice::Type += { + ## Indicates that a host performing a heartbleed attack. + SSL_Heartbeat_Attack, + ## Indicates that a host performing a heartbleed attack was probably successful. + SSL_Heartbeat_Attack_Success, + }; +} + +event ssl_heartbeat(c: connection, is_orig: bool, length: count, heartbeat_type: count, payload_length: count) + { + if ( heartbeat_type == 1 ) + { + + local checklength: count = (length<(3+16)) ? length : (length - 3 - 16); + + + if ( payload_length > checklength ) + { + c$ssl$heartbleed_detected = T; + NOTICE([$note=SSL_Heartbeat_Attack, + $msg="An TLS heartbleed attack was detected!", + $conn=c + ]); + } + } + + if ( heartbeat_type == 2 && c$ssl$heartbleed_detected ) + { + NOTICE([$note=SSL_Heartbeat_Attack_Success, + $msg="An TLS heartbleed attack was detected and probably exploited", + $conn=c + ]); + } + } diff --git a/src/analyzer/protocol/ssl/events.bif b/src/analyzer/protocol/ssl/events.bif index 3f780bdd60..e720089f45 100644 --- a/src/analyzer/protocol/ssl/events.bif +++ b/src/analyzer/protocol/ssl/events.bif @@ -139,4 +139,6 @@ event ssl_alert%(c: connection, is_orig: bool, level: count, desc: count%); ## ssl_alert event ssl_session_ticket_handshake%(c: connection, ticket_lifetime_hint: count, ticket: string%); -event ssl_heartbeat%(c: connection, is_orig: bool, length: count%); +event ssl_encrypted_heartbeat%(c: connection, is_orig: bool, length: count%); + +event ssl_heartbeat%(c: connection, is_orig: bool, length: count, heartbeat_type: count, payload_length: count%); diff --git a/src/analyzer/protocol/ssl/ssl-analyzer.pac b/src/analyzer/protocol/ssl/ssl-analyzer.pac index 1730ce8ce5..d0ac88a5a1 100644 --- a/src/analyzer/protocol/ssl/ssl-analyzer.pac +++ b/src/analyzer/protocol/ssl/ssl-analyzer.pac @@ -307,7 +307,7 @@ refine connection SSL_Conn += { function proc_ciphertext_record(rec : SSLRecord) : bool %{ if ( ${rec.content_type} == HEARTBEAT ) - BifEvent::generate_ssl_heartbeat(bro_analyzer(), + BifEvent::generate_ssl_encrypted_heartbeat(bro_analyzer(), bro_analyzer()->Conn(), ${rec.is_orig}, ${rec.length}); if ( state_ == STATE_TRACK_LOST ) @@ -325,10 +325,10 @@ refine connection SSL_Conn += { return true; %} - function proc_heartbeat(rec : SSLRecord) : bool + function proc_heartbeat(rec : SSLRecord, type: uint8, payload_length: uint16) : bool %{ BifEvent::generate_ssl_heartbeat(bro_analyzer(), - bro_analyzer()->Conn(), ${rec.is_orig}, ${rec.length}); + bro_analyzer()->Conn(), ${rec.is_orig}, ${rec.length}, type, payload_length); return true; %} @@ -353,7 +353,7 @@ refine typeattr ApplicationData += &let { }; refine typeattr Heartbeat += &let { - proc : bool = $context.connection.proc_heartbeat(rec); + proc : bool = $context.connection.proc_heartbeat(rec, type, payload_length); }; refine typeattr ClientHello += &let { diff --git a/src/analyzer/protocol/ssl/ssl-protocol.pac b/src/analyzer/protocol/ssl/ssl-protocol.pac index 944f081060..acded2dbf9 100644 --- a/src/analyzer/protocol/ssl/ssl-protocol.pac +++ b/src/analyzer/protocol/ssl/ssl-protocol.pac @@ -230,9 +230,9 @@ type ApplicationData(rec: SSLRecord) = record { # V3 Heartbeat ###################################################################### -# Heartbeats should basically always be encrypted, so we should not -# reach this point. type Heartbeat(rec: SSLRecord) = record { + type : uint8; + payload_length : uint16; data : bytestring &restofdata &transient; }; From c41810a33780b1263f2e8a1b6939d398a267fa0f Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Tue, 8 Apr 2014 11:19:30 -0700 Subject: [PATCH 008/136] polish script and probably detect encrypted attacks too. --- scripts/policy/protocols/ssl/heartbleed.bro | 65 +++++++++++++++++++-- 1 file changed, 60 insertions(+), 5 deletions(-) diff --git a/scripts/policy/protocols/ssl/heartbleed.bro b/scripts/policy/protocols/ssl/heartbleed.bro index b3f81034b0..c9a9622e2c 100644 --- a/scripts/policy/protocols/ssl/heartbleed.bro +++ b/scripts/policy/protocols/ssl/heartbleed.bro @@ -1,9 +1,11 @@ module Heartbleed; redef record SSL::Info += { -# last_originator_heartbeat_request_size: count &optional; -# originator_heartbeats: count &default=0; -# responder_heartbeats: count &default=0; + last_originator_heartbeat_request_size: count &optional; + last_responder_heartbeat_request_size: count &optional; + originator_heartbeats: count &default=0; + responder_heartbeats: count &default=0; + heartbleed_detected: bool &default=F; }; @@ -11,8 +13,14 @@ export { redef enum Notice::Type += { ## Indicates that a host performing a heartbleed attack. SSL_Heartbeat_Attack, - ## Indicates that a host performing a heartbleed attack was probably successful. + ## Indicates that a host performing a heartbleed attack was successful. SSL_Heartbeat_Attack_Success, + ## Indivcates that a host performing a heartbleed attack after encryption was started was probably successful + SSL_Heartbeat_Encrypted_Attack_Success, + ## Indicates we saw heartbeet requests with odd length. Probably an attack. + SSL_Heartbeat_Odd_Length, + ## Indicates we saw many heartbeat requests without an reply. Might be an attack. + SSL_Heartbeat_Many_Requests }; } @@ -20,7 +28,6 @@ event ssl_heartbeat(c: connection, is_orig: bool, length: count, heartbeat_type: { if ( heartbeat_type == 1 ) { - local checklength: count = (length<(3+16)) ? length : (length - 3 - 16); @@ -42,3 +49,51 @@ event ssl_heartbeat(c: connection, is_orig: bool, length: count, heartbeat_type: ]); } } + +event ssl_encrypted_heartbeat(c: connection, is_orig: bool, length: count) + { + if ( is_orig ) + ++c$ssl$originator_heartbeats; + else + ++c$ssl$responder_heartbeats; + + if ( c$ssl$originator_heartbeats > c$ssl$responder_heartbeats + 3 ) + NOTICE([$note=SSL_Heartbeat_Many_Requests, + $msg="Seeing more than 3 heartbeat requests without replies from server. Possible attack?", + $conn=c + ]); + + if ( is_orig && length < 19 ) + NOTICE([$note=SSL_Heartbeat_Odd_Length, + $msg="Heartbeat message smaller than minimum length. Probable attack.", + $conn=c + ]); + + if ( is_orig ) + { + if ( c$ssl?$last_responder_heartbeat_request_size ) + { + # server originated heartbeat. Ignore & continue + delete c$ssl$last_responder_heartbeat_request_size; + } + else + c$ssl$last_originator_heartbeat_request_size = length; + } + else + { + if ( c$ssl?$last_originator_heartbeat_request_size && c$ssl$last_originator_heartbeat_request_size > length ) + { + NOTICE([$note=SSL_Heartbeat_Encrypted_Attack_Success, + $msg="An Encrypted TLS heartbleed attack was probably detected!", + $conn=c + ]); + } + else if ( ! c$ssl?$last_originator_heartbeat_request_size ) + { + c$ssl$last_responder_heartbeat_request_size = length; + } + + if ( c$ssl?$last_originator_heartbeat_request_size ) + delete c$ssl$last_originator_heartbeat_request_size; + } + } From 4d33bdbb1ebe531a238803ef612395d8a39fc6e8 Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Tue, 8 Apr 2014 11:28:13 -0700 Subject: [PATCH 009/136] fix tabs. --- scripts/policy/protocols/ssl/heartbleed.bro | 146 ++++++++++---------- 1 file changed, 73 insertions(+), 73 deletions(-) diff --git a/scripts/policy/protocols/ssl/heartbleed.bro b/scripts/policy/protocols/ssl/heartbleed.bro index c9a9622e2c..7089758e93 100644 --- a/scripts/policy/protocols/ssl/heartbleed.bro +++ b/scripts/policy/protocols/ssl/heartbleed.bro @@ -6,94 +6,94 @@ redef record SSL::Info += { originator_heartbeats: count &default=0; responder_heartbeats: count &default=0; - heartbleed_detected: bool &default=F; + heartbleed_detected: bool &default=F; }; export { redef enum Notice::Type += { ## Indicates that a host performing a heartbleed attack. SSL_Heartbeat_Attack, - ## Indicates that a host performing a heartbleed attack was successful. - SSL_Heartbeat_Attack_Success, - ## Indivcates that a host performing a heartbleed attack after encryption was started was probably successful - SSL_Heartbeat_Encrypted_Attack_Success, - ## Indicates we saw heartbeet requests with odd length. Probably an attack. - SSL_Heartbeat_Odd_Length, - ## Indicates we saw many heartbeat requests without an reply. Might be an attack. - SSL_Heartbeat_Many_Requests - }; + ## Indicates that a host performing a heartbleed attack was successful. + SSL_Heartbeat_Attack_Success, + ## Indivcates that a host performing a heartbleed attack after encryption was started was probably successful + SSL_Heartbeat_Encrypted_Attack_Success, + ## Indicates we saw heartbeet requests with odd length. Probably an attack. + SSL_Heartbeat_Odd_Length, + ## Indicates we saw many heartbeat requests without an reply. Might be an attack. + SSL_Heartbeat_Many_Requests + }; } event ssl_heartbeat(c: connection, is_orig: bool, length: count, heartbeat_type: count, payload_length: count) - { - if ( heartbeat_type == 1 ) - { - local checklength: count = (length<(3+16)) ? length : (length - 3 - 16); + { + if ( heartbeat_type == 1 ) + { + local checklength: count = (length<(3+16)) ? length : (length - 3 - 16); - if ( payload_length > checklength ) - { - c$ssl$heartbleed_detected = T; - NOTICE([$note=SSL_Heartbeat_Attack, - $msg="An TLS heartbleed attack was detected!", - $conn=c - ]); - } - } + if ( payload_length > checklength ) + { + c$ssl$heartbleed_detected = T; + NOTICE([$note=SSL_Heartbeat_Attack, + $msg="An TLS heartbleed attack was detected!", + $conn=c + ]); + } + } - if ( heartbeat_type == 2 && c$ssl$heartbleed_detected ) - { - NOTICE([$note=SSL_Heartbeat_Attack_Success, - $msg="An TLS heartbleed attack was detected and probably exploited", - $conn=c - ]); - } - } + if ( heartbeat_type == 2 && c$ssl$heartbleed_detected ) + { + NOTICE([$note=SSL_Heartbeat_Attack_Success, + $msg="An TLS heartbleed attack was detected and probably exploited", + $conn=c + ]); + } + } event ssl_encrypted_heartbeat(c: connection, is_orig: bool, length: count) - { - if ( is_orig ) - ++c$ssl$originator_heartbeats; - else - ++c$ssl$responder_heartbeats; + { + if ( is_orig ) + ++c$ssl$originator_heartbeats; + else + ++c$ssl$responder_heartbeats; - if ( c$ssl$originator_heartbeats > c$ssl$responder_heartbeats + 3 ) - NOTICE([$note=SSL_Heartbeat_Many_Requests, - $msg="Seeing more than 3 heartbeat requests without replies from server. Possible attack?", - $conn=c - ]); + if ( c$ssl$originator_heartbeats > c$ssl$responder_heartbeats + 3 ) + NOTICE([$note=SSL_Heartbeat_Many_Requests, + $msg="Seeing more than 3 heartbeat requests without replies from server. Possible attack?", + $conn=c + ]); - if ( is_orig && length < 19 ) - NOTICE([$note=SSL_Heartbeat_Odd_Length, - $msg="Heartbeat message smaller than minimum length. Probable attack.", - $conn=c - ]); + if ( is_orig && length < 19 ) + NOTICE([$note=SSL_Heartbeat_Odd_Length, + $msg="Heartbeat message smaller than minimum length. Probable attack.", + $conn=c + ]); - if ( is_orig ) - { - if ( c$ssl?$last_responder_heartbeat_request_size ) - { - # server originated heartbeat. Ignore & continue - delete c$ssl$last_responder_heartbeat_request_size; - } - else - c$ssl$last_originator_heartbeat_request_size = length; - } - else - { - if ( c$ssl?$last_originator_heartbeat_request_size && c$ssl$last_originator_heartbeat_request_size > length ) - { - NOTICE([$note=SSL_Heartbeat_Encrypted_Attack_Success, - $msg="An Encrypted TLS heartbleed attack was probably detected!", - $conn=c - ]); - } - else if ( ! c$ssl?$last_originator_heartbeat_request_size ) - { - c$ssl$last_responder_heartbeat_request_size = length; - } + if ( is_orig ) + { + if ( c$ssl?$last_responder_heartbeat_request_size ) + { + # server originated heartbeat. Ignore & continue + delete c$ssl$last_responder_heartbeat_request_size; + } + else + c$ssl$last_originator_heartbeat_request_size = length; + } + else + { + if ( c$ssl?$last_originator_heartbeat_request_size && c$ssl$last_originator_heartbeat_request_size > length ) + { + NOTICE([$note=SSL_Heartbeat_Encrypted_Attack_Success, + $msg="An Encrypted TLS heartbleed attack was probably detected!", + $conn=c + ]); + } + else if ( ! c$ssl?$last_originator_heartbeat_request_size ) + { + c$ssl$last_responder_heartbeat_request_size = length; + } - if ( c$ssl?$last_originator_heartbeat_request_size ) - delete c$ssl$last_originator_heartbeat_request_size; - } - } + if ( c$ssl?$last_originator_heartbeat_request_size ) + delete c$ssl$last_originator_heartbeat_request_size; + } + } From cb87f834f9360aae450f778b0a9b49cee4102a4e Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Tue, 8 Apr 2014 11:40:48 -0700 Subject: [PATCH 010/136] make tls heartbeat messages a bit better. --- scripts/policy/protocols/ssl/heartbleed.bro | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/scripts/policy/protocols/ssl/heartbleed.bro b/scripts/policy/protocols/ssl/heartbleed.bro index 7089758e93..0e5abc7ab3 100644 --- a/scripts/policy/protocols/ssl/heartbleed.bro +++ b/scripts/policy/protocols/ssl/heartbleed.bro @@ -30,12 +30,11 @@ event ssl_heartbeat(c: connection, is_orig: bool, length: count, heartbeat_type: { local checklength: count = (length<(3+16)) ? length : (length - 3 - 16); - if ( payload_length > checklength ) { c$ssl$heartbleed_detected = T; NOTICE([$note=SSL_Heartbeat_Attack, - $msg="An TLS heartbleed attack was detected!", + $msg=fmt("An TLS heartbleed attack was detected! Record length %d, payload length %d", length, payload_length), $conn=c ]); } @@ -60,13 +59,15 @@ event ssl_encrypted_heartbeat(c: connection, is_orig: bool, length: count) if ( c$ssl$originator_heartbeats > c$ssl$responder_heartbeats + 3 ) NOTICE([$note=SSL_Heartbeat_Many_Requests, $msg="Seeing more than 3 heartbeat requests without replies from server. Possible attack?", - $conn=c + $conn=c, + $n=(c$ssl$originator_heartbeats-c$ssl$responder_heartbeats) ]); if ( is_orig && length < 19 ) NOTICE([$note=SSL_Heartbeat_Odd_Length, $msg="Heartbeat message smaller than minimum length. Probable attack.", - $conn=c + $conn=c, + $n=length ]); if ( is_orig ) From f2c2da92c6505a2a979051e553ff4043f1317a0e Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Tue, 8 Apr 2014 11:53:01 -0700 Subject: [PATCH 011/136] add to local.bro, add disclaimer --- scripts/policy/protocols/ssl/heartbleed.bro | 2 ++ scripts/site/local.bro | 2 ++ 2 files changed, 4 insertions(+) diff --git a/scripts/policy/protocols/ssl/heartbleed.bro b/scripts/policy/protocols/ssl/heartbleed.bro index 0e5abc7ab3..d66ff4df2a 100644 --- a/scripts/policy/protocols/ssl/heartbleed.bro +++ b/scripts/policy/protocols/ssl/heartbleed.bro @@ -1,5 +1,7 @@ module Heartbleed; +# Please note - this is not well tested. Use at your own risk. + redef record SSL::Info += { last_originator_heartbeat_request_size: count &optional; last_responder_heartbeat_request_size: count &optional; diff --git a/scripts/site/local.bro b/scripts/site/local.bro index e1a3574424..bb2cc73a53 100644 --- a/scripts/site/local.bro +++ b/scripts/site/local.bro @@ -81,3 +81,5 @@ # Detect SHA1 sums in Team Cymru's Malware Hash Registry. @load frameworks/files/detect-MHR +# Load heartbleed detection. Only superficially tested, might contain bugs. +@load policy/protocols/ssl/heartbleed From 2942a26280866c5ecad13ce8d7a63a706dc9e1af Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Tue, 8 Apr 2014 12:44:51 -0700 Subject: [PATCH 012/136] also extract payload data in ssl_heartbeat --- scripts/policy/protocols/ssl/heartbleed.bro | 2 +- src/analyzer/protocol/ssl/events.bif | 2 +- src/analyzer/protocol/ssl/ssl-analyzer.pac | 8 ++++---- src/analyzer/protocol/ssl/ssl-protocol.pac | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/scripts/policy/protocols/ssl/heartbleed.bro b/scripts/policy/protocols/ssl/heartbleed.bro index d66ff4df2a..19728b1d0c 100644 --- a/scripts/policy/protocols/ssl/heartbleed.bro +++ b/scripts/policy/protocols/ssl/heartbleed.bro @@ -26,7 +26,7 @@ export { }; } -event ssl_heartbeat(c: connection, is_orig: bool, length: count, heartbeat_type: count, payload_length: count) +event ssl_heartbeat(c: connection, is_orig: bool, length: count, heartbeat_type: count, payload_length: count, payload: string) { if ( heartbeat_type == 1 ) { diff --git a/src/analyzer/protocol/ssl/events.bif b/src/analyzer/protocol/ssl/events.bif index e720089f45..a11e7bcc68 100644 --- a/src/analyzer/protocol/ssl/events.bif +++ b/src/analyzer/protocol/ssl/events.bif @@ -141,4 +141,4 @@ event ssl_session_ticket_handshake%(c: connection, ticket_lifetime_hint: count, event ssl_encrypted_heartbeat%(c: connection, is_orig: bool, length: count%); -event ssl_heartbeat%(c: connection, is_orig: bool, length: count, heartbeat_type: count, payload_length: count%); +event ssl_heartbeat%(c: connection, is_orig: bool, length: count, heartbeat_type: count, payload_length: count, payload: string%); diff --git a/src/analyzer/protocol/ssl/ssl-analyzer.pac b/src/analyzer/protocol/ssl/ssl-analyzer.pac index d0ac88a5a1..29240161d1 100644 --- a/src/analyzer/protocol/ssl/ssl-analyzer.pac +++ b/src/analyzer/protocol/ssl/ssl-analyzer.pac @@ -325,11 +325,11 @@ refine connection SSL_Conn += { return true; %} - function proc_heartbeat(rec : SSLRecord, type: uint8, payload_length: uint16) : bool + function proc_heartbeat(rec : SSLRecord, type: uint8, payload_length: uint16, data: bytestring) : bool %{ BifEvent::generate_ssl_heartbeat(bro_analyzer(), - bro_analyzer()->Conn(), ${rec.is_orig}, ${rec.length}, type, payload_length); - + bro_analyzer()->Conn(), ${rec.is_orig}, ${rec.length}, type, payload_length, + new StringVal(data.length(), (const char*) data.data())); return true; %} @@ -353,7 +353,7 @@ refine typeattr ApplicationData += &let { }; refine typeattr Heartbeat += &let { - proc : bool = $context.connection.proc_heartbeat(rec, type, payload_length); + proc : bool = $context.connection.proc_heartbeat(rec, type, payload_length, data); }; refine typeattr ClientHello += &let { diff --git a/src/analyzer/protocol/ssl/ssl-protocol.pac b/src/analyzer/protocol/ssl/ssl-protocol.pac index acded2dbf9..f8645410dc 100644 --- a/src/analyzer/protocol/ssl/ssl-protocol.pac +++ b/src/analyzer/protocol/ssl/ssl-protocol.pac @@ -233,7 +233,7 @@ type ApplicationData(rec: SSLRecord) = record { type Heartbeat(rec: SSLRecord) = record { type : uint8; payload_length : uint16; - data : bytestring &restofdata &transient; + data : bytestring &restofdata; }; ###################################################################### From 2414aaf4bb9e1a9ba9aafbf748f2905311f8cd8e Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Tue, 8 Apr 2014 21:57:37 -0700 Subject: [PATCH 013/136] enable detection of encrypted heartbleeds. --- scripts/policy/protocols/ssl/heartbleed.bro | 2 +- src/analyzer/protocol/ssl/ssl-protocol.pac | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/policy/protocols/ssl/heartbleed.bro b/scripts/policy/protocols/ssl/heartbleed.bro index 19728b1d0c..0049c4c51f 100644 --- a/scripts/policy/protocols/ssl/heartbleed.bro +++ b/scripts/policy/protocols/ssl/heartbleed.bro @@ -84,7 +84,7 @@ event ssl_encrypted_heartbeat(c: connection, is_orig: bool, length: count) } else { - if ( c$ssl?$last_originator_heartbeat_request_size && c$ssl$last_originator_heartbeat_request_size > length ) + if ( c$ssl?$last_originator_heartbeat_request_size && c$ssl$last_originator_heartbeat_request_size < length ) { NOTICE([$note=SSL_Heartbeat_Encrypted_Attack_Success, $msg="An Encrypted TLS heartbleed attack was probably detected!", diff --git a/src/analyzer/protocol/ssl/ssl-protocol.pac b/src/analyzer/protocol/ssl/ssl-protocol.pac index f8645410dc..b8e5c9f624 100644 --- a/src/analyzer/protocol/ssl/ssl-protocol.pac +++ b/src/analyzer/protocol/ssl/ssl-protocol.pac @@ -52,7 +52,7 @@ type SSLRecord(is_orig: bool) = record { }; type RecordText(rec: SSLRecord) = case $context.connection.state() of { - STATE_ABBREV_SERVER_ENCRYPTED, STATE_CLIENT_ENCRYPTED, + STATE_ABBREV_SERVER_ENCRYPTED, STATE_CLIENT_ENCRYPTED, STATE_CLIENT_FINISHED, STATE_COMM_ENCRYPTED, STATE_CONN_ESTABLISHED -> ciphertext : CiphertextRecord(rec); default From 2b3c2bd3940cd6883dc188abbc7aa5372cae7278 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Wed, 9 Apr 2014 13:03:24 -0500 Subject: [PATCH 014/136] Fix reassembly of data w/ sizes beyond 32-bit capacities (BIT-348). The main change is that reassembly code (e.g. for TCP) now uses int64/uint64 (signedness is situational) data types in place of int types in order to support delivering data to analyzers that pass 2GB thresholds. There's also changes in logic that accompany the change in data types, e.g. to fix TCP sequence space arithmetic inconsistencies. Another significant change is in the Analyzer API: the *Packet and *Undelivered methods now use a uint64 in place of an int for the relative sequence space offset parameter. --- src/Frag.cc | 12 +- src/Frag.h | 6 +- src/Reassem.cc | 88 +- src/Reassem.h | 32 +- src/Stats.cc | 2 +- src/analyzer/Analyzer.cc | 20 +- src/analyzer/Analyzer.h | 20 +- src/analyzer/protocol/ayiya/AYIYA.cc | 2 +- src/analyzer/protocol/ayiya/AYIYA.h | 2 +- src/analyzer/protocol/backdoor/BackDoor.cc | 41 +- src/analyzer/protocol/backdoor/BackDoor.h | 34 +- .../protocol/bittorrent/BitTorrent.cc | 2 +- src/analyzer/protocol/bittorrent/BitTorrent.h | 2 +- .../protocol/bittorrent/BitTorrentTracker.cc | 2 +- .../protocol/bittorrent/BitTorrentTracker.h | 2 +- src/analyzer/protocol/conn-size/ConnSize.cc | 2 +- src/analyzer/protocol/conn-size/ConnSize.h | 2 +- src/analyzer/protocol/dhcp/DHCP.cc | 2 +- src/analyzer/protocol/dhcp/DHCP.h | 2 +- src/analyzer/protocol/dnp3/DNP3.cc | 2 +- src/analyzer/protocol/dnp3/DNP3.h | 2 +- src/analyzer/protocol/dns/DNS.cc | 2 +- src/analyzer/protocol/dns/DNS.h | 2 +- src/analyzer/protocol/file/File.cc | 10 +- src/analyzer/protocol/file/File.h | 6 +- src/analyzer/protocol/gtpv1/GTPv1.cc | 2 +- src/analyzer/protocol/gtpv1/GTPv1.h | 2 +- src/analyzer/protocol/http/HTTP.cc | 6 +- src/analyzer/protocol/http/HTTP.h | 4 +- src/analyzer/protocol/icmp/ICMP.cc | 2 +- src/analyzer/protocol/icmp/ICMP.h | 2 +- src/analyzer/protocol/interconn/InterConn.cc | 10 +- src/analyzer/protocol/interconn/InterConn.h | 6 +- src/analyzer/protocol/modbus/Modbus.cc | 2 +- src/analyzer/protocol/modbus/Modbus.h | 2 +- src/analyzer/protocol/ncp/NCP.cc | 2 +- src/analyzer/protocol/ncp/NCP.h | 2 +- src/analyzer/protocol/netbios/NetbiosSSN.cc | 2 +- src/analyzer/protocol/netbios/NetbiosSSN.h | 2 +- src/analyzer/protocol/ntp/NTP.cc | 2 +- src/analyzer/protocol/ntp/NTP.h | 2 +- src/analyzer/protocol/pia/PIA.cc | 10 +- src/analyzer/protocol/pia/PIA.h | 12 +- src/analyzer/protocol/rpc/RPC.cc | 4 +- src/analyzer/protocol/rpc/RPC.h | 4 +- src/analyzer/protocol/smtp/SMTP.cc | 4 +- src/analyzer/protocol/smtp/SMTP.h | 2 +- src/analyzer/protocol/socks/SOCKS.cc | 2 +- src/analyzer/protocol/socks/SOCKS.h | 2 +- src/analyzer/protocol/ssl/SSL.cc | 2 +- src/analyzer/protocol/ssl/SSL.h | 2 +- .../protocol/stepping-stone/SteppingStone.cc | 8 +- .../protocol/stepping-stone/SteppingStone.h | 6 +- src/analyzer/protocol/syslog/Syslog.cc | 4 +- src/analyzer/protocol/syslog/Syslog.h | 4 +- src/analyzer/protocol/tcp/ContentLine.cc | 2 +- src/analyzer/protocol/tcp/ContentLine.h | 12 +- src/analyzer/protocol/tcp/TCP.cc | 2234 +++++++++-------- src/analyzer/protocol/tcp/TCP.h | 84 +- src/analyzer/protocol/tcp/TCP_Endpoint.cc | 29 +- src/analyzer/protocol/tcp/TCP_Endpoint.h | 98 +- src/analyzer/protocol/tcp/TCP_Reassembler.cc | 163 +- src/analyzer/protocol/tcp/TCP_Reassembler.h | 49 +- src/analyzer/protocol/tcp/events.bif | 5 +- src/analyzer/protocol/teredo/Teredo.cc | 2 +- src/analyzer/protocol/teredo/Teredo.h | 2 +- src/analyzer/protocol/udp/UDP.cc | 2 +- src/analyzer/protocol/udp/UDP.h | 2 +- src/net_util.h | 6 +- .../core.tcp.large-file-reassembly/conn.log | 12 + .../core.tcp.large-file-reassembly/files.log | 11 + .../core.tcp.large-file-reassembly/out | 11 + .../weird.log | 6 +- testing/btest/Traces/ftp/bigtransfer.pcap | Bin 0 -> 32127 bytes .../btest/core/tcp/large-file-reassembly.bro | 22 + 75 files changed, 1627 insertions(+), 1540 deletions(-) create mode 100644 testing/btest/Baseline/core.tcp.large-file-reassembly/conn.log create mode 100644 testing/btest/Baseline/core.tcp.large-file-reassembly/files.log create mode 100644 testing/btest/Baseline/core.tcp.large-file-reassembly/out create mode 100644 testing/btest/Traces/ftp/bigtransfer.pcap create mode 100644 testing/btest/core/tcp/large-file-reassembly.bro diff --git a/src/Frag.cc b/src/Frag.cc index 30bec88af1..d0389c264a 100644 --- a/src/Frag.cc +++ b/src/Frag.cc @@ -97,9 +97,9 @@ void FragReassembler::AddFragment(double t, const IP_Hdr* ip, const u_char* pkt) // Linux MTU discovery for UDP can do this, for example. s->Weird("fragment_with_DF", ip); - int offset = ip->FragOffset(); - int len = ip->TotalLen(); - int hdr_len = ip->HdrLen(); + uint16 offset = ip->FragOffset(); + uint32 len = ip->TotalLen(); + uint16 hdr_len = ip->HdrLen(); if ( len < hdr_len ) { @@ -107,7 +107,7 @@ void FragReassembler::AddFragment(double t, const IP_Hdr* ip, const u_char* pkt) return; } - int upper_seq = offset + len - hdr_len; + uint64 upper_seq = offset + len - hdr_len; if ( ! offset ) // Make sure to use the first fragment header's next field. @@ -178,7 +178,7 @@ void FragReassembler::Weird(const char* name) const } } -void FragReassembler::Overlap(const u_char* b1, const u_char* b2, int n) +void FragReassembler::Overlap(const u_char* b1, const u_char* b2, uint64 n) { if ( memcmp((const void*) b1, (const void*) b2, n) ) Weird("fragment_inconsistency"); @@ -231,7 +231,7 @@ void FragReassembler::BlockInserted(DataBlock* /* start_block */) return; // We have it all. Compute the expected size of the fragment. - int n = proto_hdr_len + frag_size; + uint64 n = proto_hdr_len + frag_size; // It's possible that we have blocks associated with this fragment // that exceed this size, if we saw MF fragments (which don't lead diff --git a/src/Frag.h b/src/Frag.h index 0d2fbed5b3..7f3a0eec02 100644 --- a/src/Frag.h +++ b/src/Frag.h @@ -34,14 +34,14 @@ public: protected: void BlockInserted(DataBlock* start_block); - void Overlap(const u_char* b1, const u_char* b2, int n); + void Overlap(const u_char* b1, const u_char* b2, uint64 n); void Weird(const char* name) const; u_char* proto_hdr; IP_Hdr* reassembled_pkt; - int proto_hdr_len; + uint16 proto_hdr_len; NetSessions* s; - int frag_size; // size of fully reassembled fragment + uint64 frag_size; // size of fully reassembled fragment uint16 next_proto; // first IPv6 fragment header's next proto field HashKey* key; diff --git a/src/Reassem.cc b/src/Reassem.cc index 19beaa0a16..27fb26561f 100644 --- a/src/Reassem.cc +++ b/src/Reassem.cc @@ -7,14 +7,9 @@ #include "Reassem.h" #include "Serializer.h" -const bool DEBUG_reassem = false; +static const bool DEBUG_reassem = false; -#ifdef DEBUG -int reassem_seen_bytes = 0; -int reassem_copied_bytes = 0; -#endif - -DataBlock::DataBlock(const u_char* data, int size, int arg_seq, +DataBlock::DataBlock(const u_char* data, uint64 size, uint64 arg_seq, DataBlock* arg_prev, DataBlock* arg_next) { seq = arg_seq; @@ -23,10 +18,6 @@ DataBlock::DataBlock(const u_char* data, int size, int arg_seq, memcpy((void*) block, (const void*) data, size); -#ifdef DEBUG - reassem_copied_bytes += size; -#endif - prev = arg_prev; next = arg_next; @@ -38,9 +29,9 @@ DataBlock::DataBlock(const u_char* data, int size, int arg_seq, Reassembler::total_size += pad_size(size) + padded_sizeof(DataBlock); } -unsigned int Reassembler::total_size = 0; +uint64 Reassembler::total_size = 0; -Reassembler::Reassembler(int init_seq, ReassemblerType arg_type) +Reassembler::Reassembler(uint64 init_seq, ReassemblerType arg_type) { blocks = last_block = 0; trim_seq = last_reassem_seq = init_seq; @@ -51,24 +42,20 @@ Reassembler::~Reassembler() ClearBlocks(); } -void Reassembler::NewBlock(double t, int seq, int len, const u_char* data) +void Reassembler::NewBlock(double t, uint64 seq, uint64 len, const u_char* data) { if ( len == 0 ) return; -#ifdef DEBUG - reassem_seen_bytes += len; -#endif + uint64 upper_seq = seq + len; - int upper_seq = seq + len; - - if ( seq_delta(upper_seq, trim_seq) <= 0 ) + if ( upper_seq <= trim_seq ) // Old data, don't do any work for it. return; - if ( seq_delta(seq, trim_seq) < 0 ) + if ( seq < trim_seq ) { // Partially old data, just keep the good stuff. - int amount_old = seq_delta(trim_seq, seq); + uint64 amount_old = trim_seq - seq; data += amount_old; seq += amount_old; @@ -86,42 +73,42 @@ void Reassembler::NewBlock(double t, int seq, int len, const u_char* data) BlockInserted(start_block); } -int Reassembler::TrimToSeq(int seq) +uint64 Reassembler::TrimToSeq(uint64 seq) { - int num_missing = 0; + uint64 num_missing = 0; // Do this accounting before looking for Undelivered data, // since that will alter last_reassem_seq. if ( blocks ) { - if ( seq_delta(blocks->seq, last_reassem_seq) > 0 ) + if ( blocks->seq > last_reassem_seq ) // An initial hole. - num_missing += seq_delta(blocks->seq, last_reassem_seq); + num_missing += blocks->seq - last_reassem_seq; } - else if ( seq_delta(seq, last_reassem_seq) > 0 ) + else if ( seq > last_reassem_seq ) { // Trimming data we never delivered. if ( ! blocks ) // We won't have any accounting based on blocks // for this hole. - num_missing += seq_delta(seq, last_reassem_seq); + num_missing += seq - last_reassem_seq; } - if ( seq_delta(seq, last_reassem_seq) > 0 ) + if ( seq > last_reassem_seq ) { // We're trimming data we never delivered. Undelivered(seq); } - while ( blocks && seq_delta(blocks->upper, seq) <= 0 ) + while ( blocks && blocks->upper <= seq ) { DataBlock* b = blocks->next; - if ( b && seq_delta(b->seq, seq) <= 0 ) + if ( b && b->seq <= seq ) { if ( blocks->upper != b->seq ) - num_missing += seq_delta(b->seq, blocks->upper); + num_missing += b->seq - blocks->upper; } else { @@ -129,7 +116,7 @@ int Reassembler::TrimToSeq(int seq) // Second half of test is for acks of FINs, which // don't get entered into the sequence space. if ( blocks->upper != seq && blocks->upper != seq - 1 ) - num_missing += seq_delta(seq, blocks->upper); + num_missing += seq - blocks->upper; } delete blocks; @@ -150,7 +137,7 @@ int Reassembler::TrimToSeq(int seq) else last_block = 0; - if ( seq_delta(seq, trim_seq) > 0 ) + if ( seq > trim_seq ) // seq is further ahead in the sequence space. trim_seq = seq; @@ -169,9 +156,9 @@ void Reassembler::ClearBlocks() last_block = 0; } -int Reassembler::TotalSize() const +uint64 Reassembler::TotalSize() const { - int size = 0; + uint64 size = 0; for ( DataBlock* b = blocks; b; b = b->next ) size += b->Size(); @@ -184,18 +171,18 @@ void Reassembler::Describe(ODesc* d) const d->Add("reassembler"); } -void Reassembler::Undelivered(int up_to_seq) +void Reassembler::Undelivered(uint64 up_to_seq) { // TrimToSeq() expects this. last_reassem_seq = up_to_seq; } -DataBlock* Reassembler::AddAndCheck(DataBlock* b, int seq, int upper, +DataBlock* Reassembler::AddAndCheck(DataBlock* b, uint64 seq, uint64 upper, const u_char* data) { if ( DEBUG_reassem ) { - DEBUG_MSG("%.6f Reassembler::AddAndCheck seq=%d, upper=%d\n", + DEBUG_MSG("%.6f Reassembler::AddAndCheck seq=%"PRIu64", upper=%"PRIu64"\n", network_time, seq, upper); } @@ -209,10 +196,10 @@ DataBlock* Reassembler::AddAndCheck(DataBlock* b, int seq, int upper, // Find the first block that doesn't come completely before the // new data. - while ( b->next && seq_delta(b->upper, seq) <= 0 ) + while ( b->next && b->upper <= seq ) b = b->next; - if ( seq_delta(b->upper, seq) <= 0 ) + if ( b->upper <= seq ) { // b is the last block, and it comes completely before // the new block. @@ -222,21 +209,20 @@ DataBlock* Reassembler::AddAndCheck(DataBlock* b, int seq, int upper, DataBlock* new_b = 0; - if ( seq_delta(upper, b->seq) <= 0 ) + if ( upper <= b->seq ) { // The new block comes completely before b. - new_b = new DataBlock(data, seq_delta(upper, seq), seq, - b->prev, b); + new_b = new DataBlock(data, upper - seq, seq, b->prev, b); if ( b == blocks ) blocks = new_b; return new_b; } // The blocks overlap, complain. - if ( seq_delta(seq, b->seq) < 0 ) + if ( seq < b->seq ) { // The new block has a prefix that comes before b. - int prefix_len = seq_delta(b->seq, seq); + uint64 prefix_len = b->seq - seq; new_b = new DataBlock(data, prefix_len, seq, b->prev, b); if ( b == blocks ) blocks = new_b; @@ -247,11 +233,11 @@ DataBlock* Reassembler::AddAndCheck(DataBlock* b, int seq, int upper, else new_b = b; - int overlap_start = seq; - int overlap_offset = seq_delta(overlap_start, b->seq); - int new_b_len = seq_delta(upper, seq); - int b_len = seq_delta(b->upper, overlap_start); - int overlap_len = min(new_b_len, b_len); + uint64 overlap_start = seq; + uint64 overlap_offset = overlap_start - b->seq; + uint64 new_b_len = upper - seq; + uint64 b_len = b->upper - overlap_start; + uint64 overlap_len = min(new_b_len, b_len); Overlap(&b->block[overlap_offset], data, overlap_len); diff --git a/src/Reassem.h b/src/Reassem.h index 1f65059e02..7b77a628d8 100644 --- a/src/Reassem.h +++ b/src/Reassem.h @@ -8,16 +8,16 @@ class DataBlock { public: - DataBlock(const u_char* data, int size, int seq, + DataBlock(const u_char* data, uint64 size, uint64 seq, DataBlock* prev, DataBlock* next); ~DataBlock(); - int Size() const { return upper - seq; } + uint64 Size() const { return upper - seq; } DataBlock* next; // next block with higher seq # DataBlock* prev; // previous block with lower seq # - int seq, upper; + uint64 seq, upper; u_char* block; }; @@ -26,22 +26,22 @@ enum ReassemblerType { REASSEM_IP, REASSEM_TCP }; class Reassembler : public BroObj { public: - Reassembler(int init_seq, ReassemblerType arg_type); + Reassembler(uint64 init_seq, ReassemblerType arg_type); virtual ~Reassembler(); - void NewBlock(double t, int seq, int len, const u_char* data); + void NewBlock(double t, uint64 seq, uint64 len, const u_char* data); // Throws away all blocks up to seq. Returns number of bytes // if not all in-sequence, 0 if they were. - int TrimToSeq(int seq); + uint64 TrimToSeq(uint64 seq); // Delete all held blocks. void ClearBlocks(); int HasBlocks() const { return blocks != 0; } - int LastReassemSeq() const { return last_reassem_seq; } + uint64 LastReassemSeq() const { return last_reassem_seq; } - int TotalSize() const; // number of bytes buffered up + uint64 TotalSize() const; // number of bytes buffered up void Describe(ODesc* d) const; @@ -49,7 +49,7 @@ public: static Reassembler* Unserialize(UnserialInfo* info); // Sum over all data buffered in some reassembler. - static unsigned int TotalMemoryAllocation() { return total_size; } + static uint64 TotalMemoryAllocation() { return total_size; } protected: Reassembler() { } @@ -58,20 +58,20 @@ protected: friend class DataBlock; - virtual void Undelivered(int up_to_seq); + virtual void Undelivered(uint64 up_to_seq); virtual void BlockInserted(DataBlock* b) = 0; - virtual void Overlap(const u_char* b1, const u_char* b2, int n) = 0; + virtual void Overlap(const u_char* b1, const u_char* b2, uint64 n) = 0; - DataBlock* AddAndCheck(DataBlock* b, int seq, - int upper, const u_char* data); + DataBlock* AddAndCheck(DataBlock* b, uint64 seq, + uint64 upper, const u_char* data); DataBlock* blocks; DataBlock* last_block; - int last_reassem_seq; - int trim_seq; // how far we've trimmed + uint64 last_reassem_seq; + uint64 trim_seq; // how far we've trimmed - static unsigned int total_size; + static uint64 total_size; }; inline DataBlock::~DataBlock() diff --git a/src/Stats.cc b/src/Stats.cc index c4b0ed45b1..6cf9a622e1 100644 --- a/src/Stats.cc +++ b/src/Stats.cc @@ -160,7 +160,7 @@ void ProfileLogger::Log() file->Write(fmt("%.06f Connections expired due to inactivity: %d\n", network_time, killed_by_inactivity)); - file->Write(fmt("%.06f Total reassembler data: %dK\n", network_time, + file->Write(fmt("%.06f Total reassembler data: %"PRIu64"K\n", network_time, Reassembler::TotalMemoryAllocation() / 1024)); // Signature engine. diff --git a/src/analyzer/Analyzer.cc b/src/analyzer/Analyzer.cc index b280cbb6f8..b840e1bbd4 100644 --- a/src/analyzer/Analyzer.cc +++ b/src/analyzer/Analyzer.cc @@ -203,7 +203,7 @@ void Analyzer::Done() finished = true; } -void Analyzer::NextPacket(int len, const u_char* data, bool is_orig, int seq, +void Analyzer::NextPacket(int len, const u_char* data, bool is_orig, uint64 seq, const IP_Hdr* ip, int caplen) { if ( skip ) @@ -250,7 +250,7 @@ void Analyzer::NextStream(int len, const u_char* data, bool is_orig) } } -void Analyzer::NextUndelivered(int seq, int len, bool is_orig) +void Analyzer::NextUndelivered(uint64 seq, int len, bool is_orig) { if ( skip ) return; @@ -287,7 +287,7 @@ void Analyzer::NextEndOfData(bool is_orig) } void Analyzer::ForwardPacket(int len, const u_char* data, bool is_orig, - int seq, const IP_Hdr* ip, int caplen) + uint64 seq, const IP_Hdr* ip, int caplen) { if ( output_handler ) output_handler->DeliverPacket(len, data, is_orig, seq, @@ -335,7 +335,7 @@ void Analyzer::ForwardStream(int len, const u_char* data, bool is_orig) AppendNewChildren(); } -void Analyzer::ForwardUndelivered(int seq, int len, bool is_orig) +void Analyzer::ForwardUndelivered(uint64 seq, int len, bool is_orig) { if ( output_handler ) output_handler->Undelivered(seq, len, is_orig); @@ -595,9 +595,9 @@ SupportAnalyzer* Analyzer::FirstSupportAnalyzer(bool orig) } void Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, - int seq, const IP_Hdr* ip, int caplen) + uint64 seq, const IP_Hdr* ip, int caplen) { - DBG_LOG(DBG_ANALYZER, "%s DeliverPacket(%d, %s, %d, %p, %d) [%s%s]", + DBG_LOG(DBG_ANALYZER, "%s DeliverPacket(%d, %s, %"PRIu64", %p, %d) [%s%s]", fmt_analyzer(this).c_str(), len, is_orig ? "T" : "F", seq, ip, caplen, fmt_bytes((const char*) data, min(40, len)), len > 40 ? "..." : ""); } @@ -609,9 +609,9 @@ void Analyzer::DeliverStream(int len, const u_char* data, bool is_orig) fmt_bytes((const char*) data, min(40, len)), len > 40 ? "..." : ""); } -void Analyzer::Undelivered(int seq, int len, bool is_orig) +void Analyzer::Undelivered(uint64 seq, int len, bool is_orig) { - DBG_LOG(DBG_ANALYZER, "%s Undelivered(%d, %d, %s)", + DBG_LOG(DBG_ANALYZER, "%s Undelivered(%"PRIu64", %d, %s)", fmt_analyzer(this).c_str(), seq, len, is_orig ? "T" : "F"); } @@ -793,7 +793,7 @@ SupportAnalyzer* SupportAnalyzer::Sibling(bool only_active) const } void SupportAnalyzer::ForwardPacket(int len, const u_char* data, bool is_orig, - int seq, const IP_Hdr* ip, int caplen) + uint64 seq, const IP_Hdr* ip, int caplen) { // We do not call parent's method, as we're replacing the functionality. @@ -834,7 +834,7 @@ void SupportAnalyzer::ForwardStream(int len, const u_char* data, bool is_orig) Parent()->DeliverStream(len, data, is_orig); } -void SupportAnalyzer::ForwardUndelivered(int seq, int len, bool is_orig) +void SupportAnalyzer::ForwardUndelivered(uint64 seq, int len, bool is_orig) { // We do not call parent's method, as we're replacing the functionality. diff --git a/src/analyzer/Analyzer.h b/src/analyzer/Analyzer.h index 578020082b..f32181b9e7 100644 --- a/src/analyzer/Analyzer.h +++ b/src/analyzer/Analyzer.h @@ -44,7 +44,7 @@ public: * Analyzer::DeliverPacket(). */ virtual void DeliverPacket(int len, const u_char* data, - bool orig, int seq, + bool orig, uint64 seq, const IP_Hdr* ip, int caplen) { } @@ -59,7 +59,7 @@ public: * Hook for receiving notification of stream gaps. Parameters are the * same as for Analyzer::Undelivered(). */ - virtual void Undelivered(int seq, int len, bool orig) { } + virtual void Undelivered(uint64 seq, int len, bool orig) { } }; /** @@ -143,7 +143,7 @@ public: * @param caplen The packet's capture length, if available. */ void NextPacket(int len, const u_char* data, bool is_orig, - int seq = -1, const IP_Hdr* ip = 0, int caplen = 0); + uint64 seq = -1, const IP_Hdr* ip = 0, int caplen = 0); /** * Passes stream input to the analyzer for processing. The analyzer @@ -173,7 +173,7 @@ public: * * @param is_orig True if this is about originator-side input. */ - void NextUndelivered(int seq, int len, bool is_orig); + void NextUndelivered(uint64 seq, int len, bool is_orig); /** * Reports a message boundary. This is a generic method that can be @@ -195,7 +195,7 @@ public: * Parameters are the same as for NextPacket(). */ virtual void ForwardPacket(int len, const u_char* data, - bool orig, int seq, + bool orig, uint64 seq, const IP_Hdr* ip, int caplen); /** @@ -212,7 +212,7 @@ public: * * Parameters are the same as for NextUndelivered(). */ - virtual void ForwardUndelivered(int seq, int len, bool orig); + virtual void ForwardUndelivered(uint64 seq, int len, bool orig); /** * Forwards an end-of-data notification on to all child analyzers. @@ -227,7 +227,7 @@ public: * Parameters are the same. */ virtual void DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); /** * Hook for accessing stream input for parsing. This is called by @@ -241,7 +241,7 @@ public: * NextUndelivered() and can be overridden by derived classes. * Parameters are the same. */ - virtual void Undelivered(int seq, int len, bool orig); + virtual void Undelivered(uint64 seq, int len, bool orig); /** * Hook for accessing end-of-data notifications. This is called by @@ -749,7 +749,7 @@ public: * Parameters same as for Analyzer::ForwardPacket. */ virtual void ForwardPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); /** * Passes stream input to the next sibling SupportAnalyzer if any, or @@ -769,7 +769,7 @@ public: * * Parameters same as for Analyzer::ForwardPacket. */ - virtual void ForwardUndelivered(int seq, int len, bool orig); + virtual void ForwardUndelivered(uint64 seq, int len, bool orig); protected: friend class Analyzer; diff --git a/src/analyzer/protocol/ayiya/AYIYA.cc b/src/analyzer/protocol/ayiya/AYIYA.cc index 070a3ef3e1..a1e00e9b38 100644 --- a/src/analyzer/protocol/ayiya/AYIYA.cc +++ b/src/analyzer/protocol/ayiya/AYIYA.cc @@ -22,7 +22,7 @@ void AYIYA_Analyzer::Done() Event(udp_session_done); } -void AYIYA_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen) +void AYIYA_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, uint64 seq, const IP_Hdr* ip, int caplen) { Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); diff --git a/src/analyzer/protocol/ayiya/AYIYA.h b/src/analyzer/protocol/ayiya/AYIYA.h index f5bb379cf4..2739ff2bba 100644 --- a/src/analyzer/protocol/ayiya/AYIYA.h +++ b/src/analyzer/protocol/ayiya/AYIYA.h @@ -12,7 +12,7 @@ public: virtual void Done(); virtual void DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new AYIYA_Analyzer(conn); } diff --git a/src/analyzer/protocol/backdoor/BackDoor.cc b/src/analyzer/protocol/backdoor/BackDoor.cc index a466938ff6..984b2a5dcf 100644 --- a/src/analyzer/protocol/backdoor/BackDoor.cc +++ b/src/analyzer/protocol/backdoor/BackDoor.cc @@ -46,7 +46,7 @@ void BackDoorEndpoint::FinalCheckForRlogin() } } -int BackDoorEndpoint::DataSent(double /* t */, int seq, +int BackDoorEndpoint::DataSent(double /* t */, uint64 seq, int len, int caplen, const u_char* data, const IP_Hdr* /* ip */, const struct tcphdr* /* tp */) @@ -60,8 +60,8 @@ int BackDoorEndpoint::DataSent(double /* t */, int seq, if ( endp->state == tcp::TCP_ENDPOINT_PARTIAL ) is_partial = 1; - int ack = endp->AckSeq() - endp->StartSeq(); - int top_seq = seq + len; + uint64 ack = endp->ToRelativeSeqSpace(endp->AckSeq(), endp->AckWraps()); + uint64 top_seq = seq + len; if ( top_seq <= ack || top_seq <= max_top_seq ) // There is no new data in this packet. @@ -124,7 +124,7 @@ RecordVal* BackDoorEndpoint::BuildStats() return stats; } -void BackDoorEndpoint::CheckForRlogin(int seq, int len, const u_char* data) +void BackDoorEndpoint::CheckForRlogin(uint64 seq, int len, const u_char* data) { if ( rlogin_checking_done ) return; @@ -177,7 +177,7 @@ void BackDoorEndpoint::CheckForRlogin(int seq, int len, const u_char* data) if ( seq < max_top_seq ) { // trim to just the new data - int delta = max_top_seq - seq; + int64 delta = max_top_seq - seq; seq += delta; data += delta; len -= delta; @@ -255,7 +255,7 @@ void BackDoorEndpoint::RloginSignatureFound(int len) endp->TCP()->ConnectionEvent(rlogin_signature_found, vl); } -void BackDoorEndpoint::CheckForTelnet(int /* seq */, int len, const u_char* data) +void BackDoorEndpoint::CheckForTelnet(uint64 /* seq */, int len, const u_char* data) { if ( len >= 3 && data[0] == TELNET_IAC && IS_TELNET_NEGOTIATION_CMD(data[1]) ) @@ -346,7 +346,7 @@ void BackDoorEndpoint::TelnetSignatureFound(int len) endp->TCP()->ConnectionEvent(telnet_signature_found, vl); } -void BackDoorEndpoint::CheckForSSH(int seq, int len, const u_char* data) +void BackDoorEndpoint::CheckForSSH(uint64 seq, int len, const u_char* data) { if ( seq == 1 && CheckForString("SSH-", data, len) && len > 4 && (data[4] == '1' || data[4] == '2') ) @@ -363,8 +363,9 @@ void BackDoorEndpoint::CheckForSSH(int seq, int len, const u_char* data) if ( seq > max_top_seq ) { // Estimate number of packets in the sequence gap - int gap = seq - max_top_seq; - num_pkts += int((gap + DEFAULT_MTU - 1) / DEFAULT_MTU); + int64 gap = seq - max_top_seq; + if ( gap > 0 ) + num_pkts += uint64((gap + DEFAULT_MTU - 1) / DEFAULT_MTU); } ++num_pkts; @@ -388,7 +389,7 @@ void BackDoorEndpoint::CheckForSSH(int seq, int len, const u_char* data) } } -void BackDoorEndpoint::CheckForRootBackdoor(int seq, int len, const u_char* data) +void BackDoorEndpoint::CheckForRootBackdoor(uint64 seq, int len, const u_char* data) { // Check for root backdoor signature: an initial payload of // exactly "# ". @@ -397,7 +398,7 @@ void BackDoorEndpoint::CheckForRootBackdoor(int seq, int len, const u_char* data SignatureFound(root_backdoor_signature_found); } -void BackDoorEndpoint::CheckForFTP(int seq, int len, const u_char* data) +void BackDoorEndpoint::CheckForFTP(uint64 seq, int len, const u_char* data) { // Check for FTP signature // @@ -429,7 +430,7 @@ void BackDoorEndpoint::CheckForFTP(int seq, int len, const u_char* data) SignatureFound(ftp_signature_found); } -void BackDoorEndpoint::CheckForNapster(int seq, int len, const u_char* data) +void BackDoorEndpoint::CheckForNapster(uint64 seq, int len, const u_char* data) { // Check for Napster signature "GETfoobar" or "SENDfoobar" where // "foobar" is the Napster handle associated with the request @@ -449,7 +450,7 @@ void BackDoorEndpoint::CheckForNapster(int seq, int len, const u_char* data) SignatureFound(napster_signature_found); } -void BackDoorEndpoint::CheckForSMTP(int seq, int len, const u_char* data) +void BackDoorEndpoint::CheckForSMTP(uint64 seq, int len, const u_char* data) { const char* smtp_handshake[] = { "HELO", "EHLO", 0 }; @@ -460,7 +461,7 @@ void BackDoorEndpoint::CheckForSMTP(int seq, int len, const u_char* data) SignatureFound(smtp_signature_found); } -void BackDoorEndpoint::CheckForIRC(int seq, int len, const u_char* data) +void BackDoorEndpoint::CheckForIRC(uint64 seq, int len, const u_char* data) { if ( seq != 1 || is_partial ) return; @@ -475,7 +476,7 @@ void BackDoorEndpoint::CheckForIRC(int seq, int len, const u_char* data) SignatureFound(irc_signature_found); } -void BackDoorEndpoint::CheckForGnutella(int seq, int len, const u_char* data) +void BackDoorEndpoint::CheckForGnutella(uint64 seq, int len, const u_char* data) { // After connecting to the server, the connecting client says: // @@ -492,13 +493,13 @@ void BackDoorEndpoint::CheckForGnutella(int seq, int len, const u_char* data) SignatureFound(gnutella_signature_found); } -void BackDoorEndpoint::CheckForGaoBot(int seq, int len, const u_char* data) +void BackDoorEndpoint::CheckForGaoBot(uint64 seq, int len, const u_char* data) { if ( seq == 1 && CheckForString("220 Bot Server (Win32)", data, len) ) SignatureFound(gaobot_signature_found); } -void BackDoorEndpoint::CheckForKazaa(int seq, int len, const u_char* data) +void BackDoorEndpoint::CheckForKazaa(uint64 seq, int len, const u_char* data) { // *Some*, though not all, KaZaa connections begin with: // @@ -565,7 +566,7 @@ int is_absolute_url(const u_char* data, int len) return *abs_url_sig_pos == '\0'; } -void BackDoorEndpoint::CheckForHTTP(int seq, int len, const u_char* data) +void BackDoorEndpoint::CheckForHTTP(uint64 seq, int len, const u_char* data) { // According to the RFC, we should look for // ' SP SP HTTP/ CR LF' @@ -629,7 +630,7 @@ void BackDoorEndpoint::CheckForHTTP(int seq, int len, const u_char* data) } } -void BackDoorEndpoint::CheckForHTTPProxy(int /* seq */, int len, +void BackDoorEndpoint::CheckForHTTPProxy(uint64 /* seq */, int len, const u_char* data) { // Proxy ONLY accepts absolute URI's: "The absoluteURI form is @@ -713,7 +714,7 @@ void BackDoor_Analyzer::Init() } void BackDoor_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, - int seq, const IP_Hdr* ip, int caplen) + uint64 seq, const IP_Hdr* ip, int caplen) { Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen); diff --git a/src/analyzer/protocol/backdoor/BackDoor.h b/src/analyzer/protocol/backdoor/BackDoor.h index 5bc8a67381..b1b95ca3f8 100644 --- a/src/analyzer/protocol/backdoor/BackDoor.h +++ b/src/analyzer/protocol/backdoor/BackDoor.h @@ -14,7 +14,7 @@ class BackDoorEndpoint { public: BackDoorEndpoint(tcp::TCP_Endpoint* e); - int DataSent(double t, int seq, int len, int caplen, const u_char* data, + int DataSent(double t, uint64 seq, int len, int caplen, const u_char* data, const IP_Hdr* ip, const struct tcphdr* tp); RecordVal* BuildStats(); @@ -22,23 +22,23 @@ public: void FinalCheckForRlogin(); protected: - void CheckForRlogin(int seq, int len, const u_char* data); + void CheckForRlogin(uint64 seq, int len, const u_char* data); void RloginSignatureFound(int len); - void CheckForTelnet(int seq, int len, const u_char* data); + void CheckForTelnet(uint64 seq, int len, const u_char* data); void TelnetSignatureFound(int len); - void CheckForSSH(int seq, int len, const u_char* data); - void CheckForFTP(int seq, int len, const u_char* data); - void CheckForRootBackdoor(int seq, int len, const u_char* data); - void CheckForNapster(int seq, int len, const u_char* data); - void CheckForGnutella(int seq, int len, const u_char* data); - void CheckForKazaa(int seq, int len, const u_char* data); - void CheckForHTTP(int seq, int len, const u_char* data); - void CheckForHTTPProxy(int seq, int len, const u_char* data); - void CheckForSMTP(int seq, int len, const u_char* data); - void CheckForIRC(int seq, int len, const u_char* data); - void CheckForGaoBot(int seq, int len, const u_char* data); + void CheckForSSH(uint64 seq, int len, const u_char* data); + void CheckForFTP(uint64 seq, int len, const u_char* data); + void CheckForRootBackdoor(uint64 seq, int len, const u_char* data); + void CheckForNapster(uint64 seq, int len, const u_char* data); + void CheckForGnutella(uint64 seq, int len, const u_char* data); + void CheckForKazaa(uint64 seq, int len, const u_char* data); + void CheckForHTTP(uint64 seq, int len, const u_char* data); + void CheckForHTTPProxy(uint64 seq, int len, const u_char* data); + void CheckForSMTP(uint64 seq, int len, const u_char* data); + void CheckForIRC(uint64 seq, int len, const u_char* data); + void CheckForGaoBot(uint64 seq, int len, const u_char* data); void SignatureFound(EventHandlerPtr e, int do_orig = 0); @@ -48,11 +48,11 @@ protected: tcp::TCP_Endpoint* endp; int is_partial; - int max_top_seq; + uint64 max_top_seq; int rlogin_checking_done; int rlogin_num_null; - int rlogin_string_separator_pos; + uint64 rlogin_string_separator_pos; int rlogin_slash_seen; uint32 num_pkts; @@ -80,7 +80,7 @@ protected: // We support both packet and stream input, and can be instantiated // even if the TCP analyzer is not yet reassembling. virtual void DeliverPacket(int len, const u_char* data, bool is_orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); virtual void DeliverStream(int len, const u_char* data, bool is_orig); void StatEvent(); diff --git a/src/analyzer/protocol/bittorrent/BitTorrent.cc b/src/analyzer/protocol/bittorrent/BitTorrent.cc index 99fd9dc132..cb6fc0945e 100644 --- a/src/analyzer/protocol/bittorrent/BitTorrent.cc +++ b/src/analyzer/protocol/bittorrent/BitTorrent.cc @@ -68,7 +68,7 @@ void BitTorrent_Analyzer::DeliverStream(int len, const u_char* data, bool orig) } } -void BitTorrent_Analyzer::Undelivered(int seq, int len, bool orig) +void BitTorrent_Analyzer::Undelivered(uint64 seq, int len, bool orig) { tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); diff --git a/src/analyzer/protocol/bittorrent/BitTorrent.h b/src/analyzer/protocol/bittorrent/BitTorrent.h index 7739463052..2e303f4038 100644 --- a/src/analyzer/protocol/bittorrent/BitTorrent.h +++ b/src/analyzer/protocol/bittorrent/BitTorrent.h @@ -16,7 +16,7 @@ public: virtual void Done(); virtual void DeliverStream(int len, const u_char* data, bool orig); - virtual void Undelivered(int seq, int len, bool orig); + virtual void Undelivered(uint64 seq, int len, bool orig); virtual void EndpointEOF(bool is_orig); static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) diff --git a/src/analyzer/protocol/bittorrent/BitTorrentTracker.cc b/src/analyzer/protocol/bittorrent/BitTorrentTracker.cc index 98adcaa610..43ee6a2b21 100644 --- a/src/analyzer/protocol/bittorrent/BitTorrentTracker.cc +++ b/src/analyzer/protocol/bittorrent/BitTorrentTracker.cc @@ -207,7 +207,7 @@ void BitTorrentTracker_Analyzer::ServerReply(int len, const u_char* data) } } -void BitTorrentTracker_Analyzer::Undelivered(int seq, int len, bool orig) +void BitTorrentTracker_Analyzer::Undelivered(uint64 seq, int len, bool orig) { tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); diff --git a/src/analyzer/protocol/bittorrent/BitTorrentTracker.h b/src/analyzer/protocol/bittorrent/BitTorrentTracker.h index b041e556b7..2fa5d684cd 100644 --- a/src/analyzer/protocol/bittorrent/BitTorrentTracker.h +++ b/src/analyzer/protocol/bittorrent/BitTorrentTracker.h @@ -49,7 +49,7 @@ public: virtual void Done(); virtual void DeliverStream(int len, const u_char* data, bool orig); - virtual void Undelivered(int seq, int len, bool orig); + virtual void Undelivered(uint64 seq, int len, bool orig); virtual void EndpointEOF(bool is_orig); static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) diff --git a/src/analyzer/protocol/conn-size/ConnSize.cc b/src/analyzer/protocol/conn-size/ConnSize.cc index 227a4b1be2..5bfeb2bf90 100644 --- a/src/analyzer/protocol/conn-size/ConnSize.cc +++ b/src/analyzer/protocol/conn-size/ConnSize.cc @@ -36,7 +36,7 @@ void ConnSize_Analyzer::Done() Analyzer::Done(); } -void ConnSize_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, int seq, const IP_Hdr* ip, int caplen) +void ConnSize_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, uint64 seq, const IP_Hdr* ip, int caplen) { Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen); diff --git a/src/analyzer/protocol/conn-size/ConnSize.h b/src/analyzer/protocol/conn-size/ConnSize.h index 25f096dd32..ec3b85c0d9 100644 --- a/src/analyzer/protocol/conn-size/ConnSize.h +++ b/src/analyzer/protocol/conn-size/ConnSize.h @@ -26,7 +26,7 @@ public: protected: virtual void DeliverPacket(int len, const u_char* data, bool is_orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); uint64_t orig_bytes; diff --git a/src/analyzer/protocol/dhcp/DHCP.cc b/src/analyzer/protocol/dhcp/DHCP.cc index 1fa8759fbf..78b1c6be69 100644 --- a/src/analyzer/protocol/dhcp/DHCP.cc +++ b/src/analyzer/protocol/dhcp/DHCP.cc @@ -21,7 +21,7 @@ void DHCP_Analyzer::Done() } void DHCP_Analyzer::DeliverPacket(int len, const u_char* data, - bool orig, int seq, const IP_Hdr* ip, int caplen) + bool orig, uint64 seq, const IP_Hdr* ip, int caplen) { Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); interp->NewData(orig, data, data + len); diff --git a/src/analyzer/protocol/dhcp/DHCP.h b/src/analyzer/protocol/dhcp/DHCP.h index a1c06e8b85..7633d71351 100644 --- a/src/analyzer/protocol/dhcp/DHCP.h +++ b/src/analyzer/protocol/dhcp/DHCP.h @@ -14,7 +14,7 @@ public: virtual void Done(); virtual void DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new DHCP_Analyzer(conn); } diff --git a/src/analyzer/protocol/dnp3/DNP3.cc b/src/analyzer/protocol/dnp3/DNP3.cc index ee90a0c74d..9d9ddf0c35 100644 --- a/src/analyzer/protocol/dnp3/DNP3.cc +++ b/src/analyzer/protocol/dnp3/DNP3.cc @@ -153,7 +153,7 @@ void DNP3_Analyzer::DeliverStream(int len, const u_char* data, bool orig) } } -void DNP3_Analyzer::Undelivered(int seq, int len, bool orig) +void DNP3_Analyzer::Undelivered(uint64 seq, int len, bool orig) { TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); interp->NewGap(orig, len); diff --git a/src/analyzer/protocol/dnp3/DNP3.h b/src/analyzer/protocol/dnp3/DNP3.h index b84d3874b4..a0578808a8 100644 --- a/src/analyzer/protocol/dnp3/DNP3.h +++ b/src/analyzer/protocol/dnp3/DNP3.h @@ -14,7 +14,7 @@ public: virtual void Done(); virtual void DeliverStream(int len, const u_char* data, bool orig); - virtual void Undelivered(int seq, int len, bool orig); + virtual void Undelivered(uint64 seq, int len, bool orig); virtual void EndpointEOF(bool is_orig); static Analyzer* InstantiateAnalyzer(Connection* conn) diff --git a/src/analyzer/protocol/dns/DNS.cc b/src/analyzer/protocol/dns/DNS.cc index a97c7b8632..baa95f46de 100644 --- a/src/analyzer/protocol/dns/DNS.cc +++ b/src/analyzer/protocol/dns/DNS.cc @@ -1146,7 +1146,7 @@ void DNS_Analyzer::Done() } void DNS_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen) + uint64 seq, const IP_Hdr* ip, int caplen) { tcp::TCP_ApplicationAnalyzer::DeliverPacket(len, data, orig, seq, ip, caplen); diff --git a/src/analyzer/protocol/dns/DNS.h b/src/analyzer/protocol/dns/DNS.h index af4b8de22f..2cc1615b04 100644 --- a/src/analyzer/protocol/dns/DNS.h +++ b/src/analyzer/protocol/dns/DNS.h @@ -258,7 +258,7 @@ public: ~DNS_Analyzer(); virtual void DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); virtual void Init(); virtual void Done(); diff --git a/src/analyzer/protocol/file/File.cc b/src/analyzer/protocol/file/File.cc index 4476043721..7af16165e3 100644 --- a/src/analyzer/protocol/file/File.cc +++ b/src/analyzer/protocol/file/File.cc @@ -34,7 +34,7 @@ void File_Analyzer::DeliverStream(int len, const u_char* data, bool orig) return; } -void File_Analyzer::Undelivered(int seq, int len, bool orig) +void File_Analyzer::Undelivered(uint64 seq, int len, bool orig) { TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); } @@ -79,10 +79,10 @@ void IRC_Data::DeliverStream(int len, const u_char* data, bool orig) file_mgr->DataIn(data, len, GetAnalyzerTag(), Conn(), orig); } -void IRC_Data::Undelivered(int seq, int len, bool orig) +void IRC_Data::Undelivered(uint64 seq, int len, bool orig) { File_Analyzer::Undelivered(seq, len, orig); - file_mgr->Gap(seq, len, GetAnalyzerTag(), Conn(), orig); + file_mgr->Gap(seq - 1, len, GetAnalyzerTag(), Conn(), orig); } FTP_Data::FTP_Data(Connection* conn) @@ -102,8 +102,8 @@ void FTP_Data::DeliverStream(int len, const u_char* data, bool orig) file_mgr->DataIn(data, len, GetAnalyzerTag(), Conn(), orig); } -void FTP_Data::Undelivered(int seq, int len, bool orig) +void FTP_Data::Undelivered(uint64 seq, int len, bool orig) { File_Analyzer::Undelivered(seq, len, orig); - file_mgr->Gap(seq, len, GetAnalyzerTag(), Conn(), orig); + file_mgr->Gap(seq - 1, len, GetAnalyzerTag(), Conn(), orig); } diff --git a/src/analyzer/protocol/file/File.h b/src/analyzer/protocol/file/File.h index 7afbd569c4..f83ec82a49 100644 --- a/src/analyzer/protocol/file/File.h +++ b/src/analyzer/protocol/file/File.h @@ -17,7 +17,7 @@ public: virtual void DeliverStream(int len, const u_char* data, bool orig); - void Undelivered(int seq, int len, bool orig); + void Undelivered(uint64 seq, int len, bool orig); // static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) // { return new File_Analyzer(conn); } @@ -38,7 +38,7 @@ public: virtual void DeliverStream(int len, const u_char* data, bool orig); - virtual void Undelivered(int seq, int len, bool orig); + virtual void Undelivered(uint64 seq, int len, bool orig); static Analyzer* InstantiateAnalyzer(Connection* conn) { return new IRC_Data(conn); } @@ -52,7 +52,7 @@ public: virtual void DeliverStream(int len, const u_char* data, bool orig); - virtual void Undelivered(int seq, int len, bool orig); + virtual void Undelivered(uint64 seq, int len, bool orig); static Analyzer* InstantiateAnalyzer(Connection* conn) { return new FTP_Data(conn); } diff --git a/src/analyzer/protocol/gtpv1/GTPv1.cc b/src/analyzer/protocol/gtpv1/GTPv1.cc index 0a94a28554..361e602b5f 100644 --- a/src/analyzer/protocol/gtpv1/GTPv1.cc +++ b/src/analyzer/protocol/gtpv1/GTPv1.cc @@ -23,7 +23,7 @@ void GTPv1_Analyzer::Done() Event(udp_session_done); } -void GTPv1_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen) +void GTPv1_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, uint64 seq, const IP_Hdr* ip, int caplen) { Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); try diff --git a/src/analyzer/protocol/gtpv1/GTPv1.h b/src/analyzer/protocol/gtpv1/GTPv1.h index b58405ea7f..eebaf1d83e 100644 --- a/src/analyzer/protocol/gtpv1/GTPv1.h +++ b/src/analyzer/protocol/gtpv1/GTPv1.h @@ -12,7 +12,7 @@ public: virtual void Done(); virtual void DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new GTPv1_Analyzer(conn); } diff --git a/src/analyzer/protocol/http/HTTP.cc b/src/analyzer/protocol/http/HTTP.cc index f676643b7c..2eaff3f8c6 100644 --- a/src/analyzer/protocol/http/HTTP.cc +++ b/src/analyzer/protocol/http/HTTP.cc @@ -1115,11 +1115,11 @@ void HTTP_Analyzer::DeliverStream(int len, const u_char* data, bool is_orig) } } -void HTTP_Analyzer::Undelivered(int seq, int len, bool is_orig) +void HTTP_Analyzer::Undelivered(uint64 seq, int len, bool is_orig) { tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, is_orig); - // DEBUG_MSG("Undelivered from %d: %d bytes\n", seq, length); + // DEBUG_MSG("Undelivered from %"PRIu64": %d bytes\n", seq, length); HTTP_Message* msg = is_orig ? request_message : reply_message; @@ -1131,7 +1131,7 @@ void HTTP_Analyzer::Undelivered(int seq, int len, bool is_orig) { if ( msg ) msg->SubmitEvent(mime::MIME_EVENT_CONTENT_GAP, - fmt("seq=%d, len=%d", seq, len)); + fmt("seq=%"PRIu64", len=%d", seq, len)); } // Check if the content gap falls completely within a message body diff --git a/src/analyzer/protocol/http/HTTP.h b/src/analyzer/protocol/http/HTTP.h index 48a611b63b..6b44130505 100644 --- a/src/analyzer/protocol/http/HTTP.h +++ b/src/analyzer/protocol/http/HTTP.h @@ -161,7 +161,7 @@ public: HTTP_Analyzer(Connection* conn); ~HTTP_Analyzer(); - void Undelivered(tcp::TCP_Endpoint* sender, int seq, int len); + void Undelivered(tcp::TCP_Endpoint* sender, uint64 seq, int len); void HTTP_Header(int is_orig, mime::MIME_Header* h); void HTTP_EntityData(int is_orig, const BroString* entity_data); @@ -177,7 +177,7 @@ public: // Overriden from Analyzer. virtual void Done(); virtual void DeliverStream(int len, const u_char* data, bool orig); - virtual void Undelivered(int seq, int len, bool orig); + virtual void Undelivered(uint64 seq, int len, bool orig); // Overriden from tcp::TCP_ApplicationAnalyzer virtual void EndpointEOF(bool is_orig); diff --git a/src/analyzer/protocol/icmp/ICMP.cc b/src/analyzer/protocol/icmp/ICMP.cc index 510d3b3a80..393b5536e8 100644 --- a/src/analyzer/protocol/icmp/ICMP.cc +++ b/src/analyzer/protocol/icmp/ICMP.cc @@ -31,7 +31,7 @@ void ICMP_Analyzer::Done() } void ICMP_Analyzer::DeliverPacket(int len, const u_char* data, - bool is_orig, int seq, const IP_Hdr* ip, int caplen) + bool is_orig, uint64 seq, const IP_Hdr* ip, int caplen) { assert(ip); diff --git a/src/analyzer/protocol/icmp/ICMP.h b/src/analyzer/protocol/icmp/ICMP.h index e371f53889..116348cce6 100644 --- a/src/analyzer/protocol/icmp/ICMP.h +++ b/src/analyzer/protocol/icmp/ICMP.h @@ -29,7 +29,7 @@ protected: virtual void Done(); virtual void DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); virtual bool IsReuse(double t, const u_char* pkt); virtual unsigned int MemoryAllocation() const; diff --git a/src/analyzer/protocol/interconn/InterConn.cc b/src/analyzer/protocol/interconn/InterConn.cc index 4b298eaa52..eb529cbb6d 100644 --- a/src/analyzer/protocol/interconn/InterConn.cc +++ b/src/analyzer/protocol/interconn/InterConn.cc @@ -24,7 +24,7 @@ InterConnEndpoint::InterConnEndpoint(tcp::TCP_Endpoint* e) #define NORMAL_LINE_LENGTH 80 -int InterConnEndpoint::DataSent(double t, int seq, int len, int caplen, +int InterConnEndpoint::DataSent(double t, uint64 seq, int len, int caplen, const u_char* data, const IP_Hdr* /* ip */, const struct tcphdr* /* tp */) { @@ -37,8 +37,8 @@ int InterConnEndpoint::DataSent(double t, int seq, int len, int caplen, if ( endp->state == tcp::TCP_ENDPOINT_PARTIAL ) is_partial = 1; - int ack = endp->AckSeq() - endp->StartSeq(); - int top_seq = seq + len; + uint64 ack = endp->ToRelativeSeqSpace(endp->AckSeq(), endp->AckWraps()); + uint64 top_seq = seq + len; if ( top_seq <= ack || top_seq <= max_top_seq ) // There is no new data in this packet @@ -46,7 +46,7 @@ int InterConnEndpoint::DataSent(double t, int seq, int len, int caplen, if ( seq < max_top_seq ) { // Only consider new data - int amount_seen = max_top_seq - seq; + int64 amount_seen = max_top_seq - seq; seq += amount_seen; data += amount_seen; len -= amount_seen; @@ -184,7 +184,7 @@ void InterConn_Analyzer::Init() } void InterConn_Analyzer::DeliverPacket(int len, const u_char* data, - bool is_orig, int seq, const IP_Hdr* ip, int caplen) + bool is_orig, uint64 seq, const IP_Hdr* ip, int caplen) { tcp::TCP_ApplicationAnalyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen); diff --git a/src/analyzer/protocol/interconn/InterConn.h b/src/analyzer/protocol/interconn/InterConn.h index b13abecab1..a485e05082 100644 --- a/src/analyzer/protocol/interconn/InterConn.h +++ b/src/analyzer/protocol/interconn/InterConn.h @@ -13,7 +13,7 @@ class InterConnEndpoint : public BroObj { public: InterConnEndpoint(tcp::TCP_Endpoint* e); - int DataSent(double t, int seq, int len, int caplen, const u_char* data, + int DataSent(double t, uint64 seq, int len, int caplen, const u_char* data, const IP_Hdr* ip, const struct tcphdr* tp); RecordVal* BuildStats(); @@ -25,7 +25,7 @@ protected: tcp::TCP_Endpoint* endp; double last_keystroke_time; - int max_top_seq; + uint64 max_top_seq; uint32 num_pkts; uint32 num_keystrokes_two_in_a_row; uint32 num_normal_interarrivals; @@ -56,7 +56,7 @@ protected: // We support both packet and stream input and can be put in place even // if the TCP analyzer is not yet reassembling. virtual void DeliverPacket(int len, const u_char* data, bool is_orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); virtual void DeliverStream(int len, const u_char* data, bool is_orig); void StatEvent(); diff --git a/src/analyzer/protocol/modbus/Modbus.cc b/src/analyzer/protocol/modbus/Modbus.cc index 9d216d356b..f003ad6cc5 100644 --- a/src/analyzer/protocol/modbus/Modbus.cc +++ b/src/analyzer/protocol/modbus/Modbus.cc @@ -31,7 +31,7 @@ void ModbusTCP_Analyzer::DeliverStream(int len, const u_char* data, bool orig) interp->NewData(orig, data, data + len); } -void ModbusTCP_Analyzer::Undelivered(int seq, int len, bool orig) +void ModbusTCP_Analyzer::Undelivered(uint64 seq, int len, bool orig) { TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); interp->NewGap(orig, len); diff --git a/src/analyzer/protocol/modbus/Modbus.h b/src/analyzer/protocol/modbus/Modbus.h index 6f566be828..41448f69e3 100644 --- a/src/analyzer/protocol/modbus/Modbus.h +++ b/src/analyzer/protocol/modbus/Modbus.h @@ -14,7 +14,7 @@ public: virtual void Done(); virtual void DeliverStream(int len, const u_char* data, bool orig); - virtual void Undelivered(int seq, int len, bool orig); + virtual void Undelivered(uint64 seq, int len, bool orig); virtual void EndpointEOF(bool is_orig); static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) diff --git a/src/analyzer/protocol/ncp/NCP.cc b/src/analyzer/protocol/ncp/NCP.cc index 75b6c9f4be..3858f0b2ad 100644 --- a/src/analyzer/protocol/ncp/NCP.cc +++ b/src/analyzer/protocol/ncp/NCP.cc @@ -211,7 +211,7 @@ void Contents_NCP_Analyzer::DeliverStream(int len, const u_char* data, bool orig } } -void Contents_NCP_Analyzer::Undelivered(int seq, int len, bool orig) +void Contents_NCP_Analyzer::Undelivered(uint64 seq, int len, bool orig) { tcp::TCP_SupportAnalyzer::Undelivered(seq, len, orig); diff --git a/src/analyzer/protocol/ncp/NCP.h b/src/analyzer/protocol/ncp/NCP.h index 34174df74e..2e06babb8c 100644 --- a/src/analyzer/protocol/ncp/NCP.h +++ b/src/analyzer/protocol/ncp/NCP.h @@ -90,7 +90,7 @@ public: protected: virtual void DeliverStream(int len, const u_char* data, bool orig); - virtual void Undelivered(int seq, int len, bool orig); + virtual void Undelivered(uint64 seq, int len, bool orig); NCP_FrameBuffer buffer; NCP_Session* session; diff --git a/src/analyzer/protocol/netbios/NetbiosSSN.cc b/src/analyzer/protocol/netbios/NetbiosSSN.cc index 4d6ed8e1f1..d65a152b2f 100644 --- a/src/analyzer/protocol/netbios/NetbiosSSN.cc +++ b/src/analyzer/protocol/netbios/NetbiosSSN.cc @@ -513,7 +513,7 @@ void NetbiosSSN_Analyzer::ConnectionClosed(tcp::TCP_Endpoint* endpoint, } void NetbiosSSN_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen) + uint64 seq, const IP_Hdr* ip, int caplen) { tcp::TCP_ApplicationAnalyzer::DeliverPacket(len, data, orig, seq, ip, caplen); diff --git a/src/analyzer/protocol/netbios/NetbiosSSN.h b/src/analyzer/protocol/netbios/NetbiosSSN.h index 7c2728ef9a..7fbe967841 100644 --- a/src/analyzer/protocol/netbios/NetbiosSSN.h +++ b/src/analyzer/protocol/netbios/NetbiosSSN.h @@ -146,7 +146,7 @@ public: virtual void Done(); virtual void DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new NetbiosSSN_Analyzer(conn); } diff --git a/src/analyzer/protocol/ntp/NTP.cc b/src/analyzer/protocol/ntp/NTP.cc index b4b63d5634..5778da9a0e 100644 --- a/src/analyzer/protocol/ntp/NTP.cc +++ b/src/analyzer/protocol/ntp/NTP.cc @@ -25,7 +25,7 @@ void NTP_Analyzer::Done() Event(udp_session_done); } -void NTP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, int seq, const IP_Hdr* ip, int caplen) +void NTP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, uint64 seq, const IP_Hdr* ip, int caplen) { Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen); diff --git a/src/analyzer/protocol/ntp/NTP.h b/src/analyzer/protocol/ntp/NTP.h index 201c5a8774..87255fd2e4 100644 --- a/src/analyzer/protocol/ntp/NTP.h +++ b/src/analyzer/protocol/ntp/NTP.h @@ -46,7 +46,7 @@ public: protected: virtual void Done(); virtual void DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); int Request(const u_char* data, int len); int Reply(const u_char* data, int len); diff --git a/src/analyzer/protocol/pia/PIA.cc b/src/analyzer/protocol/pia/PIA.cc index 388d1d501d..24d4565ce1 100644 --- a/src/analyzer/protocol/pia/PIA.cc +++ b/src/analyzer/protocol/pia/PIA.cc @@ -30,7 +30,7 @@ void PIA::ClearBuffer(Buffer* buffer) buffer->size = 0; } -void PIA::AddToBuffer(Buffer* buffer, int seq, int len, const u_char* data, +void PIA::AddToBuffer(Buffer* buffer, uint64 seq, int len, const u_char* data, bool is_orig) { u_char* tmp = 0; @@ -77,7 +77,7 @@ void PIA::PIA_Done() FinishEndpointMatcher(); } -void PIA::PIA_DeliverPacket(int len, const u_char* data, bool is_orig, int seq, +void PIA::PIA_DeliverPacket(int len, const u_char* data, bool is_orig, uint64 seq, const IP_Hdr* ip, int caplen) { if ( pkt_buffer.state == SKIPPING ) @@ -256,7 +256,7 @@ void PIA_TCP::DeliverStream(int len, const u_char* data, bool is_orig) stream_buffer.state = new_state; } -void PIA_TCP::Undelivered(int seq, int len, bool is_orig) +void PIA_TCP::Undelivered(uint64 seq, int len, bool is_orig) { tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, is_orig); @@ -337,8 +337,8 @@ void PIA_TCP::ActivateAnalyzer(analyzer::Tag tag, const Rule* rule) new tcp::TCP_Reassembler(this, tcp, tcp::TCP_Reassembler::Direct, tcp->Resp()); - int orig_seq = 0; - int resp_seq = 0; + uint64 orig_seq = 0; + uint64 resp_seq = 0; for ( DataBlock* b = pkt_buffer.head; b; b = b->next ) { diff --git a/src/analyzer/protocol/pia/PIA.h b/src/analyzer/protocol/pia/PIA.h index d8c272d219..db387769e8 100644 --- a/src/analyzer/protocol/pia/PIA.h +++ b/src/analyzer/protocol/pia/PIA.h @@ -42,7 +42,7 @@ public: protected: void PIA_Done(); void PIA_DeliverPacket(int len, const u_char* data, bool is_orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); enum State { INIT, BUFFERING, MATCHING_ONLY, SKIPPING } state; @@ -52,7 +52,7 @@ protected: const u_char* data; bool is_orig; int len; - int seq; + uint64 seq; DataBlock* next; }; @@ -65,7 +65,7 @@ protected: State state; }; - void AddToBuffer(Buffer* buffer, int seq, int len, + void AddToBuffer(Buffer* buffer, uint64 seq, int len, const u_char* data, bool is_orig); void AddToBuffer(Buffer* buffer, int len, const u_char* data, bool is_orig); @@ -105,7 +105,7 @@ protected: } virtual void DeliverPacket(int len, const u_char* data, bool is_orig, - int seq, const IP_Hdr* ip, int caplen) + uint64 seq, const IP_Hdr* ip, int caplen) { Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen); PIA_DeliverPacket(len, data, is_orig, seq, ip, caplen); @@ -150,14 +150,14 @@ protected: } virtual void DeliverPacket(int len, const u_char* data, bool is_orig, - int seq, const IP_Hdr* ip, int caplen) + uint64 seq, const IP_Hdr* ip, int caplen) { Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen); PIA_DeliverPacket(len, data, is_orig, seq, ip, caplen); } virtual void DeliverStream(int len, const u_char* data, bool is_orig); - virtual void Undelivered(int seq, int len, bool is_orig); + virtual void Undelivered(uint64 seq, int len, bool is_orig); virtual void ActivateAnalyzer(analyzer::Tag tag, const Rule* rule = 0); diff --git a/src/analyzer/protocol/rpc/RPC.cc b/src/analyzer/protocol/rpc/RPC.cc index 1ffc7dd26e..38ed229a10 100644 --- a/src/analyzer/protocol/rpc/RPC.cc +++ b/src/analyzer/protocol/rpc/RPC.cc @@ -399,7 +399,7 @@ Contents_RPC::~Contents_RPC() { } -void Contents_RPC::Undelivered(int seq, int len, bool orig) +void Contents_RPC::Undelivered(uint64 seq, int len, bool orig) { tcp::TCP_SupportAnalyzer::Undelivered(seq, len, orig); NeedResync(); @@ -704,7 +704,7 @@ RPC_Analyzer::~RPC_Analyzer() } void RPC_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen) + uint64 seq, const IP_Hdr* ip, int caplen) { tcp::TCP_ApplicationAnalyzer::DeliverPacket(len, data, orig, seq, ip, caplen); len = min(len, caplen); diff --git a/src/analyzer/protocol/rpc/RPC.h b/src/analyzer/protocol/rpc/RPC.h index a705d272f6..e87f8afa95 100644 --- a/src/analyzer/protocol/rpc/RPC.h +++ b/src/analyzer/protocol/rpc/RPC.h @@ -203,7 +203,7 @@ protected: virtual void Init(); virtual bool CheckResync(int& len, const u_char*& data, bool orig); virtual void DeliverStream(int len, const u_char* data, bool orig); - virtual void Undelivered(int seq, int len, bool orig); + virtual void Undelivered(uint64 seq, int len, bool orig); virtual void NeedResync() { resync_state = NEED_RESYNC; @@ -234,7 +234,7 @@ public: protected: virtual void DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); void ExpireTimer(double t); diff --git a/src/analyzer/protocol/smtp/SMTP.cc b/src/analyzer/protocol/smtp/SMTP.cc index c3fb21b6a4..c0e34ce6f1 100644 --- a/src/analyzer/protocol/smtp/SMTP.cc +++ b/src/analyzer/protocol/smtp/SMTP.cc @@ -76,14 +76,14 @@ void SMTP_Analyzer::Done() EndData(); } -void SMTP_Analyzer::Undelivered(int seq, int len, bool is_orig) +void SMTP_Analyzer::Undelivered(uint64 seq, int len, bool is_orig) { tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, is_orig); if ( len <= 0 ) return; - const char* buf = fmt("seq = %d, len = %d", seq, len); + const char* buf = fmt("seq = %"PRIu64", len = %d", seq, len); int buf_len = strlen(buf); Unexpected(is_orig, "content gap", buf_len, buf); diff --git a/src/analyzer/protocol/smtp/SMTP.h b/src/analyzer/protocol/smtp/SMTP.h index cc12167d30..de9dc346ff 100644 --- a/src/analyzer/protocol/smtp/SMTP.h +++ b/src/analyzer/protocol/smtp/SMTP.h @@ -44,7 +44,7 @@ public: virtual void Done(); virtual void DeliverStream(int len, const u_char* data, bool orig); virtual void ConnectionFinished(int half_finished); - virtual void Undelivered(int seq, int len, bool orig); + virtual void Undelivered(uint64 seq, int len, bool orig); void SkipData() { skip_data = 1; } // skip delivery of data lines diff --git a/src/analyzer/protocol/socks/SOCKS.cc b/src/analyzer/protocol/socks/SOCKS.cc index 76212d822b..e678528f35 100644 --- a/src/analyzer/protocol/socks/SOCKS.cc +++ b/src/analyzer/protocol/socks/SOCKS.cc @@ -86,7 +86,7 @@ void SOCKS_Analyzer::DeliverStream(int len, const u_char* data, bool orig) } } -void SOCKS_Analyzer::Undelivered(int seq, int len, bool orig) +void SOCKS_Analyzer::Undelivered(uint64 seq, int len, bool orig) { tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); interp->NewGap(orig, len); diff --git a/src/analyzer/protocol/socks/SOCKS.h b/src/analyzer/protocol/socks/SOCKS.h index f005967fd8..2c72d507e6 100644 --- a/src/analyzer/protocol/socks/SOCKS.h +++ b/src/analyzer/protocol/socks/SOCKS.h @@ -23,7 +23,7 @@ public: virtual void Done(); virtual void DeliverStream(int len, const u_char* data, bool orig); - virtual void Undelivered(int seq, int len, bool orig); + virtual void Undelivered(uint64 seq, int len, bool orig); virtual void EndpointEOF(bool is_orig); static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) diff --git a/src/analyzer/protocol/ssl/SSL.cc b/src/analyzer/protocol/ssl/SSL.cc index 6cd2fa59f8..5e5d24888a 100644 --- a/src/analyzer/protocol/ssl/SSL.cc +++ b/src/analyzer/protocol/ssl/SSL.cc @@ -57,7 +57,7 @@ void SSL_Analyzer::DeliverStream(int len, const u_char* data, bool orig) } } -void SSL_Analyzer::Undelivered(int seq, int len, bool orig) +void SSL_Analyzer::Undelivered(uint64 seq, int len, bool orig) { tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); had_gap = true; diff --git a/src/analyzer/protocol/ssl/SSL.h b/src/analyzer/protocol/ssl/SSL.h index f674d64fed..7748222dea 100644 --- a/src/analyzer/protocol/ssl/SSL.h +++ b/src/analyzer/protocol/ssl/SSL.h @@ -16,7 +16,7 @@ public: // Overriden from Analyzer. virtual void Done(); virtual void DeliverStream(int len, const u_char* data, bool orig); - virtual void Undelivered(int seq, int len, bool orig); + virtual void Undelivered(uint64 seq, int len, bool orig); // Overriden from tcp::TCP_ApplicationAnalyzer. virtual void EndpointEOF(bool is_orig); diff --git a/src/analyzer/protocol/stepping-stone/SteppingStone.cc b/src/analyzer/protocol/stepping-stone/SteppingStone.cc index 09a7444213..b6473dcf6e 100644 --- a/src/analyzer/protocol/stepping-stone/SteppingStone.cc +++ b/src/analyzer/protocol/stepping-stone/SteppingStone.cc @@ -63,7 +63,7 @@ void SteppingStoneEndpoint::Done() Event(stp_remove_endp, stp_id); } -int SteppingStoneEndpoint::DataSent(double t, int seq, int len, int caplen, +int SteppingStoneEndpoint::DataSent(double t, uint64 seq, int len, int caplen, const u_char* data, const IP_Hdr* /* ip */, const struct tcphdr* tp) { @@ -90,8 +90,8 @@ int SteppingStoneEndpoint::DataSent(double t, int seq, int len, int caplen, break; } - int ack = endp->AckSeq() - endp->StartSeq(); - int top_seq = seq + len; + uint64 ack = endp->ToRelativeSeqSpace(endp->AckSeq(), endp->AckWraps()); + uint64 top_seq = seq + len; if ( top_seq <= ack || top_seq <= stp_max_top_seq ) // There is no new data in this packet @@ -179,7 +179,7 @@ void SteppingStone_Analyzer::Init() } void SteppingStone_Analyzer::DeliverPacket(int len, const u_char* data, - bool is_orig, int seq, + bool is_orig, uint64 seq, const IP_Hdr* ip, int caplen) { tcp::TCP_ApplicationAnalyzer::DeliverPacket(len, data, is_orig, seq, diff --git a/src/analyzer/protocol/stepping-stone/SteppingStone.h b/src/analyzer/protocol/stepping-stone/SteppingStone.h index 1471c08a3b..518cd64a21 100644 --- a/src/analyzer/protocol/stepping-stone/SteppingStone.h +++ b/src/analyzer/protocol/stepping-stone/SteppingStone.h @@ -22,7 +22,7 @@ public: ~SteppingStoneEndpoint(); void Done(); - int DataSent(double t, int seq, int len, int caplen, const u_char* data, + int DataSent(double t, uint64 seq, int len, int caplen, const u_char* data, const IP_Hdr* ip, const struct tcphdr* tp); protected: @@ -30,7 +30,7 @@ protected: void CreateEndpEvent(int is_orig); tcp::TCP_Endpoint* endp; - int stp_max_top_seq; + uint64 stp_max_top_seq; double stp_last_time; double stp_resume_time; SteppingStoneManager* stp_manager; @@ -60,7 +60,7 @@ protected: // We support both packet and stream input and can be put in place even // if the TCP analyzer is not yet reassebmling. virtual void DeliverPacket(int len, const u_char* data, bool is_orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); virtual void DeliverStream(int len, const u_char* data, bool is_orig); int orig_stream_pos; diff --git a/src/analyzer/protocol/syslog/Syslog.cc b/src/analyzer/protocol/syslog/Syslog.cc index 2b783afc64..5e5ce907e6 100644 --- a/src/analyzer/protocol/syslog/Syslog.cc +++ b/src/analyzer/protocol/syslog/Syslog.cc @@ -28,7 +28,7 @@ void Syslog_Analyzer::Done() Event(udp_session_done); } -void Syslog_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen) +void Syslog_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, uint64 seq, const IP_Hdr* ip, int caplen) { Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); interp->NewData(orig, data, data + len); @@ -88,7 +88,7 @@ void Syslog_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, int // interp->NewData(orig, data, data + len); // } -//void Syslog_tcp::TCP_Analyzer::Undelivered(int seq, int len, bool orig) +//void Syslog_tcp::TCP_Analyzer::Undelivered(uint64 seq, int len, bool orig) // { // tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); // interp->NewGap(orig, len); diff --git a/src/analyzer/protocol/syslog/Syslog.h b/src/analyzer/protocol/syslog/Syslog.h index 355863e36e..619ddb39ba 100644 --- a/src/analyzer/protocol/syslog/Syslog.h +++ b/src/analyzer/protocol/syslog/Syslog.h @@ -16,7 +16,7 @@ public: virtual void Done(); virtual void DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new Syslog_Analyzer(conn); } @@ -38,7 +38,7 @@ protected: // // virtual void Done(); // virtual void DeliverStream(int len, const u_char* data, bool orig); -// virtual void Undelivered(int seq, int len, bool orig); +// virtual void Undelivered(uint64 seq, int len, bool orig); // virtual void EndpointEOF(tcp::TCP_Reassembler* endp); // // static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) diff --git a/src/analyzer/protocol/tcp/ContentLine.cc b/src/analyzer/protocol/tcp/ContentLine.cc index 63a3c07f00..72314dd45d 100644 --- a/src/analyzer/protocol/tcp/ContentLine.cc +++ b/src/analyzer/protocol/tcp/ContentLine.cc @@ -109,7 +109,7 @@ void ContentLine_Analyzer::DeliverStream(int len, const u_char* data, seq += len; } -void ContentLine_Analyzer::Undelivered(int seq, int len, bool orig) +void ContentLine_Analyzer::Undelivered(uint64 seq, int len, bool orig) { ForwardUndelivered(seq, len, orig); } diff --git a/src/analyzer/protocol/tcp/ContentLine.h b/src/analyzer/protocol/tcp/ContentLine.h index ecc1347984..93c473c47c 100644 --- a/src/analyzer/protocol/tcp/ContentLine.h +++ b/src/analyzer/protocol/tcp/ContentLine.h @@ -53,14 +53,14 @@ public: void SkipBytesAfterThisLine(int64_t length); void SkipBytes(int64_t length); - bool IsSkippedContents(int64_t seq, int64_t length) + bool IsSkippedContents(uint64_t seq, int64_t length) { return seq + length <= seq_to_skip; } protected: ContentLine_Analyzer(const char* name, Connection* conn, bool orig); virtual void DeliverStream(int len, const u_char* data, bool is_orig); - virtual void Undelivered(int seq, int len, bool orig); + virtual void Undelivered(uint64 seq, int len, bool orig); virtual void EndpointEOF(bool is_orig); class State; @@ -71,19 +71,19 @@ protected: void CheckNUL(); // Returns the sequence number delivered so far. - int64_t SeqDelivered() const { return seq_delivered_in_lines; } + uint64_t SeqDelivered() const { return seq_delivered_in_lines; } u_char* buf; // where we build up the body of the request int offset; // where we are in buf int buf_len; // how big buf is, total unsigned int last_char; // last (non-option) character scanned - int64_t seq; // last seq number - int64_t seq_to_skip; + uint64_t seq; // last seq number + uint64_t seq_to_skip; // Seq delivered up to through NewLine() -- it is adjusted // *before* NewLine() is called. - int64_t seq_delivered_in_lines; + uint64_t seq_delivered_in_lines; // Number of bytes to be skipped after this line. See // comments in SkipBytesAfterThisLine(). diff --git a/src/analyzer/protocol/tcp/TCP.cc b/src/analyzer/protocol/tcp/TCP.cc index c422d01f32..552a73b7ea 100644 --- a/src/analyzer/protocol/tcp/TCP.cc +++ b/src/analyzer/protocol/tcp/TCP.cc @@ -36,1088 +36,8 @@ namespace { // local namespace static const int ORIG = 1; static const int RESP = 2; -TCP_Analyzer::TCP_Analyzer(Connection* conn) -: TransportLayerAnalyzer("TCP", conn) - { - // Set a timer to eventually time out this connection. - ADD_ANALYZER_TIMER(&TCP_Analyzer::ExpireTimer, - network_time + tcp_SYN_timeout, 0, - TIMER_TCP_EXPIRE); - - deferred_gen_event = close_deferred = 0; - - seen_first_ACK = 0; - is_active = 1; - finished = 0; - reassembling = 0; - first_packet_seen = 0; - is_partial = 0; - - orig = new TCP_Endpoint(this, 1); - resp = new TCP_Endpoint(this, 0); - - orig->SetPeer(resp); - resp->SetPeer(orig); - } - -TCP_Analyzer::~TCP_Analyzer() - { - LOOP_OVER_GIVEN_CHILDREN(i, packet_children) - delete *i; - - delete orig; - delete resp; - } - -void TCP_Analyzer::Init() - { - Analyzer::Init(); - LOOP_OVER_GIVEN_CHILDREN(i, packet_children) - (*i)->Init(); - } - -void TCP_Analyzer::Done() - { - Analyzer::Done(); - - if ( connection_pending && is_active && ! BothClosed() ) - Event(connection_pending); - - LOOP_OVER_GIVEN_CHILDREN(i, packet_children) - (*i)->Done(); - - orig->Done(); - resp->Done(); - - finished = 1; - } - -void TCP_Analyzer::EnableReassembly() - { - SetReassembler(new TCP_Reassembler(this, this, - TCP_Reassembler::Forward, orig), - new TCP_Reassembler(this, this, - TCP_Reassembler::Forward, resp)); - - reassembling = 1; - - if ( new_connection_contents ) - Event(new_connection_contents); - } - -void TCP_Analyzer::SetReassembler(TCP_Reassembler* rorig, - TCP_Reassembler* rresp) - { - orig->AddReassembler(rorig); - rorig->SetDstAnalyzer(this); - resp->AddReassembler(rresp); - rresp->SetDstAnalyzer(this); - - reassembling = 1; - - if ( new_connection_contents ) - Event(new_connection_contents); - } - -const struct tcphdr* TCP_Analyzer::ExtractTCP_Header(const u_char*& data, - int& len, int& caplen) - { - const struct tcphdr* tp = (const struct tcphdr*) data; - uint32 tcp_hdr_len = tp->th_off * 4; - - if ( tcp_hdr_len < sizeof(struct tcphdr) ) - { - Weird("bad_TCP_header_len"); - return 0; - } - - if ( tcp_hdr_len > uint32(len) || - sizeof(struct tcphdr) > uint32(caplen) ) - { - // This can happen even with the above test, due to TCP - // options. - Weird("truncated_header"); - return 0; - } - - len -= tcp_hdr_len; // remove TCP header - caplen -= tcp_hdr_len; - data += tcp_hdr_len; - - return tp; - } - -bool TCP_Analyzer::ValidateChecksum(const struct tcphdr* tp, - TCP_Endpoint* endpoint, int len, int caplen) - { - if ( ! ignore_checksums && caplen >= len && - ! endpoint->ValidChecksum(tp, len) ) - { - Weird("bad_TCP_checksum"); - endpoint->CheckHistory(HIST_CORRUPT_PKT, 'C'); - return false; - } - else - return true; - } - -void TCP_Analyzer::CheckFlagCombos(TCP_Flags flags, TCP_Endpoint* endpoint, - uint32 base_seq, int len, int dst_port) - { - bool is_orig = endpoint->IsOrig(); - - if ( is_orig && ! (first_packet_seen & ORIG) ) - is_partial = ! flags.SYN() || flags.ACK(); - - if ( ! is_orig && ! (first_packet_seen & RESP) && ! is_partial ) - is_partial = ! flags.SYN(); - - int bits_set = (flags.SYN() ? 1 : 0) + (flags.FIN() ? 1 : 0) + - (flags.RST() ? 1 : 0); - if ( bits_set > 1 ) - { - if ( flags.FIN() && flags.RST() ) - endpoint->CheckHistory(HIST_FIN_RST_PKT, 'I'); - else - endpoint->CheckHistory(HIST_MULTI_FLAG_PKT, 'Q'); - } - - else if ( bits_set == 1 ) - { - if ( flags.SYN() ) - { - char code = flags.ACK() ? 'H' : 'S'; - - if ( endpoint->CheckHistory(HIST_SYN_PKT, code) && - base_seq != endpoint->hist_last_SYN ) - endpoint->AddHistory(code); - - endpoint->hist_last_SYN = base_seq; - } - - if ( flags.FIN() ) - { - // For FIN's, the sequence number comes at the - // end of (any data in) the packet, not the - // beginning as for SYNs and RSTs. - if ( endpoint->CheckHistory(HIST_FIN_PKT, 'F') && - base_seq + len != endpoint->hist_last_FIN ) - endpoint->AddHistory('F'); - - endpoint->hist_last_FIN = base_seq + len; - } - - if ( flags.RST() ) - { - if ( endpoint->CheckHistory(HIST_RST_PKT, 'R') && - base_seq != endpoint->hist_last_RST ) - endpoint->AddHistory('R'); - - endpoint->hist_last_RST = base_seq; - } - } - - else - { // bits_set == 0 - if ( len ) - endpoint->CheckHistory(HIST_DATA_PKT, 'D'); - - else if ( flags.ACK() ) - endpoint->CheckHistory(HIST_ACK_PKT, 'A'); - } - } - -void TCP_Analyzer::UpdateWindow(TCP_Endpoint* endpoint, unsigned int window, - uint32 base_seq, uint32 ack_seq, - TCP_Flags flags) - { - // Note, the offered window on an initial SYN is unscaled, even - // if the SYN includes scaling, so we need to do the following - // test *before* updating the scaling information below. (Hmmm, - // how does this work for windows on SYN/ACKs? ###) - int scale = endpoint->window_scale; - window = window << scale; - - // Don't analyze window values off of SYNs, they're sometimes - // immediately rescinded. - if ( ! flags.SYN() ) - { - // ### Decide whether to accept new window based on Active - // Mapping policy. - if ( int(base_seq - endpoint->window_seq) >= 0 && - int(ack_seq - endpoint->window_ack_seq) >= 0 ) - { - uint32 new_edge = ack_seq + window; - uint32 old_edge = endpoint->window_ack_seq + endpoint->window; - int advance = new_edge - old_edge; - - if ( advance < 0 ) - { - // A window recision. We don't report these - // for FINs or RSTs, or if the connection - // has already been partially closed, since - // such recisions occur frequently in practice, - // probably as the receiver loses buffer memory - // due to its process going away. - // - // We also, for window scaling, allow a bit - // of slop ###. This is because sometimes - // there will be an apparent recision due - // to the granularity of the scaling. - if ( ! flags.FIN() && ! flags.RST() && - endpoint->state != TCP_ENDPOINT_CLOSED && - endpoint->state != TCP_ENDPOINT_RESET && - (-advance) >= (1 << scale) ) - Weird("window_recision"); - } - - endpoint->window = window; - endpoint->window_ack_seq = ack_seq; - endpoint->window_seq = base_seq; - } - } - } - -void TCP_Analyzer::ProcessSYN(const IP_Hdr* ip, const struct tcphdr* tp, - uint32 tcp_hdr_len, int& seq_len, - TCP_Endpoint* endpoint, TCP_Endpoint* peer, - uint32 base_seq, uint32 ack_seq, - const IPAddr& orig_addr, - int is_orig, TCP_Flags flags) - { - int len = seq_len; - - ++seq_len; // SYN consumes a byte of sequence space - - if ( flags.RST() ) - Weird("TCP_christmas"); - - if ( flags.URG() ) - Weird("baroque_SYN"); - - if ( len > 0 ) - // T/TCP definitely complicates this. - Weird("SYN_with_data"); - - RecordVal* SYN_vals = BuildSYNPacketVal(is_orig, ip, tp)->AsRecordVal(); - - // ### In the following, we could be fooled by an - // inconsistent SYN retransmission. Where's a normalizer - // when you need one? - - // ### We know that field 5 is the window scaling .... - int scale = int(SYN_vals->Lookup(5)->CoerceToInt()); - - if ( scale < 0 ) - { // no window scaling option - if ( flags.ACK() ) - { // window scaling not negotiated - endpoint->window_scale = 0; - peer->window_scale = 0; - } - else - // We're not offering window scaling. - // Ideally, we'd remember this fact so that - // if the SYN/ACK *does* include window - // scaling, we know it won't be negotiated. - // But it's a pain to track that, and hard - // to see how an adversarial responder could - // use it to evade. Also, if we *do* want - // to track it, we could do so using - // connection_SYN_packet. - endpoint->window_scale = 0; - } - else - { - endpoint->window_scale = scale; - endpoint->window_seq = base_seq; - endpoint->window_ack_seq = ack_seq; - - peer->window_seq = ack_seq; - peer->window_ack_seq = base_seq; - } - - if ( connection_SYN_packet ) - { - val_list* vl = new val_list; - vl->append(BuildConnVal()); - vl->append(SYN_vals); - ConnectionEvent(connection_SYN_packet, vl); - } - else - Unref(SYN_vals); - - // Passive fingerprinting. - // - // is_orig will be removed once we can do SYN-ACK fingerprinting. - if ( OS_version_found && is_orig ) - { - AddrVal src_addr_val(orig_addr); - if ( generate_OS_version_event->Size() == 0 || - generate_OS_version_event->Lookup(&src_addr_val) ) - { - RecordVal* OS_val = - BuildOSVal(is_orig, ip, tp, tcp_hdr_len); - if ( OS_val ) - { // found new OS version - val_list* vl = new val_list; - vl->append(BuildConnVal()); - vl->append(new AddrVal(orig_addr)); - vl->append(OS_val); - ConnectionEvent(OS_version_found, vl); - } - } - } - } - -void TCP_Analyzer::ProcessFIN(double t, TCP_Endpoint* endpoint, - int& seq_len, uint32 base_seq) - { - ++seq_len; // FIN consumes a byte of sequence space. - ++endpoint->FIN_cnt; // remember that we've seen a FIN - - if ( t < endpoint->last_time + tcp_storm_interarrival_thresh && - endpoint->FIN_cnt == tcp_storm_thresh ) - Weird("FIN_storm"); - - // Remember the relative seq in FIN_seq. - endpoint->FIN_seq = base_seq - endpoint->StartSeq() + seq_len; - } - -void TCP_Analyzer::ProcessRST(double t, TCP_Endpoint* endpoint, - const IP_Hdr* ip, uint32 base_seq, - int len, int& seq_len) - { - if ( t < endpoint->last_time + tcp_storm_interarrival_thresh && - ++endpoint->RST_cnt == tcp_storm_thresh ) - Weird("RST_storm"); - - else if ( endpoint->RST_cnt == 0 ) - ++endpoint->RST_cnt; // Remember we've seen a RST - - if ( len > 0 ) - { - // This now happens often enough that it's - // not in the least interesting. - // Weird("RST_with_data"); - - // Don't include the data in the computation of - // the sequence space for this connection, as - // it's not in fact part of the TCP stream. - seq_len = 0; - } - - PacketWithRST(); - } - -void TCP_Analyzer::ProcessFlags(double t, - const IP_Hdr* ip, const struct tcphdr* tp, - uint32 tcp_hdr_len, int len, int& seq_len, - TCP_Endpoint* endpoint, TCP_Endpoint* peer, - uint32 base_seq, uint32 ack_seq, - const IPAddr& orig_addr, - int is_orig, TCP_Flags flags) - { - if ( flags.SYN() ) - ProcessSYN(ip, tp, tcp_hdr_len, seq_len, endpoint, peer, - base_seq, ack_seq, orig_addr, is_orig, flags); - - if ( flags.FIN() ) - ProcessFIN(t, endpoint, seq_len, base_seq); - - if ( flags.RST() ) - ProcessRST(t, endpoint, ip, base_seq, len, seq_len); - - if ( flags.ACK() ) - ProcessACK(endpoint, peer, ack_seq, is_orig, flags); - } - -void TCP_Analyzer::TransitionFromInactive(double t, TCP_Endpoint* endpoint, - uint32 base_seq, - uint32 last_seq, int SYN) - { - if ( SYN ) - { - // ## endpoint->AckSeq() = endpoint->start_seq = base_seq; - endpoint->InitAckSeq(base_seq); - endpoint->InitStartSeq(base_seq); - } - else - { - // This is a partial connection - set up the - // initial sequence numbers as though we saw - // a SYN, to keep the relative byte numbering - // consistent. - // ## endpoint->AckSeq() = endpoint->start_seq = base_seq - 1; - endpoint->InitAckSeq(base_seq - 1); - endpoint->InitStartSeq(base_seq - 1); - } - - // ## endpoint->last_seq = last_seq; - endpoint->InitLastSeq(last_seq); - endpoint->start_time = t; - } - -int TCP_Analyzer::UpdateLastSeq(TCP_Endpoint* endpoint, uint32 last_seq, - TCP_Flags flags) - { - int delta_last = seq_delta(last_seq, endpoint->LastSeq()); - - if ( (flags.SYN() || flags.RST()) && - (delta_last > TOO_LARGE_SEQ_DELTA || - delta_last < -TOO_LARGE_SEQ_DELTA) ) - // ### perhaps trust RST seq #'s if initial and not too - // outlandish, but not if they're coming after the other - // side has sent a FIN - trust the FIN ack instead - ; - - else if ( flags.FIN() && - endpoint->LastSeq() == endpoint->StartSeq() + 1 ) - // Update last_seq based on the FIN even if delta_last < 0. - // This is to accommodate > 2 GB connections for which - // we've only seen the SYN and the FIN (hence the check - // for last_seq == start_seq + 1). - endpoint->UpdateLastSeq(last_seq); - - else if ( endpoint->state == TCP_ENDPOINT_RESET ) - // don't trust any subsequent sequence numbers - ; - - else if ( delta_last > 0 ) - // ### check for large jumps here. - // ## endpoint->last_seq = last_seq; - endpoint->UpdateLastSeq(last_seq); - - else if ( delta_last <= 0 ) - { // ### ++retransmit, unless this is a pure ack - } - - return delta_last; - } - -void TCP_Analyzer::ProcessACK(TCP_Endpoint* endpoint, TCP_Endpoint* peer, - uint32 ack_seq, int is_orig, - TCP_Flags flags) - { - if ( is_orig && ! seen_first_ACK && - (endpoint->state == TCP_ENDPOINT_ESTABLISHED || - endpoint->state == TCP_ENDPOINT_SYN_SENT) ) - { - seen_first_ACK = 1; - Event(connection_first_ACK); - } - - if ( peer->state == TCP_ENDPOINT_INACTIVE ) - { - if ( ! flags.SYN() && ! flags.FIN() && ! flags.RST() ) - { - if ( endpoint->state == TCP_ENDPOINT_SYN_SENT || - endpoint->state == TCP_ENDPOINT_SYN_ACK_SENT || - endpoint->state == TCP_ENDPOINT_ESTABLISHED ) - { - // We've already sent a SYN, but that - // hasn't roused the other end, yet we're - // ack'ing their data. - - if ( ! Conn()->DidWeird() ) - Weird("possible_split_routing"); - } - } - - // Start the sequence numbering as if there was an initial - // SYN, so the relative numbering of subsequent data packets - // stays consistent. - // ## peer->start_seq = peer->AckSeq() = peer->last_seq = - // ## ack_seq - 1; - peer->InitStartSeq(ack_seq - 1); - peer->InitAckSeq(ack_seq - 1); - peer->InitLastSeq(ack_seq - 1); - } - - else if ( ! flags.RST() ) - { // don't trust ack's in RST packets - int delta_ack = seq_delta(ack_seq, peer->AckSeq()); - if ( ack_seq == 0 && delta_ack > TOO_LARGE_SEQ_DELTA ) - // More likely that this is a broken ack than a - // large connection that happens to land on 0 in the - // sequence space. - ; - - else if ( delta_ack > 0 ) - peer->UpdateAckSeq(ack_seq); - } - - peer->AckReceived(ack_seq - peer->StartSeq()); - } - -void TCP_Analyzer::UpdateInactiveState(double t, - TCP_Endpoint* endpoint, TCP_Endpoint* peer, - uint32 base_seq, uint32 ack_seq, - int len, int is_orig, TCP_Flags flags, - int& do_close, int& gen_event) - { - if ( flags.SYN() ) - { - if ( is_orig ) - { - if ( flags.ACK() ) - { - Weird("connection_originator_SYN_ack"); - endpoint->SetState(TCP_ENDPOINT_SYN_ACK_SENT); - } - else - endpoint->SetState(TCP_ENDPOINT_SYN_SENT); - - if ( tcp_attempt_delay ) - ADD_ANALYZER_TIMER(&TCP_Analyzer::AttemptTimer, - t + tcp_attempt_delay, 1, - TIMER_TCP_ATTEMPT); - } - else - { - if ( flags.ACK() ) - { - if ( peer->state != TCP_ENDPOINT_INACTIVE && - peer->state != TCP_ENDPOINT_PARTIAL && - ! seq_between(ack_seq, peer->StartSeq(), peer->LastSeq()) ) - Weird("bad_SYN_ack"); - } - - else if ( peer->state == TCP_ENDPOINT_SYN_ACK_SENT && - base_seq == endpoint->StartSeq() ) - { - // This is a SYN/SYN-ACK reversal, - // per the discussion in IsReuse. - // Flip the endpoints and establish - // the connection. - is_partial = 0; - Conn()->FlipRoles(); - peer->SetState(TCP_ENDPOINT_ESTABLISHED); - } - - else - Weird("simultaneous_open"); - - if ( peer->state == TCP_ENDPOINT_SYN_SENT ) - peer->SetState(TCP_ENDPOINT_ESTABLISHED); - else if ( peer->state == TCP_ENDPOINT_INACTIVE ) - { - // If we were to ignore SYNs and - // only instantiate state on SYN - // acks, then we'd do: - // peer->SetState(TCP_ENDPOINT_ESTABLISHED); - // here. - Weird("unsolicited_SYN_response"); - } - - endpoint->SetState(TCP_ENDPOINT_ESTABLISHED); - - if ( peer->state != TCP_ENDPOINT_PARTIAL ) - { - Event(connection_established); - Conn()->EnableStatusUpdateTimer(); - } - } - } - - if ( flags.FIN() ) - { - endpoint->SetState(TCP_ENDPOINT_CLOSED); - do_close = gen_event = 1; - if ( peer->state != TCP_ENDPOINT_PARTIAL && ! flags.SYN() ) - Weird("spontaneous_FIN"); - } - - if ( flags.RST() ) - { - endpoint->SetState(TCP_ENDPOINT_RESET); - - int is_reject = 0; - - if ( is_orig ) - { - // If our peer is established then we saw - // a SYN-ack but not SYN - so a reverse - // scan, and we should treat this as a - // reject. - if ( peer->state == TCP_ENDPOINT_ESTABLISHED ) - is_reject = 1; - } - - else if ( peer->state == TCP_ENDPOINT_SYN_SENT || - peer->state == TCP_ENDPOINT_SYN_ACK_SENT ) - // We're rejecting an initial SYN. - is_reject = 1; - - do_close = 1; - gen_event = ! is_reject; - - if ( is_reject ) - Event(connection_rejected); - - else if ( peer->state == TCP_ENDPOINT_INACTIVE ) - Weird("spontaneous_RST"); - } - - if ( endpoint->state == TCP_ENDPOINT_INACTIVE ) - { // No control flags to change the state. - if ( ! is_orig && len == 0 && - orig->state == TCP_ENDPOINT_SYN_SENT ) - // Some eccentric TCP's will ack an initial - // SYN prior to sending a SYN reply (hello, - // ftp.microsoft.com). For those, don't - // consider the ack as forming a partial - // connection. - ; - else - { - endpoint->SetState(TCP_ENDPOINT_PARTIAL); - Conn()->EnableStatusUpdateTimer(); - - if ( peer->state == TCP_ENDPOINT_PARTIAL ) - // We've seen both sides of a partial - // connection, report it. - Event(partial_connection); - } - } - } - -void TCP_Analyzer::UpdateSYN_SentState(double t, - TCP_Endpoint* endpoint, TCP_Endpoint* peer, - uint32 base_seq, uint32 last_seq, - int len, int is_orig, TCP_Flags flags, - int& do_close, int& gen_event) - { - if ( flags.SYN() ) - { - if ( is_orig ) - { - if ( flags.ACK() && ! flags.FIN() && ! flags.RST() && - endpoint->state != TCP_ENDPOINT_SYN_ACK_SENT ) - Weird("repeated_SYN_with_ack"); - } - else - { - if ( ! flags.ACK() && - endpoint->state != TCP_ENDPOINT_SYN_SENT ) - Weird("repeated_SYN_reply_wo_ack"); - } - - if ( base_seq != endpoint->StartSeq() ) - { - Weird("SYN_seq_jump"); - // ## endpoint->AckSeq() = endpoint->start_seq = base_seq; - // ## endpoint->last_seq = last_seq; - endpoint->InitStartSeq(base_seq); - endpoint->InitAckSeq(base_seq); - endpoint->InitLastSeq(last_seq); - } - } - - if ( flags.FIN() ) - { - if ( peer->state == TCP_ENDPOINT_INACTIVE || - peer->state == TCP_ENDPOINT_SYN_SENT ) - Weird("inappropriate_FIN"); - - endpoint->SetState(TCP_ENDPOINT_CLOSED); - do_close = gen_event = 1; - } - - if ( flags.RST() ) - { - endpoint->SetState(TCP_ENDPOINT_RESET); - ConnectionReset(); - do_close = 1; - } - - else if ( len > 0 ) - Weird("data_before_established"); - } - -void TCP_Analyzer::UpdateEstablishedState(double t, - TCP_Endpoint* endpoint, TCP_Endpoint* peer, - uint32 base_seq, uint32 last_seq, - int is_orig, TCP_Flags flags, - int& do_close, int& gen_event) - { - if ( flags.SYN() ) - { - if ( endpoint->state == TCP_ENDPOINT_PARTIAL && - peer->state == TCP_ENDPOINT_INACTIVE && ! flags.ACK() ) - { - Weird("SYN_after_partial"); - endpoint->SetState(TCP_ENDPOINT_SYN_SENT); - } - - if ( endpoint->Size() > 0 ) - Weird("SYN_inside_connection"); - - if ( base_seq != endpoint->StartSeq() ) - Weird("SYN_seq_jump"); - - // Make a guess that somehow the connection didn't - // get established, and this SYN will be the - // one that actually sets it up. - // ## endpoint->AckSeq() = endpoint->start_seq = base_seq; - // ## endpoint->last_seq = last_seq; - endpoint->InitStartSeq(base_seq); - endpoint->InitAckSeq(base_seq); - endpoint->InitLastSeq(last_seq); - } - - if ( flags.FIN() && ! flags.RST() ) // ### - { // should check sequence/ack numbers here ### - endpoint->SetState(TCP_ENDPOINT_CLOSED); - - if ( peer->state == TCP_ENDPOINT_RESET && - peer->prev_state == TCP_ENDPOINT_CLOSED ) - // The peer sent a FIN followed by a RST. - // Turn it back into CLOSED state, because - // this was actually normal termination. - peer->SetState(TCP_ENDPOINT_CLOSED); - - do_close = gen_event = 1; - } - - if ( flags.RST() ) - { - endpoint->SetState(TCP_ENDPOINT_RESET); - do_close = 1; - - if ( peer->state != TCP_ENDPOINT_RESET || - peer->prev_state != TCP_ENDPOINT_ESTABLISHED ) - ConnectionReset(); - } - } - -void TCP_Analyzer::UpdateClosedState(double t, TCP_Endpoint* endpoint, - int delta_last, TCP_Flags flags, int& do_close) - { - if ( flags.SYN() ) - Weird("SYN_after_close"); - - if ( flags.FIN() && delta_last > 0 ) - // Probably should also complain on FIN recision. - // That requires an extra state variable to avoid - // generating slews of weird's when a TCP gets - // seriously confused (this from experience). - Weird("FIN_advanced_last_seq"); - - // Previously, our state was CLOSED, since we sent a FIN. - // If our peer was also closed, then don't change our state - // now on a RST, since this connection has already seen a FIN - // exchange. - if ( flags.RST() && endpoint->peer->state != TCP_ENDPOINT_CLOSED ) - { - endpoint->SetState(TCP_ENDPOINT_RESET); - - if ( ! endpoint->did_close ) - // RST after FIN. - do_close = 1; - - if ( connection_reset ) - ADD_ANALYZER_TIMER(&TCP_Analyzer::ResetTimer, - t + tcp_reset_delay, 1, - TIMER_TCP_RESET); - } - } - -void TCP_Analyzer::UpdateResetState(int len, TCP_Flags flags, - TCP_Endpoint* endpoint, uint32 base_seq, - uint32 last_seq) - { - if ( flags.SYN() ) - { - Weird("SYN_after_reset"); - - if ( endpoint->prev_state == TCP_ENDPOINT_INACTIVE ) - { - // Seq. numbers were initialized by a RST packet from this endpoint, - // but now that a SYN is seen from it, that could mean the earlier - // RST was spoofed/injected, so re-initialize. This mostly just - // helps prevent misrepresentations of payload sizes that are based - // on bad initial sequence values. - endpoint->InitStartSeq(base_seq); - endpoint->InitAckSeq(base_seq); - endpoint->InitLastSeq(last_seq); - } - } - - if ( flags.FIN() ) - Weird("FIN_after_reset"); - - if ( len > 0 && ! flags.RST() ) - Weird("data_after_reset"); - } - -void TCP_Analyzer::UpdateStateMachine(double t, - TCP_Endpoint* endpoint, TCP_Endpoint* peer, - uint32 base_seq, uint32 ack_seq, uint32 last_seq, - int len, int delta_last, int is_orig, TCP_Flags flags, - int& do_close, int& gen_event) - { - do_close = 0; // whether to report the connection as closed - gen_event = 0; // if so, whether to generate an event - - switch ( endpoint->state ) { - - case TCP_ENDPOINT_INACTIVE: - UpdateInactiveState(t, endpoint, peer, base_seq, ack_seq, - len, is_orig, flags, - do_close, gen_event); - break; - - case TCP_ENDPOINT_SYN_SENT: - case TCP_ENDPOINT_SYN_ACK_SENT: - UpdateSYN_SentState(t, endpoint, peer, base_seq, last_seq, - len, is_orig, flags, - do_close, gen_event); - break; - - case TCP_ENDPOINT_ESTABLISHED: - case TCP_ENDPOINT_PARTIAL: - UpdateEstablishedState(t, endpoint, peer, base_seq, last_seq, - is_orig, flags, do_close, gen_event); - break; - - case TCP_ENDPOINT_CLOSED: - UpdateClosedState(t, endpoint, delta_last, flags, do_close); - break; - - case TCP_ENDPOINT_RESET: - UpdateResetState(len, flags, endpoint, base_seq, last_seq); - break; - } - } - -void TCP_Analyzer::GeneratePacketEvent(TCP_Endpoint* endpoint, - TCP_Endpoint* peer, - uint32 base_seq, uint32 ack_seq, - const u_char* data, int len, int caplen, - int is_orig, TCP_Flags flags) - { - char tcp_flags[256]; - int tcp_flag_len = 0; - - if ( flags.SYN() ) tcp_flags[tcp_flag_len++] = 'S'; - if ( flags.FIN() ) tcp_flags[tcp_flag_len++] = 'F'; - if ( flags.RST() ) tcp_flags[tcp_flag_len++] = 'R'; - if ( flags.ACK() ) tcp_flags[tcp_flag_len++] = 'A'; - if ( flags.PUSH() ) tcp_flags[tcp_flag_len++] = 'P'; - if ( flags.URG() ) tcp_flags[tcp_flag_len++] = 'U'; - - tcp_flags[tcp_flag_len] = '\0'; - - val_list* vl = new val_list(); - - vl->append(BuildConnVal()); - vl->append(new Val(is_orig, TYPE_BOOL)); - vl->append(new StringVal(tcp_flags)); - vl->append(new Val(base_seq - endpoint->StartSeq(), TYPE_COUNT)); - vl->append(new Val(flags.ACK() ? - ack_seq - peer->StartSeq() : 0, TYPE_COUNT)); - vl->append(new Val(len, TYPE_COUNT)); - - // We need the min() here because Ethernet padding can lead to - // caplen > len. - vl->append(new StringVal(min(caplen, len), (const char*) data)); - - ConnectionEvent(tcp_packet, vl); - } - -int TCP_Analyzer::DeliverData(double t, const u_char* data, int len, int caplen, - const IP_Hdr* ip, const struct tcphdr* tp, - TCP_Endpoint* endpoint, uint32 base_seq, - int is_orig, TCP_Flags flags) - { - int data_seq = base_seq - endpoint->StartSeq(); - if ( flags.SYN() ) - ++data_seq; // skip over SYN octet - - int need_contents = endpoint->DataSent(t, data_seq, - len, caplen, data, ip, tp); - - return need_contents; - } - -void TCP_Analyzer::CheckRecording(int need_contents, TCP_Flags flags) - { - bool record_current_content = need_contents || Conn()->RecordContents(); - bool record_current_packet = - Conn()->RecordPackets() || - flags.SYN() || flags.FIN() || flags.RST(); - - Conn()->SetRecordCurrentContent(record_current_content); - Conn()->SetRecordCurrentPacket(record_current_packet); - } - -void TCP_Analyzer::CheckPIA_FirstPacket(int is_orig, const IP_Hdr* ip) - { - if ( is_orig && ! (first_packet_seen & ORIG) ) - { - pia::PIA_TCP* pia = static_cast(Conn()->GetPrimaryPIA()); - if ( pia ) - pia->FirstPacket(is_orig, ip); - first_packet_seen |= ORIG; - } - - if ( ! is_orig && ! (first_packet_seen & RESP) ) - { - pia::PIA_TCP* pia = static_cast(Conn()->GetPrimaryPIA()); - if ( pia ) - pia->FirstPacket(is_orig, ip); - first_packet_seen |= RESP; - } - } - -void TCP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, - int seq, const IP_Hdr* ip, int caplen) - { - TransportLayerAnalyzer::DeliverPacket(len, data, orig, seq, ip, caplen); - - const struct tcphdr* tp = ExtractTCP_Header(data, len, caplen); - if ( ! tp ) - return; - - // We need the min() here because Ethernet frame padding can lead to - // caplen > len. - if ( packet_contents ) - PacketContents(data, min(len, caplen)); - - TCP_Endpoint* endpoint = is_orig ? orig : resp; - TCP_Endpoint* peer = endpoint->peer; - - if ( ! ValidateChecksum(tp, endpoint, len, caplen) ) - return; - - TCP_Flags flags(tp); - - uint32 base_seq = ntohl(tp->th_seq); - uint32 ack_seq = ntohl(tp->th_ack); - - CheckFlagCombos(flags, endpoint, base_seq, len, ntohs(tp->th_dport)); - - UpdateWindow(endpoint, ntohs(tp->th_win), base_seq, ack_seq, flags); - - double t = current_timestamp; - - if ( ! orig->did_close || ! resp->did_close ) - Conn()->SetLastTime(t); - - const IPAddr orig_addr = Conn()->OrigAddr(); - - uint32 tcp_hdr_len = data - (const u_char*) tp; - - int seq_len = len; // length in terms of sequence space - - ProcessFlags(t, ip, tp, tcp_hdr_len, len, seq_len, endpoint, peer, base_seq, - ack_seq, orig_addr, is_orig, flags); - - uint32 last_seq = base_seq + seq_len; - - if ( endpoint->state == TCP_ENDPOINT_INACTIVE ) - TransitionFromInactive(t, endpoint, base_seq, last_seq, - flags.SYN()); - - int delta_last = UpdateLastSeq(endpoint, last_seq, flags); - - endpoint->last_time = t; - - int do_close; - int gen_event; - UpdateStateMachine(t, endpoint, peer, base_seq, ack_seq, last_seq, - len, delta_last, is_orig, flags, - do_close, gen_event); - - if ( tcp_packet ) - GeneratePacketEvent(endpoint, peer, base_seq, ack_seq, - data, len, caplen, is_orig, flags); - - if ( tcp_option && tcp_hdr_len > sizeof(*tp) && - tcp_hdr_len <= uint32(caplen) ) - ParseTCPOptions(tp, TCPOptionEvent, this, is_orig, 0); - - if ( DEBUG_tcp_data_sent ) - { - DEBUG_MSG("%.6f before DataSent: len=%d caplen=%d skip=%d\n", - network_time, len, caplen, Skipping()); - } - - int need_contents = 0; - if ( len > 0 && (caplen >= len || packet_children.size()) && - ! flags.RST() && ! Skipping() ) - need_contents = DeliverData(t, data, len, caplen, ip, tp, - endpoint, base_seq, - is_orig, flags); - - endpoint->CheckEOF(); - - if ( do_close ) - { - // We need to postpone doing this until after we process - // DataSent, so we don't generate a connection_finished event - // until after data perhaps included with the FIN is processed. - ConnectionClosed(endpoint, peer, gen_event); - } - - CheckRecording(need_contents, flags); - - // Handle child_packet analyzers. Note: This happens *after* the - // packet has been processed and the TCP state updated. - LOOP_OVER_GIVEN_CHILDREN(i, packet_children) - (*i)->NextPacket(len, data, is_orig, - base_seq - endpoint->StartSeq(), ip, caplen); - - if ( ! reassembling ) - ForwardPacket(len, data, is_orig, - base_seq - endpoint->StartSeq(), ip, caplen); - - CheckPIA_FirstPacket(is_orig, ip); - } - -void TCP_Analyzer::DeliverStream(int len, const u_char* data, bool orig) - { - Analyzer::DeliverStream(len, data, orig); - } - -void TCP_Analyzer::Undelivered(int seq, int len, bool is_orig) - { - Analyzer::Undelivered(seq, len, orig); - } - -void TCP_Analyzer::FlipRoles() - { - Analyzer::FlipRoles(); - - sessions->tcp_stats.FlipState(orig->state, resp->state); - TCP_Endpoint* tmp_ep = resp; - resp = orig; - orig = tmp_ep; - orig->is_orig = !orig->is_orig; - resp->is_orig = !resp->is_orig; - } - -void TCP_Analyzer::UpdateConnVal(RecordVal *conn_val) - { - RecordVal *orig_endp_val = conn_val->Lookup("orig")->AsRecordVal(); - RecordVal *resp_endp_val = conn_val->Lookup("resp")->AsRecordVal(); - - orig_endp_val->Assign(0, new Val(orig->Size(), TYPE_COUNT)); - orig_endp_val->Assign(1, new Val(int(orig->state), TYPE_COUNT)); - resp_endp_val->Assign(0, new Val(resp->Size(), TYPE_COUNT)); - resp_endp_val->Assign(1, new Val(int(resp->state), TYPE_COUNT)); - - // Call children's UpdateConnVal - Analyzer::UpdateConnVal(conn_val); - - // Have to do packet_children ourselves. - LOOP_OVER_GIVEN_CHILDREN(i, packet_children) - (*i)->UpdateConnVal(conn_val); - } - -Val* TCP_Analyzer::BuildSYNPacketVal(int is_orig, const IP_Hdr* ip, - const struct tcphdr* tcp) +static RecordVal* build_syn_packet_val(int is_orig, const IP_Hdr* ip, + const struct tcphdr* tcp) { int winscale = -1; int MSS = 0; @@ -1195,8 +115,8 @@ Val* TCP_Analyzer::BuildSYNPacketVal(int is_orig, const IP_Hdr* ip, return v; } -RecordVal* TCP_Analyzer::BuildOSVal(int is_orig, const IP_Hdr* ip, - const struct tcphdr* tcp, uint32 tcp_hdr_len) +static RecordVal* build_os_val(int is_orig, const IP_Hdr* ip, + const struct tcphdr* tcp, uint32 tcp_hdr_len) { if ( ! is_orig ) // Later we might use SYN-ACK fingerprinting here. @@ -1361,6 +281,1134 @@ RecordVal* TCP_Analyzer::BuildOSVal(int is_orig, const IP_Hdr* ip, return 0; } + +static void passive_fingerprint(TCP_Analyzer* tcp, bool is_orig, + const IP_Hdr* ip, const struct tcphdr* tp, + uint32 tcp_hdr_len) + { + // is_orig will be removed once we can do SYN-ACK fingerprinting + if ( OS_version_found && is_orig ) + { + const IPAddr& orig_addr = tcp->Conn()->OrigAddr(); + AddrVal* src_addr_val = new AddrVal(orig_addr); + + if ( generate_OS_version_event->Size() == 0 || + generate_OS_version_event->Lookup(src_addr_val) ) + { + RecordVal* OS_val = build_os_val(is_orig, ip, tp, tcp_hdr_len); + + if ( OS_val ) + { // found new OS version + val_list* vl = new val_list; + vl->append(tcp->BuildConnVal()); + vl->append(src_addr_val->Ref()); + vl->append(OS_val); + tcp->ConnectionEvent(OS_version_found, vl); + } + } + + Unref(src_addr_val); + } + } + +TCP_Analyzer::TCP_Analyzer(Connection* conn) +: TransportLayerAnalyzer("TCP", conn) + { + // Set a timer to eventually time out this connection. + ADD_ANALYZER_TIMER(&TCP_Analyzer::ExpireTimer, + network_time + tcp_SYN_timeout, 0, + TIMER_TCP_EXPIRE); + + deferred_gen_event = close_deferred = 0; + + seen_first_ACK = 0; + is_active = 1; + finished = 0; + reassembling = 0; + first_packet_seen = 0; + is_partial = 0; + + orig = new TCP_Endpoint(this, 1); + resp = new TCP_Endpoint(this, 0); + + orig->SetPeer(resp); + resp->SetPeer(orig); + } + +TCP_Analyzer::~TCP_Analyzer() + { + LOOP_OVER_GIVEN_CHILDREN(i, packet_children) + delete *i; + + delete orig; + delete resp; + } + +void TCP_Analyzer::Init() + { + Analyzer::Init(); + LOOP_OVER_GIVEN_CHILDREN(i, packet_children) + (*i)->Init(); + } + +void TCP_Analyzer::Done() + { + Analyzer::Done(); + + if ( connection_pending && is_active && ! BothClosed() ) + Event(connection_pending); + + LOOP_OVER_GIVEN_CHILDREN(i, packet_children) + (*i)->Done(); + + orig->Done(); + resp->Done(); + + finished = 1; + } + +void TCP_Analyzer::EnableReassembly() + { + SetReassembler(new TCP_Reassembler(this, this, + TCP_Reassembler::Forward, orig), + new TCP_Reassembler(this, this, + TCP_Reassembler::Forward, resp)); + + reassembling = 1; + + if ( new_connection_contents ) + Event(new_connection_contents); + } + +void TCP_Analyzer::SetReassembler(TCP_Reassembler* rorig, + TCP_Reassembler* rresp) + { + orig->AddReassembler(rorig); + rorig->SetDstAnalyzer(this); + resp->AddReassembler(rresp); + rresp->SetDstAnalyzer(this); + + reassembling = 1; + + if ( new_connection_contents ) + Event(new_connection_contents); + } + +const struct tcphdr* TCP_Analyzer::ExtractTCP_Header(const u_char*& data, + int& len, int& caplen) + { + const struct tcphdr* tp = (const struct tcphdr*) data; + uint32 tcp_hdr_len = tp->th_off * 4; + + if ( tcp_hdr_len < sizeof(struct tcphdr) ) + { + Weird("bad_TCP_header_len"); + return 0; + } + + if ( tcp_hdr_len > uint32(len) || + sizeof(struct tcphdr) > uint32(caplen) ) + { + // This can happen even with the above test, due to TCP + // options. + Weird("truncated_header"); + return 0; + } + + len -= tcp_hdr_len; // remove TCP header + caplen -= tcp_hdr_len; + data += tcp_hdr_len; + + return tp; + } + +bool TCP_Analyzer::ValidateChecksum(const struct tcphdr* tp, + TCP_Endpoint* endpoint, int len, int caplen) + { + if ( ! ignore_checksums && caplen >= len && + ! endpoint->ValidChecksum(tp, len) ) + { + Weird("bad_TCP_checksum"); + endpoint->CheckHistory(HIST_CORRUPT_PKT, 'C'); + return false; + } + else + return true; + } + +void TCP_Analyzer::SetPartialStatus(TCP_Flags flags, bool is_orig) + { + if ( is_orig ) + { + if ( ! (first_packet_seen & ORIG) ) + is_partial = ! flags.SYN() || flags.ACK(); + } + else + { + if ( ! (first_packet_seen & RESP) && ! is_partial ) + is_partial = ! flags.SYN(); + } + } + +static void update_history(TCP_Flags flags, TCP_Endpoint* endpoint, + uint64 rel_seq, int len) + { + int bits_set = (flags.SYN() ? 1 : 0) + (flags.FIN() ? 1 : 0) + + (flags.RST() ? 1 : 0); + if ( bits_set > 1 ) + { + if ( flags.FIN() && flags.RST() ) + endpoint->CheckHistory(HIST_FIN_RST_PKT, 'I'); + else + endpoint->CheckHistory(HIST_MULTI_FLAG_PKT, 'Q'); + } + + else if ( bits_set == 1 ) + { + if ( flags.SYN() ) + { + char code = flags.ACK() ? 'H' : 'S'; + + if ( endpoint->CheckHistory(HIST_SYN_PKT, code) && + rel_seq != endpoint->hist_last_SYN ) + endpoint->AddHistory(code); + + endpoint->hist_last_SYN = rel_seq; + } + + if ( flags.FIN() ) + { + // For FIN's, the sequence number comes at the + // end of (any data in) the packet, not the + // beginning as for SYNs and RSTs. + if ( endpoint->CheckHistory(HIST_FIN_PKT, 'F') && + rel_seq + len != endpoint->hist_last_FIN ) + endpoint->AddHistory('F'); + + endpoint->hist_last_FIN = rel_seq + len; + } + + if ( flags.RST() ) + { + if ( endpoint->CheckHistory(HIST_RST_PKT, 'R') && + rel_seq != endpoint->hist_last_RST ) + endpoint->AddHistory('R'); + + endpoint->hist_last_RST = rel_seq; + } + } + + else + { // bits_set == 0 + if ( len ) + endpoint->CheckHistory(HIST_DATA_PKT, 'D'); + + else if ( flags.ACK() ) + endpoint->CheckHistory(HIST_ACK_PKT, 'A'); + } + } + +static void init_window(TCP_Endpoint* endpoint, TCP_Endpoint* peer, + TCP_Flags flags, bro_int_t scale, uint32 base_seq, + uint32 ack_seq) + { + // ### In the following, we could be fooled by an + // inconsistent SYN retransmission. Where's a normalizer + // when you need one? + + if ( scale < 0 ) + { // no window scaling option + if ( flags.ACK() ) + { // window scaling not negotiated + endpoint->window_scale = 0; + peer->window_scale = 0; + } + else + // We're not offering window scaling. + // Ideally, we'd remember this fact so that + // if the SYN/ACK *does* include window + // scaling, we know it won't be negotiated. + // But it's a pain to track that, and hard + // to see how an adversarial responder could + // use it to evade. Also, if we *do* want + // to track it, we could do so using + // connection_SYN_packet. + endpoint->window_scale = 0; + } + else + { + endpoint->window_scale = scale; + endpoint->window_seq = base_seq; + endpoint->window_ack_seq = ack_seq; + + peer->window_seq = ack_seq; + peer->window_ack_seq = base_seq; + } + } + +static void update_window(TCP_Endpoint* endpoint, unsigned int window, + uint32 base_seq, uint32 ack_seq, TCP_Flags flags) + { + // Note, the offered window on an initial SYN is unscaled, even + // if the SYN includes scaling, so we need to do the following + // test *before* updating the scaling information below. (Hmmm, + // how does this work for windows on SYN/ACKs? ###) + int scale = endpoint->window_scale; + window = window << scale; + + // Don't analyze window values off of SYNs, they're sometimes + // immediately rescinded. + if ( ! flags.SYN() ) + { + // ### Decide whether to accept new window based on Active + // Mapping policy. + if ( seq_delta(base_seq, endpoint->window_seq) >= 0 && + seq_delta(ack_seq, endpoint->window_ack_seq) >= 0 ) + { + uint32 new_edge = ack_seq + window; + uint32 old_edge = endpoint->window_ack_seq + endpoint->window; + int32 advance = seq_delta(new_edge, old_edge); + + if ( advance < 0 ) + { + // A window recision. We don't report these + // for FINs or RSTs, or if the connection + // has already been partially closed, since + // such recisions occur frequently in practice, + // probably as the receiver loses buffer memory + // due to its process going away. + // + // We also, for window scaling, allow a bit + // of slop ###. This is because sometimes + // there will be an apparent recision due + // to the granularity of the scaling. + if ( ! flags.FIN() && ! flags.RST() && + endpoint->state != TCP_ENDPOINT_CLOSED && + endpoint->state != TCP_ENDPOINT_RESET && + (-advance) >= (1 << scale) ) + endpoint->Conn()->Weird("window_recision"); + } + + endpoint->window = window; + endpoint->window_ack_seq = ack_seq; + endpoint->window_seq = base_seq; + } + } + } + +static void syn_weirds(TCP_Flags flags, TCP_Endpoint* endpoint, int data_len) + { + if ( flags.RST() ) + endpoint->Conn()->Weird("TCP_christmas"); + + if ( flags.URG() ) + endpoint->Conn()->Weird("baroque_SYN"); + + if ( data_len > 0 ) + // Not technically wrong according to RFC 793, but the other side + // would be forced to buffer data until the handshake succeeds, and + // that could be bad in some cases, e.g. SYN floods. + // T/TCP definitely complicates this. + endpoint->Conn()->Weird("SYN_with_data"); + } + +void TCP_Analyzer::UpdateInactiveState(double t, + TCP_Endpoint* endpoint, TCP_Endpoint* peer, + uint32 base_seq, uint32 ack_seq, + int len, int is_orig, TCP_Flags flags, + int& do_close, int& gen_event) + { + if ( flags.SYN() ) + { + if ( is_orig ) + { + if ( flags.ACK() ) + { + Weird("connection_originator_SYN_ack"); + endpoint->SetState(TCP_ENDPOINT_SYN_ACK_SENT); + } + else + endpoint->SetState(TCP_ENDPOINT_SYN_SENT); + + if ( tcp_attempt_delay ) + ADD_ANALYZER_TIMER(&TCP_Analyzer::AttemptTimer, + t + tcp_attempt_delay, 1, + TIMER_TCP_ATTEMPT); + } + else + { + if ( flags.ACK() ) + { + if ( peer->state != TCP_ENDPOINT_INACTIVE && + peer->state != TCP_ENDPOINT_PARTIAL && + ! seq_between(ack_seq, peer->StartSeq(), peer->LastSeq()) ) + Weird("bad_SYN_ack"); + } + + else if ( peer->state == TCP_ENDPOINT_SYN_ACK_SENT && + base_seq == endpoint->StartSeq() ) + { + // This is a SYN/SYN-ACK reversal, + // per the discussion in IsReuse. + // Flip the endpoints and establish + // the connection. + is_partial = 0; + Conn()->FlipRoles(); + peer->SetState(TCP_ENDPOINT_ESTABLISHED); + } + + else + Weird("simultaneous_open"); + + if ( peer->state == TCP_ENDPOINT_SYN_SENT ) + peer->SetState(TCP_ENDPOINT_ESTABLISHED); + else if ( peer->state == TCP_ENDPOINT_INACTIVE ) + { + // If we were to ignore SYNs and + // only instantiate state on SYN + // acks, then we'd do: + // peer->SetState(TCP_ENDPOINT_ESTABLISHED); + // here. + Weird("unsolicited_SYN_response"); + } + + endpoint->SetState(TCP_ENDPOINT_ESTABLISHED); + + if ( peer->state != TCP_ENDPOINT_PARTIAL ) + { + Event(connection_established); + Conn()->EnableStatusUpdateTimer(); + } + } + } + + if ( flags.FIN() ) + { + endpoint->SetState(TCP_ENDPOINT_CLOSED); + do_close = gen_event = 1; + if ( peer->state != TCP_ENDPOINT_PARTIAL && ! flags.SYN() ) + Weird("spontaneous_FIN"); + } + + if ( flags.RST() ) + { + endpoint->SetState(TCP_ENDPOINT_RESET); + + int is_reject = 0; + + if ( is_orig ) + { + // If our peer is established then we saw + // a SYN-ack but not SYN - so a reverse + // scan, and we should treat this as a + // reject. + if ( peer->state == TCP_ENDPOINT_ESTABLISHED ) + is_reject = 1; + } + + else if ( peer->state == TCP_ENDPOINT_SYN_SENT || + peer->state == TCP_ENDPOINT_SYN_ACK_SENT ) + // We're rejecting an initial SYN. + is_reject = 1; + + do_close = 1; + gen_event = ! is_reject; + + if ( is_reject ) + Event(connection_rejected); + + else if ( peer->state == TCP_ENDPOINT_INACTIVE ) + Weird("spontaneous_RST"); + } + + if ( endpoint->state == TCP_ENDPOINT_INACTIVE ) + { // No control flags to change the state. + if ( ! is_orig && len == 0 && + orig->state == TCP_ENDPOINT_SYN_SENT ) + // Some eccentric TCP's will ack an initial + // SYN prior to sending a SYN reply (hello, + // ftp.microsoft.com). For those, don't + // consider the ack as forming a partial + // connection. + ; + else + { + endpoint->SetState(TCP_ENDPOINT_PARTIAL); + Conn()->EnableStatusUpdateTimer(); + + if ( peer->state == TCP_ENDPOINT_PARTIAL ) + // We've seen both sides of a partial + // connection, report it. + Event(partial_connection); + } + } + } + +void TCP_Analyzer::UpdateSYN_SentState( + TCP_Endpoint* endpoint, TCP_Endpoint* peer, + int len, int is_orig, TCP_Flags flags, + int& do_close, int& gen_event) + { + if ( flags.SYN() ) + { + if ( is_orig ) + { + if ( flags.ACK() && ! flags.FIN() && ! flags.RST() && + endpoint->state != TCP_ENDPOINT_SYN_ACK_SENT ) + Weird("repeated_SYN_with_ack"); + } + else + { + if ( ! flags.ACK() && + endpoint->state != TCP_ENDPOINT_SYN_SENT ) + Weird("repeated_SYN_reply_wo_ack"); + } + } + + if ( flags.FIN() ) + { + if ( peer->state == TCP_ENDPOINT_INACTIVE || + peer->state == TCP_ENDPOINT_SYN_SENT ) + Weird("inappropriate_FIN"); + + endpoint->SetState(TCP_ENDPOINT_CLOSED); + do_close = gen_event = 1; + } + + if ( flags.RST() ) + { + endpoint->SetState(TCP_ENDPOINT_RESET); + ConnectionReset(); + do_close = 1; + } + + else if ( len > 0 ) + Weird("data_before_established"); + } + +void TCP_Analyzer::UpdateEstablishedState( + TCP_Endpoint* endpoint, TCP_Endpoint* peer, + TCP_Flags flags, int& do_close, int& gen_event) + { + if ( flags.SYN() ) + { + if ( endpoint->state == TCP_ENDPOINT_PARTIAL && + peer->state == TCP_ENDPOINT_INACTIVE && ! flags.ACK() ) + { + Weird("SYN_after_partial"); + endpoint->SetState(TCP_ENDPOINT_SYN_SENT); + } + } + + if ( flags.FIN() && ! flags.RST() ) // ### + { // should check sequence/ack numbers here ### + endpoint->SetState(TCP_ENDPOINT_CLOSED); + + if ( peer->state == TCP_ENDPOINT_RESET && + peer->prev_state == TCP_ENDPOINT_CLOSED ) + // The peer sent a FIN followed by a RST. + // Turn it back into CLOSED state, because + // this was actually normal termination. + peer->SetState(TCP_ENDPOINT_CLOSED); + + do_close = gen_event = 1; + } + + if ( flags.RST() ) + { + endpoint->SetState(TCP_ENDPOINT_RESET); + do_close = 1; + + if ( peer->state != TCP_ENDPOINT_RESET || + peer->prev_state != TCP_ENDPOINT_ESTABLISHED ) + ConnectionReset(); + } + } + +void TCP_Analyzer::UpdateClosedState(double t, TCP_Endpoint* endpoint, + int32 delta_last, TCP_Flags flags, int& do_close) + { + if ( flags.SYN() ) + Weird("SYN_after_close"); + + if ( flags.FIN() && delta_last > 0 ) + // Probably should also complain on FIN recision. + // That requires an extra state variable to avoid + // generating slews of weird's when a TCP gets + // seriously confused (this from experience). + Weird("FIN_advanced_last_seq"); + + // Previously, our state was CLOSED, since we sent a FIN. + // If our peer was also closed, then don't change our state + // now on a RST, since this connection has already seen a FIN + // exchange. + if ( flags.RST() && endpoint->peer->state != TCP_ENDPOINT_CLOSED ) + { + endpoint->SetState(TCP_ENDPOINT_RESET); + + if ( ! endpoint->did_close ) + // RST after FIN. + do_close = 1; + + if ( connection_reset ) + ADD_ANALYZER_TIMER(&TCP_Analyzer::ResetTimer, + t + tcp_reset_delay, 1, + TIMER_TCP_RESET); + } + } + +void TCP_Analyzer::UpdateResetState(int len, TCP_Flags flags) + { + if ( flags.SYN() ) + Weird("SYN_after_reset"); + + if ( flags.FIN() ) + Weird("FIN_after_reset"); + + if ( len > 0 && ! flags.RST() ) + Weird("data_after_reset"); + } + +void TCP_Analyzer::UpdateStateMachine(double t, + TCP_Endpoint* endpoint, TCP_Endpoint* peer, + uint32 base_seq, uint32 ack_seq, + int len, int32 delta_last, int is_orig, TCP_Flags flags, + int& do_close, int& gen_event) + { + do_close = 0; // whether to report the connection as closed + gen_event = 0; // if so, whether to generate an event + + switch ( endpoint->state ) { + + case TCP_ENDPOINT_INACTIVE: + UpdateInactiveState(t, endpoint, peer, base_seq, ack_seq, + len, is_orig, flags, + do_close, gen_event); + break; + + case TCP_ENDPOINT_SYN_SENT: + case TCP_ENDPOINT_SYN_ACK_SENT: + UpdateSYN_SentState(endpoint, peer, len, is_orig, flags, do_close, + gen_event); + break; + + case TCP_ENDPOINT_ESTABLISHED: + case TCP_ENDPOINT_PARTIAL: + UpdateEstablishedState(endpoint, peer, flags, do_close, gen_event); + break; + + case TCP_ENDPOINT_CLOSED: + UpdateClosedState(t, endpoint, delta_last, flags, do_close); + break; + + case TCP_ENDPOINT_RESET: + UpdateResetState(len, flags); + break; + } + } + +void TCP_Analyzer::GeneratePacketEvent( + uint64 rel_seq, uint64 rel_ack, + const u_char* data, int len, int caplen, + int is_orig, TCP_Flags flags) + { + char tcp_flags[256]; + int tcp_flag_len = 0; + + if ( flags.SYN() ) tcp_flags[tcp_flag_len++] = 'S'; + if ( flags.FIN() ) tcp_flags[tcp_flag_len++] = 'F'; + if ( flags.RST() ) tcp_flags[tcp_flag_len++] = 'R'; + if ( flags.ACK() ) tcp_flags[tcp_flag_len++] = 'A'; + if ( flags.PUSH() ) tcp_flags[tcp_flag_len++] = 'P'; + if ( flags.URG() ) tcp_flags[tcp_flag_len++] = 'U'; + + tcp_flags[tcp_flag_len] = '\0'; + + val_list* vl = new val_list(); + + vl->append(BuildConnVal()); + vl->append(new Val(is_orig, TYPE_BOOL)); + vl->append(new StringVal(tcp_flags)); + vl->append(new Val(rel_seq, TYPE_COUNT)); + vl->append(new Val(flags.ACK() ? rel_ack : 0, TYPE_COUNT)); + vl->append(new Val(len, TYPE_COUNT)); + + // We need the min() here because Ethernet padding can lead to + // caplen > len. + vl->append(new StringVal(min(caplen, len), (const char*) data)); + + ConnectionEvent(tcp_packet, vl); + } + +int TCP_Analyzer::DeliverData(double t, const u_char* data, int len, int caplen, + const IP_Hdr* ip, const struct tcphdr* tp, + TCP_Endpoint* endpoint, uint64 rel_data_seq, + int is_orig, TCP_Flags flags) + { + return endpoint->DataSent(t, rel_data_seq, len, caplen, data, ip, tp); + } + +void TCP_Analyzer::CheckRecording(int need_contents, TCP_Flags flags) + { + bool record_current_content = need_contents || Conn()->RecordContents(); + bool record_current_packet = + Conn()->RecordPackets() || + flags.SYN() || flags.FIN() || flags.RST(); + + Conn()->SetRecordCurrentContent(record_current_content); + Conn()->SetRecordCurrentPacket(record_current_packet); + } + +void TCP_Analyzer::CheckPIA_FirstPacket(int is_orig, const IP_Hdr* ip) + { + if ( is_orig && ! (first_packet_seen & ORIG) ) + { + pia::PIA_TCP* pia = static_cast(Conn()->GetPrimaryPIA()); + if ( pia ) + pia->FirstPacket(is_orig, ip); + first_packet_seen |= ORIG; + } + + if ( ! is_orig && ! (first_packet_seen & RESP) ) + { + pia::PIA_TCP* pia = static_cast(Conn()->GetPrimaryPIA()); + if ( pia ) + pia->FirstPacket(is_orig, ip); + first_packet_seen |= RESP; + } + } + +static uint64 get_relative_seq(const TCP_Endpoint* endpoint, + uint32 cur_base, uint32 last, uint32 wraps, + bool* underflow = 0) + { + int32 delta = seq_delta(cur_base, last); + + if ( delta < 0 ) + { + if ( wraps && cur_base > last ) + // Seems to be a part of a previous 32-bit sequence space. + --wraps; + } + else if ( delta > 0 ) + { + if ( cur_base < last ) + // The sequence space wrapped around. + ++wraps; + } + + if ( wraps == 0 ) + { + delta = seq_delta(cur_base, endpoint->StartSeq()); + + if ( underflow && delta < 0 ) + *underflow = true; + + return delta; + } + + return endpoint->ToRelativeSeqSpace(cur_base, wraps); + } + +static int get_segment_len(int payload_len, TCP_Flags flags) + { + int seg_len = payload_len; + + if ( flags.SYN() ) + // SYN consumes a byte of sequence space. + ++seg_len; + + if ( flags.FIN() ) + // FIN consumes a bytes of sequence space. + ++seg_len; + + if ( flags.RST() ) + // Don't include the data in the computation of + // the sequence space for this connection, as + // it's not in fact part of the TCP stream. + seg_len -= payload_len; + + return seg_len; + } + +static void init_endpoint(TCP_Endpoint* endpoint, TCP_Flags flags, + uint32 first_seg_seq, uint32 last_seq, double t) + { + switch ( endpoint->state ) { + case TCP_ENDPOINT_INACTIVE: + if ( flags.SYN() ) + { + endpoint->InitAckSeq(first_seg_seq); + endpoint->InitStartSeq(first_seg_seq); + } + else + { + // This is a partial connection - set up the initial sequence + // numbers as though we saw a SYN, to keep the relative byte + // numbering consistent. + endpoint->InitAckSeq(first_seg_seq - 1); + endpoint->InitStartSeq(first_seg_seq - 1); + } + + endpoint->InitLastSeq(last_seq); + endpoint->start_time = t; + break; + + case TCP_ENDPOINT_SYN_SENT: + case TCP_ENDPOINT_SYN_ACK_SENT: + if ( flags.SYN() && first_seg_seq != endpoint->StartSeq() ) + { + endpoint->Conn()->Weird("SYN_seq_jump"); + endpoint->InitStartSeq(first_seg_seq); + endpoint->InitAckSeq(first_seg_seq); + endpoint->InitLastSeq(last_seq); + } + break; + + case TCP_ENDPOINT_ESTABLISHED: + case TCP_ENDPOINT_PARTIAL: + if ( flags.SYN() ) + { + if ( endpoint->Size() > 0 ) + endpoint->Conn()->Weird("SYN_inside_connection"); + + if ( first_seg_seq != endpoint->StartSeq() ) + endpoint->Conn()->Weird("SYN_seq_jump"); + + // Make a guess that somehow the connection didn't get established, + // and this SYN will be the one that actually sets it up. + endpoint->InitStartSeq(first_seg_seq); + endpoint->InitAckSeq(first_seg_seq); + endpoint->InitLastSeq(last_seq); + } + break; + + case TCP_ENDPOINT_RESET: + if ( flags.SYN() ) + { + if ( endpoint->prev_state == TCP_ENDPOINT_INACTIVE ) + { + // Seq. numbers were initialized by a RST packet from this + // endpoint, but now that a SYN is seen from it, that could mean + // the earlier RST was spoofed/injected, so re-initialize. This + // mostly just helps prevent misrepresentations of payload sizes + // that are based on bad initial sequence values. + endpoint->InitStartSeq(first_seg_seq); + endpoint->InitAckSeq(first_seg_seq); + endpoint->InitLastSeq(last_seq); + } + } + break; + + default: + break; + } + } + +static void init_peer(TCP_Endpoint* peer, TCP_Endpoint* endpoint, + TCP_Flags flags, uint32 ack_seq) + { + if ( ! flags.SYN() && ! flags.FIN() && ! flags.RST() ) + { + if ( endpoint->state == TCP_ENDPOINT_SYN_SENT || + endpoint->state == TCP_ENDPOINT_SYN_ACK_SENT || + endpoint->state == TCP_ENDPOINT_ESTABLISHED ) + { + // We've already sent a SYN, but that + // hasn't roused the other end, yet we're + // ack'ing their data. + + if ( ! endpoint->Conn()->DidWeird() ) + endpoint->Conn()->Weird("possible_split_routing"); + } + } + + // Start the sequence numbering as if there was an initial + // SYN, so the relative numbering of subsequent data packets + // stays consistent. + peer->InitStartSeq(ack_seq - 1); + peer->InitAckSeq(ack_seq - 1); + peer->InitLastSeq(ack_seq - 1); + } + +static void update_ack_seq(TCP_Endpoint* endpoint, uint32 ack_seq) + { + int32 delta_ack = seq_delta(ack_seq, endpoint->AckSeq()); + + if ( ack_seq == 0 && delta_ack > TOO_LARGE_SEQ_DELTA ) + // More likely that this is a broken ack than a + // large connection that happens to land on 0 in the + // sequence space. + ; + else if ( delta_ack > 0 ) + endpoint->UpdateAckSeq(ack_seq); + } + +// Returns the difference between last_seq and the last sequence +// seen by the endpoint (may be negative). +static int32 update_last_seq(TCP_Endpoint* endpoint, uint32 last_seq, + TCP_Flags flags) + { + int32 delta_last = seq_delta(last_seq, endpoint->LastSeq()); + + if ( (flags.SYN() || flags.RST()) && + (delta_last > TOO_LARGE_SEQ_DELTA || + delta_last < -TOO_LARGE_SEQ_DELTA) ) + // ### perhaps trust RST seq #'s if initial and not too + // outlandish, but not if they're coming after the other + // side has sent a FIN - trust the FIN ack instead + ; + + else if ( flags.FIN() && + endpoint->LastSeq() == endpoint->StartSeq() + 1 ) + // Update last_seq based on the FIN even if delta_last < 0. + // This is to accommodate > 2 GB connections for which + // we've only seen the SYN and the FIN (hence the check + // for last_seq == start_seq + 1). + endpoint->UpdateLastSeq(last_seq); + + else if ( endpoint->state == TCP_ENDPOINT_RESET ) + // don't trust any subsequent sequence numbers + ; + + else if ( delta_last > 0 ) + // ### check for large jumps here. + // ## endpoint->last_seq = last_seq; + endpoint->UpdateLastSeq(last_seq); + + else if ( delta_last <= 0 ) + { // ### ++retransmit, unless this is a pure ack + } + + return delta_last; + } + +void TCP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, + uint64 seq, const IP_Hdr* ip, int caplen) + { + TransportLayerAnalyzer::DeliverPacket(len, data, orig, seq, ip, caplen); + + const struct tcphdr* tp = ExtractTCP_Header(data, len, caplen); + if ( ! tp ) + return; + + // We need the min() here because Ethernet frame padding can lead to + // caplen > len. + if ( packet_contents ) + PacketContents(data, min(len, caplen)); + + TCP_Endpoint* endpoint = is_orig ? orig : resp; + TCP_Endpoint* peer = endpoint->peer; + + if ( ! ValidateChecksum(tp, endpoint, len, caplen) ) + return; + + uint32 tcp_hdr_len = data - (const u_char*) tp; + TCP_Flags flags(tp); + SetPartialStatus(flags, endpoint->IsOrig()); + + uint32 base_seq = ntohl(tp->th_seq); + uint32 ack_seq = ntohl(tp->th_ack); + + int seg_len = get_segment_len(len, flags); + uint32 seq_one_past_segment = base_seq + seg_len; + + init_endpoint(endpoint, flags, base_seq, seq_one_past_segment, + current_timestamp); + + bool seq_underflow = false; + uint64 rel_seq = get_relative_seq(endpoint, base_seq, endpoint->LastSeq(), + endpoint->SeqWraps(), &seq_underflow); + + if ( seq_underflow && ! flags.RST() ) + // Can't tell if if this is a retransmit/out-of-order or something + // before the sequence Bro initialized the endpoint at or the TCP is + // just broken and sending garbage sequences. In either case, some + // standard analysis doesn't apply (e.g. reassembly). + Weird("TCP_seq_underflow_or_misorder"); + + update_history(flags, endpoint, rel_seq, len); + update_window(endpoint, ntohs(tp->th_win), base_seq, ack_seq, flags); + + if ( ! orig->did_close || ! resp->did_close ) + Conn()->SetLastTime(current_timestamp); + + if ( flags.SYN() ) + { + syn_weirds(flags, endpoint, len); + RecordVal* SYN_vals = build_syn_packet_val(is_orig, ip, tp); + init_window(endpoint, peer, flags, SYN_vals->Lookup(5)->CoerceToInt(), + base_seq, ack_seq); + + if ( connection_SYN_packet ) + { + val_list* vl = new val_list; + vl->append(BuildConnVal()); + vl->append(SYN_vals->Ref()); + ConnectionEvent(connection_SYN_packet, vl); + } + + passive_fingerprint(this, is_orig, ip, tp, tcp_hdr_len); + + Unref(SYN_vals); + } + + if ( flags.FIN() ) + { + ++endpoint->FIN_cnt; + + if ( endpoint->FIN_cnt >= tcp_storm_thresh && current_timestamp < + endpoint->last_time + tcp_storm_interarrival_thresh ) + Weird("FIN_storm"); + + endpoint->FIN_seq = rel_seq + seg_len; + } + + if ( flags.RST() ) + { + ++endpoint->RST_cnt; + + if ( endpoint->RST_cnt >= tcp_storm_thresh && current_timestamp < + endpoint->last_time + tcp_storm_interarrival_thresh ) + Weird("RST_storm"); + + // This now happens often enough that it's + // not in the least interesting. + //if ( len > 0 ) + // Weird("RST_with_data"); + + PacketWithRST(); + } + + uint64 rel_ack = 0; + + if ( flags.ACK() ) + { + if ( is_orig && ! seen_first_ACK && + (endpoint->state == TCP_ENDPOINT_ESTABLISHED || + endpoint->state == TCP_ENDPOINT_SYN_SENT) ) + { + seen_first_ACK = 1; + Event(connection_first_ACK); + } + + if ( peer->state == TCP_ENDPOINT_INACTIVE ) + { + rel_ack = 1; + init_peer(peer, endpoint, flags, ack_seq); + } + else + { + bool ack_underflow = false; + rel_ack = get_relative_seq(peer, ack_seq, peer->AckSeq(), + peer->AckWraps(), &ack_underflow); + + if ( ack_underflow ) + { + rel_ack = 0; + Weird("TCP_ack_underflow_or_misorder"); + } + else if ( ! flags.RST() ) + // Don't trust ack's in RSt packets. + update_ack_seq(peer, ack_seq); + } + + peer->AckReceived(rel_ack); + } + + int32 delta_last = update_last_seq(endpoint, seq_one_past_segment, flags); + endpoint->last_time = current_timestamp; + + int do_close; + int gen_event; + UpdateStateMachine(current_timestamp, endpoint, peer, base_seq, ack_seq, + len, delta_last, is_orig, flags, do_close, gen_event); + + if ( tcp_packet ) + GeneratePacketEvent(rel_seq, rel_ack, data, len, caplen, is_orig, + flags); + + if ( tcp_option && tcp_hdr_len > sizeof(*tp) && + tcp_hdr_len <= uint32(caplen) ) + ParseTCPOptions(tp, TCPOptionEvent, this, is_orig, 0); + + if ( DEBUG_tcp_data_sent ) + { + DEBUG_MSG("%.6f before DataSent: len=%d caplen=%d skip=%d\n", + network_time, len, caplen, Skipping()); + } + + uint64 rel_data_seq = flags.SYN() ? rel_seq + 1 : rel_seq; + + int need_contents = 0; + if ( len > 0 && (caplen >= len || packet_children.size()) && + ! flags.RST() && ! Skipping() && ! seq_underflow ) + need_contents = DeliverData(current_timestamp, data, len, caplen, ip, + tp, endpoint, rel_data_seq, is_orig, flags); + + endpoint->CheckEOF(); + + if ( do_close ) + { + // We need to postpone doing this until after we process + // DataSent, so we don't generate a connection_finished event + // until after data perhaps included with the FIN is processed. + ConnectionClosed(endpoint, peer, gen_event); + } + + CheckRecording(need_contents, flags); + + // Handle child_packet analyzers. Note: This happens *after* the + // packet has been processed and the TCP state updated. + LOOP_OVER_GIVEN_CHILDREN(i, packet_children) + (*i)->NextPacket(len, data, is_orig, rel_data_seq, ip, caplen); + + if ( ! reassembling ) + ForwardPacket(len, data, is_orig, rel_data_seq, ip, caplen); + + CheckPIA_FirstPacket(is_orig, ip); + } + +void TCP_Analyzer::DeliverStream(int len, const u_char* data, bool orig) + { + Analyzer::DeliverStream(len, data, orig); + } + +void TCP_Analyzer::Undelivered(uint64 seq, int len, bool is_orig) + { + Analyzer::Undelivered(seq, len, orig); + } + +void TCP_Analyzer::FlipRoles() + { + Analyzer::FlipRoles(); + + sessions->tcp_stats.FlipState(orig->state, resp->state); + TCP_Endpoint* tmp_ep = resp; + resp = orig; + orig = tmp_ep; + orig->is_orig = !orig->is_orig; + resp->is_orig = !resp->is_orig; + } + +void TCP_Analyzer::UpdateConnVal(RecordVal *conn_val) + { + RecordVal *orig_endp_val = conn_val->Lookup("orig")->AsRecordVal(); + RecordVal *resp_endp_val = conn_val->Lookup("resp")->AsRecordVal(); + + orig_endp_val->Assign(0, new Val(orig->Size(), TYPE_COUNT)); + orig_endp_val->Assign(1, new Val(int(orig->state), TYPE_COUNT)); + resp_endp_val->Assign(0, new Val(resp->Size(), TYPE_COUNT)); + resp_endp_val->Assign(1, new Val(int(resp->state), TYPE_COUNT)); + + // Call children's UpdateConnVal + Analyzer::UpdateConnVal(conn_val); + + // Have to do packet_children ourselves. + LOOP_OVER_GIVEN_CHILDREN(i, packet_children) + (*i)->UpdateConnVal(conn_val); + } + int TCP_Analyzer::ParseTCPOptions(const struct tcphdr* tcp, proc_tcp_option_t proc, TCP_Analyzer* analyzer, @@ -1849,11 +1897,11 @@ void TCP_ApplicationAnalyzer::ProtocolViolation(const char* reason, } void TCP_ApplicationAnalyzer::DeliverPacket(int len, const u_char* data, - bool is_orig, int seq, + bool is_orig, uint64 seq, const IP_Hdr* ip, int caplen) { Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen); - DBG_LOG(DBG_ANALYZER, "TCP_ApplicationAnalyzer ignoring DeliverPacket(%d, %s, %d, %p, %d) [%s%s]", + DBG_LOG(DBG_ANALYZER, "TCP_ApplicationAnalyzer ignoring DeliverPacket(%d, %s, %"PRIu64", %p, %d) [%s%s]", len, is_orig ? "T" : "F", seq, ip, caplen, fmt_bytes((const char*) data, min(40, len)), len > 40 ? "..." : ""); } @@ -1930,7 +1978,7 @@ int endian_flip(int n) return ((n & 0xff) << 8) | ((n & 0xff00) >> 8); } -int TCPStats_Endpoint::DataSent(double /* t */, int seq, int len, int caplen, +int TCPStats_Endpoint::DataSent(double /* t */, uint64 seq, int len, int caplen, const u_char* /* data */, const IP_Hdr* ip, const struct tcphdr* /* tp */) { @@ -1990,14 +2038,14 @@ int TCPStats_Endpoint::DataSent(double /* t */, int seq, int len, int caplen, ++num_in_order; - int top_seq = seq + len; + uint64 top_seq = seq + len; - int data_in_flight = endp->LastSeq() - endp->AckSeq(); + int32 data_in_flight = seq_delta(endp->LastSeq(), endp->AckSeq()); if ( data_in_flight < 0 ) data_in_flight = 0; - int seq_delta = top_seq - max_top_seq; - if ( seq_delta <= 0 ) + int64 sequence_delta = top_seq - max_top_seq; + if ( sequence_delta <= 0 ) { if ( ! BifConst::ignore_keep_alive_rexmit || len > 1 || data_in_flight > 0 ) { @@ -2005,7 +2053,7 @@ int TCPStats_Endpoint::DataSent(double /* t */, int seq, int len, int caplen, num_rxmit_bytes += len; } - DEBUG_MSG("%.6f rexmit %d + %d <= %d data_in_flight = %d\n", + DEBUG_MSG("%.6f rexmit %"PRIu64" + %d <= %"PRIu64" data_in_flight = %d\n", network_time, seq, len, max_top_seq, data_in_flight); if ( tcp_rexmit ) @@ -2073,7 +2121,7 @@ void TCPStats_Analyzer::Done() ConnectionEvent(conn_stats, vl); } -void TCPStats_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, int seq, const IP_Hdr* ip, int caplen) +void TCPStats_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, uint64 seq, const IP_Hdr* ip, int caplen) { TCP_ApplicationAnalyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen); diff --git a/src/analyzer/protocol/tcp/TCP.h b/src/analyzer/protocol/tcp/TCP.h index b2649b4ab8..b00e73d348 100644 --- a/src/analyzer/protocol/tcp/TCP.h +++ b/src/analyzer/protocol/tcp/TCP.h @@ -102,9 +102,9 @@ protected: // Analyzer interface. virtual void Init(); virtual void Done(); - virtual void DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen); + virtual void DeliverPacket(int len, const u_char* data, bool orig, uint64 seq, const IP_Hdr* ip, int caplen); virtual void DeliverStream(int len, const u_char* data, bool orig); - virtual void Undelivered(int seq, int len, bool orig); + virtual void Undelivered(uint64 seq, int len, bool orig); virtual void FlipRoles(); virtual bool IsReuse(double t, const u_char* pkt); @@ -119,42 +119,7 @@ protected: bool ValidateChecksum(const struct tcphdr* tp, TCP_Endpoint* endpoint, int len, int caplen); - // Update analysis based on flag combinations. The endpoint, base_seq - // and len are needed for tracking various history information. - // dst_port is needed for trimming of FIN packets. - void CheckFlagCombos(TCP_Flags flags, TCP_Endpoint* endpoint, - uint32 base_seq, int len, int dst_port); - - void UpdateWindow(TCP_Endpoint* endpoint, unsigned int window, - uint32 base_seq, uint32 ack_seq, - TCP_Flags flags); - - void ProcessSYN(const IP_Hdr* ip, const struct tcphdr* tp, - uint32 tcp_hdr_len, int& seq_len, - TCP_Endpoint* endpoint, TCP_Endpoint* peer, - uint32 base_seq, uint32 ack_seq, - const IPAddr& orig_addr, - int is_orig, TCP_Flags flags); - - void ProcessFIN(double t, TCP_Endpoint* endpoint, int& seq_len, - uint32 base_seq); - - void ProcessRST(double t, TCP_Endpoint* endpoint, const IP_Hdr* ip, - uint32 base_seq, int len, int& seq_len); - - void ProcessACK(TCP_Endpoint* endpoint, TCP_Endpoint* peer, - uint32 ack_seq, int is_orig, TCP_Flags flags); - - void ProcessFlags(double t, const IP_Hdr* ip, const struct tcphdr* tp, - uint32 tcp_hdr_len, int len, int& seq_len, - TCP_Endpoint* endpoint, TCP_Endpoint* peer, - uint32 base_seq, uint32 ack_seq, - const IPAddr& orig_addr, - int is_orig, TCP_Flags flags); - - void TransitionFromInactive(double t, TCP_Endpoint* endpoint, - uint32 base_seq, uint32 last_seq, - int SYN); + void SetPartialStatus(TCP_Flags flags, bool is_orig); // Update the state machine of the TCPs based on the activity. This // includes our pseudo-states such as TCP_ENDPOINT_PARTIAL. @@ -164,8 +129,8 @@ protected: // this fact. void UpdateStateMachine(double t, TCP_Endpoint* endpoint, TCP_Endpoint* peer, - uint32 base_seq, uint32 ack_seq, uint32 last_seq, - int len, int delta_last, int is_orig, TCP_Flags flags, + uint32 base_seq, uint32 ack_seq, + int len, int32 delta_last, int is_orig, TCP_Flags flags, int& do_close, int& gen_event); void UpdateInactiveState(double t, @@ -174,43 +139,34 @@ protected: int len, int is_orig, TCP_Flags flags, int& do_close, int& gen_event); - void UpdateSYN_SentState(double t, + void UpdateSYN_SentState( TCP_Endpoint* endpoint, TCP_Endpoint* peer, - uint32 base_seq, uint32 last_seq, int len, int is_orig, TCP_Flags flags, int& do_close, int& gen_event); - void UpdateEstablishedState(double t, + void UpdateEstablishedState( TCP_Endpoint* endpoint, TCP_Endpoint* peer, - uint32 base_seq, uint32 last_seq, - int is_orig, TCP_Flags flags, - int& do_close, int& gen_event); + TCP_Flags flags, int& do_close, int& gen_event); void UpdateClosedState(double t, TCP_Endpoint* endpoint, - int delta_last, TCP_Flags flags, + int32 delta_last, TCP_Flags flags, int& do_close); - void UpdateResetState(int len, TCP_Flags flags, TCP_Endpoint* endpoint, - uint32 base_seq, uint32 last_seq); + void UpdateResetState(int len, TCP_Flags flags); - void GeneratePacketEvent(TCP_Endpoint* endpoint, TCP_Endpoint* peer, - uint32 base_seq, uint32 ack_seq, + void GeneratePacketEvent( + uint64 rel_seq, uint64 rel_ack, const u_char* data, int len, int caplen, int is_orig, TCP_Flags flags); int DeliverData(double t, const u_char* data, int len, int caplen, const IP_Hdr* ip, const struct tcphdr* tp, - TCP_Endpoint* endpoint, uint32 base_seq, + TCP_Endpoint* endpoint, uint64 rel_data_seq, int is_orig, TCP_Flags flags); void CheckRecording(int need_contents, TCP_Flags flags); void CheckPIA_FirstPacket(int is_orig, const IP_Hdr* ip); - // Returns the difference between last_seq and the last sequence - // seen by the endpoint (may be negative). - int UpdateLastSeq(TCP_Endpoint* endpoint, uint32 last_seq, - TCP_Flags flags); - friend class ConnectionTimer; void AttemptTimer(double t); void PartialCloseTimer(double t); @@ -228,12 +184,6 @@ protected: void SetReassembler(tcp::TCP_Reassembler* rorig, tcp::TCP_Reassembler* rresp); - Val* BuildSYNPacketVal(int is_orig, - const IP_Hdr* ip, const struct tcphdr* tcp); - - RecordVal* BuildOSVal(int is_orig, const IP_Hdr* ip, - const struct tcphdr* tcp, uint32 tcp_hdr_len); - // Needs to be static because it's passed as a pointer-to-function // rather than pointer-to-member-function. static int TCPOptionEvent(unsigned int opt, unsigned int optlen, @@ -304,7 +254,7 @@ public: virtual void PacketWithRST(); virtual void DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); virtual void Init(); // This suppresses violations if the TCP connection wasn't @@ -341,7 +291,7 @@ class TCPStats_Endpoint { public: TCPStats_Endpoint(TCP_Endpoint* endp); - int DataSent(double t, int seq, int len, int caplen, const u_char* data, + int DataSent(double t, uint64 seq, int len, int caplen, const u_char* data, const IP_Hdr* ip, const struct tcphdr* tp); RecordVal* BuildStats(); @@ -354,7 +304,7 @@ protected: int num_in_order; int num_OO; int num_repl; - int max_top_seq; + uint64 max_top_seq; int last_id; int endian_type; }; @@ -372,7 +322,7 @@ public: protected: virtual void DeliverPacket(int len, const u_char* data, bool is_orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); TCPStats_Endpoint* orig_stats; TCPStats_Endpoint* resp_stats; diff --git a/src/analyzer/protocol/tcp/TCP_Endpoint.cc b/src/analyzer/protocol/tcp/TCP_Endpoint.cc index ad642a46e3..2e8d6e593b 100644 --- a/src/analyzer/protocol/tcp/TCP_Endpoint.cc +++ b/src/analyzer/protocol/tcp/TCP_Endpoint.cc @@ -20,7 +20,7 @@ TCP_Endpoint::TCP_Endpoint(TCP_Analyzer* arg_analyzer, int arg_is_orig) peer = 0; start_time = last_time = 0.0; start_seq = last_seq = ack_seq = 0; - last_seq_high = ack_seq_high = 0; + seq_wraps = ack_wraps = 0; window = 0; window_scale = 0; window_seq = window_ack_seq = 0; @@ -108,7 +108,8 @@ void TCP_Endpoint::CheckEOF() contents_processor->CheckEOF(); } -void TCP_Endpoint::SizeBufferedData(int& waiting_on_hole, int& waiting_on_ack) +void TCP_Endpoint::SizeBufferedData(uint64& waiting_on_hole, + uint64& waiting_on_ack) { if ( contents_processor ) contents_processor->SizeBufferedData(waiting_on_hole, waiting_on_ack); @@ -159,7 +160,7 @@ void TCP_Endpoint::SetState(EndpointState new_state) } } -bro_int_t TCP_Endpoint::Size() const +uint64 TCP_Endpoint::Size() const { if ( prev_state == TCP_ENDPOINT_SYN_SENT && state == TCP_ENDPOINT_RESET && peer->state == TCP_ENDPOINT_INACTIVE && ! NoDataAcked() ) @@ -168,14 +169,18 @@ bro_int_t TCP_Endpoint::Size() const // and there was never a chance for this endpoint to send data anyway. return 0; - bro_int_t size; + uint64 size; + uint64 last_seq_64 = ToFullSeqSpace(LastSeq(), SeqWraps()); + uint64 ack_seq_64 = ToFullSeqSpace(AckSeq(), AckWraps()); - uint64 last_seq_64 = (uint64(last_seq_high) << 32) | last_seq; - uint64 ack_seq_64 = (uint64(ack_seq_high) << 32) | ack_seq; + // Going straight to relative sequence numbers and comparing those might + // make more sense, but there's some cases (e.g. due to RSTs) where + // last_seq might not be initialized to a trustworthy value such that + // rel_seq > rel_ack, but last_seq_64 < start_seq, which is obviously wrong. if ( last_seq_64 > ack_seq_64 ) - size = last_seq_64 - start_seq; + size = last_seq_64 - StartSeqI64(); else - size = ack_seq_64 - start_seq; + size = ack_seq_64 - StartSeqI64(); // Don't include SYN octet in sequence space. For partial connections // (no SYN seen), we're still careful to adjust start_seq as though @@ -190,7 +195,7 @@ bro_int_t TCP_Endpoint::Size() const return size; } -int TCP_Endpoint::DataSent(double t, int seq, int len, int caplen, +int TCP_Endpoint::DataSent(double t, uint64 seq, int len, int caplen, const u_char* data, const IP_Hdr* ip, const struct tcphdr* tp) { @@ -205,7 +210,7 @@ int TCP_Endpoint::DataSent(double t, int seq, int len, int caplen, if ( contents_file && ! contents_processor && seq + len > contents_start_seq ) { - int under_seq = contents_start_seq - seq; + int64 under_seq = contents_start_seq - seq; if ( under_seq > 0 ) { seq += under_seq; @@ -236,7 +241,7 @@ int TCP_Endpoint::DataSent(double t, int seq, int len, int caplen, return status; } -void TCP_Endpoint::AckReceived(int seq) +void TCP_Endpoint::AckReceived(uint64 seq) { if ( contents_processor ) contents_processor->AckReceived(seq); @@ -246,7 +251,7 @@ void TCP_Endpoint::SetContentsFile(BroFile* f) { Ref(f); contents_file = f; - contents_start_seq = last_seq - start_seq; + contents_start_seq = ToRelativeSeqSpace(last_seq, seq_wraps); if ( contents_start_seq == 0 ) contents_start_seq = 1; // skip SYN diff --git a/src/analyzer/protocol/tcp/TCP_Endpoint.h b/src/analyzer/protocol/tcp/TCP_Endpoint.h index 31e239225b..471b9b9535 100644 --- a/src/analyzer/protocol/tcp/TCP_Endpoint.h +++ b/src/analyzer/protocol/tcp/TCP_Endpoint.h @@ -38,32 +38,92 @@ public: EndpointState State() const { return state; } void SetState(EndpointState new_state); - bro_int_t Size() const; + uint64 Size() const; int IsActive() const { return state != TCP_ENDPOINT_INACTIVE && ! did_close; } double StartTime() const { return start_time; } double LastTime() const { return last_time; } - uint32 StartSeq() const { return start_seq; } + /** + * @return The starting TCP sequence number for this endpoint. + */ + uint32 StartSeq() const { return static_cast(start_seq); } + + /** + * @return The starting TCP sequence number for this endpoint, in terms + * of a signed sequence space, which may account for initial + * sequence space wraparounds (underflow/overflow). + */ + int64 StartSeqI64() const { return start_seq; } + + /** + * @return The sequence number after the last TCP sequence number seen + * from this endpoint. + */ uint32 LastSeq() const { return last_seq; } + + /** + * @return The last TCP acknowledgement number seen from this endpoint. + */ uint32 AckSeq() const { return ack_seq; } - void InitStartSeq(uint32 seq) { start_seq = seq; } + /** + * @return The number of times the TCP sequence has wrapped around + * for this endpoint (i.e. overflowed a uint32). + */ + uint32 SeqWraps() const { return seq_wraps; } + + /** + * @return The number of times the TCP acknowledgement sequence has + * wrapped around for this endpoint (i.e. overflowed a uint32). + */ + uint32 AckWraps() const { return ack_wraps; } + + /** + * @param wraps Number of times a 32-bit sequence space has wrapped. + * @return A 64-bit sequence space number it would take to overflow + * a 32-bit sequence space \a wraps number of times. + */ + static uint64 ToFullSeqSpace(uint32 wraps) + { return (uint64(wraps) << 32); } + + /** + * @param tcp_seq_num A 32-bit TCP sequence space number. + * @param wraparounds Number of times a 32-bit sequence space has wrapped. + * @return \a tcp_seq_num expanded out in to a 64-bit sequence space, + * accounting for the number of times the 32-bit space overflowed. + */ + static uint64 ToFullSeqSpace(uint32 tcp_seq_num, uint32 wraparounds) + { return ToFullSeqSpace(wraparounds) + tcp_seq_num; } + + /** + * @param tcp_seq_num A 32-bit TCP sequence space number. + * @param wraparounds Number of times a 32-bit sequence space has wrapped. + * @return \a tcp_seq_num expanded out in to a 64-bit sequence space, + * accounting for the number of times the 32-bit space overflowed + * and relative the the starting sequence number for this endpoint. + */ + uint64 ToRelativeSeqSpace(uint32 tcp_seq_num, uint32 wraparounds) const + { + return ToFullSeqSpace(tcp_seq_num, wraparounds) - StartSeqI64(); + } + + void InitStartSeq(int64 seq) { start_seq = seq; } void InitLastSeq(uint32 seq) { last_seq = seq; } void InitAckSeq(uint32 seq) { ack_seq = seq; } void UpdateLastSeq(uint32 seq) { if ( seq < last_seq ) - ++last_seq_high; + ++seq_wraps; last_seq = seq; } void UpdateAckSeq(uint32 seq) { if ( seq < ack_seq ) - ++ack_seq_high; + ++ack_wraps; ack_seq = seq; } @@ -71,7 +131,10 @@ public: // We allow for possibly one octet being ack'd in the case of // an initial SYN exchange. int NoDataAcked() const - { return ack_seq == start_seq || ack_seq == start_seq + 1; } + { + uint64 ack = ToFullSeqSpace(ack_seq, ack_wraps); + return ack == StartSeqI64() || ack == StartSeqI64() + 1; + } Connection* Conn() const; @@ -96,16 +159,16 @@ public: // // If we're not processing contents, then naturally each of // these is empty. - void SizeBufferedData(int& waiting_on_hole, int& waiting_on_ack); + void SizeBufferedData(uint64& waiting_on_hole, uint64& waiting_on_ack); int ValidChecksum(const struct tcphdr* tp, int len) const; // Returns true if the data was used (and hence should be recorded // in the save file), false otherwise. - int DataSent(double t, int seq, int len, int caplen, const u_char* data, + int DataSent(double t, uint64 seq, int len, int caplen, const u_char* data, const IP_Hdr* ip, const struct tcphdr* tp); - void AckReceived(int seq); + void AckReceived(uint64 seq); void SetContentsFile(BroFile* f); BroFile* GetContentsFile() const { return contents_file; } @@ -139,20 +202,25 @@ public: int window_scale; // from the TCP option uint32 window_ack_seq; // at which ack_seq number did we record 'window' uint32 window_seq; // at which sending sequence number did we record 'window' - int contents_start_seq; // relative seq # where contents file starts - int FIN_seq; // relative seq # to start_seq + uint64 contents_start_seq; // relative seq # where contents file starts + uint64 FIN_seq; // relative seq # to start_seq int SYN_cnt, FIN_cnt, RST_cnt; int did_close; // whether we've reported it closing int is_orig; - // Sequence numbers associated with last control packets. + // Relative sequence numbers associated with last control packets. // Used to determine whether ones seen again are interesting, // for tracking history. - uint32 hist_last_SYN, hist_last_FIN, hist_last_RST; + uint64 hist_last_SYN, hist_last_FIN, hist_last_RST; protected: - uint32 start_seq, last_seq, ack_seq; // in host order - uint32 last_seq_high, ack_seq_high; + int64 start_seq; // Initial TCP sequence number in host order. + // Signed 64-bit to detect initial sequence wrapping. + // Use StartSeq() accessor if need it in terms of + // an absolute TCP sequence number. + uint32 last_seq, ack_seq; // in host order + uint32 seq_wraps, ack_wraps; // Number of times 32-bit TCP sequence space + // has wrapped around (overflowed). }; #define ENDIAN_UNKNOWN 0 diff --git a/src/analyzer/protocol/tcp/TCP_Reassembler.cc b/src/analyzer/protocol/tcp/TCP_Reassembler.cc index da8dd857fd..1fabfc5d73 100644 --- a/src/analyzer/protocol/tcp/TCP_Reassembler.cc +++ b/src/analyzer/protocol/tcp/TCP_Reassembler.cc @@ -14,11 +14,6 @@ using namespace analyzer::tcp; // Note, sequence numbers are relative. I.e., they start with 1. -// TODO: The Reassembler should start using 64 bit ints for keeping track of -// sequence numbers; currently they become negative once 2GB are exceeded. -// -// See #348 for more information. - const bool DEBUG_tcp_contents = false; const bool DEBUG_tcp_connection_close = false; const bool DEBUG_tcp_match_undelivered = false; @@ -44,9 +39,7 @@ TCP_Reassembler::TCP_Reassembler(analyzer::Analyzer* arg_dst_analyzer, deliver_tcp_contents = 0; skip_deliveries = 0; did_EOF = 0; -#ifdef ENABLE_SEQ_TO_SKIP seq_to_skip = 0; -#endif in_delivery = false; if ( tcp_contents ) @@ -73,12 +66,11 @@ TCP_Reassembler::~TCP_Reassembler() void TCP_Reassembler::Done() { - MatchUndelivered(-1); + MatchUndelivered(-1, true); if ( record_contents_file ) { // Record any undelivered data. - if ( blocks && - seq_delta(last_reassem_seq, last_block->upper) < 0 ) + if ( blocks && last_reassem_seq < last_block->upper ) RecordToSeq(last_reassem_seq, last_block->upper, record_contents_file); @@ -86,13 +78,13 @@ void TCP_Reassembler::Done() } } -void TCP_Reassembler::SizeBufferedData(int& waiting_on_hole, - int& waiting_on_ack) const +void TCP_Reassembler::SizeBufferedData(uint64& waiting_on_hole, + uint64& waiting_on_ack) const { waiting_on_hole = waiting_on_ack = 0; for ( DataBlock* b = blocks; b; b = b->next ) { - if ( seq_delta(b->seq, last_reassem_seq) <= 0 ) + if ( b->seq <= last_reassem_seq ) // We must have delivered this block, but // haven't yet trimmed it. waiting_on_ack += b->Size(); @@ -126,7 +118,7 @@ void TCP_Reassembler::SetContentsFile(BroFile* f) } -void TCP_Reassembler::Undelivered(int up_to_seq) +void TCP_Reassembler::Undelivered(uint64 up_to_seq) { TCP_Endpoint* endpoint = endp; TCP_Endpoint* peer = endpoint->peer; @@ -142,13 +134,7 @@ void TCP_Reassembler::Undelivered(int up_to_seq) // was a keep-alive. So, in either case, just ignore it. // TODO: Don't we need to update last_reassm_seq ???? - if ( up_to_seq >=0 ) - // Since seq are currently only 32 bit signed - // integers, they will become negative if a - // connection has more than 2GB of data. Remove the - // above if and always return here, once we're using - // 64 bit ints - return; + return; } #if 0 @@ -156,15 +142,14 @@ void TCP_Reassembler::Undelivered(int up_to_seq) { // Make sure we're not worrying about undelivered // FIN control octets! - int FIN_seq = endpoint->FIN_seq - endpoint->start_seq; - if ( seq_delta(up_to_seq, FIN_seq) >= 0 ) - up_to_seq = FIN_seq - 1; + if ( up_to_seq >= endpoint->FIN_seq ) + up_to_seq = endpoint->FIN_seq - 1; } #endif if ( DEBUG_tcp_contents ) { - DEBUG_MSG("%.6f Undelivered: IsOrig()=%d up_to_seq=%d, last_reassm=%d, " + DEBUG_MSG("%.6f Undelivered: IsOrig()=%d up_to_seq=%"PRIu64", last_reassm=%"PRIu64", " "endp: FIN_cnt=%d, RST_cnt=%d, " "peer: FIN_cnt=%d, RST_cnt=%d\n", network_time, IsOrig(), up_to_seq, last_reassem_seq, @@ -172,7 +157,7 @@ void TCP_Reassembler::Undelivered(int up_to_seq) peer->FIN_cnt, peer->RST_cnt); } - if ( seq_delta(up_to_seq, last_reassem_seq) <= 0 ) + if ( up_to_seq <= last_reassem_seq ) // This should never happen. (Reassembler::TrimToSeq has the only call // to this method and only if this condition is not true). reporter->InternalError("Calling Undelivered for data that has already been delivered (or has already been marked as undelivered"); @@ -195,10 +180,10 @@ void TCP_Reassembler::Undelivered(int up_to_seq) { if ( DEBUG_tcp_contents ) { - DEBUG_MSG("%.6f Undelivered: IsOrig()=%d, seq=%d, len=%d, " + DEBUG_MSG("%.6f Undelivered: IsOrig()=%d, seq=%"PRIu64", len=%"PRIu64", " "skip_deliveries=%d\n", network_time, IsOrig(), last_reassem_seq, - seq_delta(up_to_seq, last_reassem_seq), + up_to_seq - last_reassem_seq, skip_deliveries); } @@ -210,8 +195,8 @@ void TCP_Reassembler::Undelivered(int up_to_seq) // packet, but it's undelievered because it's out of // sequence. - int seq = last_reassem_seq; - int len = seq_delta(up_to_seq, last_reassem_seq); + uint64 seq = last_reassem_seq; + uint64 len = up_to_seq - last_reassem_seq; // Only report on content gaps for connections that // are in a cleanly established state. In other @@ -255,19 +240,19 @@ void TCP_Reassembler::Undelivered(int up_to_seq) RecordToSeq(last_reassem_seq, up_to_seq, record_contents_file); if ( tcp_match_undelivered ) - MatchUndelivered(up_to_seq); + MatchUndelivered(up_to_seq, false); // But we need to re-adjust last_reassem_seq in either case. last_reassem_seq = up_to_seq; // we've done our best ... } -void TCP_Reassembler::MatchUndelivered(int up_to_seq) +void TCP_Reassembler::MatchUndelivered(uint64 up_to_seq, bool use_last_upper) { if ( ! blocks || ! rule_matcher ) return; ASSERT(last_block); - if ( up_to_seq == -1 ) + if ( use_last_upper ) up_to_seq = last_block->upper; // ### Note: the original code did not check whether blocks have @@ -277,36 +262,35 @@ void TCP_Reassembler::MatchUndelivered(int up_to_seq) // We are to match any undelivered data, from last_reassem_seq to // min(last_block->upper, up_to_seq). // Is there such data? - if ( seq_delta(up_to_seq, last_reassem_seq) <= 0 || - seq_delta(last_block->upper, last_reassem_seq) <= 0 ) + if ( up_to_seq <= last_reassem_seq || + last_block->upper <= last_reassem_seq ) return; // Skip blocks that are already delivered (but not ACK'ed). // Question: shall we instead keep a pointer to the first undelivered // block? DataBlock* b; - for ( b = blocks; b && seq_delta(b->upper, last_reassem_seq) <= 0; - b = b->next ) + for ( b = blocks; b && b->upper <= last_reassem_seq; b = b->next ) tcp_analyzer->Conn()->Match(Rule::PAYLOAD, b->block, b->Size(), false, false, IsOrig(), false); ASSERT(b); } -void TCP_Reassembler::RecordToSeq(int start_seq, int stop_seq, BroFile* f) +void TCP_Reassembler::RecordToSeq(uint64 start_seq, uint64 stop_seq, BroFile* f) { DataBlock* b = blocks; // Skip over blocks up to the start seq. - while ( b && seq_delta(b->upper, start_seq) <= 0 ) + while ( b && b->upper <= start_seq ) b = b->next; if ( ! b ) return; - int last_seq = start_seq; - while ( b && seq_delta(b->upper, stop_seq) <= 0 ) + uint64 last_seq = start_seq; + while ( b && b->upper <= stop_seq ) { - if ( seq_delta(b->seq, last_seq) > 0 ) + if ( b->seq > last_seq ) RecordGap(last_seq, b->seq, f); RecordBlock(b, f); @@ -316,7 +300,7 @@ void TCP_Reassembler::RecordToSeq(int start_seq, int stop_seq, BroFile* f) if ( b ) // Check for final gap. - if ( seq_delta(last_seq, stop_seq) < 0 ) + if ( last_seq < stop_seq ) RecordGap(last_seq, stop_seq, f); } @@ -337,9 +321,9 @@ void TCP_Reassembler::RecordBlock(DataBlock* b, BroFile* f) } } -void TCP_Reassembler::RecordGap(int start_seq, int upper_seq, BroFile* f) +void TCP_Reassembler::RecordGap(uint64 start_seq, uint64 upper_seq, BroFile* f) { - if ( f->Write(fmt("\n<>\n", seq_delta(upper_seq, start_seq))) ) + if ( f->Write(fmt("\n<>\n", upper_seq - start_seq)) ) return; reporter->Error("TCP_Reassembler contents gap write failed"); @@ -356,8 +340,8 @@ void TCP_Reassembler::RecordGap(int start_seq, int upper_seq, BroFile* f) void TCP_Reassembler::BlockInserted(DataBlock* start_block) { - if ( seq_delta(start_block->seq, last_reassem_seq) > 0 || - seq_delta(start_block->upper, last_reassem_seq) <= 0 ) + if ( start_block->seq > last_reassem_seq || + start_block->upper <= last_reassem_seq ) return; // We've filled a leading hole. Deliver as much as possible. @@ -367,12 +351,12 @@ void TCP_Reassembler::BlockInserted(DataBlock* start_block) // loop we have to take care not to deliver already-delivered // data. for ( DataBlock* b = start_block; - b && seq_delta(b->seq, last_reassem_seq) <= 0; b = b->next ) + b && b->seq <= last_reassem_seq; b = b->next ) { if ( b->seq == last_reassem_seq ) { // New stuff. - int len = b->Size(); - int seq = last_reassem_seq; + uint64 len = b->Size(); + uint64 seq = last_reassem_seq; last_reassem_seq += len; @@ -406,10 +390,10 @@ void TCP_Reassembler::BlockInserted(DataBlock* start_block) // TCP_Connection::NextPacket. } -void TCP_Reassembler::Overlap(const u_char* b1, const u_char* b2, int n) +void TCP_Reassembler::Overlap(const u_char* b1, const u_char* b2, uint64 n) { if ( DEBUG_tcp_contents ) - DEBUG_MSG("%.6f TCP contents overlap: %d IsOrig()=%d\n", network_time, n, IsOrig()); + DEBUG_MSG("%.6f TCP contents overlap: %"PRIu64" IsOrig()=%d\n", network_time, n, IsOrig()); if ( rexmit_inconsistency && memcmp((const void*) b1, (const void*) b2, n) && @@ -438,7 +422,7 @@ bool TCP_Reassembler::DoUnserialize(UnserialInfo* info) return false; // Cannot be reached. } -void TCP_Reassembler::Deliver(int seq, int len, const u_char* data) +void TCP_Reassembler::Deliver(uint64 seq, int len, const u_char* data) { if ( type == Direct ) dst_analyzer->NextStream(len, data, IsOrig()); @@ -446,24 +430,24 @@ void TCP_Reassembler::Deliver(int seq, int len, const u_char* data) dst_analyzer->ForwardStream(len, data, IsOrig()); } -int TCP_Reassembler::DataSent(double t, int seq, int len, +int TCP_Reassembler::DataSent(double t, uint64 seq, int len, const u_char* data, bool replaying) { - int ack = seq_delta(endp->AckSeq(), endp->StartSeq()); - int upper_seq = seq + len; + uint64 ack = endp->ToRelativeSeqSpace(endp->AckSeq(), endp->AckWraps()); + uint64 upper_seq = seq + len; if ( DEBUG_tcp_contents ) { - DEBUG_MSG("%.6f DataSent: IsOrig()=%d seq=%d upper=%d ack=%d\n", + DEBUG_MSG("%.6f DataSent: IsOrig()=%d seq=%"PRIu64" upper=%"PRIu64" ack=%"PRIu64"\n", network_time, IsOrig(), seq, upper_seq, ack); } if ( skip_deliveries ) return 0; - if ( seq_delta(seq, ack) < 0 && ! replaying ) + if ( seq < ack && ! replaying ) { - if ( seq_delta(upper_seq, ack) <= 0 ) + if ( upper_seq <= ack ) // We've already delivered this and it's been acked. return 0; @@ -472,7 +456,7 @@ int TCP_Reassembler::DataSent(double t, int seq, int len, // packet held [a, a+b) and this packet holds [a, a+c) for c>b // (which some TCP's will do when retransmitting). Trim the // packet to just the unacked data. - int amount_acked = seq_delta(ack, seq); + uint64 amount_acked = ack - seq; seq += amount_acked; data += amount_acked; len -= amount_acked; @@ -500,16 +484,13 @@ int TCP_Reassembler::DataSent(double t, int seq, int len, } -void TCP_Reassembler::AckReceived(int seq) +void TCP_Reassembler::AckReceived(uint64 seq) { - if ( endp->FIN_cnt > 0 && seq_delta(seq, endp->FIN_seq) >= 0 ) - // TrimToSeq: FIN_seq - 1 + if ( endp->FIN_cnt > 0 && seq >= endp->FIN_seq ) seq = endp->FIN_seq - 1; - int bytes_covered = seq_delta(seq, trim_seq); - - if ( bytes_covered <= 0 ) - // Zero, or negative in sequence-space terms. Nothing to do. + if ( seq <= trim_seq ) + // Nothing to do. return; bool test_active = ! skip_deliveries && ! tcp_analyzer->Skipping() && @@ -517,12 +498,12 @@ void TCP_Reassembler::AckReceived(int seq) (endp->state == TCP_ENDPOINT_ESTABLISHED && endp->peer->state == TCP_ENDPOINT_ESTABLISHED ) ); - int num_missing = TrimToSeq(seq); + uint64 num_missing = TrimToSeq(seq); if ( test_active ) { ++tot_ack_events; - tot_ack_bytes += bytes_covered; + tot_ack_bytes += seq - trim_seq; if ( num_missing > 0 ) { @@ -602,20 +583,18 @@ void TCP_Reassembler::CheckEOF() // Deliver, DeliverBlock is not virtual, and this allows us to insert // operations that apply to all connections using TCP_Contents. -void TCP_Reassembler::DeliverBlock(int seq, int len, const u_char* data) +void TCP_Reassembler::DeliverBlock(uint64 seq, int len, const u_char* data) { -#ifdef ENABLE_SEQ_TO_SKIP - if ( seq_delta(seq + len, seq_to_skip) <= 0 ) + if ( seq + len <= seq_to_skip ) return; - if ( seq_delta(seq, seq_to_skip) < 0 ) + if ( seq < seq_to_skip ) { - int to_skip = seq_delta(seq_to_skip, seq); + uint64 to_skip = seq_to_skip - seq; len -= to_skip; data += to_skip; seq = seq_to_skip; } -#endif if ( deliver_tcp_contents ) { @@ -640,23 +619,21 @@ void TCP_Reassembler::DeliverBlock(int seq, int len, const u_char* data) in_delivery = true; Deliver(seq, len, data); in_delivery = false; -#ifdef ENABLE_SEQ_TO_SKIP - if ( seq_delta(seq + len, seq_to_skip) < 0 ) + + if ( seq + len < seq_to_skip ) SkipToSeq(seq_to_skip); -#endif + } -#ifdef ENABLE_SEQ_TO_SKIP -void TCP_Reassembler::SkipToSeq(int seq) +void TCP_Reassembler::SkipToSeq(uint64 seq) { - if ( seq_delta(seq, seq_to_skip) > 0 ) + if ( seq > seq_to_skip ) { seq_to_skip = seq; if ( ! in_delivery ) TrimToSeq(seq); } } -#endif int TCP_Reassembler::DataPending() const { @@ -665,20 +642,28 @@ int TCP_Reassembler::DataPending() const if ( skip_deliveries ) return 0; - uint32 delivered_seq = Endpoint()->StartSeq() + DataSeq(); + uint64 delivered_seq = Endpoint()->StartSeqI64() + DataSeq(); + uint64 last_seq = TCP_Endpoint::ToFullSeqSpace(Endpoint()->LastSeq(), + Endpoint()->SeqWraps()); + + if ( last_seq < delivered_seq ) + return 0; // Q. Can we say that? - // ASSERT(delivered_seq <= Endpoint()->LastSeq()); + // ASSERT(delivered_seq <= last_seq); // - // A. Yes, but only if we express it with 64-bit comparison - // to handle sequence wrapping around. (Or perhaps seq_delta - // is enough here?) + // A. That should be true if endpoints are always initialized w/ + // trustworthy sequence numbers, though it seems that may not currently + // be the case. e.g. a RST packet may end up initializing the endpoint. + // In that case, maybe there's not any "right" way to initialize it, so + // the check for last_seq < delivered_seq sort of serves as a check for + // endpoints that weren't initialized w/ meaningful sequence numbers. // We've delivered everything if we're up to the penultimate // sequence number (since a FIN consumes an octet in the // sequence space), or right at it (because a RST does not). - if ( delivered_seq != Endpoint()->LastSeq() - 1 && - delivered_seq != Endpoint()->LastSeq() ) + if ( delivered_seq != last_seq - 1 && + delivered_seq != last_seq ) return 1; // If we've sent RST, then we can't send ACKs any more. diff --git a/src/analyzer/protocol/tcp/TCP_Reassembler.h b/src/analyzer/protocol/tcp/TCP_Reassembler.h index e3dcf82a1b..3dfe75bf10 100644 --- a/src/analyzer/protocol/tcp/TCP_Reassembler.h +++ b/src/analyzer/protocol/tcp/TCP_Reassembler.h @@ -4,13 +4,6 @@ #include "Reassem.h" #include "TCP_Endpoint.h" -// The skip_to_seq feature does not work correctly with connections >2GB due -// to use of 32 bit signed ints (see comments in TCP_Reassembler.cc) Since -// it's not used by any analyzer or policy script we disable it. Could be -// added back in once we start using 64bit integers. -// -// #define ENABLE_SEQ_TO_SKIP - class BroFile; class Connection; @@ -48,12 +41,12 @@ public: // // If we're not processing contents, then naturally each of // these is empty. - void SizeBufferedData(int& waiting_on_hole, int& waiting_on_ack) const; + void SizeBufferedData(uint64& waiting_on_hole, uint64& waiting_on_ack) const; // How much data is pending delivery since it's not yet reassembled. // Includes the data due to holes (so this value is a bit different // from waiting_on_hole above; and is computed in a different fashion). - int NumUndeliveredBytes() const + uint64 NumUndeliveredBytes() const { if ( last_block ) return last_block->upper - last_reassem_seq; @@ -64,19 +57,15 @@ public: void SetContentsFile(BroFile* f); BroFile* GetContentsFile() const { return record_contents_file; } - void MatchUndelivered(int up_to_seq = -1); + void MatchUndelivered(uint64 up_to_seq, bool use_last_upper); -#ifdef ENABLE_SEQ_TO_SKIP // Skip up to seq, as if there's a content gap. // Can be used to skip HTTP data for performance considerations. - void SkipToSeq(int seq); -} } // namespace analyzer::* + void SkipToSeq(uint64 seq); -#endif - - int DataSent(double t, int seq, int len, const u_char* data, + int DataSent(double t, uint64 seq, int len, const u_char* data, bool replaying=true); - void AckReceived(int seq); + void AckReceived(uint64 seq); // Checks if we have delivered all contents that we can possibly // deliver for this endpoint. Calls TCP_Analyzer::EndpointEOF() @@ -86,35 +75,32 @@ public: int HasUndeliveredData() const { return HasBlocks(); } int HadGap() const { return had_gap; } int DataPending() const; - int DataSeq() const { return LastReassemSeq(); } + uint64 DataSeq() const { return LastReassemSeq(); } - void DeliverBlock(int seq, int len, const u_char* data); - virtual void Deliver(int seq, int len, const u_char* data); + void DeliverBlock(uint64 seq, int len, const u_char* data); + virtual void Deliver(uint64 seq, int len, const u_char* data); TCP_Endpoint* Endpoint() { return endp; } const TCP_Endpoint* Endpoint() const { return endp; } int IsOrig() const { return endp->IsOrig(); } -#ifdef ENABLE_SEQ_TO_SKIP - bool IsSkippedContents(int seq, int length) const - { return seq + length <= seq_to_skip; } -} } // namespace analyzer::* -#endif + bool IsSkippedContents(uint64 seq, int length) const + { return seq + length <= seq_to_skip; } private: TCP_Reassembler() { } DECLARE_SERIAL(TCP_Reassembler); - void Undelivered(int up_to_seq); + void Undelivered(uint64 up_to_seq); - void RecordToSeq(int start_seq, int stop_seq, BroFile* f); + void RecordToSeq(uint64 start_seq, uint64 stop_seq, BroFile* f); void RecordBlock(DataBlock* b, BroFile* f); - void RecordGap(int start_seq, int upper_seq, BroFile* f); + void RecordGap(uint64 start_seq, uint64 upper_seq, BroFile* f); void BlockInserted(DataBlock* b); - void Overlap(const u_char* b1, const u_char* b2, int n); + void Overlap(const u_char* b1, const u_char* b2, uint64 n); TCP_Endpoint* endp; @@ -123,9 +109,8 @@ private: unsigned int did_EOF:1; unsigned int skip_deliveries:1; -#ifdef ENABLE_SEQ_TO_SKIP - int seq_to_skip; -#endif + uint64 seq_to_skip; + bool in_delivery; BroFile* record_contents_file; // file on which to reassemble contents diff --git a/src/analyzer/protocol/tcp/events.bif b/src/analyzer/protocol/tcp/events.bif index cac18bfa3e..f52fadaebb 100644 --- a/src/analyzer/protocol/tcp/events.bif +++ b/src/analyzer/protocol/tcp/events.bif @@ -223,9 +223,10 @@ event connection_EOF%(c: connection, is_orig: bool%); ## corresponds to one set flag, as follows: ``S`` -> SYN; ``F`` -> FIN; ## ``R`` -> RST; ``A`` -> ACK; ``P`` -> PUSH. ## -## seq: The packet's TCP sequence number. +## seq: The packet's relative TCP sequence number. ## -## ack: The packet's ACK number. +## ack: If the ACK flag is set for the packet, the packet's relative ACK +## number, else zero. ## ## len: The length of the TCP payload, as specified in the packet header. ## diff --git a/src/analyzer/protocol/teredo/Teredo.cc b/src/analyzer/protocol/teredo/Teredo.cc index d81f90d840..400f38839e 100644 --- a/src/analyzer/protocol/teredo/Teredo.cc +++ b/src/analyzer/protocol/teredo/Teredo.cc @@ -140,7 +140,7 @@ RecordVal* TeredoEncapsulation::BuildVal(const IP_Hdr* inner) const } void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen) + uint64 seq, const IP_Hdr* ip, int caplen) { Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); diff --git a/src/analyzer/protocol/teredo/Teredo.h b/src/analyzer/protocol/teredo/Teredo.h index 0da007187d..68dfb8bb73 100644 --- a/src/analyzer/protocol/teredo/Teredo.h +++ b/src/analyzer/protocol/teredo/Teredo.h @@ -19,7 +19,7 @@ public: virtual void Done(); virtual void DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new Teredo_Analyzer(conn); } diff --git a/src/analyzer/protocol/udp/UDP.cc b/src/analyzer/protocol/udp/UDP.cc index 4c26ae5d99..36d5831a6a 100644 --- a/src/analyzer/protocol/udp/UDP.cc +++ b/src/analyzer/protocol/udp/UDP.cc @@ -38,7 +38,7 @@ void UDP_Analyzer::Done() } void UDP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, - int seq, const IP_Hdr* ip, int caplen) + uint64 seq, const IP_Hdr* ip, int caplen) { assert(ip); diff --git a/src/analyzer/protocol/udp/UDP.h b/src/analyzer/protocol/udp/UDP.h index bcfee401b0..792f83de8a 100644 --- a/src/analyzer/protocol/udp/UDP.h +++ b/src/analyzer/protocol/udp/UDP.h @@ -28,7 +28,7 @@ public: protected: virtual void Done(); virtual void DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); virtual bool IsReuse(double t, const u_char* pkt); virtual unsigned int MemoryAllocation() const; diff --git a/src/net_util.h b/src/net_util.h index e5dbbcdae2..0f34335267 100644 --- a/src/net_util.h +++ b/src/net_util.h @@ -119,7 +119,7 @@ struct ip6_rthdr { // True if sequence # a is between b and c (b <= a <= c). It must be true // that b <= c in the sequence space. -inline int seq_between(uint32 a, uint32 b, uint32 c) +inline bool seq_between(uint32 a, uint32 b, uint32 c) { if ( b <= c ) return a >= b && a <= c; @@ -128,9 +128,9 @@ inline int seq_between(uint32 a, uint32 b, uint32 c) } // Returns a - b, adjusted for sequence wraparound. -inline int seq_delta(uint32 a, uint32 b) +inline int32 seq_delta(uint32 a, uint32 b) { - return int(a-b); + return a - b; } class IPAddr; diff --git a/testing/btest/Baseline/core.tcp.large-file-reassembly/conn.log b/testing/btest/Baseline/core.tcp.large-file-reassembly/conn.log new file mode 100644 index 0000000000..c76f4dd03b --- /dev/null +++ b/testing/btest/Baseline/core.tcp.large-file-reassembly/conn.log @@ -0,0 +1,12 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open 2014-04-09-16-44-53 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string bool count string count count count count set[string] +1395939406.175845 CjhGID4nQcgTWjvg4c 192.168.56.1 59763 192.168.56.101 63988 tcp ftp-data 0.001676 0 270 SF - 0 ShAdfFa 5 272 4 486 (empty) +1395939411.361078 CCvvfg3TEfuqmmG4bh 192.168.56.1 59764 192.168.56.101 37150 tcp ftp-data 150.496065 0 5416666670 SF - 4675708816 ShAdfFa 13 688 12 24454 (empty) +1395939399.984671 CXWv6p3arKYeMETxOg 192.168.56.1 59762 192.168.56.101 21 tcp ftp 169.634297 104 1041 SF - 0 ShAdDaFf 31 1728 18 1985 (empty) +#close 2014-04-09-16-44-54 diff --git a/testing/btest/Baseline/core.tcp.large-file-reassembly/files.log b/testing/btest/Baseline/core.tcp.large-file-reassembly/files.log new file mode 100644 index 0000000000..b8b9bf9db1 --- /dev/null +++ b/testing/btest/Baseline/core.tcp.large-file-reassembly/files.log @@ -0,0 +1,11 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path files +#open 2014-04-09-16-44-53 +#fields ts fuid tx_hosts rx_hosts conn_uids source depth analyzers mime_type filename duration local_orig is_orig seen_bytes total_bytes missing_bytes overflow_bytes timedout parent_fuid md5 sha1 sha256 extracted +#types time string set[addr] set[addr] set[string] string count set[string] string string interval bool bool count count count count bool string string string string string +1395939406.177079 FAb5m22Dhe2Zi95anf 192.168.56.101 192.168.56.1 CjhGID4nQcgTWjvg4c FTP_DATA 0 DATA_EVENT text/plain - 0.000000 - F 270 - 0 0 F - - - - - +1395939411.364462 FhI0ao2FNTjabdfSBd 192.168.56.101 192.168.56.1 CCvvfg3TEfuqmmG4bh FTP_DATA 0 DATA_EVENT text/plain - 150.490904 - F 23822 - 5416642848 0 F - - - - - +#close 2014-04-09-16-44-54 diff --git a/testing/btest/Baseline/core.tcp.large-file-reassembly/out b/testing/btest/Baseline/core.tcp.large-file-reassembly/out new file mode 100644 index 0000000000..dd3960bdb7 --- /dev/null +++ b/testing/btest/Baseline/core.tcp.large-file-reassembly/out @@ -0,0 +1,11 @@ +file_chunk, 270, 0, drwxr-xr-x 3 0 0 4096 Mar 27 11:55 .^M^Jdrwxr-xr-x 3 0 0 4096 Mar 27 11:55 ..^M^Jdrwxr-xr-x 2 0 0 4096 Mar 27 11:43 pub^M^J-rw-rw-r-- 1 1000 1000 5416666670 Mar 27 11:52 rand.txt^M^J +file_chunk, 14480, 0, TCf8ZQLH67eBQks8SjFaumquAt7f9eg6GNvyLgvdbRl4QShP5o47kdBupR8IxbCz^JZ1sR200ZDSWX1TeH7UVjxBg+eQ8YpmUbnjqePKMUBbb0uq6tDGYGauJiZnSHVNez^JVZmm+pCPVdIGyWe27Xgub9s8PyDBjVD3amDxvoFb8ad86eTDcrzuPZ0/iFP4CnDY^JHFLAvEbvgBVuKTmveyUjmis9nRgvjaeoHhBV7/XtC6fP9ayGCHqJIYs7pGHEm0hi^Ji95bgfyFCEB2hBvwGGNQStTigpE89eURtsmxnK+I3Hxk+dyBQjQ6hTxQlwmqZuto^J/ZMEv8KCfrZUtTh4s3l621DN7wRiUbgltFXAIoaWwc5YACR65582L9aEX86XVNXt^J8IfLL0klmNgaRO49b1He7exMUA0UCUY9DFdFfqyt2hMoPJqEfm4nRH0x/xQs5x/G^Jq5K+JPJtkyxvqI7AwMSRaN+k7ez12fZCwzpPIU8taS++y0op+kmXsPaTSJpPe8Ev^Js1XyutkfH5OPmrt413q80e4UTlV73zGs8XMBO+VL+Jb+0IUNnmiyWzqIuYokI9RS^JCdLbWCdLGGb6+k76rY4oIDnUbAP7YCDdr2s3QZ9aLMNaSpuyKY19WNzNbw8cI81O^JIuTY6C3NzXMItjWriqAzmMl2AXztrPZZ2GFhyUy1Hwf4DufBEVeDMvhVd+WlfzVn^JlRdy8Os5X0ULPhFDmej+1igX/AD9a2Yf26vqak8AUvLbJciJWFZp17sZYXus6zos^JR17iUaq63Mfl0dk6wnktVLIGt6EHBYb/oJ65ZGLMuFSDqv+NvVhuyNd/IIR4tUKO^JqNVH/+FHHqjbpZQvFHSTqOGA62rb1AecBRnliYKjRTsg7u4/HI+v/jwPnp89pntJ^JkztVIkc7VVG0GhvgnKFjmV+bVddG3UpB3juIVMJwcFOFnQNzF0hm7oDdfEYXEUht^JW/TCpIox9O+VQknCTo4iZcZOOXGkEYRc11C+P2WPk46b2OER/l8agJPG9qS6Yf35^J+ljLAVFNgW12iqiqCYmfQM6z1l+6RIo/DlDSALbhYjTV9CG02WwyQiG4WpkAHnx+^JiaSwwrKYCklvFoUtisVGfV19rTo1HGGG2FFo5oCY4BPmbIQWidTXJtA1JkHsni5R^JPlG8elgJkTJJKkzdwAh5V0UL+m1y2zH+NyQHFzj9zunB0g5QEmuYMt18TvXy7D/W^JkgJbWGvDCKY36ZKVhWTTqsgQ2xecH+vKBaCF4IofA0joodZzBv9GH6UOSkhTML57^J5BRbLoPr3IqbTAx7PFlixb+fIur2UeUo+RYZeDudo7HmvLBnsGFw0K9rBVNg1D8C^JwcO4lpwxZEPsLeqKChpHpQugpkfSnC9B2/Oywoep2FAI2OL4zL9nOWb+QnE8kibe^JmZVCAm6p2qnr1nfKMUP2YWKbTeyowi6dlS9SfQdzc5+a1Asg/+S8ZWOPDJGauS6h^JNrfV2HRoHwYmpqvxN3/8A7vkF+rPgx1yeGHK0mDVn4F2ke1E+r5e1F9IZzM90EkR^JFX1hEcNcqzPX/rerGjD6WNBDdoAvmsth8mrcsIf0iq/yvNblB9R4Vg1+bxHYOXYf^JE70vkvtaSmWCQ5gi19SYK01XR42Jnu+cnUtuCr3P2relXC5TjBqz3V2CO3St9tX/^J8sdKZWDc/kHAQ5uVZAIonoVp6Ffeu2Zz3B0NFjJj9hyJtLIJ+Qg2Bru0YeplIIQz^Jw8WXZ3xHw7nN2pIMRMkef8pAoonGsrUySUhhSjEMZCYDXvWpTSrOwm+LRsyJ9czy^J4kUBxgoiCdxGi0NpljEzvrj27ElBmqa2E/bOoK39ff89GSBvXeHw6NVrrDZhEFrU^JfnALNwjCGdxCrkPm2sw03cdsPRVO0yQppyYbT8MhWuzlq31VGps+EiwfpU+jHsw2^J7CuI4qC/n6yui5irPTV+GJmS900rfqCDab+PW6XJ82rGAN1lvV7+lz/x3lGcFCux^JUudDhQANxzHwTQGmwJeR4Fk+PGTAvQoWfgN+21hgPgIW4Yug1uKtL5IOK2rRVMTf^JljjxQ8FlEfZLdLZgiOOHnpioRz4n/SbcSMw15i9GHMmHE3wOmV7En11vBFPmUcYb^J+d2UaodnxE6psPmSfawBFI6TNT9fKaZchANali9OdFieh79e/7mox79DrzX4tuQT^JNLs1nj0jb+4Tm+LNqkJ5cvDkyFds0FbBd3CblDHNtdkIcSVj3TpkYz1wwYYogt7r^JV6wVmRQ09dhDmRSM8kVinGhVudTpBRH6+F922anxF9exYYKfYi7M/ODjuQLRCK7R^JwSNg7BDBVXt/Q31ryukAzcE5UtCk0LSlci02B1taq2Bp1ChFDpSzaqeshwgCQvYJ^JVLBPFdy21eqa8IQwXZ3wU2TEiGgJIv3k6M07uSDMCJF8/IPf7KmmOy/dotWXWSCe^J9FqYiGMYW5KRrTZnknhS2JYhC4iIHqlGYFYd5cSm3dtx6m1Y4hmqE4+JWRDK2I/s^JCkDbfOvU8UwES3k4tHORdqDn/b54EdEbnG06hfcg2B5FEg7cr90Qjdh838ldIcwG^JI0k9UewaVjjPL1dG585WFMQa3bZChzNN25kRGMQP24BGvA8wuKDseza7rn1dmrYw^JCRSsA2U7gNy96DKQFQX6Ga9uT9OCW+Ukvq2sejhL5cgiqZ6xZpV3WCFlFEjHEZDU^J/Jcaes5cbbkWLHe9PXwlLeCArWkwsrwhM/zS2vWN9xnvPzyYAaDqSlOPNeyBYW0t^JwEca4eu9Kg7dLNrZ8S6tEECdpor+9EAU6T8o60s20nUzmqG96yWhdl1mns+IHW8N^JwJ9u1uYlEKoAHPVdYY6MnWToAxH5KI1OaEfJ4He929/QGkIso6gRRyWlF2shqR+W^Jx74nIGsLeou4Ao8WGVjV0aa1qZiNw5KSB5QB5UuKlmTWG/gdk1APdsmudyg+Vc1T^JAXLdMwj7uvngrIZxFxqipXnWB7FPC4yzeiPu8qOoestmuqkhkD0FPCW5QFhk965F^Jxm9fqwgJPsjBTC5YTB2LOfTO5ZYdJiPYQmETOOe4a9ztL6HwQ2Y/zxc7GD4AbwQp^JM/AbXtIaCYgNkeG9vkJaLn6byDwdmJUZGHHNVjZca8wV6+YlboGrAYrJbX+ndyqH^JKquD7o1PkJTO+4H04lDmYquf/fRembQ51YGyVQaNqbLF1mbyfVd/lc+JJICTVT/o^Ju4+9yTKOhJG2Gb1DmBG+jOIuZkGv6m9CqZYfKTtDv9zwkUeNHMGcAX6n+TPc2WPI^JsBSKIdYnzlvRCMI9BJAWoNej5yQzzfCPlXd15Og+SK0mfM8+44iDRv/051rLVhcI^JCxQpRjq/NdINYF+WwwDoN4VlpPXLZkw1+qYoSHdstDiHv7uhRgP+cEbZXH8mDpe1^Jkj47aUHCLiGP8u1UgRXGH8A0jFp5yPEFU3SBePIehSZZynNB8u04mRpXc1kIlubA^JqnhGKpscdIZnO7KB7pQA2qF+s1I45amehPIBDBzbaGkMJe2Esqphgh3Rk695uPDm^JQM7JjrfhBTlNXxoxC48WdbI9+xzhTavuwP4BhUNADgDel9vxs+HkT1rLR907NaN1^JxWJdo2bsRFNdftSKf2XCthor9VHwOmyU0XI2yeVSxu9hdA1jK4M4C7fmRrQrwuoO^JS6fTlgbMeTey2ZHrJO/iDT+9sGfgT/oGDXYzZrbaFbiBRj5HLweXE+rAyIG77yUY^JZEqkeh1BA1KHSxqhXmkrYr+ambErzrQHIr6fTujmPVc5W1kIZEAhMdLDJ8U/C1dL^JjqjEA/VyjJr8A2gELABBiATb5ro485x/GdUHgOam0sYpHqG4wmsxnM8iVuxbwlS5^JC9z/MjVvBoLl83/YZjG1jfRLkaX6wzWXuSeybIDk7TilDwAdeFAbUfgEqH5xnXND^JPHnSaA8yOxba7kpuRDWJebGb2GPxiP6u0Wk8iXd3jnSJdE3+b69SXzgM82Wht6NH^JFkBEQWf8hDu0pAhxxU32yPCrLoRxCpl/K/p1cL01xtzDbj5Ncfhg5TbYYUyRw2UN^JSHQ46bN/ozKIQ02T+bhA7Z4BVjVw3Fens8jbZX+Z5ClnEiY5q4g+hR6estFTli3z^J0bQBij3OB0yseeOCcyLt9ZpepxQwgO6BNvecNuNtBwEq/xCx7ESzX3N7dVZAjWKE^JdyjbFMIPKMfIMlfU7wvuaxiyWkbVsBcPDPcyLja3qzO85GZgh0Uln+mCModfqZc/^JcplyVPYQBIFXAViGIFZONpAOWC29fy4j0uRsNYKKhRv6fSZzVNbVgeljKFwTCAXu^J8CtcxnpNOTYXuGZbgISo6oHxCy+fIK1Q14eaZepMWWYT22kWR7FlN4BOLcj50K/Z^JBxpcOexNb0QreketOWPWfHflY9YxB07ykX6djOH9ZOlITbZ0c2BMxfJxOaaNbidn^JX1Vka0i06Sk2iFw2MmxHJm5zwN6Ln4S9hCrwaPCDkmXOCoN0pr1jt9teBBA/LkDG^Jn+rp2U4CwSAtJy690+HlZ+Ni/m5QkchnSsGuYXeBE7feao+dBTJ5hyFpMKjjyOS3^Jf+vZkyNxOzgugBnQ5e0suK46y5GhpbrmNIbP8lJn04B6CFe/lidABVS50GK5LqCD^JtdtAyr+6LD0PCJU2pJeqwePqlbQmA5XZxOW1vJVNQJ4EEJfcJj8Ha2hynAOQaiT/^JAXtlD22EXutFfFgFBgkFJZ35+nO4TuSIawad8xkIBnpMX87wpp4nVi3aWd4sMr0o^JyXWSHcd3Y+izqfXH/6BqlUeXNGQjLlj7biMCosz3iFBRhOvUK1a5r90ZcVy+8+Ty^J4qT52tO7+bQOngxBiwqpnvKAONsxFFHWgR7/LjYbYKtgtq+1ibACiaSzQg+IVFP3^J1V7aZb9fZP0YBvbhv4JxdTXxFfJ4knugi+5mmm1PIyznXWnsWOEbYEnZV4dZIq5M^JQqBIYxrS+aWnUyE8DTsXqDUwVL/rBjbhK/1RxNT+mzHG7Q/phD3y2d8ysHlmAWfl^JDGZbZ8+Plpm7uhj/fK6b6FqYO9qJYoTSesyEsZ0Pfjb7uMrYjSbRyRg6yTuV3Qe+^Jjz+g9Nj63cFMlXVlvaBZgwu8giF/SmdkTM48IVc8BkeMJlPg0fnqcEbEgnMrYBsG^Jv8FdEUWTWvzoDFCiQRFrSnPF8GIBcwgrxN7wGqWexfQlzQsQ9XbJlACIwKMLzh2t^JQTr0zs9g8yAk9SQMahWtYJG4IPdAI0mH9dBSYzt0ATxtBe3NpAhrewtcNqTBnII5^JhUcSoygg4JGCBjxZpxle7/anr4CBduMHcAiL9JFCcWb/cg8uwFPm8p+Ddsz+e3ir^J5WZPHa8uXRupG0ZIY3kQXebizwq6aULjDSFy+ggEWHlkGHIAUYpvKXmCiQAWiKiP^JeBSIUBicoJSDOkf0xo1pvC+yKnjlYXhJob3YxuiKoYH6guAz/OSu0Yr/Y+w8fY2r^JmvpnxCwaLbjmYG/ihbaXtiic6xXYjb+OQKfrRywvDQ28UKoLj7lZ0rZfBPPjqGvv^J/qFSiqKvgDua36DPiFy6UO4D2747V7uZoXtWJQEmSEJZOC1NEbyhztzIksHVcT8Z^JKVIHWPyVa69yvmKpIGgEqE92sEvgrKpbeH3xJEekHPkDpCtojjVGJ1Vm2/OrNitV^JMWha/HsUn6obKV7MYIgSIH2BQfs01araaHR54nKL1PmwHvTnYKo7BY3IKxFsDVq/^J/QQWyib6DNqYagd8+jz8tgG3m8/RX0ZO3V8wLgpPNXgXruBIdaqimwPYu6Msstuc^Jj9tPBWiX8XVhrrtoTg7bV2L9rlOdVY10amL4qfcFFjtlbce25vXRwr+DO2En/lqR^JDUngzYLwMTCCb5fEQPPIh/3/paYE+4T1eYQE5WoIO7OLaryzHXqWR1TfWEKAm2gx^JZvlf1Gtwlnuy+Qi8s7TG2/uGg6GqlS3DnL1ryzntYO+7J41qJw3u3Kiv+AhO23eZ^JgUhR5E9InJ4kPQ+g5TyB0l/nAIS4ztOXvAgXDOa0YnkJYlHEJry/UlRGCijyrDr+^Jlumbv8YtfhzX3Px3ufUYVxhW+utGUI24AVKpUf4FjlX7ClDulSGVdE8AxHNZHK00^JpjAPL1SigMdn7Y8xym+NG7XIcHadTc0HW4U45wAZBICwE5Q60vzCbNIEqy8luyAJ^JaTMiI9W9rL0Pf7mkoSZhmfdzdQ2+CV+m0I4EapkS2kBUGOUdyVm51lmsFLGsAtnb^JRlKhBOnSB9tnLy7u2bXqju6c+BW97DLB1mApXC149/KBbsVpxxC8B/WKmDMnFwgk^JGuRP7bMBxZTamnBUFoFazFFUf/JvhG/8ZRn3bn9zcpBVmK65p/6aua5oIEF8lHQJ^Jj69dCO2JnECvpuuLmPzX0KITgnsXec0jKMbkujHsSB1q0WzO4roQCP33d7QhWbb9^J93xNd8S7vWs+jENQ/d+Sab4bIsEAZzjzRhBd6Z2Y+2e0lL4225SjTlQV0rTK4hbI^JV26RP3ooaA2cl0dMZ4n7L+kMKh83wRvHxV0oD218YzsVZZk7azUr+6L4KvzOU6Xf^JFQDP05ykX6k3Ix7Xg+aoIUvThAU0hyYxn2aEcZtQqVtJ45FYym9/8mdeBbNlmI++^JZK1fC7vylUhO9comEAUWcAeIETXwnb2O0syp6ArLVPuTPF07OdpqY9g5ooje/vGA^JCOCF3OCghSfV4HmgHaMDbxV040bMyUrFwX+33QKg6H8tZr9H3FHoKSrn6D8viKyf^Jw1iA2H8fb8HSN2hHjlUFJZEvaYTnUWWmXTzwcNsAJGwpdilBZCB+kfTpHuc0j7TS^JbzbMh7eZRLBrPH/B8PGv3s+vG02KwKrBPRN8saDMRFlp3Y+dfYlycpVLkbYTiP0D^JdadaY/6GaX4dYrGNhHS0uZwcwUjSmaOniwgmEPyjwPmAN9DdNYR/d9cd3eRYEXor^JyJYEPiSt3OLT3Qn5+L9+dKnIaJs0CqjItKgoNAvmEACxdGui2T1G+TOVSupPlHwX^JYJaiMo99b0u5WfPefYXPLAO6yBXu1lKvLSPbyyd8epZY2i5Y+/arhEp99fJPt8Ja^Jfy9Kl1XWi2nDaDFhuV+26wGK/hasMdgkl4MpFR1SaZOTIHnjOI8j7DqqdZ3yE3xz^Jzvh+NYohCU4K6WD7nkkQydb3ddMHd12fdJvI0YRw/QmsRQ5N3BLMVhPYFhHuVHan^JHeyfnIKzmS9uaDiuSkx7c7or7fyLP93uDjs1w7DoMn1/oWWV8A+k/wNcw+TCybkd^J9ZZbX/5hBy+jdc4UuRt57B2cm/HWuVaM3zZngz9k01iy8R3xik+D8Kd4bfpO3Rfx^J/u3qB973X46IX9YkRi0nfRM+PGYvC62FaUArk7h5vxEuSuG6hDF2AtIfdsWSQv31^J5hL6I9IxT5vbhRK+h15V3rdTDcN6MlF6mwN72cLPsylxfR9jpUVW2ab+gL6/v7rn^JHgZeyYV9CpIBEelHIY9TMqCY8GeGQno8K9vvwugx2ky1yGoZ8fCrLZy4umRd9wGE^JIoqdDAlWqIpvqf675V4Db5s/y7uv5p7CMNCWh/APdpWvzlWQ2XgVQtecl6sAhB6J^Jh9XbFWh4dVAC/ftbzd1nxuqDNUBDZYR6WniWIuPZIDsv+mcxrqA/8uSDAKfCT+VQ^JZIy9aMLfli23hZOlayfOTzBrl4/cDgnw3fWMVB8WZEdj2GQqeGZu3upC4QdR0c2Y^JKDdkAh2ekhJEiNA9L2DnZXtxXcgKA4x6Ok1AXY2SIRpTN4UED2CWnqqA54Cg0s66^JpIWUZZrK2t+wKumRXkszD8+s0tpgqjCCjHLagzIB2jphatxseHVe/RE+Sp+Ooo6t^JKqJn7fFIL81GA4SB/qwinU0jV2pyW9naCTO7clu1d4BTAE2Kz9q54zp37BlKmcTF^JloBrygICa/NvtyinA4nqkGJKO75Q15eDEXhzW8PUMxZkNJzqUHY8QkifKkVmYp2k^J4VSZ7VObaui3sH8mc+uh0i2vlXNHJMOrt4taJ0SyWbryPXP3wxDxzo2gbyTlqPDF^J2JBSRPIGTTf4WeeN51j7ZrQK8zYktg1urhtBYABHdeSz3aIoE2qTR9U5lvNB/bCN^JwPN5Elb/grlAyD/d4k+d8Vy9GgKNq1nqtjI2uGqf4x69CSn7HH2Bfe6MUx0L70da^Jd07M4tkaFBMbOwen7rnP2T3nqmrikYWyyS1GXjW9Ts6UPF3O4UpL0ZaUsTwv2+F5^Jzc/IFns7Udyys8+sJnRg0EaFN/VnOk943VTWidbN6ezorOF5dBAPloXhcBaRs5jB^JeDta11oVC4PmOo55lwKMAMG8kyTps+tFFLJl+uXiYTj+pTayYPEk6d/zWp/wB/3S^J40VLs00fF+OeaguQ2bElfnXK9+HP0Hyusa77YpetVmIYAoOuySVcjsa5xS6MncIU^JEQdNnDhiN/MWKikaLzcaF7KTKtkaYzrs/Wx29n/eb+53xKKU5qwPCFQuGzwbcUST^JbbnMA0ucEYthm2//t2drRFQJc5vdUjr5wyjrAH00c1OLovXW+jsdvpQjYOBwG/OI^JlWOdt+aDoxwdz4mn9QXG3+9UjDpIYPj4XehovH++hWJj0fdiySNKaacOoNwVV6ty^Jl6MkknvVhYIPG5l29n2voBSYzMoBZmOvU1D9wG7y4rwPDC9K+5cIGk1Q7U3FzvBG^J2oOBgdrBa8VXwAZkC+PIHhgmEqRHvzAIhRLfzgNTwSXeeu8gHck8CD+lBWkayV1g^JKvsGRgQ8h89RRHo6Ky0L8XoCsOsEyb+m4Zsq6YeCceNV7DFCFw+GEzVvtLSYtFtr^JF08tKhpYZOEMSqPv9SUbcL/HtVl1+FRnTUe5UxDXrwVX16RvPaqFs15nJfFLqgDm^J3WFjmi7W4aIgSQUBUlEue34hTWPRpauluaAuKStu3xNoNm9aKfo24cPJsQdCIiMD^JuRL3FqyjNfZKo82X/OKqt0EYfK3w9ys7t0ewAO59Bm4eokdARepljfbHXy4X8+/O^JF5aguc6m74jgVoEPxdffprU4T7vXwVO8k3FmZ7+JrBsPRI4hTwVqRevgIoPYBpxe^JngSfxNNFscFYjbRIPcMlauvnwkrVnD48VZnsOpNszl/FbCNfolM19WCdLHCiIUPB^JiJA+ozEbiijt92F4hv+ALQksEzrgbrr48t1/YOK3WvZJrFNhKoQKpQ3JTWMnMoke^JOHel5uQez/iUSwNLxlnFaBRptfUgugdb6i5NkWxudWYAWJSoxHwQMUuE9NpTG3ha^JiFEPCIzX1FqXkZCnGyTdWc1WQwthefC3atUR2dSR0MeGhAbVpDputwB6gJB263mX^Jh0J9Gd1G8/6g93fM7AXHC3K67phaLmLHG2NkNH6Q2HnOw7BkRuhYuWhG9/v15ih1^JuhoMnEHvgnDke4C5FxpV6A3T0XaGJjfqre/4MAHELmXfSd+RlF5FR7ZnWNjPTL9l^JlnsqEXQ+DpsHFWfo0SU5tC5PBM//ZwozP45FOVxKEjk4z59tGZwg7wgJEZfEzjTb^JQotqYrFWpa8LwueJPbsPnFTOGDtIVPzg12Gg0s5mNTXv3LgyZjJ5Ot1aQUOeoMEd^JaYK3G9a92Hq/6ugfvlqtOe7uV2NJp3K6Kav5RI7di1K+4Hl6T6ohq0BEo1JU+BHT^JyWPSVqkrNIAYA/ShG3ipO8cV6MUcnlRzBgYvn7/fWpeAbDkXDNxYxmfmTIgUwMm1^JzUgAj8KNEjGc7NRIkIhD/taYl/H0dbBbGdlhzGQMu9a1xQ2w+3wQBo2cLywAAf+A^JsbQvkP3L7+8DJ8Ai76GSuA238Coj/k2WFLvGJCG53kNxydjZT9Q9NhP0/bwUObaI^J0Hw2mXfxhBn6+qNJN+hwktzS4zrgq8nbdLtPRvBYYbubYASw1ZUWfJy6GxmiT3OA^JOuGA4C+siVqQRpTAW4AyzNEwNgjw5Apxq790EwMC8lZhdmSbAdRvI4LUgZFKU7sq^JOGKF46fAxsgVcJI7JgpRB4LX7jOrSiqHj6BptA1fHndIrQ/6XTOzsC3JTnKKIXBC^JXAp3HO9zAas7llLvSRDmVR0NfBpjNwCeIFxp4bY3eYHKxruGylwelY87G73UoTmp^J7BpfYuOtdFXi+MfWzSd4hQsoxBiLbDbXL+OSMI2aegXGtMJMGt7NL0QYqqO0d+z+^JnvezoFA7xnqZou/M3Zjo/VABy/m1HBMdTU5g6G4WD+8aw+TDfvPK+Op4Lb7MuyxE^JSmPBxPaHEQYmCKMzOwGQEI/AH0mM5UTOLpfurfQ/FaQthUuPfL1sraZBV1uxWWZ+^JunTkttIUWlX1CF7AqN6o92QF4MpjZwn6dtU/WLmDm/j64CjlRifNP3hPL7xDXR4O^JfFU3aFO1AjB0Md0d4OnbtiBHd3xVtg9o2noglEdSEoboBz8ikZa1kq5vu3kgqAVQ^Jz/w+zhw49o9GDo583jLECbxOIrfMgxnv2RND/Etoc9XOY3U6d2C55GTzN5CwvG8y^JmObnT77IkD8PHKb7B4+zO40GWfsGdc1JwJ8VuetrEZKqxpyf3TtgPQ8gWkJt7zt5^JWjoZhrHI7opFo3uFDC23dOmVBPQkXzC8IyYcRT1B/Wh7um3X+ZXdUTyq1e60sC8A^JRNRy+Nd2OQkEH5BiCmunb+kvfdx739i5dLQWrIgvDFJPmfbUhyuyqDboxTMedNpn^JbebTEbrFJFxCwOLREtTWMaXorDnEd9X0YrxkkljwYUweiZIgOZu7QALj4G0an8EZ^J+i88NMdD+KONWySuZL8UGpuWMqOG5qpt8oMAXuNZgjnGu+dPmQ7PiTIftkIldgA0^J/mzOt31RkN/+YuL9sEHXfZPCATwqRJoWfTHYKRLjyvnKK8UclTAiwkgehUD8dpJK^J/f0kzIA0AaNotwMIY2S8h+2wAsDpTUmg+47izIoAiylX2Ek0kMLY/cMQp/pZJII+^JnSqLkbbJC1iJTkzzkA4Sq9BEwYHX+AQACfR1XSi5fQ1cwFl4oIftsFhUnrW1yIkD^JkqnvkFP21puNq/Cb8uKJD+qRTpePrke3+Q5cndY0nPI9S2PABdmPOPABA380EjtN^Jva499Dxgcuozj7C42DVdthSiedF1V/MZgWTG6CCdDZijf0/dEkxpMFDrdCm9gr9/^J0BzznU1hXXrug0xIlZ81W935KgcSwzT62vp1EAT5L8vZN57Oog8VTVTmTPKnOSo4^J/1YPJnTYkvBoW1YeHBSvJaik6g9lqtqUsb+aup5QoY2SKM/WMZIpHz0OUsidZywA^JX2GgunrW8R2jgYqi7icCt6soC0a/M1AeT2g6zAaGD8TI5gRZWmrGvqKZXFK1zkP1^J+1ri6w2Bothzg8tz1eG7Uuyu/jHP0ENz4DlfTawIRot55VHPh4dNiv2akdza0LUs^J7rdoa+ZIevf2jyvC7YZP46i3V4OHhdh8u8DLJFTpK4yzSSaFNpFJ0hurpyqwAtf5^JoB70MY69lVZwhuCn7249QbGZ7vc9aCBtWP9sx2kUHQG9l/WQ5VSrrsfcJqnw9AzY^JePk/Yv0O0LFIuHL8ZjkSNVfvaC59Fi7cRqJ7PKZDbFQz3cMfyaGs9NBE73EDv7lF^JOCCh8G/Ocg3EWzBkin6mnrvOy1hu4EDD7yQqeVS0+xHQPZICr9X0SKGXXUyvn4eL^J89+8cIACBlOecMs3pnrhlLIla790gySCmCybrwXtAfN1byomJL2wsQqcLeXiLAwJ^JgGXKTjJZXgRTq8qFjrqw1JBuqYo/BMuOAO8P175zbX97Nn5uy4YE15aBG/5GsDhn^JhhVhncMJUyJNyhj//PSDPvXWbDWD5TG58PZih6mhadE3Do6eRPfVVx8OlOsfLiHg^JHa7+s1aX/bX9+Ibng4khoSjNGYIIg3dmF+EZ0MUEfxmV2OxItlPCcxvK7850S3C5^JcOuJHqzzbJdz7J1/hAFs8z0w2ndIFNdf23jWZ/BsfaHhyjel2KEnrTpSVqSiOi3Z^JYxIiHk2EH+0VAlcmtbfFSreDi+1E+Mi1O3DMUoNZJpiPwJxGjPaBdM6yRACrByy8^JY4YRH1VBJ6zZcIiKjjP08csRizu1nfKOsalhmaMpPGCvPkDvKFIp2BJxDcpMU/Cc^JyyDmV57jx7BH3txuyIw/TQIDuQ/As0+37GW1t+n0hyuaG3LjjZRPM1oqR0svvmU2^JiuXx2lkuwcKcrvKcXYiueacKdkizP3SirDTsDsTejrbGLkIoFWg11vNl/AZ7KW8F^J3s6EwVAdSaVTn6kb9TE0045O1bTuu8DHbDbGJnA7u+4am7ToX0iSo1yaOOIEzhA7^JYvVoTDFsfKSdLtHNEO/wlXoYHBuOAQw093Z+2GAyWfq5y/qT7vh5FYL2WbF6g8xc^Jta6ebB9Rqno1xC2BTwgwJ6VPzpFS3r8ArWdelq/0GCHIj/6x/2AfXQX+mvbE77gE^JMEHB2Qo+tZQCIqAnNNuaAjbBHuvLSy3c+sNYnvJoyzQ5yK8+gdtbJethaaWXk7jI^J4PU0t1LamlEWGZMKISK3zn8pfQAdh+ozYprnaQsqYjSBUsb3SAsI1CgVMSd/p4iW^JZdeA2vt35dsm3JaJNIrbk82AP12PH1DQW84zEee4+ljsUmnNnocNAyTqfkjTdRCZ^Jm5m2kTijKb+72KH5qnMRIMJHOZJ1etLLWGxGPwQ6ZcIW1qSkisv3HjjTkKGaHiyQ^JCBViKUVCZ70DAtEhdxnt4We4AqkHLF/HQKkKixTiQyYmmuHGr0NqOaNxcG05tPZ+^J4mBbI97OnVszlYi3XYIvd2gll/+KCrun3yURvzVML6RrnqPwnGeLyGoFpqvvUSji^JVi0S6tgNKEA1644bmTuWP9zszpKVNRH8mbgVMpxNN+830CbqiBZosE4TuP36D2Ug^JLq265sflRY62rzGEI/EsJ2L47t7waTIQk3sxIzR70mZlJqchH6VhnfTk6S2Xgrv9^J6cMZxvVtAeSCsXAi5J9wgdso8z07jgRvzPG5Lzx6ILVEKE2sJQdxaleHFAjY/fXG^Jdb4vLk3NELU4zh4iNgB77XshiNeeCoYp3a9TipOrHCPj5txwICaUeaE42auHkdjb^JQSBABJwLOd+bXZWuQpFqZ8j9OjXC6q1HZi13VVreLhsD2yiUjhQn00V3d8gEfPFv^J045cUboZlWsU110UV/7OLDke2Vvd/gTp9EAb62EPAR7W8kRA2gfYbxoa0LqB1zK4^J9H6Dbir4dd7WOx+CfQD/LbRVWUBgL8E5Kt3WhAFkb1Rtnzs0fVAijk/bauFIadLT^J5wKK6nfjv73wYAKbwkw6+Rmo5Ki86YjF5VgFbjtYwcUvN9xabNl7xh9rtdtyq/4b^JkhzC/jwyg5pvg7p8v/q8Mbm7wY9Xv0fZxYaLin+tcq150yNycwmxoO4oyEXLx8NK^JTrmZKIGbJ1MiFmh/AuB1kMoZbDy37kvOs0yJjl0fA2SuSlulkFzWekmuLnVfbZJF^JvhLRPdpM5OY55IY62ICkRAnCX+j9/i5jx0BSSfmB4Yhh63szrF6slKZfITssSAkp^JhdaAyfAhBTu/APBF2GgEh4BiL2fpK8a4LFZtSZWIqwHa4bmWjyjRJBuvK7GjbLeg^JDnCuPPdNOwfPeuhW2B8h7FM8rEhwtJIysP62lpNuIeD876yB2uCsYYvnIx6Sx3qX^JhX+2xkF5p5vh6sM8WnnZqbVN9lI/5ru/sghlopPt/mUMuYcR73ja9odPtYCYbZTa^JK/oCCS3lu6BFmyCsHOUgn7Dn8mGsorOdzfa/W6/Es4AgtqPS3VynrTgt/nKUULi0^Jez0yIkIOHqYkl6DrmJIOXrwwxqMgSrTe0vvrOdTifQaDF/MTgfHp1+xuEpi3Xgzz^J8gKRAPIgMJkm44YPlBRRfYTzrFYPGJxeMe4CnL6NgcN6TCE7Y0aOvpbgBw6/JZd9^JqC1sLRbKuUkkRzzN0T6LcHX95RCcL/9Lp1RKqaoQnX0wZhskLkGz3/L9rDDtLeAM^JhTYExb6VAciL9a9oeOTJDXjJ2MQGjUVAHjouLLtFJLdmrqpc+tUFB2L5IW/ZgP1u^JHcmlIa2m5lxxcFHdYRo8FVtM8avDhunvmtMaYL0LBP1HmHr8xl42ICSqASRPUw8t^JE0siS+GwIdM/F2X2NH0sz/leTvVVl2iD7suRUHVk0vHa5+lypZcCSQ9qvp7mXIfs^JmOfwRNn8VT4UHRi1gjsEwXEUyLXPxOAq7MlO714gWtZYWiXJXnDVPL88Tai1eMz3^JVrzkpFUTW5DtNiRRM4DbZMtjcv0J+tunLbrHvVRaVYKnuwZlFL+6X+Cr0BzmkOoL^Jxm+8Gf8+Iih859+rRj8/T7lPV+S87zQAUcXXTiEvJrl86DJ9Kl +file_chunk, 752, 380370192, GsvqfXiJ4np0khHUmapJNPmJQKa0luEG6FpCzgp0Dyl47QbUHksinrhMu^Jo8584ANcgv0sVUAruYbHZKqWHF1iaF33J5moGutRzOir5TpCwsYtUJTItLPqAigi^JUZIpKxPbO1Qu7ogRR+m96RRQWPGMM0gtauwU8a4i920bBrETqumRuEBs11GgfVBH^JZAc44gk8Dg0YmuX2XnxxWHxqQkVbpHoDLGzeFh/3DkQ9xmAFWktrZHoefkUFgJ68^J1JG8ovCJUheKpSkhI7xcm/OLvfXpVZMatajQGo+4pCA28fQ7SlO0NJuQQUB1Dl9H^JYKuqg6sXuXE3n2BtmQW3LMUG4EIA7bplb0Njb2sCxh/XjApgMVQXzzAmhwuz4o4k^JiaecwnEheh8CLnv8JWMshGw1zDgidP5HbJ3siVD1QhFGmMvkX/ZM7bo7zMZfpRbE^JMdVIb5jJBGUXl1lCol3qbMnSoHNhOo7doGEFhTuVvXK8lP/bmlssoH8aGc52bjws^JYZXn2kVUhUV7d4TJzPhByjKFHg1mY4WZVwRUG2TbgOiy74z5brEhU5/he3helhy8^JqXMSQKGZlMqbHByHDEjBYpR2PqebUuuDPNpkmZ2nNG4NAVOa0gvDcrocMsCEbW8F^JXp2Bmrxj4idyuqruml/tmhYEm1JSPqnAtJCvldK/Ksu7WSMXDYZSitG+2Q4n0L6V^Ju62Pt8j5vMU0RRCbqq3ETqSUEqasL96nHQys/ppzaraC +file_chunk, 752, 380763408, gXdxRZzzH8TAPLeCpKo4lkFco7^JVvkx0JG2M4OVAYmaExT9D1KAHw2PxHnIgNUBq1jHnyj9VEq9r4q3ImdsoysEswws^JNzUDy0dboVl7ZetTP6iOLaeghpKUezHDfHFdgQJK0M7l0GTps9dKqumA6vb8zElx^Jf7tgGXKbPgGXirMekktHzJmb0egVOxwdxRihS5KggKG4u8uNGqq/0vcIZuQCBvVZ^JDCUdJG8s0L9aqifuzQ+3y/4v0l+qQ3daY20plf/KWhbp9T3QBCiutmbMSnIQoK/H^JZ7yqa1h2w1aSgSOStv2tWtCcjjgmBI8acLZ/D6/LZAgF9ZdEfSnK9+39yw9vHg9W^J2IpsFzmtD+CyQ1eVrarHiGL0cDd9kKPE45czXjT96cjk40+SgN/08efxvRvOZpV4^JMvW3fHpSFS8UQecdE+NKyPqf9zEMd/8UBwzKD6PQHJ8HpCLIFdy+wsbwU4+yRJBC^JTdEOlDT8j+laAmErlQw8Mgf5KcPx1hBIqecPaZqfpz5r6LmCXYbZQVW8E318CJfF^J7vGlrZLQh/x6/0oOICTUqd/CaPGhXDrrS2MRGbCEG5N/n/qIQUyyBJoXbPp1AAwG^J8OlwvOcAQWh0AJoXwI4bFF3lqIsBvLwVOL20uRIqsAfmxle6nfwSKAT8FDnqyAng^JBsPh4X3wUmOKuqG9cZhc5544WG1Ec8WRKmEB8ru24k3Lw0GsFPYNLpmbrYPofVlh^JXbH69HCe18 +file_chunk, 752, 2293234960, bE5SAPMll^Jaib84k6IRyHiKCbCiaAZVHGn7mK06uxYUbD7bZSfWLRVOrJpAwF7KCprFfMglIo0^JwCSYXGRoYX87FbYLtOCxuc/rFQE3JjNQMmNbTjxQv69xmpCQ6VWs8ePj3n9hDuAC^JBLq/iJ2h6hKeLUfcpblaJ4+2hHO+Bfr1PX6juuATkCex1QMCAr0ykNuXrirTvGm9^JHFjQyOKV1Mk5srxRXf0o9CZDnw0h02cDV1Zm/MzpnmA1uRy4mNBGXmR4tXn6Jype^JCwrONyUP6jDaRQDeqLnniEKnZrPvu+33rAdFK+1TRzr//gnudo2nj6ehzw5GavxS^JOYOjpXTQKo3sXtDuO0XKtGlQMN7cdV95tkXEpyatfdjFs57BBXyih/w50WfNRlJ9^JvDcC21ht9AuYP/7/N1sSAZ8O5icTEqiLox1gm/s7CJR38nN695+0aGRrI2zdnZJD^JffR7ha8uqFsfJbJSIBrqHXsSleF8hjqlVTXyGpd/yo96KsYk1qKsIdgkMVT+cMuf^JjFwxhTW+BH8s+K00eNzpjIUzJY8fUOusUYbWNlvRHZVzs1zKUzJiWNmKSEQkAVnx^Jp+wWj5yQKPJyIwJUR2DcGzkXES8udDbfstiPqRHeAUcm3otjWQzn78jdQ/trYq03^Jh/yu+wuWsMazmSoDY5kEXCYLovRX8zBfPsT0/yx4Jk9eTdo1AY10E7mMFOufZ31O^JNSZ5clGw/3oyPNw0Dthl6RJGRMl +file_chunk, 752, 2338716944, rKkq7+/L7WcTv1pXM2kK^JARYWqoQyfEpftTMC+UdQgVQxklO0zOYQwIOF3I50JNSycpqO6QWEVCr/yNarcSQC^JALVtH/fJKp76r/825GduosjDFDlYyohREwQqqvYlnXszy6DeIVN3Fpb+ChkwvNmw^J1XVj74VT8QQH2g1fbwQsjL4QOw/xLqgZtq/3SiDLvOsnrpvuN5oQcUdV+1g12I1N^JJCznvVYVUTBnNWV1wNFecvuBxGYRETJE1aRHFimjFAezAVSW+FcwwHhcXY/8mpNN^JJieshkOjYKeUjhla2fDXH7OY1aS0T/bqBUqkdVTjkm0C3E6NlUGUA5t31I4jqEb5^JbNwrKpLJqCjpr/uRs+e9ef1mais77rMwxMxu3zOgI0+Wl7oEt4HXPMbLw7FlXByH^JPm3D3f0Vm/rsfABU7nPH8EOfR0Ad5WY4Ul+K8HGgFL5EpWgagrAxIm8ZMba0G37O^Jyt0CBAy0FJvTMCaIuFlL1VshcatltJqKgVoClur2gn8mnsMEKMsgLNE57G/v75aa^JK2G1EuFFg8F27Ry8WPFJhdnMBno5NIlBlp4a+GNnoyYypvSiyCH6ep0mmHCkInjI^Js25AU8PJzVK5fgJgZITJcS2ID4bQCFy4mVn4MtlPAQOGbZ4f1mNHWKXEj/arz9jx^J2LnF9I9OfP2SIUNuGr6EnZ1JO1ycPFh5Pmd7Cpl1MO9APB2RpwZ7FwAuwfNzRtHv^Jsgutwr6ceMsddeT9 +file_chunk, 752, 4260756752, 4Qr21M3p5vrxpuLqal1FrU4X8z1+r05kDvqcs1RzecdzoBp/FCMU^JykfOgs1BNZU6UypSW2vwOxaQFJSTb90OAdX6hpyTSRT+k1RaGwGdWgn7OdFgdizP^J4Qo6W9abCfi+6BnzHkxxSFTQfd9AFWZ1LlPw5+NjUXfxdi/jGLtDIopnKAE8LshA^J108MLfjjWwlcqs4v1XJHGfjCaauVsrRdes8uhXfiCZgUL0KOKvwHvBy2TKLDb3ZY^JAeJxEBZlgadEjxXjyQZ4BcvU1Gwa2TaIfKsM/2mCTiCIqBo3Mw5tVHkDvEBGKUdS^JvY8E9bpKp26Y2ejYdVk8JSt58wDHzNBeO7ocmzBn3s2fQNbiwX3I+eeJjkogqKTa^JjQSAGi+bUGKWE9dZyDkMZd7NnvLhxO2gEoRlYYjVuDDeDbXvBtLHDa6puLcO1p0Q^JHIkzRmtMTV5SVPhXjQCJyps/bp5v/HzViCLRfXiL0+nDDVesaVbhko71aICGI9Pn^JsvSR7E4qvDdzOppjmWKkau8QcuhLKlzUpyEI1SNAGzrSqL2OuHqdUK5ypuL8RZmm^JXGGDmJ27yMYNjgr3aTJ13eJLH/MQvLAIBys7GKM9BZ0UJW8W4KpbDFRRJieo/62U^JWtkGoNw6dRiCdkuHkWRs40aKc1yhDaoMxY9BHpMtUuxid9Qu9MCiAs33JHLzc+so^JBeFtAtKFW1VSSe31oO9fUfgGucj9BP3QpaqFA0t30TazwxUj3 +file_chunk, 2896, 4303090112, yZg/LJ/GpmwgXe+ESFWIDa^JxR4TdIMTekg4qqCL5PpNJ6DHfkkdsjsQ9zqkWNtrc/GpqBPClN8IwD4qThUGd+tI^JTe38v0hZWuuNnOjY9eJO747wIiPqy15oBYpstGeIdESgUFr9/xg82fGjalkY2ZVQ^JJAlH0xNX+TF5QIn9BUMnxn6OCA0DkQYqybz2eq82jB7ZEnGLdDvB8WeaQIjxBuVx^JDAiCwzjC2jpO+wNYCorVym4VFti4AgGYghyLmyAicit9NqPTMsaD2BbRpb/qHg0P^JdX53dFZe0qlqsrA15n3KCuLiw5YXEFUmUQuAN0dAOqlzOTOPpNmJakHF3TqIXvw6^JV/qERQeuiNPwnBZWrZvpTjO50VatjcUizhJRwTiQjbQ7+mqgHxiEa9abpzqlTN2I^JW/uUssi0jaVeFdL3MHZYHltusyTx0F4iH+KGJ1n7YRefPAI5klNZu3XmTQsQafkF^J1DMVbqcJT+aLdlz2hWMy1R0BfV2XMrO2/XhG2nOScnRzS8Z7EmAgqZmzFfF+nqyP^J9UCd39Si6aUrss3N0oCJ/44F3T55uSHYf2LCgoaaiR5IML5tk9mHVRyTile5iF3P^JNPwMnlSeka31pzsqLRiWIAvKqk5yZJ1v290/Aff0SSIxKggtVMBq3YmJeRb6LrkJ^JjkYC41zT+lvvvMRBJCFOOXBgesIBHq7pOKBKPY/xAcN/e+AQqHLlY/OGMT6+GK9v^JGXN4TvdRLBYHZQqyk2ITYWD5iQqweeZ2UmjB3Is3lDKtnlO6qbWvvYmYPoXDrNI5^JhRX0gaiVC5LyZZ9NheeAgb5ZTqYUcvNCxM7BFV7gJMFXc8gT7A0FG3YbkV9Y4D7v^J3NduhJG8kgS814/l3Il9K3jc12uv8V25orXa4lDXTbTu8WanSYUkg4cLjqfKD5Vh^Jly0ZTpYeNx1NdO8FoSGJhqI0BC/p2NyjzmTh3mrGk6tnfHuqXAMH5tIt/EC10MmP^JE2WTu0XrNk7I9bWBRRNWx+ysP1CJUd5GbYOcQpFHBfG+9ApIf3LjxSLU00/b7Ui2^Jz/92JI8T6X4TdKxA7DY10IJg6KJBsUAUJ9Co6Fxr9+9OIo0bdj1IcD5+w/qB7xzJ^JNC3dgXc86uEDpvICZS2vIeCZTrc9vgxBxpftsdVNn1nDYlalXZeNsAmDiy3QJ/wO^JPS3Li40x0KtDWbxMzgflfzuyMZQBFSNeQ7CXFh9mJMJQkuAtHN+yAEqJJKaYV1bt^JJM2jAeKb64mN31lIzTnkJEGWcvLNS0uiZKJQrm0lqsentMitzc/+U0gSxzsfbqmW^J187RzZAsNlfWnLN7miAPsdxas2JGGrmHzjaUkL7U+YJdAToYlxjMTnZgztt9LJxA^JSprIv68hyNVF+4+fpL7QER9EOmgQOIxjlxCx75SDd5g3CWJkVbXl8uU6G+j02j+Y^JcOXNTTwX2ptbc/79Kw9iDMV9YkAZtP8BD0Any1Fqh/IMx4QcMXEx46yDV2ji7umH^J1SO686Lv9zGXYb+ApuY6PVuICTJrWLIZBE48otTKBXTJ27wGiEf28Z7bh74P06Qv^JXMTUryBMDg9JrcCGTvelIZO+DbMMMN72Mh/lXBAOLIkfh9WvgqyMIH1kfg0H3AwN^JB9b689RpbK0N+xhfV/aIqGp3a1KbXqPA/h85vUI1aLXPreBN9gyTKe5K0HXw3Edo^JqMcB6m//PN72r6epmEMgdthZs5GtNcQBx2GbOonY1sot6ZA41GR4hfl+EJPc81uY^J55uCcANhvaaIl+V7GCjV414dNq89TzNFHF1sG3ifM5ePRhFHVnsE8HgoE3hsMhqH^J87vMDghqNZi7+tGPNjZvZGVtB+RL8ltGhUSuoE9OjU9S96T14TZT8ksIo2jb6+Tq^J6Vo3Y3vKc6krHH93OKiXN0hwqPupBD6xo/23Ivnk1qu4xAZ2fnR1Ob0BKcPCrNdi^JREI++RJzxugNvbGOf2LIdoI/2yChB5i4tg3qYRRRagUpNohIxW5eJy5ugiCwOH6d^JuPmvLXUzs3J0HWdCVpmgURIP4omxgUkLYeJNp4CmeTAUr6uVrqzRCDYPOYrCT4tB^JYL6uyxhmOfwL5/YuVtsCcKjX8nGvOIHdtiMolPpeH8qdv0zp9kY+h8eTE/WGh5HF^JA4VLUCH5d8qok38Q2Xvtiji0QrKr4j+P5Vhp8YbKLwFEqs3+NvA1iEx/RQhTvPO+^JHCdnaCc0vIaAp3jR88OrMDhHyKePPMk6shiWiFM4atdQesswq11pHaUrUoATZGm+^JG4IsH5+DZVk+ztcDnA2+f1+FKDFHloA7VWMiuccer4ZHFqaB1WGpTOMTBF0xhBYo^JmhRBLM+O3SJ3+I3FwbmE4mPnh8PMalte/qm9IFtDIhVdoo5+lS4tarJTPwazW+cs^JAIxETVWHanH/QOtyEdrnufA+kcj9DLRA0IUQLySOYCGQ3ZZsHyyEDV/9IWOjpARW^JDObwlGFQk2mWcH4/CdOl0ZQajrk2hWbwDuFx+RVy84JapHNIAFgH48u+bn+hgf3V^JVX1bUYtRpwrBEEBwD9rQJ6iMmeqg2B/Ih9RxPBq3wyvbhzk/VVCaUq3c+XLz+6B/^JwaUQeYEQ32U8XkaKbWsXxrcKZvZ70oYLGU1+mHLV/Lc/vwch4nAJmtRYRrZ8hXgx^J7CRciM9baxlkZ8zAaRXcGW2Gbl8m//oHERz8/8j7YpbkY3Y0qfeIqNoQyHieLPc+^JWwUfKskpxIgL7MhKlDs1fmJe6X6o3KW11JZqldPwKL6WGK5P4OS2fULClB9MD605^JNpjTRR0NBoNpKKr6UApGAqwfZmc+7oGZHVBw41tiCKuAavQydcOtOg7Xj84i26J1^JBppraxJIvxoJ3 +file_chunk, 752, 4675468560, +DcPcn4qO^JffnlMfb0kLM2x5RyTcNksyV29GDPpFDXWpehoJ56Wt8CMltAlRzSEEPAjWTISMvB^JgYHW2wKs9VHgQ4x2pxmnLTGmMKS49QFadEaILpCb7Vbi+EnWeDwitcBjWI2GrSMq^JYvex9t0vSEt1BrebNcumhwZ4fEjJ8+aci+ZW/r6ZVd7NMrSKMYpMTp1YxTqbp4xJ^JoogVMhE9enlaPiI39lS6mcjK9PZoY2nxTAjxD+vmsFrToCFtxp0aMcJzLsbjhQ7E^JTJX+jYH9mwJiX+mjghmb1npCkjCCZkl04m2cQwYN6xtyXRniEQwpKNK5KCcbfIPb^JYXDXWKvy61KJQli/DtUjh9rhBLVGrn70CCuoCHxnYSlmq6Np3BBDt1PIGYxnhCak^J31ueqgP7CVDs+2/Hh7t4syiABQmA+Xvw3E+Zd9zPp+TjZoux7nPxFUx/rm3YFj5T^JvjlF+AruGVrzTVRmpKSY01wo1Nxv+pSpHg0GukvDnRqFHGSamlyxDrgx3orpqj3e^JD4Pg4voGdHLoVkTF+HXNjUZq8UGKz95B4Tvrpy5Ll9NwX3DD0wDG1RDJLw618W6U^JLThJEdnZcI6460SCpiqKhVXZo9vL0f2dYc+nswEjtgkFnUPQMvp2fK9XVEozQNiQ^JKAjg0dXTDJ2K4mSxc6UlXqLpYgomE9vX0dEq1i6b9IktZi9WckHR4nfV9F4Zd9bI^JgQbfa6KTmdmTrHM4+jtC5dZBDtV +file_chunk, 752, 4675730704, QvDDMBnvKD^Jf6O7XhaaVuulyRhTZPY7oJjJJXSEq/UK6XMmMRzTuPVwjK5hL8H8MvA9T5NPDNDN^J6awIHAtx9vRxa+fNXhfoE8roipZABMXCD510gRsS/yxmYat/2XSUVuwVcVfmLcUB^JGEIYmzbGTxPB9TfPccJVsKAD35jzeyTGsQjaW4B9I1cykWedRhvEd8AeL0O+vBCJ^JxUIWFEHet3dbQvasUZ30o0hMbgOiserhgO4tQ56U66e+Vl/VZUX+DpmxtTYTiVn5^JpVZfYQaoTUpzjAi9t8Iy3YJRwlQRgZHcnzmcDYNuvo4InrEHS1xZC6WcbenTIpSW^JkCGI7fhCLMabTW0FQ5AaSTFKXP7O9+nxdqdup0XJT8Twtuz8l6Mn4PkgqOn0A+bc^JQbtonpY5uIQwVCiAcYjpKAhGV+D1B3TDI5q2+Aj6WPQ9Bfi/pqfv3fBK5ihgY9LS^JW8jZEJCJduoEdsDyatqtSK3UOtftqPWVptW5JfuajYR3CPl84Xk4K1/cQxx5nAKi^JRGpvr0SVoJsS9HRSsoMlJB42Md0SVY0nwp3MO1gcOvKCA5SBI/KXIu0HQ3YpxT39^JV/sR/QjJZvj3u0hFehggRQVo25pQhq4RdCt2edeBwYoxmcJDhnOZD+nEYax8GRUu^JfrkPGVECNPqfzEePAZSv/8nW7ZHXz2+Cted/eRd0Y6qKO4KysL+kjDy2SX8ayrmA^JGlc8VABynj/sshoQi5/nz8nq7S +file_chunk, 1182, 5416665488, w7c/SP4xbc2p6HIRdJLpymJYcB8aLuc^JltM7qmD7UWqSwePzdNZkOYSY0/p2PiZikeQ4wn1fZW+24gY3Dr+oghOLSyl9RIc1^JgO1jwi/vDVySgarwx2QcGsqac32ow212k0FzWuHSsI5SY3e9Cxb279S79PH23+NC^Jrs3mJw0arb7RYD4ZYIrtnnrSHncN944NEmooPcHD/y10bpQFlvIDO5dPX5SC7ryP^JAHOAkFGnlbNJasU9jjuGbl5KfwAG+lm/WyBS3Qzs/jZKEm8xcba1t+4Tmy4HPfIH^JQycTiGZvabxgg34ZrUkRS/VRyNs5DYEl08BsJFJ4ErXqMxqIgqndmqmFCMWRbqm3^JW1SyJLU1BpESS7O/WtdE0h52qeMibJCuMmSLZ6Ji3ObkDuWnJyQOD6DiywAOd4MK^JRAKw6c/G6daqMCLAR8iYNbKv5vizBN0xq38jnjN78n2L+Q0cHigtBVYOb6g/tOod^JsLW0MZnv2UQ+GkD7mz0FgctEtk7LnEGwwFrOOHFTZWJ69Z670dS9KVIVNLVom+wU^JM2bjpD82xE3kLHtZ/VZ/p5UzZkhFZTMqHisrXqcE2hs3StrJj50t49UK+JeBmNSV^JH9rY7uihuKU1BQrSxgXtgW6HZ2st2VMNWsAFyXDtWAO6PrmSF6L+D811cXHCGZx2^JqmEH4/fh3Qyz4wWp+2qJgdfqlvIR9glBAvF/612vO7ig4LN3+g7LLaXy/gtujFki^J9Dnfq/yKN4IzQspkrRJEd/Zitw4HMnO40iTvk/qmfq0lvfCaJkLNlVqD19XJCPrt^J4gvtRiwNs9QfQht7lhUp/Wnt++6jJ7xrHqmqOMvd7oBX9H7VtZwAN/5tOhznLs9a^JqcBtokxx9c2lWCtgLnOHdNssIC5WcBfQqCnfCPrnq2A1QVGFoIkFin+RmvgdpC0x^JTJHK1ceRTrnNb6VBcmXnraSn5QZTIZ5F+SQ2rgqTNfofokJtEKAt8fUVrHZ81emS^Jf3sbH8UPfa9Xj0jmZmcjRRggrJ1yu0RsxUlxg5siQ2Fy5i3vAb0ZZ5ItWdIt8Jwt^JJFX0FWYGmphyo0Nwj/XP27NaqTwSOmo6xAfoyU7z/28U3k/qEbtLpn5xzVHk6Dny^JP0XGw4JttE7CmvwEi057FGGBu4pUYERfRNu7o+THlsQ=^J diff --git a/testing/btest/Baseline/scripts.base.protocols.modbus.exception_handling/weird.log b/testing/btest/Baseline/scripts.base.protocols.modbus.exception_handling/weird.log index 57fa59a1ef..d387f9682b 100644 --- a/testing/btest/Baseline/scripts.base.protocols.modbus.exception_handling/weird.log +++ b/testing/btest/Baseline/scripts.base.protocols.modbus.exception_handling/weird.log @@ -3,9 +3,11 @@ #empty_field (empty) #unset_field - #path weird -#open 2013-08-26-19-36-36 +#open 2014-04-07-19-37-09 #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer #types time string addr port addr port string string bool string 1153491909.414066 - - - - - truncated_IP - F bro 1153491912.529443 CXWv6p3arKYeMETxOg 192.168.66.235 2582 166.161.16.230 502 binpac exception: out_of_bound: WriteSingleRegisterRequest: 4 > 0 - F bro -#close 2013-08-26-19-36-36 +1153491920.661039 CXWv6p3arKYeMETxOg 192.168.66.235 2582 166.161.16.230 502 TCP_ack_underflow_or_misorder - F bro +1153491929.715910 CXWv6p3arKYeMETxOg 192.168.66.235 2582 166.161.16.230 502 TCP_seq_underflow_or_misorder - F bro +#close 2014-04-07-19-37-09 diff --git a/testing/btest/Traces/ftp/bigtransfer.pcap b/testing/btest/Traces/ftp/bigtransfer.pcap new file mode 100644 index 0000000000000000000000000000000000000000..f08f051c5357593dff181c5ff48a3531301d6536 GIT binary patch literal 32127 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 literal 0 HcmV?d00001 diff --git a/testing/btest/core/tcp/large-file-reassembly.bro b/testing/btest/core/tcp/large-file-reassembly.bro new file mode 100644 index 0000000000..655d030d96 --- /dev/null +++ b/testing/btest/core/tcp/large-file-reassembly.bro @@ -0,0 +1,22 @@ +# @TEST-EXEC: bro -r $TRACES/ftp/bigtransfer.pcap %INPUT >out +# @TEST-EXEC: btest-diff out +# @TEST-EXEC: btest-diff files.log +# @TEST-EXEC: btest-diff conn.log + +# The pcap has been truncated on purpose, so there's going to be large +# gaps that are there by design and shouldn't trigger the "skip +# deliveries" code paths because this test still needs to know about the +# payloads being delivered around critical boundaries (e.g. 32-bit TCP +# sequence wraparound and 32-bit data offsets). +redef tcp_excessive_data_without_further_acks=0; + +event file_chunk(f: fa_file, data: string, off: count) + { + print "file_chunk", |data|, off, data; + } + +event file_new(f: fa_file) + { + Files::add_analyzer(f, Files::ANALYZER_DATA_EVENT, + [$chunk_event=file_chunk]); + } From 04344d09eb708c23fa22288d718ce5059c168eeb Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Wed, 9 Apr 2014 13:36:44 -0500 Subject: [PATCH 015/136] Update SNMP analyzer's DeliverPacket method signature. --- src/analyzer/protocol/snmp/SNMP.cc | 2 +- src/analyzer/protocol/snmp/SNMP.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/analyzer/protocol/snmp/SNMP.cc b/src/analyzer/protocol/snmp/SNMP.cc index bed2e3c12d..36282087fa 100644 --- a/src/analyzer/protocol/snmp/SNMP.cc +++ b/src/analyzer/protocol/snmp/SNMP.cc @@ -25,7 +25,7 @@ void SNMP_Analyzer::Done() } void SNMP_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen) + uint64 seq, const IP_Hdr* ip, int caplen) { Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); diff --git a/src/analyzer/protocol/snmp/SNMP.h b/src/analyzer/protocol/snmp/SNMP.h index 31f4450d9b..d01704d2ae 100644 --- a/src/analyzer/protocol/snmp/SNMP.h +++ b/src/analyzer/protocol/snmp/SNMP.h @@ -16,7 +16,7 @@ public: virtual void Done(); virtual void DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) { return new SNMP_Analyzer(conn); } From cc838c6b2e1d20bb8ae07bec91840eca13285dc6 Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Thu, 10 Apr 2014 15:11:43 -0700 Subject: [PATCH 016/136] rip out state handline from ssl analyzer. still seems to work, but basically untested. --- src/analyzer/protocol/ssl/ssl-analyzer.pac | 79 ++----- src/analyzer/protocol/ssl/ssl-protocol.pac | 249 ++++----------------- 2 files changed, 55 insertions(+), 273 deletions(-) diff --git a/src/analyzer/protocol/ssl/ssl-analyzer.pac b/src/analyzer/protocol/ssl/ssl-analyzer.pac index 49104fa549..39388c448e 100644 --- a/src/analyzer/protocol/ssl/ssl-analyzer.pac +++ b/src/analyzer/protocol/ssl/ssl-analyzer.pac @@ -107,25 +107,6 @@ refine connection SSL_Conn += { %cleanup{ %} - function proc_change_cipher_spec(rec: SSLRecord) : bool - %{ - if ( state_ == STATE_TRACK_LOST ) - bro_analyzer()->ProtocolViolation(fmt("unexpected ChangeCipherSpec from %s at state %s", - orig_label(${rec.is_orig}).c_str(), - state_label(old_state_).c_str())); - return true; - %} - - function proc_application_data(rec: SSLRecord) : bool - %{ - if ( state_ != STATE_CONN_ESTABLISHED && - (state_ != STATE_CLIENT_FINISHED && ! ${rec.is_orig}) ) - bro_analyzer()->ProtocolViolation(fmt("unexpected ApplicationData from %s at state %s", - orig_label(${rec.is_orig}).c_str(), - state_label(old_state_).c_str())); - return true; - %} - function proc_alert(rec: SSLRecord, level : int, desc : int) : bool %{ BifEvent::generate_ssl_alert(bro_analyzer(), bro_analyzer()->Conn(), @@ -267,11 +248,6 @@ refine connection SSL_Conn += { function proc_v2_client_master_key(rec: SSLRecord, cipher_kind: int) : bool %{ - if ( state_ == STATE_TRACK_LOST ) - bro_analyzer()->ProtocolViolation(fmt("unexpected v2 client master key message from %s in state %s", - orig_label(${rec.is_orig}).c_str(), - state_label(old_state_).c_str())); - BifEvent::generate_ssl_established(bro_analyzer(), bro_analyzer()->Conn()); @@ -285,17 +261,6 @@ refine connection SSL_Conn += { return true; %} - function proc_handshake(hs: Handshake, is_orig: bool) : bool - %{ - if ( state_ == STATE_TRACK_LOST ) - bro_analyzer()->ProtocolViolation(fmt("unexpected Handshake message %s from %s in state %s", - handshake_type_label(${hs.msg_type}).c_str(), - orig_label(is_orig).c_str(), - state_label(old_state_).c_str())); - - return true; - %} - function proc_unknown_record(rec: SSLRecord) : bool %{ bro_analyzer()->ProtocolViolation(fmt("unknown SSL record type (%d) from %s", @@ -306,13 +271,8 @@ refine connection SSL_Conn += { function proc_ciphertext_record(rec : SSLRecord) : bool %{ - if ( state_ == STATE_TRACK_LOST ) - bro_analyzer()->ProtocolViolation(fmt("unexpected ciphertext record from %s in state %s", - orig_label(${rec.is_orig}).c_str(), - state_label(old_state_).c_str())); - - else if ( state_ == STATE_CONN_ESTABLISHED && - old_state_ == STATE_COMM_ENCRYPTED ) + if ( client_state_ == STATE_ENCRYPTED && + server_state_ == STATE_ENCRYPTED ) { BifEvent::generate_ssl_established(bro_analyzer(), bro_analyzer()->Conn()); @@ -322,10 +282,10 @@ refine connection SSL_Conn += { %} }; -refine typeattr ChangeCipherSpec += &let { - proc : bool = $context.connection.proc_change_cipher_spec(rec) - &requires(state_changed); -}; +#refine typeattr ChangeCipherSpec += &let { +# proc : bool = $context.connection.proc_change_cipher_spec(rec) +# &requires(state_changed); +#}; refine typeattr Alert += &let { proc : bool = $context.connection.proc_alert(rec, level, description); @@ -335,42 +295,37 @@ refine typeattr V2Error += &let { proc : bool = $context.connection.proc_alert(rec, -1, error_code); }; -refine typeattr ApplicationData += &let { - proc : bool = $context.connection.proc_application_data(rec); -}; +#refine typeattr ApplicationData += &let { +# proc : bool = $context.connection.proc_application_data(rec); +#}; refine typeattr ClientHello += &let { proc : bool = $context.connection.proc_client_hello(rec, client_version, gmt_unix_time, random_bytes, - session_id, csuits, 0) - &requires(state_changed); + session_id, csuits, 0); }; refine typeattr V2ClientHello += &let { proc : bool = $context.connection.proc_client_hello(rec, client_version, 0, - challenge, session_id, 0, ciphers) - &requires(state_changed); + challenge, session_id, 0, ciphers); }; refine typeattr ServerHello += &let { proc : bool = $context.connection.proc_server_hello(rec, server_version, gmt_unix_time, random_bytes, session_id, cipher_suite, 0, - compression_method) - &requires(state_changed); + compression_method); }; refine typeattr V2ServerHello += &let { proc : bool = $context.connection.proc_server_hello(rec, server_version, 0, - conn_id_data, 0, 0, ciphers, 0) - &requires(state_changed); + conn_id_data, 0, 0, ciphers, 0); cert : bool = $context.connection.proc_v2_certificate(rec, cert_data) &requires(proc); }; refine typeattr Certificate += &let { - proc : bool = $context.connection.proc_v3_certificate(rec, certificates) - &requires(state_changed); + proc : bool = $context.connection.proc_v3_certificate(rec, certificates); }; refine typeattr V2ClientMasterKey += &let { @@ -382,9 +337,9 @@ refine typeattr UnknownHandshake += &let { proc : bool = $context.connection.proc_unknown_handshake(hs, is_orig); }; -refine typeattr Handshake += &let { - proc : bool = $context.connection.proc_handshake(this, rec.is_orig); -}; +#refine typeattr Handshake += &let { +# proc : bool = $context.connection.proc_handshake(this, rec.is_orig); +#}; refine typeattr SessionTicketHandshake += &let { proc : bool = $context.connection.proc_session_ticket_handshake(this, rec.is_orig); diff --git a/src/analyzer/protocol/ssl/ssl-protocol.pac b/src/analyzer/protocol/ssl/ssl-protocol.pac index 9368122eaa..7ee71df352 100644 --- a/src/analyzer/protocol/ssl/ssl-protocol.pac +++ b/src/analyzer/protocol/ssl/ssl-protocol.pac @@ -34,7 +34,7 @@ type SSLRecord(is_orig: bool) = record { head4 : uint8; rec : RecordText(this)[] &length=length, &requires(content_type); } &length = length+5, &byteorder=bigendian, - &let { + &let { version : int = $context.connection.determine_ssl_version(head0, head1, head2); @@ -51,9 +51,8 @@ type SSLRecord(is_orig: bool) = record { }; }; -type RecordText(rec: SSLRecord) = case $context.connection.state() of { - STATE_ABBREV_SERVER_ENCRYPTED, STATE_CLIENT_ENCRYPTED, - STATE_COMM_ENCRYPTED, STATE_CONN_ESTABLISHED +type RecordText(rec: SSLRecord) = case $context.connection.state(rec.is_orig) of { + STATE_ENCRYPTED -> ciphertext : CiphertextRecord(rec); default -> plaintext : PlaintextRecord(rec); @@ -82,64 +81,18 @@ type SSLExtension(rec: SSLRecord) = record { ###################################################################### enum AnalyzerState { - STATE_INITIAL, - STATE_CLIENT_HELLO_RCVD, - STATE_IN_SERVER_HELLO, - STATE_SERVER_HELLO_DONE, - STATE_CLIENT_CERT, - STATE_CLIENT_KEY_WITH_CERT, - STATE_CLIENT_KEY_NO_CERT, - STATE_CLIENT_CERT_VERIFIED, - STATE_CLIENT_ENCRYPTED, - STATE_CLIENT_FINISHED, - STATE_ABBREV_SERVER_ENCRYPTED, - STATE_ABBREV_SERVER_FINISHED, - STATE_COMM_ENCRYPTED, - STATE_CONN_ESTABLISHED, - STATE_V2_CL_MASTER_KEY_EXPECTED, - - STATE_TRACK_LOST, - STATE_ANY + STATE_CLEAR, + STATE_ENCRYPTED }; %code{ string state_label(int state_nr) { switch ( state_nr ) { - case STATE_INITIAL: - return string("INITIAL"); - case STATE_CLIENT_HELLO_RCVD: - return string("CLIENT_HELLO_RCVD"); - case STATE_IN_SERVER_HELLO: - return string("IN_SERVER_HELLO"); - case STATE_SERVER_HELLO_DONE: - return string("SERVER_HELLO_DONE"); - case STATE_CLIENT_CERT: - return string("CLIENT_CERT"); - case STATE_CLIENT_KEY_WITH_CERT: - return string("CLIENT_KEY_WITH_CERT"); - case STATE_CLIENT_KEY_NO_CERT: - return string("CLIENT_KEY_NO_CERT"); - case STATE_CLIENT_CERT_VERIFIED: - return string("CLIENT_CERT_VERIFIED"); - case STATE_CLIENT_ENCRYPTED: - return string("CLIENT_ENCRYPTED"); - case STATE_CLIENT_FINISHED: - return string("CLIENT_FINISHED"); - case STATE_ABBREV_SERVER_ENCRYPTED: - return string("ABBREV_SERVER_ENCRYPTED"); - case STATE_ABBREV_SERVER_FINISHED: - return string("ABBREV_SERVER_FINISHED"); - case STATE_COMM_ENCRYPTED: - return string("COMM_ENCRYPTED"); - case STATE_CONN_ESTABLISHED: - return string("CONN_ESTABLISHED"); - case STATE_V2_CL_MASTER_KEY_EXPECTED: - return string("STATE_V2_CL_MASTER_KEY_EXPECTED"); - case STATE_TRACK_LOST: - return string("TRACK_LOST"); - case STATE_ANY: - return string("ANY"); + case STATE_CLEAR: + return string("CLEAR"); + case STATE_ENCRYPTED: + return string("ENCRYPTED"); default: return string(fmt("UNKNOWN (%d)", state_nr)); @@ -176,21 +129,7 @@ type ChangeCipherSpec(rec: SSLRecord) = record { type : uint8; } &length = 1, &let { state_changed : bool = - $context.connection.transition(STATE_CLIENT_FINISHED, - STATE_COMM_ENCRYPTED, rec.is_orig, false) || - $context.connection.transition(STATE_IN_SERVER_HELLO, - STATE_ABBREV_SERVER_ENCRYPTED, rec.is_orig, false) || - $context.connection.transition(STATE_CLIENT_KEY_NO_CERT, - STATE_CLIENT_ENCRYPTED, rec.is_orig, true) || - $context.connection.transition(STATE_CLIENT_CERT_VERIFIED, - STATE_CLIENT_ENCRYPTED, rec.is_orig, true) || - $context.connection.transition(STATE_CLIENT_CERT, - STATE_CLIENT_ENCRYPTED, rec.is_orig, true) || - $context.connection.transition(STATE_CLIENT_KEY_WITH_CERT, - STATE_CLIENT_ENCRYPTED, rec.is_orig, true) || - $context.connection.transition(STATE_ABBREV_SERVER_FINISHED, - STATE_COMM_ENCRYPTED, rec.is_orig, true) || - $context.connection.lost_track(); + $context.connection.startEncryption(rec.is_orig); }; @@ -209,7 +148,7 @@ type Alert(rec: SSLRecord) = record { ###################################################################### type V2Error(rec: SSLRecord) = record { - data: bytestring &restofdata &transient; + data : bytestring &restofdata &transient; } &let { error_code : uint16 = ((rec.head3 << 8) | rec.head4); }; @@ -234,9 +173,7 @@ type ApplicationData(rec: SSLRecord) = record { ###################################################################### # Hello Request is empty -type HelloRequest(rec: SSLRecord) = empty &let { - hr: bool = $context.connection.set_hello_requested(true); -}; +type HelloRequest(rec: SSLRecord) = empty; ###################################################################### @@ -257,13 +194,6 @@ type ClientHello(rec: SSLRecord) = record { # of the following fields. ext_len: uint16[] &until($element == 0 || $element != 0); extensions : SSLExtension(rec)[] &until($input.length() == 0); -} &let { - state_changed : bool = - $context.connection.transition(STATE_INITIAL, - STATE_CLIENT_HELLO_RCVD, rec.is_orig, true) || - ($context.connection.hello_requested() && - $context.connection.transition(STATE_ANY, STATE_CLIENT_HELLO_RCVD, rec.is_orig, true)) || - $context.connection.lost_track(); }; @@ -279,13 +209,6 @@ type V2ClientHello(rec: SSLRecord) = record { session_id : uint8[session_len]; challenge : bytestring &length = chal_len; } &length = 6 + csuit_len + session_len + chal_len, &let { - state_changed : bool = - $context.connection.transition(STATE_INITIAL, - STATE_CLIENT_HELLO_RCVD, rec.is_orig, true) || - ($context.connection.hello_requested() && - $context.connection.transition(STATE_ANY, STATE_CLIENT_HELLO_RCVD, rec.is_orig, true)) || - $context.connection.lost_track(); - client_version : int = rec.version; }; @@ -306,11 +229,6 @@ type ServerHello(rec: SSLRecord) = record { # of the following fields. ext_len: uint16[] &until($element == 0 || $element != 0); extensions : SSLExtension(rec)[] &until($input.length() == 0); -} &let { - state_changed : bool = - $context.connection.transition(STATE_CLIENT_HELLO_RCVD, - STATE_IN_SERVER_HELLO, rec.is_orig, false) || - $context.connection.lost_track(); }; @@ -329,14 +247,6 @@ type V2ServerHello(rec: SSLRecord) = record { ciphers : uint24[ciph_len/3]; conn_id_data : bytestring &length = conn_id_len; } &let { - state_changed : bool = - (session_id_hit > 0 ? - $context.connection.transition(STATE_CLIENT_HELLO_RCVD, - STATE_CONN_ESTABLISHED, rec.is_orig, false) : - $context.connection.transition(STATE_CLIENT_HELLO_RCVD, - STATE_V2_CL_MASTER_KEY_EXPECTED, rec.is_orig, false)) || - $context.connection.lost_track(); - session_id_hit : uint8 = rec.head3; cert_type : uint8 = rec.head4; }; @@ -357,12 +267,10 @@ type Certificate(rec: SSLRecord) = record { length : uint24; certificates : CertificateList &length = to_int()(length); } &let { - state_changed : bool = - $context.connection.transition(STATE_IN_SERVER_HELLO, - STATE_IN_SERVER_HELLO, rec.is_orig, false) || - $context.connection.transition(STATE_SERVER_HELLO_DONE, - STATE_CLIENT_CERT, rec.is_orig, true) || - $context.connection.lost_track(); + state_changed_client : bool = + $context.connection.startEncryption(true); + state_changed_server : bool = + $context.connection.startEncryption(false); }; @@ -373,11 +281,6 @@ type Certificate(rec: SSLRecord) = record { # For now ignore details; just eat up complete message type ServerKeyExchange(rec: SSLRecord) = record { key : bytestring &restofdata &transient; -} &let { - state_changed : bool = - $context.connection.transition(STATE_IN_SERVER_HELLO, - STATE_IN_SERVER_HELLO, rec.is_orig, false) || - $context.connection.lost_track(); }; @@ -388,11 +291,6 @@ type ServerKeyExchange(rec: SSLRecord) = record { # For now, ignore Certificate Request Details; just eat up message. type CertificateRequest(rec: SSLRecord) = record { cont : bytestring &restofdata &transient; -} &let { - state_changed : bool = - $context.connection.transition(STATE_IN_SERVER_HELLO, - STATE_IN_SERVER_HELLO, rec.is_orig, false) || - $context.connection.lost_track(); }; @@ -401,12 +299,7 @@ type CertificateRequest(rec: SSLRecord) = record { ###################################################################### # Server Hello Done is empty -type ServerHelloDone(rec: SSLRecord) = empty &let { - state_changed : bool = - $context.connection.transition(STATE_IN_SERVER_HELLO, - STATE_SERVER_HELLO_DONE, rec.is_orig, false) || - $context.connection.lost_track(); -}; +type ServerHelloDone(rec: SSLRecord) = empty; ###################################################################### @@ -425,15 +318,6 @@ type ServerHelloDone(rec: SSLRecord) = empty &let { # encrypted anyway); just eat up message. type ClientKeyExchange(rec: SSLRecord) = record { key : bytestring &restofdata &transient; -} &let { - state_changed : bool = - $context.connection.transition(STATE_SERVER_HELLO_DONE, - STATE_CLIENT_KEY_NO_CERT, rec.is_orig, true) || - $context.connection.transition(STATE_CLIENT_CERT, - STATE_CLIENT_KEY_WITH_CERT, rec.is_orig, true) || - $context.connection.transition(STATE_CLIENT_CERT, - STATE_CLIENT_KEY_WITH_CERT, rec.is_orig, true) || - $context.connection.lost_track(); }; ###################################################################### @@ -449,11 +333,6 @@ type V2ClientMasterKey(rec: SSLRecord) = record { en_key_data : bytestring &length = en_key_len &transient; key_arg_data : bytestring &length = key_arg_len &transient; } &length = 7 + cl_key_len + en_key_len + key_arg_len, &let { - state_changed : bool = - $context.connection.transition(STATE_V2_CL_MASTER_KEY_EXPECTED, - STATE_CONN_ESTABLISHED, rec.is_orig, true) || - $context.connection.lost_track(); - cipher_kind : int = (((rec.head3 << 16) | (rec.head4 << 8)) | cipher_kind_8); }; @@ -465,11 +344,6 @@ type V2ClientMasterKey(rec: SSLRecord) = record { # For now, ignore Certificate Verify; just eat up the message. type CertificateVerify(rec: SSLRecord) = record { cont : bytestring &restofdata &transient; -} &let { - state_changed : bool = - $context.connection.transition(STATE_CLIENT_KEY_WITH_CERT, - STATE_CLIENT_CERT_VERIFIED, rec.is_orig, true) || - $context.connection.lost_track(); }; @@ -481,13 +355,6 @@ type CertificateVerify(rec: SSLRecord) = record { # so we will not be able to read those messages. type Finished(rec: SSLRecord) = record { cont : bytestring &restofdata &transient; -} &let { - state_changed : bool = - $context.connection.transition(STATE_SERVER_HELLO_DONE, - STATE_COMM_ENCRYPTED, rec.is_orig, true) || - $context.connection.transition(STATE_CLIENT_FINISHED, - STATE_COMM_ENCRYPTED, rec.is_orig, false) || - $context.connection.lost_track(); }; type SessionTicketHandshake(rec: SSLRecord) = record { @@ -499,10 +366,8 @@ type SessionTicketHandshake(rec: SSLRecord) = record { # V3 Handshake Protocol (7.) ###################################################################### -type UnknownHandshake(hs: Handshake, is_orig: bool) = record { +type UnknownHandshake(hs: Handshake, is_orig: bool) = record { data : bytestring &restofdata &transient; -} &let { - state_changed : bool = $context.connection.lost_track(); }; type Handshake(rec: SSLRecord) = record { @@ -532,33 +397,12 @@ type Handshake(rec: SSLRecord) = record { # Fragmentation (6.2.1.) ###################################################################### -type UnknownRecord(rec: SSLRecord) = record { +type UnknownRecord(rec: SSLRecord) = record { cont : bytestring &restofdata &transient; -} &let { - state_changed : bool = $context.connection.lost_track(); }; type CiphertextRecord(rec: SSLRecord) = record { cont : bytestring &restofdata &transient; -} &let { - state_changed : bool = - $context.connection.transition(STATE_CLIENT_FINISHED, - STATE_CLIENT_FINISHED, rec.is_orig, false) || - $context.connection.transition(STATE_CLIENT_FINISHED, - STATE_CLIENT_FINISHED, rec.is_orig, true) || - $context.connection.transition(STATE_ABBREV_SERVER_ENCRYPTED, - STATE_ABBREV_SERVER_FINISHED, rec.is_orig, false) || - $context.connection.transition(STATE_CLIENT_ENCRYPTED, - STATE_CLIENT_FINISHED, rec.is_orig, true) || - $context.connection.transition(STATE_COMM_ENCRYPTED, - STATE_CONN_ESTABLISHED, rec.is_orig, false) || - $context.connection.transition(STATE_COMM_ENCRYPTED, - STATE_CONN_ESTABLISHED, rec.is_orig, true) || - $context.connection.transition(STATE_CONN_ESTABLISHED, - STATE_CONN_ESTABLISHED, rec.is_orig, false) || - $context.connection.transition(STATE_CONN_ESTABLISHED, - STATE_CONN_ESTABLISHED, rec.is_orig, true) || - $context.connection.lost_track(); }; @@ -578,22 +422,22 @@ type SSLPDU(is_orig: bool) = record { refine connection SSL_Conn += { %member{ - int state_; + int client_state_; + int server_state_; int old_state_; bool hello_requested_; %} %init{ - state_ = STATE_INITIAL; - old_state_ = STATE_INITIAL; - hello_requested_ = false; + server_state_ = STATE_CLEAR; + client_state_ = STATE_CLEAR; %} function determine_ssl_version(head0 : uint8, head1 : uint8, head2 : uint8) : int %{ if ( head0 >= 20 && head0 <= 23 && - head1 == 0x03 && head2 <= 0x03 ) + head1 == 0x03 && head2 <= 0x03 ) // This is most probably SSL version 3. return (head1 << 8) | head2; @@ -606,39 +450,22 @@ refine connection SSL_Conn += { return UNKNOWN_VERSION; %} - function state() : int %{ return state_; %} - function old_state() : int %{ return old_state_; %} + function client_state() : int %{ return client_state_; %} + function server_state() : int %{ return client_state_; %} + function state(is_orig: bool) : int + %{ + if ( is_orig ) + return client_state_; + else + return server_state_; + %} - function transition(olds : AnalyzerState, news : AnalyzerState, - current_record_is_orig : bool, is_orig : bool) : bool + function startEncryption(is_orig: bool) : bool %{ - if ( (olds != STATE_ANY && olds != state_) || - current_record_is_orig != is_orig ) - return false; - - old_state_ = state_; - state_ = news; - - //printf("transitioning from %s to %s\n", state_label(old_state()).c_str(), state_label(state()).c_str()); + if ( is_orig ) + client_state_ = STATE_ENCRYPTED; + else + server_state_ = STATE_ENCRYPTED; return true; %} - - function lost_track() : bool - %{ - state_ = STATE_TRACK_LOST; - return false; - %} - - function hello_requested() : bool - %{ - bool ret = hello_requested_; - hello_requested_ = false; - return ret; - %} - - function set_hello_requested(val : bool) : bool - %{ - hello_requested_ = val; - return val; - %} }; From db80947b5f285a49d8bf8c60f816aad9ab4b0b98 Mon Sep 17 00:00:00 2001 From: Seth Hall Date: Mon, 14 Apr 2014 15:58:37 -0400 Subject: [PATCH 017/136] Updated snmp script. Feedback would be welcome! --- scripts/base/protocols/snmp/main.bro | 157 ++++++++++++++++++++++++++- 1 file changed, 156 insertions(+), 1 deletion(-) diff --git a/scripts/base/protocols/snmp/main.bro b/scripts/base/protocols/snmp/main.bro index a2fbb23713..1c92e73ce0 100644 --- a/scripts/base/protocols/snmp/main.bro +++ b/scripts/base/protocols/snmp/main.bro @@ -3,13 +3,168 @@ module SNMP; export { + redef enum Log::ID += { LOG }; + + type Info: record { + ts: time &log; + uid: string &log; + id: conn_id &log; + duration: interval &log &default=0secs; + + version: string &log; + community: string &log &optional; + + get_requests: count &log &default=0; + get_bulk_requests: count &log &default=0; + get_responses: count &log &default=0; + + set_requests: count &log &default=0; + + display_string: string &log &optional; + up_since: time &log &optional; + }; + + redef record connection += { + snmp: SNMP::Info &optional; + }; + + global log_snmp: event(rec: Info); } const ports = { 161/udp, 162/udp }; - redef likely_server_ports += { ports }; +const version_map = { + [0] = "1", + [1] = "2c", + [3] = "3", +}; + event bro_init() &priority=5 { Analyzer::register_for_ports(Analyzer::ANALYZER_SNMP, ports); + Log::create_stream(SNMP::LOG, [$columns=SNMP::Info, $ev=log_snmp]); + } + +function init_state(c: connection, h: SNMP::Header): Info + { + if ( ! c?$snmp ) + { + c$snmp = Info($ts=network_time(), + $uid=c$uid, $id=c$id, + $version=version_map[h$version]); + } + + local s = c$snmp; + if ( ! s?$community ) + { + if ( h?$v1 ) + s$community = h$v1$community; + if ( h?$v2 ) + s$community = h$v2$community; + } + + s$duration = network_time() - s$ts; + return s; + } + + +event connection_state_remove(c: connection) &priority=-5 + { + if ( c?$snmp ) + Log::write(LOG, c$snmp); + } + +event snmp_get_request(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::PDU) &priority=5 + { + local s = init_state(c, header); + for ( i in pdu$bindings ) + { + ++s$get_requests; + } + } + +event snmp_get_bulk_request(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::BulkPDU) &priority=5 + { + local s = init_state(c, header); + for ( i in pdu$bindings ) + { + ++s$get_bulk_requests; + } + } + +event snmp_get_next_request(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::PDU) &priority=5 + { + local s = init_state(c, header); + for ( i in pdu$bindings ) + { + ++s$get_requests; + } + } + +event snmp_response(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::PDU) &priority=5 + { + local s = init_state(c, header); + + for ( i in pdu$bindings ) + { + ++s$get_responses; + + local binding = pdu$bindings[i]; + if ( binding$oid == "1.3.6.1.2.1.1.1.0" && binding$value?$octets ) + c$snmp$display_string = binding$value$octets; + else if ( binding$oid == "1.3.6.1.2.1.1.3.0" && binding$value?$unsigned ) + { + local up_seconds = binding$value$unsigned / 100.0; + s$up_since = network_time() - double_to_interval(up_seconds); + } + } + } + +event snmp_set_request(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::PDU) &priority=5 + { + local s = init_state(c, header); + for ( i in pdu$bindings ) + { + ++s$set_requests; + } + } + +event snmp_trap(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::TrapPDU) &priority=5 + { + init_state(c, header); + } + +event snmp_inform_request(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::PDU) &priority=5 + { + init_state(c, header); + } + +event snmp_trapV2(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::PDU) &priority=5 + { + init_state(c, header); + } + +event snmp_report(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::PDU) &priority=5 + { + init_state(c, header); + } + +event snmp_unknown_pdu(c: connection, is_orig: bool, header: SNMP::Header, tag: count) &priority=5 + { + init_state(c, header); + } + +event snmp_unknown_scoped_pdu(c: connection, is_orig: bool, header: SNMP::Header, tag: count) &priority=5 + { + init_state(c, header); + } + +event snmp_encrypted_pdu(c: connection, is_orig: bool, header: SNMP::Header) &priority=5 + { + init_state(c, header); + } + +event snmp_unknown_header_version(c: connection, is_orig: bool, version: count) &priority=5 + { } From 2dbca1ccd93da3b949e90f76a236060d0b04bdae Mon Sep 17 00:00:00 2001 From: jshlbrd Date: Tue, 15 Apr 2014 09:07:21 -0400 Subject: [PATCH 018/136] Add Intel::ADDR lookup to host field IP addresses are often seen in the HTTP host field; this change checks if the value in the host field is a valid IP address and processes the Intel::seen event to check for an Intel::ADDR indicator. --- .../frameworks/intel/seen/http-headers.bro | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/scripts/policy/frameworks/intel/seen/http-headers.bro b/scripts/policy/frameworks/intel/seen/http-headers.bro index 2a74548023..b9393c93a6 100644 --- a/scripts/policy/frameworks/intel/seen/http-headers.bro +++ b/scripts/policy/frameworks/intel/seen/http-headers.bro @@ -8,12 +8,18 @@ event http_header(c: connection, is_orig: bool, name: string, value: string) { switch ( name ) { - case "HOST": - Intel::seen([$indicator=value, - $indicator_type=Intel::DOMAIN, - $conn=c, - $where=HTTP::IN_HOST_HEADER]); - break; + case "HOST": + if ( is_valid_ip(value) ) + Intel::seen([$host=to_addr(value), + $conn=c, + $where=HTTP::IN_HOST_HEADER]); + else + Intel::seen([$indicator=value, + $indicator_type=Intel::DOMAIN, + $conn=c, + $where=HTTP::IN_HOST_HEADER]); + break; + case "REFERER": Intel::seen([$indicator=sub(value, /^.*:\/\//, ""), From 85bbc391949240e80780a586f2d5957cff5eb900 Mon Sep 17 00:00:00 2001 From: jshlbrd Date: Tue, 15 Apr 2014 09:10:38 -0400 Subject: [PATCH 019/136] Update http-headers.bro --- scripts/policy/frameworks/intel/seen/http-headers.bro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/policy/frameworks/intel/seen/http-headers.bro b/scripts/policy/frameworks/intel/seen/http-headers.bro index b9393c93a6..b736946bfa 100644 --- a/scripts/policy/frameworks/intel/seen/http-headers.bro +++ b/scripts/policy/frameworks/intel/seen/http-headers.bro @@ -9,7 +9,7 @@ event http_header(c: connection, is_orig: bool, name: string, value: string) switch ( name ) { case "HOST": - if ( is_valid_ip(value) ) + if ( is_valid_ip(value) ) Intel::seen([$host=to_addr(value), $conn=c, $where=HTTP::IN_HOST_HEADER]); From 9083b03bd6e26d82b0a701919004cf1a62c5e9e3 Mon Sep 17 00:00:00 2001 From: jshlbrd Date: Tue, 15 Apr 2014 09:12:09 -0400 Subject: [PATCH 020/136] Update http-headers.bro --- scripts/policy/frameworks/intel/seen/http-headers.bro | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/policy/frameworks/intel/seen/http-headers.bro b/scripts/policy/frameworks/intel/seen/http-headers.bro index b736946bfa..c2e2160f57 100644 --- a/scripts/policy/frameworks/intel/seen/http-headers.bro +++ b/scripts/policy/frameworks/intel/seen/http-headers.bro @@ -11,6 +11,7 @@ event http_header(c: connection, is_orig: bool, name: string, value: string) case "HOST": if ( is_valid_ip(value) ) Intel::seen([$host=to_addr(value), + $indicator_type=Intel::ADDR, $conn=c, $where=HTTP::IN_HOST_HEADER]); else From b43c2c347b1761cfeb9dd433c574d78089392df7 Mon Sep 17 00:00:00 2001 From: jshlbrd Date: Tue, 15 Apr 2014 09:15:57 -0400 Subject: [PATCH 021/136] Update http-headers.bro --- scripts/policy/frameworks/intel/seen/http-headers.bro | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/policy/frameworks/intel/seen/http-headers.bro b/scripts/policy/frameworks/intel/seen/http-headers.bro index c2e2160f57..3746ec9def 100644 --- a/scripts/policy/frameworks/intel/seen/http-headers.bro +++ b/scripts/policy/frameworks/intel/seen/http-headers.bro @@ -21,7 +21,6 @@ event http_header(c: connection, is_orig: bool, name: string, value: string) $where=HTTP::IN_HOST_HEADER]); break; - case "REFERER": Intel::seen([$indicator=sub(value, /^.*:\/\//, ""), $indicator_type=Intel::URL, From ef41cc7189cf199d8d229aa47acd58b37e6d0eb4 Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Wed, 16 Apr 2014 10:48:22 -0700 Subject: [PATCH 022/136] Nicer notices for heartbleed. Duplicates are now excluded and the notice texts contain a bit more useful information. --- scripts/policy/protocols/ssl/heartbleed.bro | 40 +++++++++++++-------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/scripts/policy/protocols/ssl/heartbleed.bro b/scripts/policy/protocols/ssl/heartbleed.bro index 0049c4c51f..dc38c66f73 100644 --- a/scripts/policy/protocols/ssl/heartbleed.bro +++ b/scripts/policy/protocols/ssl/heartbleed.bro @@ -15,11 +15,9 @@ export { redef enum Notice::Type += { ## Indicates that a host performing a heartbleed attack. SSL_Heartbeat_Attack, - ## Indicates that a host performing a heartbleed attack was successful. + ## Indicates that a host performing a heartbleed attack was probably successful. SSL_Heartbeat_Attack_Success, - ## Indivcates that a host performing a heartbleed attack after encryption was started was probably successful - SSL_Heartbeat_Encrypted_Attack_Success, - ## Indicates we saw heartbeet requests with odd length. Probably an attack. + ## Indicates we saw heartbeat requests with odd length. Probably an attack. SSL_Heartbeat_Odd_Length, ## Indicates we saw many heartbeat requests without an reply. Might be an attack. SSL_Heartbeat_Many_Requests @@ -37,7 +35,8 @@ event ssl_heartbeat(c: connection, is_orig: bool, length: count, heartbeat_type: c$ssl$heartbleed_detected = T; NOTICE([$note=SSL_Heartbeat_Attack, $msg=fmt("An TLS heartbleed attack was detected! Record length %d, payload length %d", length, payload_length), - $conn=c + $conn=c, + $identifier=cat(c$uid, length, payload_length) ]); } } @@ -45,8 +44,9 @@ event ssl_heartbeat(c: connection, is_orig: bool, length: count, heartbeat_type: if ( heartbeat_type == 2 && c$ssl$heartbleed_detected ) { NOTICE([$note=SSL_Heartbeat_Attack_Success, - $msg="An TLS heartbleed attack was detected and probably exploited", - $conn=c + $msg=fmt("An TLS heartbleed attack detected before was probably exploited. Transmitted payload length in first packet: %d", payload_length), + $conn=c, + $identifier=c$uid ]); } } @@ -60,16 +60,26 @@ event ssl_encrypted_heartbeat(c: connection, is_orig: bool, length: count) if ( c$ssl$originator_heartbeats > c$ssl$responder_heartbeats + 3 ) NOTICE([$note=SSL_Heartbeat_Many_Requests, - $msg="Seeing more than 3 heartbeat requests without replies from server. Possible attack?", + $msg=fmt("Seeing more than 3 heartbeat requests without replies from server. Possible attack. Client count: %d, server count: %d", c$ssl$originator_heartbeats, c$ssl$responder_heartbeats), $conn=c, - $n=(c$ssl$originator_heartbeats-c$ssl$responder_heartbeats) + $n=(c$ssl$originator_heartbeats-c$ssl$responder_heartbeats), + $identifier=fmt("%s%d", c$uid, c$ssl$responder_heartbeats/1000) # re-throw every 1000 heartbeats + ]); + + if ( c$ssl$responder_heartbeats > c$ssl$originator_heartbeats + 3 ) + NOTICE([$note=SSL_Heartbeat_Many_Requests, + $msg=fmt("Server is sending more heartbleed responsed than requests were seen. Possible attack. Client count: %d, server count: %d", c$ssl$originator_heartbeats, c$ssl$responder_heartbeats), + $conn=c, + $n=(c$ssl$originator_heartbeats-c$ssl$responder_heartbeats), + $identifier=fmt("%s%d", c$uid, c$ssl$responder_heartbeats/1000) # re-throw every 1000 heartbeats ]); if ( is_orig && length < 19 ) NOTICE([$note=SSL_Heartbeat_Odd_Length, - $msg="Heartbeat message smaller than minimum length. Probable attack.", + $msg=fmt("Heartbeat message smaller than minimum required length. Probable attack. Message length: %d", length), $conn=c, - $n=length + $n=length, + $identifier=cat(c$uid, length) ]); if ( is_orig ) @@ -86,9 +96,11 @@ event ssl_encrypted_heartbeat(c: connection, is_orig: bool, length: count) { if ( c$ssl?$last_originator_heartbeat_request_size && c$ssl$last_originator_heartbeat_request_size < length ) { - NOTICE([$note=SSL_Heartbeat_Encrypted_Attack_Success, - $msg="An Encrypted TLS heartbleed attack was probably detected!", - $conn=c + NOTICE([$note=SSL_Heartbeat_Attack_Success, + $msg=fmt("An Encrypted TLS heartbleed attack was probably detected! First packet client record length %d, first packet server record length %d", + c$ssl?$last_originator_heartbeat_request_size, c$ssl$last_originator_heartbeat_request_size), + $conn=c, + $identifier=c$uid # only throw once per connection ]); } else if ( ! c$ssl?$last_originator_heartbeat_request_size ) From e8a5ea88446d3e648349b54e514b33651be20aa7 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Fri, 18 Apr 2014 13:19:50 -0500 Subject: [PATCH 023/136] Refactor various hex escaping code. --- src/Desc.cc | 68 +++++++++++++++++-------------- src/Desc.h | 26 ++++++++---- src/logging/writers/Ascii.cc | 6 +-- src/threading/formatters/Ascii.cc | 6 +-- src/threading/formatters/JSON.cc | 7 ++-- src/util.cc | 30 +++++++++----- src/util.h | 19 ++++++++- 7 files changed, 102 insertions(+), 60 deletions(-) diff --git a/src/Desc.cc b/src/Desc.cc index 62c6130f40..f636a028b5 100644 --- a/src/Desc.cc +++ b/src/Desc.cc @@ -216,18 +216,32 @@ void ODesc::Indent() } } -static const char hex_chars[] = "0123456789abcdef"; - -static const char* find_first_unprintable(ODesc* d, const char* bytes, unsigned int n) +static bool starts_with(const char* str1, const char* str2, size_t len) { - if ( d->IsBinary() ) + for ( size_t i = 0; i < len; ++i ) + if ( str1[i] != str2[i] ) + return false; + + return true; + } + +size_t ODesc::StartsWithEscapeSequence(const char* start, const char* end) + { + if ( escape_sequences.empty() ) return 0; - while ( n-- ) + escape_set::const_iterator it; + + for ( it = escape_sequences.begin(); it != escape_sequences.end(); ++it ) { - if ( ! isprint(*bytes) ) - return bytes; - ++bytes; + const string& esc_str = *it; + size_t esc_len = esc_str.length(); + + if ( start + esc_len > end ) + continue; + + if ( starts_with(start, esc_str.c_str(), esc_len) ) + return esc_len; } return 0; @@ -235,21 +249,23 @@ static const char* find_first_unprintable(ODesc* d, const char* bytes, unsigned pair ODesc::FirstEscapeLoc(const char* bytes, size_t n) { - pair p(find_first_unprintable(this, bytes, n), 1); + typedef pair escape_pos; - string str(bytes, n); - list::const_iterator it; - for ( it = escape_sequences.begin(); it != escape_sequences.end(); ++it ) + if ( IsBinary() ) + return escape_pos(0, 0); + + for ( size_t i = 0; i < n; ++i ) { - size_t pos = str.find(*it); - if ( pos != string::npos && (p.first == 0 || bytes + pos < p.first) ) - { - p.first = bytes + pos; - p.second = it->size(); - } + if ( ! isprint(bytes[i]) ) + return escape_pos(bytes + i, 1); + + size_t len = StartsWithEscapeSequence(bytes + i, bytes + n); + + if ( len ) + return escape_pos(bytes + i, len); } - return p; + return escape_pos(0, 0); } void ODesc::AddBytes(const void* bytes, unsigned int n) @@ -266,21 +282,11 @@ void ODesc::AddBytes(const void* bytes, unsigned int n) while ( s < e ) { pair p = FirstEscapeLoc(s, e - s); + if ( p.first ) { AddBytesRaw(s, p.first - s); - if ( p.second == 1 ) - { - char hex[6] = "\\x00"; - hex[2] = hex_chars[((*p.first) & 0xf0) >> 4]; - hex[3] = hex_chars[(*p.first) & 0x0f]; - AddBytesRaw(hex, 4); - } - else - { - string esc_str = get_escaped_string(string(p.first, p.second), true); - AddBytesRaw(esc_str.c_str(), esc_str.size()); - } + get_escaped_string(this, p.first, p.second, true); s = p.first + p.second; } else diff --git a/src/Desc.h b/src/Desc.h index 27dc326ff0..b7df7d75f7 100644 --- a/src/Desc.h +++ b/src/Desc.h @@ -4,7 +4,7 @@ #define descriptor_h #include -#include +#include #include #include "BroString.h" @@ -54,16 +54,16 @@ public: void SetFlush(int arg_do_flush) { do_flush = arg_do_flush; } void EnableEscaping(); - void AddEscapeSequence(const char* s) { escape_sequences.push_back(s); } + void AddEscapeSequence(const char* s) { escape_sequences.insert(s); } void AddEscapeSequence(const char* s, size_t n) - { escape_sequences.push_back(string(s, n)); } + { escape_sequences.insert(string(s, n)); } void AddEscapeSequence(const string & s) - { escape_sequences.push_back(s); } - void RemoveEscapeSequence(const char* s) { escape_sequences.remove(s); } + { escape_sequences.insert(s); } + void RemoveEscapeSequence(const char* s) { escape_sequences.erase(s); } void RemoveEscapeSequence(const char* s, size_t n) - { escape_sequences.remove(string(s, n)); } + { escape_sequences.erase(string(s, n)); } void RemoveEscapeSequence(const string & s) - { escape_sequences.remove(s); } + { escape_sequences.erase(s); } void PushIndent(); void PopIndent(); @@ -163,6 +163,15 @@ protected: */ pair FirstEscapeLoc(const char* bytes, size_t n); + /** + * @param start start of string to check for starting with an espace + * sequence. + * @param end one byte past the last character in the string. + * @return The number of bytes in the escape sequence that the string + * starts with. + */ + size_t StartsWithEscapeSequence(const char* start, const char* end); + desc_type type; desc_style style; @@ -171,7 +180,8 @@ protected: unsigned int size; // size of buffer in bytes bool escape; // escape unprintable characters in output? - list escape_sequences; // additional sequences of chars to escape + typedef set escape_set; + escape_set escape_sequences; // additional sequences of chars to escape BroFile* f; // or the file we're using. diff --git a/src/logging/writers/Ascii.cc b/src/logging/writers/Ascii.cc index 43ffe47308..fe79089b04 100644 --- a/src/logging/writers/Ascii.cc +++ b/src/logging/writers/Ascii.cc @@ -335,10 +335,10 @@ bool Ascii::DoWrite(int num_fields, const Field* const * fields, if ( strncmp(bytes, meta_prefix.data(), meta_prefix.size()) == 0 ) { // It would so escape the first character. - char buf[16]; - snprintf(buf, sizeof(buf), "\\x%02x", bytes[0]); + char hex[4] = {'\\', 'x', '0', '0'}; + bytetohex(bytes[0], hex + 2); - if ( ! safe_write(fd, buf, strlen(buf)) ) + if ( ! safe_write(fd, hex, 4) ) goto write_error; ++bytes; diff --git a/src/threading/formatters/Ascii.cc b/src/threading/formatters/Ascii.cc index 3120549f13..6c114ff3fd 100644 --- a/src/threading/formatters/Ascii.cc +++ b/src/threading/formatters/Ascii.cc @@ -122,10 +122,8 @@ bool Ascii::Describe(ODesc* desc, threading::Value* val, const string& name) con // place-holder we use for unset optional fields. We // escape the first character so that the output // won't be ambigious. - static const char hex_chars[] = "0123456789abcdef"; - char hex[6] = "\\x00"; - hex[2] = hex_chars[((*data) & 0xf0) >> 4]; - hex[3] = hex_chars[(*data) & 0x0f]; + char hex[4] = {'\\', 'x', '0', '0'}; + bytetohex(*data, hex + 2); desc->AddRaw(hex, 4); ++data; diff --git a/src/threading/formatters/JSON.cc b/src/threading/formatters/JSON.cc index 17712e8d53..472023e0f8 100644 --- a/src/threading/formatters/JSON.cc +++ b/src/threading/formatters/JSON.cc @@ -160,10 +160,11 @@ bool JSON::Describe(ODesc* desc, Value* val, const string& name) const // 2byte Unicode escape special characters. if ( c < 32 || c > 126 || c == '\n' || c == '"' || c == '\'' || c == '\\' || c == '&' ) { - static const char hex_chars[] = "0123456789abcdef"; desc->AddRaw("\\u00", 4); - desc->AddRaw(&hex_chars[(c & 0xf0) >> 4], 1); - desc->AddRaw(&hex_chars[c & 0x0f], 1); + char hex[2] = {'0', '0'}; + bytetohex(c, hex); + desc->AddRaw(hex, 1); + desc->AddRaw(hex + 1, 1); } else desc->AddRaw(&c, 1); diff --git a/src/util.cc b/src/util.cc index 434783a340..6190067aa6 100644 --- a/src/util.cc +++ b/src/util.cc @@ -120,31 +120,41 @@ std::string get_unescaped_string(const std::string& arg_str) * Takes a string, escapes characters into equivalent hex codes (\x##), and * returns a string containing all escaped values. * + * @param d an ODesc object to store the escaped hex version of the string, + * if null one will be allocated and returned from the function. * @param str string to escape * @param escape_all If true, all characters are escaped. If false, only * characters are escaped that are either whitespace or not printable in * ASCII. - * @return A std::string containing a list of escaped hex values of the form - * \x## */ -std::string get_escaped_string(const std::string& str, bool escape_all) + * @return A ODesc object containing a list of escaped hex values of the form + * \x##, which may be newly allocated if \a d was a null pointer. */ +ODesc* get_escaped_string(ODesc* d, const char* str, size_t len, + bool escape_all) { - char tbuf[16]; - string esc = ""; + if ( ! d ) + d = new ODesc(); - for ( size_t i = 0; i < str.length(); ++i ) + for ( size_t i = 0; i < len; ++i ) { char c = str[i]; if ( escape_all || isspace(c) || ! isascii(c) || ! isprint(c) ) { - snprintf(tbuf, sizeof(tbuf), "\\x%02x", str[i]); - esc += tbuf; + char hex[4] = {'\\', 'x', '0', '0' }; + bytetohex(c, hex + 2); + d->AddRaw(hex, 4); } else - esc += c; + d->AddRaw(&c, 1); } - return esc; + return d; + } + +std::string get_escaped_string(const char* str, size_t len, bool escape_all) + { + ODesc d; + return get_escaped_string(&d, str, len, escape_all)->Description(); } char* copy_string(const char* s) diff --git a/src/util.h b/src/util.h index aebc8bbc43..c6b657b7a8 100644 --- a/src/util.h +++ b/src/util.h @@ -102,8 +102,25 @@ void delete_each(T* t) std::string extract_ip(const std::string& i); std::string extract_ip_and_len(const std::string& i, int* len); +inline void bytetohex(unsigned char byte, char* hex_out) + { + static const char hex_chars[] = "0123456789abcdef"; + hex_out[0] = hex_chars[(byte & 0xf0) >> 4]; + hex_out[1] = hex_chars[byte & 0x0f]; + } + std::string get_unescaped_string(const std::string& str); -std::string get_escaped_string(const std::string& str, bool escape_all); + +class ODesc; + +ODesc* get_escaped_string(ODesc* d, const char* str, size_t len, + bool escape_all); +std::string get_escaped_string(const char* str, size_t len, bool escape_all); + +inline std::string get_escaped_string(const std::string& str, bool escape_all) + { + return get_escaped_string(str.data(), str.length(), escape_all); + } std::vector* tokenize_string(std::string input, const std::string& delim, From bc5c02cb745189c6672b88fde48b3fff338a1c5c Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Fri, 18 Apr 2014 16:35:43 -0500 Subject: [PATCH 024/136] Refactor file analysis file ID lookup. Now using a dictionary instead of std::map as order doesn't matter and lookup time shouldn't increase as more files are in process of being analyzed. --- src/file_analysis/Manager.cc | 44 ++++++++++++++++++------------------ src/file_analysis/Manager.h | 14 +++++++----- 2 files changed, 30 insertions(+), 28 deletions(-) diff --git a/src/file_analysis/Manager.cc b/src/file_analysis/Manager.cc index 5ff7bd7186..3f04ebfc2b 100644 --- a/src/file_analysis/Manager.cc +++ b/src/file_analysis/Manager.cc @@ -54,8 +54,11 @@ void Manager::Terminate() { vector keys; - for ( IDMap::iterator it = id_map.begin(); it != id_map.end(); ++it ) - keys.push_back(it->first); + IterCookie* it = id_map.InitForIteration(); + HashKey* key; + + while ( id_map.NextEntry(key, it) ) + keys.push_back(static_cast(key->Key())); for ( size_t i = 0; i < keys.size(); ++i ) Timeout(keys[i], true); @@ -249,11 +252,12 @@ File* Manager::GetFile(const string& file_id, Connection* conn, if ( IsIgnored(file_id) ) return 0; - File* rval = id_map[file_id]; + File* rval = id_map.Lookup(file_id.c_str()); if ( ! rval ) { - rval = id_map[file_id] = new File(file_id, conn, tag, is_orig); + rval = new File(file_id, conn, tag, is_orig); + id_map.Insert(file_id.c_str(), rval); rval->ScheduleInactivityTimer(); if ( IsIgnored(file_id) ) @@ -272,12 +276,7 @@ File* Manager::GetFile(const string& file_id, Connection* conn, File* Manager::LookupFile(const string& file_id) const { - IDMap::const_iterator it = id_map.find(file_id); - - if ( it == id_map.end() ) - return 0; - - return it->second; + return id_map.Lookup(file_id.c_str()); } void Manager::Timeout(const string& file_id, bool is_terminating) @@ -308,37 +307,38 @@ void Manager::Timeout(const string& file_id, bool is_terminating) bool Manager::IgnoreFile(const string& file_id) { - if ( id_map.find(file_id) == id_map.end() ) + if ( ! id_map.Lookup(file_id.c_str()) ) return false; DBG_LOG(DBG_FILE_ANALYSIS, "Ignore FileID %s", file_id.c_str()); - ignored.insert(file_id); - + delete ignored.Insert(file_id.c_str(), new bool); return true; } bool Manager::RemoveFile(const string& file_id) { - IDMap::iterator it = id_map.find(file_id); + HashKey key(file_id.c_str()); + // Can't remove from the dictionary/map right away as invoking EndOfFile + // may cause some events to be executed which actually depend on the file + // still being in the dictionary/map. + File* f = static_cast(id_map.Lookup(&key)); - if ( it == id_map.end() ) + if ( ! f ) return false; DBG_LOG(DBG_FILE_ANALYSIS, "Remove FileID %s", file_id.c_str()); - it->second->EndOfFile(); - - delete it->second; - id_map.erase(file_id); - ignored.erase(file_id); - + f->EndOfFile(); + delete f; + id_map.Remove(&key); + delete static_cast(ignored.Remove(&key)); return true; } bool Manager::IsIgnored(const string& file_id) { - return ignored.find(file_id) != ignored.end(); + return ignored.Lookup(file_id.c_str()) != 0; } string Manager::GetFileID(analyzer::Tag tag, Connection* c, bool is_orig) diff --git a/src/file_analysis/Manager.h b/src/file_analysis/Manager.h index bb6aaab971..2137e81389 100644 --- a/src/file_analysis/Manager.h +++ b/src/file_analysis/Manager.h @@ -4,10 +4,9 @@ #define FILE_ANALYSIS_MANAGER_H #include -#include -#include #include +#include "Dict.h" #include "Net.h" #include "Conn.h" #include "Val.h" @@ -27,6 +26,9 @@ namespace file_analysis { +declare(PDict,bool); +declare(PDict,File); + /** * Main entry point for interacting with file analysis. */ @@ -288,8 +290,8 @@ public: protected: friend class FileTimer; - typedef set IDSet; - typedef map IDMap; + typedef PDict(bool) IDSet; + typedef PDict(File) IDMap; /** * Create a new file to be analyzed or retrieve an existing one. @@ -361,8 +363,8 @@ protected: private: - IDMap id_map; /**< Map file ID to file_analysis::File records. */ - IDSet ignored; /**< Ignored files. Will be finally removed on EOF. */ + PDict(File) id_map; /**< Map file ID to file_analysis::File records. */ + PDict(bool) ignored; /**< Ignored files. Will be finally removed on EOF. */ string current_file_id; /**< Hash of what get_file_handle event sets. */ RuleFileMagicState* magic_state; /**< File magic signature match state. */ From b283883997c4ea6e1213768fb3112686a1d19b0f Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Fri, 18 Apr 2014 16:29:51 -0700 Subject: [PATCH 025/136] define empty request_key method for sumstats in cluster mode. This prevents the worker nodes from crashing, when request_key is used in cluster mode and called on the worker and the manager nodes (i.e. when a non-cluster-aware script is used). Addresses BIT-1177 --- scripts/base/frameworks/sumstats/cluster.bro | 28 +++++++---- .../frameworks/sumstats/on-demand-cluster.bro | 47 +++++++------------ 2 files changed, 35 insertions(+), 40 deletions(-) diff --git a/scripts/base/frameworks/sumstats/cluster.bro b/scripts/base/frameworks/sumstats/cluster.bro index 67c59a8728..b609abf472 100644 --- a/scripts/base/frameworks/sumstats/cluster.bro +++ b/scripts/base/frameworks/sumstats/cluster.bro @@ -28,10 +28,6 @@ export { ## values for a sumstat. global cluster_ss_request: event(uid: string, ss_name: string, cleanup: bool); - # Event sent by nodes that are collecting sumstats after receiving a - # request for the sumstat from the manager. - #global cluster_ss_response: event(uid: string, ss_name: string, data: ResultTable, done: bool, cleanup: bool); - ## This event is sent by the manager in a cluster to initiate the ## collection of a single key value from a sumstat. It's typically used ## to get intermediate updates before the break interval triggers to @@ -144,7 +140,7 @@ event SumStats::cluster_ss_request(uid: string, ss_name: string, cleanup: bool) sending_results[uid] = (ss_name in result_store) ? result_store[ss_name] : table(); # Lookup the actual sumstats and reset it, the reference to the data - # currently stored will be maintained internally from the + # currently stored will be maintained internally from the # sending_results table. if ( cleanup && ss_name in stats_store ) reset(stats_store[ss_name]); @@ -159,7 +155,7 @@ event SumStats::cluster_get_result(uid: string, ss_name: string, key: Key, clean if ( uid in sending_results && key in sending_results[uid] ) { # Note: copy is needed to compensate serialization caching issue. This should be - # changed to something else later. + # changed to something else later. event SumStats::cluster_send_result(uid, ss_name, key, copy(sending_results[uid][key]), cleanup); delete sending_results[uid][key]; } @@ -170,12 +166,12 @@ event SumStats::cluster_get_result(uid: string, ss_name: string, key: Key, clean event SumStats::cluster_send_result(uid, ss_name, key, table(), cleanup); } } - else + else { if ( ss_name in result_store && key in result_store[ss_name] ) { # Note: copy is needed to compensate serialization caching issue. This should be - # changed to something else later. + # changed to something else later. event SumStats::cluster_send_result(uid, ss_name, key, copy(result_store[ss_name][key]), cleanup); } else @@ -195,6 +191,19 @@ event SumStats::cluster_threshold_crossed(ss_name: string, key: SumStats::Key, t threshold_tracker[ss_name][key] = thold_index; } +# request-key is a non-op on the workers. +# It only should be called by the manager. Due to the fact that we usually run the same scripts on the +# workers and the manager, it might also be called by the workers, so we just ignore it here. +# +# There is a small chance that people will try running it on events that are just thrown on the workers. +# This does not work at the moment and we cannot throw an error message, because we cannot distinguish it +# from the "script is running it everywhere" case. But - people should notice that they do not get results. +# Not entirely pretty, sorry :( +function request_key(ss_name: string, key: Key): Result + { + return Result(); + } + @endif @@ -215,7 +224,6 @@ global stats_keys: table[string] of set[Key] &read_expire=1min # matches the number of peer nodes that results should be coming from, the # result is written out and deleted from here. # Indexed on a uid. -# TODO: add an &expire_func in case not all results are received. global done_with: table[string] of count &read_expire=1min &default=0; # This variable is maintained by managers to track intermediate responses as @@ -414,7 +422,7 @@ event SumStats::cluster_send_result(uid: string, ss_name: string, key: Key, resu # Mark that a worker is done. if ( uid !in done_with ) done_with[uid] = 0; - + #print fmt("MANAGER: got a result for %s %s from %s", uid, key, get_event_peer()$descr); ++done_with[uid]; diff --git a/testing/btest/scripts/base/frameworks/sumstats/on-demand-cluster.bro b/testing/btest/scripts/base/frameworks/sumstats/on-demand-cluster.bro index 48068d8cfe..4e3e765500 100644 --- a/testing/btest/scripts/base/frameworks/sumstats/on-demand-cluster.bro +++ b/testing/btest/scripts/base/frameworks/sumstats/on-demand-cluster.bro @@ -7,6 +7,7 @@ # @TEST-EXEC: btest-bg-wait 15 # @TEST-EXEC: btest-diff manager-1/.stdout +# @TEST-START-FILE cluster-layout.bro redef Cluster::nodes = { @@ -36,6 +37,20 @@ event remote_connection_closed(p: event_peer) global ready_for_data: event(); redef Cluster::manager2worker_events += /^ready_for_data$/; +event on_demand() + { + local host = 7.2.1.5; + when ( local result = SumStats::request_key("test sumstat", [$host=host]) ) + { + print "SumStat key request"; + if ( "test" in result ) + print fmt(" Host: %s -> %.0f", host, result["test"]$sum); + + if ( Cluster::node == "manager-1" ) + terminate(); + } + } + event ready_for_data() { if ( Cluster::node == "worker-1" ) @@ -52,33 +67,8 @@ event ready_for_data() SumStats::observe("test", [$host=7.2.1.5], [$num=91]); SumStats::observe("test", [$host=10.10.10.10], [$num=5]); } - } - -event on_demand2() - { - local host = 7.2.1.5; - when ( local result = SumStats::request_key("test sumstat", [$host=host]) ) - { - print "SumStat key request"; - if ( "test" in result ) - print fmt(" Host: %s -> %.0f", host, result["test"]$sum); - terminate(); - } - } - -event on_demand() - { - #when ( local results = SumStats::request("test sumstat") ) - # { - # print "Complete SumStat request"; - # print fmt(" Host: %s -> %.0f", 6.5.4.3, results[[$host=6.5.4.3]]["test"]$sum); - # print fmt(" Host: %s -> %.0f", 10.10.10.10, results[[$host=10.10.10.10]]["test"]$sum); - # print fmt(" Host: %s -> %.0f", 1.2.3.4, results[[$host=1.2.3.4]]["test"]$sum); - # print fmt(" Host: %s -> %.0f", 7.2.1.5, results[[$host=7.2.1.5]]["test"]$sum); - - event on_demand2(); - # } + schedule 1sec { on_demand() }; } global peer_count = 0; @@ -87,10 +77,7 @@ event remote_connection_handshake_done(p: event_peer) &priority=-5 ++peer_count; if ( peer_count == 2 ) { - if ( Cluster::local_node_type() == Cluster::MANAGER ) - event ready_for_data(); - - schedule 1sec { on_demand() }; + event ready_for_data(); } } From 594975c93d88d3a176fd5ab967cf2d35a883747f Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Mon, 21 Apr 2014 11:23:12 -0700 Subject: [PATCH 026/136] Make SSL/TLS version detection less brittle. This still cannot deal with v2 hellos that use the long length. On the other hand - OpenSSL also cannot deal with these and we should not see many sslv2 connections in any case - so... they probably would not work in practice in any case. --- src/analyzer/protocol/ssl/ssl-analyzer.pac | 13 +++- src/analyzer/protocol/ssl/ssl-protocol.pac | 84 +++++++++++++++------- 2 files changed, 68 insertions(+), 29 deletions(-) diff --git a/src/analyzer/protocol/ssl/ssl-analyzer.pac b/src/analyzer/protocol/ssl/ssl-analyzer.pac index 997faf0436..b6422584e3 100644 --- a/src/analyzer/protocol/ssl/ssl-analyzer.pac +++ b/src/analyzer/protocol/ssl/ssl-analyzer.pac @@ -293,6 +293,14 @@ refine connection SSL_Conn += { return true; %} + function proc_check_v2_server_hello_version(version: uint16) : bool + %{ + if ( version != SSLv20 ) + bro_analyzer()->ProtocolViolation(fmt("Invalid version in SSL server hello. Version: %d", version)); + + return true; + %} + }; #refine typeattr ChangeCipherSpec += &let { @@ -337,6 +345,8 @@ refine typeattr V2ServerHello += &let { proc : bool = $context.connection.proc_server_hello(rec, server_version, 0, conn_id_data, 0, 0, ciphers, 0); + check_v2 : bool = $context.connection.proc_check_v2_server_hello_version(server_version); + cert : bool = $context.connection.proc_v2_certificate(rec, cert_data) &requires(proc); }; @@ -346,8 +356,7 @@ refine typeattr Certificate += &let { }; refine typeattr V2ClientMasterKey += &let { - proc : bool = $context.connection.proc_v2_client_master_key(rec, cipher_kind) - &requires(state_changed); + proc : bool = $context.connection.proc_v2_client_master_key(rec, cipher_kind); }; refine typeattr UnknownHandshake += &let { diff --git a/src/analyzer/protocol/ssl/ssl-protocol.pac b/src/analyzer/protocol/ssl/ssl-protocol.pac index f72f34e9cc..d32d926f65 100644 --- a/src/analyzer/protocol/ssl/ssl-protocol.pac +++ b/src/analyzer/protocol/ssl/ssl-protocol.pac @@ -36,16 +36,14 @@ type SSLRecord(is_orig: bool) = record { } &length = length+5, &byteorder=bigendian, &let { version : int = - $context.connection.determine_ssl_version(head0, head1, head2); + $context.connection.determine_ssl_record_layer(head0, head1, head2, head3, head4); content_type : int = case version of { - # UNKNOWN_VERSION -> 0; assume tls on unknown version SSLv20 -> head2+300; default -> head0; }; length : int = case version of { - # UNKNOWN_VERSION -> 0; assume tls on unknown version SSLv20 -> (((head0 & 0x7f) << 8) | head1) - 3; default -> (head3 << 8) | head4; }; @@ -277,11 +275,6 @@ type CertificateList = X509Certificate[] &until($input.length() == 0); type Certificate(rec: SSLRecord) = record { length : uint24; certificates : CertificateList &length = to_int()(length); -} &let { - state_changed_client : bool = - $context.connection.startEncryption(true); - state_changed_server : bool = - $context.connection.startEncryption(false); }; @@ -345,6 +338,9 @@ type V2ClientMasterKey(rec: SSLRecord) = record { key_arg_data : bytestring &length = key_arg_len &transient; } &length = 7 + cl_key_len + en_key_len + key_arg_len, &let { cipher_kind : int = (((rec.head3 << 16) | (rec.head4 << 8)) | cipher_kind_8); + # encryption starts for both sides after this message. + state_changed_client : bool = $context.connection.startEncryption(true); + state_changed_server : bool = $context.connection.startEncryption(false); }; @@ -435,41 +431,75 @@ refine connection SSL_Conn += { %member{ int client_state_; int server_state_; - int old_state_; - bool hello_requested_; + int record_layer_version_; %} %init{ server_state_ = STATE_CLEAR; client_state_ = STATE_CLEAR; + record_layer_version_ = UNKNOWN_VERSION; %} - function determine_ssl_version(head0 : uint8, head1 : uint8, - head2 : uint8) : int + function determine_ssl_record_layer(head0 : uint8, head1 : uint8, + head2 : uint8, head3: uint8, head4: uint8) : int %{ - if ( head0 >= 20 && head0 <= 23 && - head1 == 0x03 && head2 <= 0x03 ) - // This is most probably SSL version 3. - return (head1 << 8) | head2; + if ( record_layer_version_ != UNKNOWN_VERSION ) + return record_layer_version_; - else if ( head0 >= 128 && head2 < 5 && head2 != 3 ) - // Not very strong evidence, but we suspect - // this to be SSLv2. - return SSLv20; + if ( head0 & 0x80 ) + { + if ( head2 == 0x01 ) // SSLv2 client hello. + { + uint16 version = (head3<<8) | head4; + if ( version != SSLv20 && version != SSLv30 && version != TLSv10 + && version != TLSv11 && version != TLSv12 ) + { + bro_analyzer()->ProtocolViolation(fmt("Invalid version in SSL client hello. Version: %d", version)); + return UNKNOWN_VERSION; + } + else + return SSLv20; + } - else + else if ( head2 == 0x04 ) // SSLv2 server hello. This connection will continue using SSLv2. + { + record_layer_version_ = SSLv20; + return SSLv20; + } + else // this is not SSL or TLS. + { + bro_analyzer()->ProtocolViolation(fmt("Invalid headers in SSL connection. Head1: %d, head2: %d, head3: %d", head1, head2, head3)); + return UNKNOWN_VERSION; + } + } + + uint16 version = (head1<<8) | head2; + if ( version != SSLv30 && version != TLSv10 + && version != TLSv11 && version != TLSv12 ) + { + bro_analyzer()->ProtocolViolation(fmt("Invalid version in TLS connection. Version: %d", version)); return UNKNOWN_VERSION; + } + + if ( head0 >=20 && head0 <= 30 ) + { // ok, set record layer version, this never can be downgraded to v2 + record_layer_version_ = version; + return version; + } + + bro_analyzer()->ProtocolViolation(fmt("Invalid type in TLS connection. Version: %d, Type: %d", version, head0)); + return UNKNOWN_VERSION; %} function client_state() : int %{ return client_state_; %} function server_state() : int %{ return client_state_; %} function state(is_orig: bool) : int - %{ - if ( is_orig ) - return client_state_; - else - return server_state_; - %} + %{ + if ( is_orig ) + return client_state_; + else + return server_state_; + %} function startEncryption(is_orig: bool) : bool %{ From 8126f06ffb3402d380a80774a11f7df4b3f1b774 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 21 Apr 2014 16:43:33 -0500 Subject: [PATCH 027/136] Enforce data size limit when checking files for MIME matches. The value of *bof_buffer_size* in the *fa_file* record was supposed to always limit the amount of data used by the signature matching engine, but some corner cases would cause matching to be performed on data beyond that. --- src/file_analysis/File.cc | 1 + .../doc.sphinx.mimestats/btest-doc.sphinx.mimestats#1 | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/file_analysis/File.cc b/src/file_analysis/File.cc index e8a7ea15ee..2772b55418 100644 --- a/src/file_analysis/File.cc +++ b/src/file_analysis/File.cc @@ -283,6 +283,7 @@ bool File::BufferBOF(const u_char* data, uint64 len) bool File::DetectMIME(const u_char* data, uint64 len) { RuleMatcher::MIME_Matches matches; + len = min(len, LookupFieldDefaultCount(bof_buffer_size_idx)); file_mgr->DetectMIME(data, len, &matches); if ( matches.empty() ) diff --git a/testing/btest/Baseline/doc.sphinx.mimestats/btest-doc.sphinx.mimestats#1 b/testing/btest/Baseline/doc.sphinx.mimestats/btest-doc.sphinx.mimestats#1 index 3cd6a49e11..3d6b9dffad 100644 --- a/testing/btest/Baseline/doc.sphinx.mimestats/btest-doc.sphinx.mimestats#1 +++ b/testing/btest/Baseline/doc.sphinx.mimestats/btest-doc.sphinx.mimestats#1 @@ -16,15 +16,15 @@ #empty_field (empty) #unset_field - #path mime_metrics - #open 2014-03-06-17-30-44 + #open 2014-04-21-21-34-08 #fields ts ts_delta mtype uniq_hosts hits bytes #types time interval string count count count - 1389719059.311698 300.000000 text/html 1 4 53070 + 1389719059.311698 300.000000 text/html 1 3 47335 1389719059.311698 300.000000 image/jpeg 1 1 186859 1389719059.311698 300.000000 application/pgp-signature 1 1 836 - 1389719059.311698 300.000000 text/plain 1 12 113982 + 1389719059.311698 300.000000 text/plain 1 13 119717 1389719059.311698 300.000000 image/gif 1 1 172 1389719059.311698 300.000000 image/png 1 9 82176 1389719059.311698 300.000000 image/x-icon 1 2 2300 - #close 2014-03-06-17-30-44 + #close 2014-04-21-21-34-08 From 171c6ce86bfc53bed837458d946f9cd097f4c463 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Mon, 21 Apr 2014 16:55:51 -0500 Subject: [PATCH 028/136] Refactor regex/signature AcceptingSet data structure and usages. Several parts of that code would do membership checks and that's going to be more efficient with a set instead of a list data structure. --- src/DFA.cc | 28 +++------- src/RE.cc | 42 +++++++-------- src/RE.h | 20 ++++--- src/RuleMatcher.cc | 130 +++++++++++++++++++-------------------------- src/RuleMatcher.h | 3 ++ 5 files changed, 99 insertions(+), 124 deletions(-) diff --git a/src/DFA.cc b/src/DFA.cc index ad9521709e..dbfed71ba3 100644 --- a/src/DFA.cc +++ b/src/DFA.cc @@ -211,9 +211,10 @@ void DFA_State::Dump(FILE* f, DFA_Machine* m) if ( accept ) { - for ( int i = 0; i < accept->length(); ++i ) - fprintf(f, "%s accept #%d", - i > 0 ? "," : "", int((*accept)[i])); + AcceptingSet::const_iterator it; + + for ( it = accept->begin(); it != accept->end(); ++it ) + fprintf(f, "%s accept #%d", it == accept->begin() ? "" : ",", *it); } fprintf(f, "\n"); @@ -285,7 +286,7 @@ unsigned int DFA_State::Size() { return sizeof(*this) + pad_size(sizeof(DFA_State*) * num_sym) - + (accept ? pad_size(sizeof(int) * accept->length()) : 0) + + (accept ? pad_size(sizeof(int) * accept->size()) : 0) + (nfa_states ? pad_size(sizeof(NFA_State*) * nfa_states->length()) : 0) + (meta_ec ? meta_ec->Size() : 0) + (centry ? padded_sizeof(CacheEntry) : 0); @@ -470,33 +471,20 @@ int DFA_Machine::StateSetToDFA_State(NFA_state_list* state_set, return 0; AcceptingSet* accept = new AcceptingSet; + for ( int i = 0; i < state_set->length(); ++i ) { int acc = (*state_set)[i]->Accept(); if ( acc != NO_ACCEPT ) - { - int j; - for ( j = 0; j < accept->length(); ++j ) - if ( (*accept)[j] == acc ) - break; - - if ( j >= accept->length() ) - // It's not already present. - accept->append(acc); - } + accept->insert(acc); } - if ( accept->length() == 0 ) + if ( accept->empty() ) { delete accept; accept = 0; } - else - { - accept->sort(int_list_cmp); - accept->resize(0); - } DFA_State* ds = new DFA_State(state_count++, ec, state_set, accept); d = dfa_state_cache->Insert(ds, hash); diff --git a/src/RE.cc b/src/RE.cc index 87117c1c3a..4855b0e39a 100644 --- a/src/RE.cc +++ b/src/RE.cc @@ -3,6 +3,7 @@ #include "config.h" #include +#include #include "RE.h" #include "DFA.h" @@ -266,6 +267,15 @@ void Specific_RE_Matcher::Dump(FILE* f) dfa->Dump(f); } +inline void RE_Match_State::AddMatches(const AcceptingSet& as, + MatchPos position) + { + typedef std::pair am_idx; + + for ( AcceptingSet::const_iterator it = as.begin(); it != as.end(); ++it ) + accepted_matches.insert(am_idx(*it, position)); + } + bool RE_Match_State::Match(const u_char* bv, int n, bool bol, bool eol, bool clear) { @@ -283,14 +293,9 @@ bool RE_Match_State::Match(const u_char* bv, int n, current_state = dfa->StartState(); const AcceptingSet* ac = current_state->Accept(); + if ( ac ) - { - loop_over_list(*ac, i) - { - accepted.append((*ac)[i]); - match_pos.append(0); - } - } + AddMatches(*ac, 0); } else if ( clear ) @@ -301,7 +306,7 @@ bool RE_Match_State::Match(const u_char* bv, int n, current_pos = 0; - int old_matches = accepted.length(); + size_t old_matches = accepted_matches.size(); int ec; int m = bol ? n + 1 : n; @@ -324,25 +329,17 @@ bool RE_Match_State::Match(const u_char* bv, int n, break; } - if ( next_state->Accept() ) - { - const AcceptingSet* ac = next_state->Accept(); - loop_over_list(*ac, i) - { - if ( ! accepted.is_member((*ac)[i]) ) - { - accepted.append((*ac)[i]); - match_pos.append(current_pos); - } - } - } + const AcceptingSet* ac = next_state->Accept(); + + if ( ac ) + AddMatches(*ac, current_pos); ++current_pos; current_state = next_state; } - return accepted.length() != old_matches; + return accepted_matches.size() != old_matches; } int Specific_RE_Matcher::LongestMatch(const u_char* bv, int n) @@ -399,7 +396,8 @@ unsigned int Specific_RE_Matcher::MemoryAllocation() const + equiv_class.Size() - padded_sizeof(EquivClass) + (dfa ? dfa->MemoryAllocation() : 0) // this is ref counted; consider the bytes here? + padded_sizeof(*any_ccl) - + accepted->MemoryAllocation(); + + padded_sizeof(*accepted) + + accepted->size() * padded_sizeof(AcceptingSet::key_type); } RE_Matcher::RE_Matcher() diff --git a/src/RE.h b/src/RE.h index a2fc709c88..7437dbb8b8 100644 --- a/src/RE.h +++ b/src/RE.h @@ -9,6 +9,9 @@ #include "CCL.h" #include "EquivClass.h" +#include +#include + #include typedef int (*cce_func)(int); @@ -33,7 +36,10 @@ extern int re_lex(void); extern int clower(int); extern void synerr(const char str[]); -typedef int_list AcceptingSet; +typedef int AcceptIdx; +typedef std::set AcceptingSet; +typedef uint64 MatchPos; +typedef std::map AcceptingMatchSet; typedef name_list string_list; typedef enum { MATCH_ANYWHERE, MATCH_EXACTLY, } match_type; @@ -135,8 +141,8 @@ public: current_state = 0; } - const AcceptingSet* Accepted() const { return &accepted; } - const int_list* MatchPositions() const { return &match_pos; } + const AcceptingMatchSet& AcceptedMatches() const + { return accepted_matches; } // Returns the number of bytes feeded into the matcher so far int Length() { return current_pos; } @@ -149,16 +155,16 @@ public: { current_pos = -1; current_state = 0; - accepted.clear(); - match_pos.clear(); + accepted_matches.clear(); } + void AddMatches(const AcceptingSet& as, MatchPos position); + protected: DFA_Machine* dfa; int* ecs; - AcceptingSet accepted; - int_list match_pos; + AcceptingMatchSet accepted_matches; DFA_State* current_state; int current_pos; }; diff --git a/src/RuleMatcher.cc b/src/RuleMatcher.cc index 5e9dff0a1f..5cea843c8d 100644 --- a/src/RuleMatcher.cc +++ b/src/RuleMatcher.cc @@ -594,6 +594,29 @@ RuleFileMagicState* RuleMatcher::InitFileMagic() const return state; } +bool RuleMatcher::AllRulePatternsMatched(const Rule* r, MatchPos matchpos, + const AcceptingMatchSet& ams) + { + DBG_LOG(DBG_RULES, "Checking rule: %s", r->id); + + // Check whether all patterns of the rule have matched. + loop_over_list(r->patterns, j) + { + if ( ams.find(r->patterns[j]->id) == ams.end() ) + return false; + + // See if depth is satisfied. + if ( matchpos > r->patterns[j]->offset + r->patterns[j]->depth ) + return false; + + // FIXME: How to check for offset ??? ### + } + + DBG_LOG(DBG_RULES, "All patterns of rule satisfied"); + + return true; + } + RuleMatcher::MIME_Matches* RuleMatcher::Match(RuleFileMagicState* state, const u_char* data, uint64 len, MIME_Matches* rval) const @@ -636,56 +659,39 @@ RuleMatcher::MIME_Matches* RuleMatcher::Match(RuleFileMagicState* state, DBG_LOG(DBG_RULES, "New pattern match found"); - AcceptingSet accepted; - int_list matchpos; + AcceptingMatchSet accepted_matches; loop_over_list(state->matchers, y) { RuleFileMagicState::Matcher* m = state->matchers[y]; - const AcceptingSet* ac = m->state->Accepted(); - - loop_over_list(*ac, k) - { - if ( ! accepted.is_member((*ac)[k]) ) - { - accepted.append((*ac)[k]); - matchpos.append((*m->state->MatchPositions())[k]); - } - } + const AcceptingMatchSet& ams = m->state->AcceptedMatches(); + accepted_matches.insert(ams.begin(), ams.end()); } // Find rules for which patterns have matched. - rule_list matched; + set rule_matches; - loop_over_list(accepted, i) + for ( AcceptingMatchSet::const_iterator it = accepted_matches.begin(); + it != accepted_matches.end(); ++it ) { - Rule* r = Rule::rule_table[accepted[i] - 1]; + AcceptIdx aidx = it->first; + MatchPos mpos = it->second; - DBG_LOG(DBG_RULES, "Checking rule: %v", r->id); + Rule* r = Rule::rule_table[aidx - 1]; - loop_over_list(r->patterns, j) - { - if ( ! accepted.is_member(r->patterns[j]->id) ) - continue; - - if ( (unsigned int) matchpos[i] > - r->patterns[j]->offset + r->patterns[j]->depth ) - continue; - - DBG_LOG(DBG_RULES, "All patterns of rule satisfied"); - } - - if ( ! matched.is_member(r) ) - matched.append(r); + if ( AllRulePatternsMatched(r, mpos, accepted_matches) ) + rule_matches.insert(r); } - loop_over_list(matched, j) + for ( set::const_iterator it = rule_matches.begin(); + it != rule_matches.end(); ++it ) { - Rule* r = matched[j]; + Rule* r = *it; loop_over_list(r->actions, rai) { - const RuleActionMIME* ram = dynamic_cast(r->actions[rai]); + const RuleActionMIME* ram = + dynamic_cast(r->actions[rai]); if ( ! ram ) continue; @@ -876,66 +882,40 @@ void RuleMatcher::Match(RuleEndpointState* state, Rule::PatternType type, DBG_LOG(DBG_RULES, "New pattern match found"); - // Build a joined AcceptingSet. - AcceptingSet accepted; - int_list matchpos; + AcceptingMatchSet accepted_matches; - loop_over_list(state->matchers, y) + loop_over_list(state->matchers, y ) { RuleEndpointState::Matcher* m = state->matchers[y]; - const AcceptingSet* ac = m->state->Accepted(); - - loop_over_list(*ac, k) - { - if ( ! accepted.is_member((*ac)[k]) ) - { - accepted.append((*ac)[k]); - matchpos.append((*m->state->MatchPositions())[k]); - } - } + const AcceptingMatchSet& ams = m->state->AcceptedMatches(); + accepted_matches.insert(ams.begin(), ams.end()); } // Determine the rules for which all patterns have matched. // This code should be fast enough as long as there are only very few // matched patterns per connection (which is a plausible assumption). - rule_list matched; + // Find rules for which patterns have matched. + set rule_matches; - loop_over_list(accepted, i) + for ( AcceptingMatchSet::const_iterator it = accepted_matches.begin(); + it != accepted_matches.end(); ++it ) { - Rule* r = Rule::rule_table[accepted[i] - 1]; + AcceptIdx aidx = it->first; + MatchPos mpos = it->second; - DBG_LOG(DBG_RULES, "Checking rule: %s", r->id); + Rule* r = Rule::rule_table[aidx - 1]; - // Check whether all patterns of the rule have matched. - loop_over_list(r->patterns, j) - { - if ( ! accepted.is_member(r->patterns[j]->id) ) - goto next_pattern; - - // See if depth is satisfied. - if ( (unsigned int) matchpos[i] > - r->patterns[j]->offset + r->patterns[j]->depth ) - goto next_pattern; - - DBG_LOG(DBG_RULES, "All patterns of rule satisfied"); - - // FIXME: How to check for offset ??? ### - } - - // If not already in the list of matching rules, add it. - if ( ! matched.is_member(r) ) - matched.append(r); - -next_pattern: - continue; + if ( AllRulePatternsMatched(r, mpos, accepted_matches) ) + rule_matches.insert(r); } // Check which of the matching rules really belong to any of our nodes. - loop_over_list(matched, j) + for ( set::const_iterator it = rule_matches.begin(); + it != rule_matches.end(); ++it ) { - Rule* r = matched[j]; + Rule* r = *it; DBG_LOG(DBG_RULES, "Accepted rule: %s", r->id); diff --git a/src/RuleMatcher.h b/src/RuleMatcher.h index 52e00f6bad..da2838cb6d 100644 --- a/src/RuleMatcher.h +++ b/src/RuleMatcher.h @@ -361,6 +361,9 @@ private: void DumpStateStats(BroFile* f, RuleHdrTest* hdr_test); + static bool AllRulePatternsMatched(const Rule* r, MatchPos matchpos, + const AcceptingMatchSet& ams); + int RE_level; bool parse_error; RuleHdrTest* root; From e24f3f5fd514832ecb26c9b606b9dbfed56792f2 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Tue, 22 Apr 2014 16:32:22 -0700 Subject: [PATCH 029/136] Updating CHANGES and VERSION. --- CHANGES | 4 ++++ aux/broctl | 2 +- scripts/base/protocols/dns/main.bro | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index d91a2e4700..aad47320de 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,8 @@ +2.2-341 | 2014-04-17 18:01:41 -0500 + + * Fix duplicate DNS log entries. (Robin Sommer) + 2.2-341 | 2014-04-17 18:01:01 -0500 * Refactor initialization of ASCII log writer options. (Jon Siwek) diff --git a/aux/broctl b/aux/broctl index d99150801b..f249570e3f 160000 --- a/aux/broctl +++ b/aux/broctl @@ -1 +1 @@ -Subproject commit d99150801b7844e082b5421d1efe4050702d350e +Subproject commit f249570e3fb4c83e532cc0813786f0ff60c4dea9 diff --git a/scripts/base/protocols/dns/main.bro b/scripts/base/protocols/dns/main.bro index fe371de2a8..d7280602e6 100644 --- a/scripts/base/protocols/dns/main.bro +++ b/scripts/base/protocols/dns/main.bro @@ -183,7 +183,7 @@ function log_unmatched_msgs(msgs: PendingMessages) for ( trans_id in msgs ) log_unmatched_msgs_queue(msgs[trans_id]); - msgs = PendingMessages(); + clear_table(msgs); } function enqueue_new_msg(msgs: PendingMessages, id: count, msg: Info) From b9e956176e83cbc28ff785fb598c980e6e26c8ff Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Tue, 22 Apr 2014 21:35:30 -0700 Subject: [PATCH 030/136] Updating submodule(s). [nomail] --- aux/bro-aux | 2 +- aux/broctl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aux/bro-aux b/aux/bro-aux index 3f86e2d5db..5c0043d587 160000 --- a/aux/bro-aux +++ b/aux/bro-aux @@ -1 +1 @@ -Subproject commit 3f86e2d5db2a0c5f2f104b15f359f4b752bb4558 +Subproject commit 5c0043d587314c57070e5362762e3e0f6408c2be diff --git a/aux/broctl b/aux/broctl index f249570e3f..d99150801b 160000 --- a/aux/broctl +++ b/aux/broctl @@ -1 +1 @@ -Subproject commit f249570e3fb4c83e532cc0813786f0ff60c4dea9 +Subproject commit d99150801b7844e082b5421d1efe4050702d350e From 782615e9ddea93c5ea46d21f7001e48fa7e8ef00 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Wed, 23 Apr 2014 10:44:47 -0500 Subject: [PATCH 031/136] Remove unused Val::attribs member. --- src/Serializer.h | 2 +- src/Val.cc | 7 ------- src/Val.h | 13 ------------- 3 files changed, 1 insertion(+), 21 deletions(-) diff --git a/src/Serializer.h b/src/Serializer.h index af4878ccf5..543797a7af 100644 --- a/src/Serializer.h +++ b/src/Serializer.h @@ -125,7 +125,7 @@ protected: // This will be increased whenever there is an incompatible change // in the data format. - static const uint32 DATA_FORMAT_VERSION = 24; + static const uint32 DATA_FORMAT_VERSION = 25; ChunkedIO* io; diff --git a/src/Val.cc b/src/Val.cc index aa9c888d49..2d75680182 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -32,7 +32,6 @@ Val::Val(Func* f) val.func_val = f; ::Ref(val.func_val); type = f->FType()->Ref(); - attribs = 0; #ifdef DEBUG bound_id = 0; #endif @@ -49,7 +48,6 @@ Val::Val(BroFile* f) assert(f->FType()->Tag() == TYPE_STRING); type = string_file_type->Ref(); - attribs = 0; #ifdef DEBUG bound_id = 0; #endif @@ -190,8 +188,6 @@ bool Val::DoSerialize(SerialInfo* info) const if ( ! type->Serialize(info) ) return false; - SERIALIZE_OPTIONAL(attribs); - switch ( type->InternalType() ) { case TYPE_INTERNAL_VOID: info->s->Error("type is void"); @@ -251,9 +247,6 @@ bool Val::DoUnserialize(UnserialInfo* info) if ( ! (type = BroType::Unserialize(info)) ) return false; - UNSERIALIZE_OPTIONAL(attribs, - (RecordVal*) Val::Unserialize(info, TYPE_RECORD)); - switch ( type->InternalType() ) { case TYPE_INTERNAL_VOID: info->s->Error("type is void"); diff --git a/src/Val.h b/src/Val.h index b94cb2d621..58b24a3e5d 100644 --- a/src/Val.h +++ b/src/Val.h @@ -80,7 +80,6 @@ public: { val.int_val = b; type = base_type(t); - attribs = 0; #ifdef DEBUG bound_id = 0; #endif @@ -90,7 +89,6 @@ public: { val.int_val = bro_int_t(i); type = base_type(t); - attribs = 0; #ifdef DEBUG bound_id = 0; #endif @@ -100,7 +98,6 @@ public: { val.uint_val = bro_uint_t(u); type = base_type(t); - attribs = 0; #ifdef DEBUG bound_id = 0; #endif @@ -110,7 +107,6 @@ public: { val.int_val = i; type = base_type(t); - attribs = 0; #ifdef DEBUG bound_id = 0; #endif @@ -120,7 +116,6 @@ public: { val.uint_val = u; type = base_type(t); - attribs = 0; #ifdef DEBUG bound_id = 0; #endif @@ -130,7 +125,6 @@ public: { val.double_val = d; type = base_type(t); - attribs = 0; #ifdef DEBUG bound_id = 0; #endif @@ -145,7 +139,6 @@ public: Val(BroType* t, bool type_type) // Extra arg to differentiate from protected version. { type = new TypeType(t->Ref()); - attribs = 0; #ifdef DEBUG bound_id = 0; #endif @@ -155,7 +148,6 @@ public: { val.int_val = 0; type = base_type(TYPE_ERROR); - attribs = 0; #ifdef DEBUG bound_id = 0; #endif @@ -364,7 +356,6 @@ protected: { val.string_val = s; type = base_type(t); - attribs = 0; #ifdef DEBUG bound_id = 0; #endif @@ -376,7 +367,6 @@ protected: Val(TypeTag t) { type = base_type(t); - attribs = 0; #ifdef DEBUG bound_id = 0; #endif @@ -385,7 +375,6 @@ protected: Val(BroType* t) { type = t->Ref(); - attribs = 0; #ifdef DEBUG bound_id = 0; #endif @@ -400,7 +389,6 @@ protected: BroValUnion val; BroType* type; - RecordVal* attribs; #ifdef DEBUG // For debugging, we keep the name of the ID to which a Val is bound. @@ -944,7 +932,6 @@ public: { val.int_val = i; type = t; - attribs = 0; } Val* SizeVal() const { return new Val(val.int_val, TYPE_INT); } From 02504897306075c2b9a42603e0f776fbe4688590 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Wed, 23 Apr 2014 16:14:13 -0500 Subject: [PATCH 032/136] Adapt IRC/FTP analyzers to cache file analysis IDs. --- src/analyzer/protocol/file/File.cc | 71 ++++++++++-------------------- src/analyzer/protocol/file/File.h | 22 ++++----- 2 files changed, 32 insertions(+), 61 deletions(-) diff --git a/src/analyzer/protocol/file/File.cc b/src/analyzer/protocol/file/File.cc index 4476043721..4ea8dffaa8 100644 --- a/src/analyzer/protocol/file/File.cc +++ b/src/analyzer/protocol/file/File.cc @@ -31,12 +31,25 @@ void File_Analyzer::DeliverStream(int len, const u_char* data, bool orig) if ( buffer_len == BUFFER_SIZE ) Identify(); } - return; + + if ( orig ) + file_id_orig = file_mgr->DataIn(data, len, GetAnalyzerTag(), Conn(), + orig, file_id_orig); + else + file_id_resp = file_mgr->DataIn(data, len, GetAnalyzerTag(), Conn(), + orig, file_id_resp); } void File_Analyzer::Undelivered(int seq, int len, bool orig) { TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); + + if ( orig ) + file_id_orig = file_mgr->Gap(seq, len, GetAnalyzerTag(), Conn(), orig, + file_id_orig); + else + file_id_resp = file_mgr->Gap(seq, len, GetAnalyzerTag(), Conn(), orig, + file_id_resp); } void File_Analyzer::Done() @@ -45,6 +58,16 @@ void File_Analyzer::Done() if ( buffer_len && buffer_len != BUFFER_SIZE ) Identify(); + + if ( ! file_id_orig.empty() ) + file_mgr->EndOfFile(file_id_orig); + else + file_mgr->EndOfFile(GetAnalyzerTag(), Conn(), true); + + if ( ! file_id_resp.empty() ) + file_mgr->EndOfFile(file_id_resp); + else + file_mgr->EndOfFile(GetAnalyzerTag(), Conn(), false); } void File_Analyzer::Identify() @@ -61,49 +84,3 @@ void File_Analyzer::Identify() vl->append(new StringVal(match)); ConnectionEvent(file_transferred, vl); } - -IRC_Data::IRC_Data(Connection* conn) - : File_Analyzer("IRC_Data", conn) - { - } - -void IRC_Data::Done() - { - File_Analyzer::Done(); - file_mgr->EndOfFile(GetAnalyzerTag(), Conn()); - } - -void IRC_Data::DeliverStream(int len, const u_char* data, bool orig) - { - File_Analyzer::DeliverStream(len, data, orig); - file_mgr->DataIn(data, len, GetAnalyzerTag(), Conn(), orig); - } - -void IRC_Data::Undelivered(int seq, int len, bool orig) - { - File_Analyzer::Undelivered(seq, len, orig); - file_mgr->Gap(seq, len, GetAnalyzerTag(), Conn(), orig); - } - -FTP_Data::FTP_Data(Connection* conn) - : File_Analyzer("FTP_Data", conn) - { - } - -void FTP_Data::Done() - { - File_Analyzer::Done(); - file_mgr->EndOfFile(GetAnalyzerTag(), Conn()); - } - -void FTP_Data::DeliverStream(int len, const u_char* data, bool orig) - { - File_Analyzer::DeliverStream(len, data, orig); - file_mgr->DataIn(data, len, GetAnalyzerTag(), Conn(), orig); - } - -void FTP_Data::Undelivered(int seq, int len, bool orig) - { - File_Analyzer::Undelivered(seq, len, orig); - file_mgr->Gap(seq, len, GetAnalyzerTag(), Conn(), orig); - } diff --git a/src/analyzer/protocol/file/File.h b/src/analyzer/protocol/file/File.h index 7afbd569c4..9376dcc7c3 100644 --- a/src/analyzer/protocol/file/File.h +++ b/src/analyzer/protocol/file/File.h @@ -28,17 +28,15 @@ protected: static const int BUFFER_SIZE = 1024; char buffer[BUFFER_SIZE]; int buffer_len; + string file_id_orig; + string file_id_resp; }; class IRC_Data : public File_Analyzer { public: - IRC_Data(Connection* conn); - - virtual void Done(); - - virtual void DeliverStream(int len, const u_char* data, bool orig); - - virtual void Undelivered(int seq, int len, bool orig); + IRC_Data(Connection* conn) + : File_Analyzer("IRC_Data", conn) + { } static Analyzer* InstantiateAnalyzer(Connection* conn) { return new IRC_Data(conn); } @@ -46,13 +44,9 @@ public: class FTP_Data : public File_Analyzer { public: - FTP_Data(Connection* conn); - - virtual void Done(); - - virtual void DeliverStream(int len, const u_char* data, bool orig); - - virtual void Undelivered(int seq, int len, bool orig); + FTP_Data(Connection* conn) + : File_Analyzer("FTP_Data", conn) + { } static Analyzer* InstantiateAnalyzer(Connection* conn) { return new FTP_Data(conn); } From de8f8f87b69b562d8afb71b1dd19d8ae41478256 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Wed, 23 Apr 2014 16:26:18 -0500 Subject: [PATCH 033/136] Adapt more of HTTP analyzer to use cached file analysis IDs. Some EndOfFile calls can re-use a cached file ID. --- src/analyzer/protocol/http/HTTP.cc | 24 +++++++++++++++++++----- src/analyzer/protocol/http/HTTP.h | 1 + 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/analyzer/protocol/http/HTTP.cc b/src/analyzer/protocol/http/HTTP.cc index f676643b7c..bc0081ab52 100644 --- a/src/analyzer/protocol/http/HTTP.cc +++ b/src/analyzer/protocol/http/HTTP.cc @@ -583,9 +583,16 @@ void HTTP_Message::Done(const int interrupted, const char* detail) top_level->EndOfData(); if ( is_orig || MyHTTP_Analyzer()->HTTP_ReplyCode() != 206 ) - // multipart/byteranges may span multiple connections - file_mgr->EndOfFile(MyHTTP_Analyzer()->GetAnalyzerTag(), - MyHTTP_Analyzer()->Conn(), is_orig); + { + // multipart/byteranges may span multiple connections, so don't EOF. + HTTP_Entity* he = dynamic_cast(top_level); + + if ( he && ! he->FileID().empty() ) + file_mgr->EndOfFile(he->FileID()); + else + file_mgr->EndOfFile(MyHTTP_Analyzer()->GetAnalyzerTag(), + MyHTTP_Analyzer()->Conn(), is_orig); + } if ( http_message_done ) { @@ -663,8 +670,15 @@ void HTTP_Message::EndEntity(mime::MIME_Entity* entity) Done(); else if ( is_orig || MyHTTP_Analyzer()->HTTP_ReplyCode() != 206 ) - file_mgr->EndOfFile(MyHTTP_Analyzer()->GetAnalyzerTag(), - MyHTTP_Analyzer()->Conn(), is_orig); + { + HTTP_Entity* he = dynamic_cast(entity); + + if ( he && ! he->FileID().empty() ) + file_mgr->EndOfFile(he->FileID()); + else + file_mgr->EndOfFile(MyHTTP_Analyzer()->GetAnalyzerTag(), + MyHTTP_Analyzer()->Conn(), is_orig); + } } void HTTP_Message::SubmitHeader(mime::MIME_Header* h) diff --git a/src/analyzer/protocol/http/HTTP.h b/src/analyzer/protocol/http/HTTP.h index 48a611b63b..0318dc9601 100644 --- a/src/analyzer/protocol/http/HTTP.h +++ b/src/analyzer/protocol/http/HTTP.h @@ -46,6 +46,7 @@ public: int64_t BodyLength() const { return body_length; } int64_t HeaderLength() const { return header_length; } void SkipBody() { deliver_body = 0; } + const string& FileID() const { return precomputed_file_id; } protected: class UncompressedOutput; From 4ae52d9e1c0153282a012ec38d910a106bc77117 Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Wed, 23 Apr 2014 14:34:06 -0700 Subject: [PATCH 034/136] Support parsing of several TLS extensions. At the moment, we have support for: elliptic_curves: client supported elliptic curves ec_point_formats: list of client supported EC point formats application_layer_protocol_negotiation: list of supported application layer protocols (used for spdy/http2 negotiation) server_name: server name sent by client. This was supported before, but... a bit brittle. --- scripts/base/frameworks/notice/weird.bro | 1 + scripts/base/protocols/ssl/main.bro | 10 +- src/analyzer/protocol/ssl/events.bif | 8 + src/analyzer/protocol/ssl/ssl-analyzer.pac | 161 ++++++++++++++++----- src/analyzer/protocol/ssl/ssl-defs.pac | 32 ++++ src/analyzer/protocol/ssl/ssl-protocol.pac | 90 ++++++++++-- 6 files changed, 252 insertions(+), 50 deletions(-) diff --git a/scripts/base/frameworks/notice/weird.bro b/scripts/base/frameworks/notice/weird.bro index e7faf38df4..474f021cef 100644 --- a/scripts/base/frameworks/notice/weird.bro +++ b/scripts/base/frameworks/notice/weird.bro @@ -185,6 +185,7 @@ export { ["RPC_underflow"] = ACTION_LOG, ["RST_storm"] = ACTION_LOG, ["RST_with_data"] = ACTION_LOG, + ["SSL_many_server_names"] = ACTION_LOG, ["simultaneous_open"] = ACTION_LOG_PER_CONN, ["spontaneous_FIN"] = ACTION_IGNORE, ["spontaneous_RST"] = ACTION_IGNORE, diff --git a/scripts/base/protocols/ssl/main.bro b/scripts/base/protocols/ssl/main.bro index 5b974222a1..eb128483a4 100644 --- a/scripts/base/protocols/ssl/main.bro +++ b/scripts/base/protocols/ssl/main.bro @@ -159,12 +159,16 @@ event ssl_server_hello(c: connection, version: count, possible_ts: time, server_ c$ssl$cipher = cipher_desc[cipher]; } -event ssl_extension(c: connection, is_orig: bool, code: count, val: string) &priority=5 +event tls_extension_server_name(c: connection, is_orig: bool, names: string_vec) &priority=5 { set_session(c); - if ( is_orig && extensions[code] == "server_name" ) - c$ssl$server_name = sub_bytes(val, 6, |val|); + if ( is_orig && |names| > 0 ) + { + c$ssl$server_name = names[0]; + if ( |names| > 1 ) + event conn_weird("SSL_many_server_names", c, cat(names)); + } } event ssl_alert(c: connection, is_orig: bool, level: count, desc: count) &priority=5 diff --git a/src/analyzer/protocol/ssl/events.bif b/src/analyzer/protocol/ssl/events.bif index a11e7bcc68..457d18ea39 100644 --- a/src/analyzer/protocol/ssl/events.bif +++ b/src/analyzer/protocol/ssl/events.bif @@ -80,6 +80,14 @@ event ssl_server_hello%(c: connection, version: count, possible_ts: time, server ## ssl_session_ticket_handshake event ssl_extension%(c: connection, is_orig: bool, code: count, val: string%); +event tls_extension_ec_point_formats%(c: connection, is_orig: bool, point_formats: index_vec%); + +event tls_extension_elliptic_curves%(c: connection, is_orig: bool, curves: index_vec%); + +event tls_extension_application_layer_protocol_negotiation%(c: connection, is_orig: bool, protocols: string_vec%); + +event tls_extension_server_name%(c: connection, is_orig: bool, names: string_vec%); + ## Generated at the end of an SSL/TLS handshake. SSL/TLS sessions start with ## an unencrypted handshake, and Bro extracts as much information out of that ## as it can. This event signals the time when an SSL/TLS has finished the diff --git a/src/analyzer/protocol/ssl/ssl-analyzer.pac b/src/analyzer/protocol/ssl/ssl-analyzer.pac index b6422584e3..043b2271ec 100644 --- a/src/analyzer/protocol/ssl/ssl-analyzer.pac +++ b/src/analyzer/protocol/ssl/ssl-analyzer.pac @@ -86,23 +86,19 @@ function version_ok(vers : uint16) : bool refine connection SSL_Conn += { - %member{ - int eof; - %} - - %init{ - eof=0; - %} - - #%eof{ - # if ( ! eof && - # state_ != STATE_CONN_ESTABLISHED && - # state_ != STATE_TRACK_LOST && - # state_ != STATE_INITIAL ) - # bro_analyzer()->ProtocolViolation(fmt("unexpected end of connection in state %s", - # state_label(state_).c_str())); - # ++eof; - #%} +# %member{ +# int eof; +# %} +# +# %init{ +# eof=0; +# %} +# +# %eof{ +# if ( ! eof ) +# bro_analyzer()->ProtocolViolation(fmt("unexpected end of connection")); +# ++eof; +# %} %cleanup{ %} @@ -198,12 +194,104 @@ refine connection SSL_Conn += { return true; %} - function proc_ssl_extension(rec: SSLRecord, type: int, data: bytestring) : bool + function proc_ssl_extension(rec: SSLRecord, type: int, sourcedata: const_bytestring) : bool %{ + // we cheat a little bit here. We want to throw this event for every extension we encounter, + // even those that are handled by more specialized events later. + // To access the parsed data, we use sourcedata, which contains the whole data blob of + // the extension, including headers. We skip over those (4 bytes). + size_t length = sourcedata.length(); + if ( length < 4 ) + { + // this should be impossible due to the binpac parser and protocol description + bro_analyzer()->ProtocolViolation(fmt("Impossible extension length: %lu", length)); + return true; + } + length -= 4; + const unsigned char* data = sourcedata.begin() + 4; + if ( ssl_extension ) BifEvent::generate_ssl_extension(bro_analyzer(), bro_analyzer()->Conn(), ${rec.is_orig}, type, - new StringVal(data.length(), (const char*) data.data())); + new StringVal(length, reinterpret_cast(data))); + return true; + %} + + function proc_ec_point_formats(rec: SSLRecord, point_format_list: uint8[]) : bool + %{ + VectorVal* points = new VectorVal(internal_type("index_vec")->AsVectorType()); + if ( point_format_list ) + { + for ( unsigned int i = 0; i < point_format_list->size(); ++i ) + { + points->Assign(i, new Val((*point_format_list)[i], TYPE_COUNT)); + } + } + + BifEvent::generate_tls_extension_ec_point_formats(bro_analyzer(), bro_analyzer()->Conn(), + ${rec.is_orig}, points); + + return true; + %} + + function proc_elliptic_curves(rec: SSLRecord, list: uint16[]) : bool + %{ + VectorVal* curves = new VectorVal(internal_type("index_vec")->AsVectorType()); + if ( list ) + { + for ( unsigned int i = 0; i < list->size(); ++i ) + { + curves->Assign(i, new Val((*list)[i], TYPE_COUNT)); + } + } + + BifEvent::generate_tls_extension_elliptic_curves(bro_analyzer(), bro_analyzer()->Conn(), + ${rec.is_orig}, curves); + + return true; + %} + + function proc_apnl(rec: SSLRecord, protocols: ProtocolName[]) : bool + %{ + VectorVal* plist = new VectorVal(internal_type("string_vec")->AsVectorType()); + if ( protocols ) + { + for ( unsigned int i = 0; i < protocols->size(); ++i ) + { + plist->Assign(i, new StringVal((*protocols)[i]->name().length(), (const char*) (*protocols)[i]->name().data())); + } + } + + BifEvent::generate_tls_extension_application_layer_protocol_negotiation(bro_analyzer(), bro_analyzer()->Conn(), + ${rec.is_orig}, plist); + + return true; + %} + + function proc_server_name(rec: SSLRecord, list: ServerName[]) : bool + %{ + VectorVal* servers = new VectorVal(internal_type("string_vec")->AsVectorType()); + if ( list ) + { + for ( unsigned int i = 0, j=0; i < list->size(); ++i ) + { + ServerName* servername = (*list)[i]; + if ( servername->name_type() != 0 ) + { + bro_analyzer()->Weird(fmt("Encountered unknown type in server name tls extension: %d", servername->name_type())); + continue; + } + + if ( servername->host_name() ) + servers->Assign(j++, new StringVal(servername->host_name()->host_name().length(), (const char*) servername->host_name()->host_name().data())); + else + bro_analyzer()->Weird("Empty server_name extension in tls connection"); + } + } + + BifEvent::generate_tls_extension_server_name(bro_analyzer(), bro_analyzer()->Conn(), + ${rec.is_orig}, servers); + return true; %} @@ -233,9 +321,9 @@ refine connection SSL_Conn += { return ret; %} - function proc_v3_certificate(rec: SSLRecord, cl : CertificateList) : bool + function proc_v3_certificate(rec: SSLRecord, cl : X509Certificate[]) : bool %{ - vector* certs = cl->val(); + vector* certs = cl; vector* cert_list = new vector(); std::transform(certs->begin(), certs->end(), @@ -303,11 +391,6 @@ refine connection SSL_Conn += { }; -#refine typeattr ChangeCipherSpec += &let { -# proc : bool = $context.connection.proc_change_cipher_spec(rec) -# &requires(state_changed); -#}; - refine typeattr Alert += &let { proc : bool = $context.connection.proc_alert(rec, level, description); }; @@ -316,10 +399,6 @@ refine typeattr V2Error += &let { proc : bool = $context.connection.proc_alert(rec, -1, error_code); }; -#refine typeattr ApplicationData += &let { -# proc : bool = $context.connection.proc_application_data(rec); -#}; - refine typeattr Heartbeat += &let { proc : bool = $context.connection.proc_heartbeat(rec, type, payload_length, data); }; @@ -363,10 +442,6 @@ refine typeattr UnknownHandshake += &let { proc : bool = $context.connection.proc_unknown_handshake(hs, is_orig); }; -#refine typeattr Handshake += &let { -# proc : bool = $context.connection.proc_handshake(this, rec.is_orig); -#}; - refine typeattr SessionTicketHandshake += &let { proc : bool = $context.connection.proc_session_ticket_handshake(this, rec.is_orig); } @@ -380,5 +455,21 @@ refine typeattr CiphertextRecord += &let { } refine typeattr SSLExtension += &let { - proc : bool = $context.connection.proc_ssl_extension(rec, type, data); + proc : bool = $context.connection.proc_ssl_extension(rec, type, sourcedata); +}; + +refine typeattr EcPointFormats += &let { + proc : bool = $context.connection.proc_ec_point_formats(rec, point_format_list); +}; + +refine typeattr EllipticCurves += &let { + proc : bool = $context.connection.proc_elliptic_curves(rec, elliptic_curve_list); +}; + +refine typeattr ApplicationLayerProtocolNegotiationExtension += &let { + proc : bool = $context.connection.proc_apnl(rec, protocol_name_list); +}; + +refine typeattr ServerNameExt += &let { + proc : bool = $context.connection.proc_server_name(rec, server_names); }; diff --git a/src/analyzer/protocol/ssl/ssl-defs.pac b/src/analyzer/protocol/ssl/ssl-defs.pac index 23fa7abce5..24827d3621 100644 --- a/src/analyzer/protocol/ssl/ssl-defs.pac +++ b/src/analyzer/protocol/ssl/ssl-defs.pac @@ -20,6 +20,7 @@ enum ContentType { UNKNOWN_OR_V2_ENCRYPTED = 400 }; +# If you add a new TLS version here, do not forget to also adjust the DPD signature. enum SSLVersions { UNKNOWN_VERSION = 0x0000, SSLv20 = 0x0002, @@ -28,3 +29,34 @@ enum SSLVersions { TLSv11 = 0x0302, TLSv12 = 0x0303 }; + +enum SSLExtensions { + EXT_SERVER_NAME = 0, + EXT_MAX_FRAGMENT_LENGTH = 1, + EXT_CLIENT_CERTIFICATE_URL = 2, + EXT_TRUSTED_CA_KEYS = 3, + EXT_TRUNCATED_HMAC = 4, + EXT_STATUS_REQUEST = 5, + EXT_USER_MAPPING = 6, + EXT_CLIENT_AUTHZ = 7, + EXT_SERVER_AUTHZ = 8, + EXT_CERT_TYPE = 9, + EXT_ELLIPTIC_CURVES = 10, + EXT_EC_POINT_FORMATS = 11, + EXT_SRP = 12, + EXT_SIGNATURE_ALGORITHMS = 13, + EXT_USE_SRTP = 14, + EXT_HEARTBEAT = 15, + EXT_APPLICATION_LAYER_PROTOCOL_NEGOTIATION = 16, + EXT_STATUS_REQUEST_V2 = 17, + EXT_SIGNED_CERTIFICATE_TIMESTAMP = 18, + EXT_SESSIONTICKET_TLS = 35, + EXT_EXTENDED_RANDOM = 40, + EXT_NEXT_PROTOCOL_NEGOTIATION = 13172, + EXT_ORIGIN_BOUND_CERTIFICATES = 13175, + EXT_ENCRYPTED_CLIENT_CERTIFICATES = 13180, + EXT_CHANNEL_ID = 30031, + EXT_CHANNEL_ID_NEW = 30032, + EXT_PADDING = 35655, + EXT_RENEGOTIATION_INFO = 65281 +}; diff --git a/src/analyzer/protocol/ssl/ssl-protocol.pac b/src/analyzer/protocol/ssl/ssl-protocol.pac index d32d926f65..857bd01f26 100644 --- a/src/analyzer/protocol/ssl/ssl-protocol.pac +++ b/src/analyzer/protocol/ssl/ssl-protocol.pac @@ -69,14 +69,81 @@ type PlaintextRecord(rec: SSLRecord) = case rec.content_type of { default -> unknown_record : UnknownRecord(rec); }; +###################################################################### +# TLS Extensions +###################################################################### + type SSLExtension(rec: SSLRecord) = record { type: uint16; data_len: uint16; - data: bytestring &length=data_len; + + # Pretty code ahead. Deal with the fact that perhaps extensions are not really present and we do not want to fail because of that. + ext: case type of { + EXT_APPLICATION_LAYER_PROTOCOL_NEGOTIATION -> apnl: ApplicationLayerProtocolNegotiationExtension(rec)[] &until($element == 0 || $element != 0); + EXT_ELLIPTIC_CURVES -> elliptic_curves: EllipticCurves(rec)[] &until($element == 0 || $element != 0); + EXT_EC_POINT_FORMATS -> ec_point_formats: EcPointFormats(rec)[] &until($element == 0 || $element != 0); +# EXT_STATUS_REQUEST -> status_request: StatusRequest(rec)[] &until($element == 0 || $element != 0); + EXT_SERVER_NAME -> server_name: ServerNameExt(rec)[] &until($element == 0 || $element != 0); + default -> data: bytestring &restofdata; + }; +} &length=data_len+4 &exportsourcedata; + +type ServerNameHostName() = record { + length: uint16; + host_name: bytestring &length=length; }; +type ServerName() = record { + name_type: uint8; # has to be 0 for host-name + name: case name_type of { + 0 -> host_name: ServerNameHostName; + default -> data : bytestring &restofdata; # unknown name + }; +}; + +type ServerNameExt(rec: SSLRecord) = record { + length: uint16; + server_names: ServerName[] &until($input.length() == 0); +} &length=length+2; + +# Do not parse for now. Structure is correct, but only contains asn.1 data that we would not use further. +#type OcspStatusRequest(rec: SSLRecord) = record { +# responder_id_list_length: uint16; +# responder_id_list: bytestring &length=responder_id_list_length; +# request_extensions_length: uint16; +# request_extensions: bytestring &length=request_extensions_length; +#}; +# +#type StatusRequest(rec: SSLRecord) = record { +# status_type: uint8; # 1 -> ocsp +# req: case status_type of { +# 1 -> ocsp_status_request: OcspStatusRequest(rec); +# default -> data : bytestring &restofdata; # unknown +# }; +#}; + +type EcPointFormats(rec: SSLRecord) = record { + length: uint8; + point_format_list: uint8[length]; +}; + +type EllipticCurves(rec: SSLRecord) = record { + length: uint16; + elliptic_curve_list: uint16[length/2]; +}; + +type ProtocolName() = record { + length: uint8; + name: bytestring &length=length; +}; + +type ApplicationLayerProtocolNegotiationExtension(rec: SSLRecord) = record { + length: uint16; + protocol_name_list: ProtocolName[] &until($input.length() == 0); +} &length=length+2; + ###################################################################### -# state management according to Section 7.3. in spec +# Encryption Tracking ###################################################################### enum AnalyzerState { @@ -173,10 +240,6 @@ type Heartbeat(rec: SSLRecord) = record { data : bytestring &restofdata; }; -###################################################################### -# Handshake Protocol (7.4.) -###################################################################### - ###################################################################### # V3 Hello Request (7.4.1.1.) ###################################################################### @@ -205,7 +268,6 @@ type ClientHello(rec: SSLRecord) = record { extensions : SSLExtension(rec)[] &until($input.length() == 0); }; - ###################################################################### # V2 Client Hello (SSLv2 2.5.) ###################################################################### @@ -270,13 +332,17 @@ type X509Certificate = record { certificate : bytestring &length = to_int()(length); }; -type CertificateList = X509Certificate[] &until($input.length() == 0); - type Certificate(rec: SSLRecord) = record { length : uint24; - certificates : CertificateList &length = to_int()(length); -}; + certificates : X509Certificate[] &until($input.length() == 0); +} &length = to_int()(length)+3; +# OCSP Stapling + +type CertificateStatus(rec: SSLRecord) = record { + status_type: uint8; # 1 = ocsp, everything else is undefined + response: bytestring &restofdata; +}; ###################################################################### # V3 Server Key Exchange Message (7.4.3.) @@ -394,7 +460,7 @@ type Handshake(rec: SSLRecord) = record { CLIENT_KEY_EXCHANGE -> client_key_exchange : ClientKeyExchange(rec); FINISHED -> finished : Finished(rec); CERTIFICATE_URL -> certificate_url : bytestring &restofdata &transient; - CERTIFICATE_STATUS -> certificate_status : bytestring &restofdata &transient; + CERTIFICATE_STATUS -> certificate_status : CertificateStatus(rec); default -> unknown_handshake : UnknownHandshake(this, rec.is_orig); } &length = to_int()(length); }; From 58efa09426d330901adf6f11aeaa6041b06210d1 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Wed, 23 Apr 2014 16:57:19 -0500 Subject: [PATCH 035/136] Adapt SSL analyzer to generate file analysis handles itself. --- scripts/base/protocols/ssl/files.bro | 18 ++---------------- src/Conn.cc | 11 +++++++++++ src/Conn.h | 1 + src/analyzer/protocol/ssl/ssl-analyzer.pac | 19 +++++++++++++++---- 4 files changed, 29 insertions(+), 20 deletions(-) diff --git a/scripts/base/protocols/ssl/files.bro b/scripts/base/protocols/ssl/files.bro index 6b33c0f87b..fbdd6e454e 100644 --- a/scripts/base/protocols/ssl/files.bro +++ b/scripts/base/protocols/ssl/files.bro @@ -52,22 +52,8 @@ export { function get_file_handle(c: connection, is_orig: bool): string { - set_session(c); - - local depth: count; - - if ( is_orig ) - { - depth = c$ssl$client_depth; - ++c$ssl$client_depth; - } - else - { - depth = c$ssl$server_depth; - ++c$ssl$server_depth; - } - - return cat(Analyzer::ANALYZER_SSL, c$start_time, is_orig, id_string(c$id), depth); + # Unused. File handles are generated in the analyzer. + return ""; } function describe_file(f: fa_file): string diff --git a/src/Conn.cc b/src/Conn.cc index fa89f26d35..bc62902421 100644 --- a/src/Conn.cc +++ b/src/Conn.cc @@ -811,6 +811,17 @@ void Connection::Describe(ODesc* d) const d->NL(); } +void Connection::IDString(ODesc* d) const + { + d->Add(orig_addr); + d->AddRaw(":", 1); + d->Add(ntohs(orig_port)); + d->AddRaw(" > ", 3); + d->Add(resp_addr); + d->AddRaw(":", 1); + d->Add(ntohs(resp_port)); + } + bool Connection::Serialize(SerialInfo* info) const { return SerialObj::Serialize(info); diff --git a/src/Conn.h b/src/Conn.h index d982d3879d..966c77a9f8 100644 --- a/src/Conn.h +++ b/src/Conn.h @@ -204,6 +204,7 @@ public: bool IsPersistent() { return persistent; } void Describe(ODesc* d) const; + void IDString(ODesc* d) const; TimerMgr* GetTimerMgr() const; diff --git a/src/analyzer/protocol/ssl/ssl-analyzer.pac b/src/analyzer/protocol/ssl/ssl-analyzer.pac index 49104fa549..5f9d092440 100644 --- a/src/analyzer/protocol/ssl/ssl-analyzer.pac +++ b/src/analyzer/protocol/ssl/ssl-analyzer.pac @@ -231,15 +231,26 @@ refine connection SSL_Conn += { if ( certificates->size() == 0 ) return true; + ODesc common; + common.AddRaw("Analyzer::ANALYZER_SSL"); + common.Add(bro_analyzer()->Conn()->StartTime()); + common.AddRaw(${rec.is_orig} ? "T" : "F", 1); + bro_analyzer()->Conn()->IDString(&common); + for ( unsigned int i = 0; i < certificates->size(); ++i ) { const bytestring& cert = (*certificates)[i]; - string fid = file_mgr->DataIn(reinterpret_cast(cert.data()), cert.length(), - bro_analyzer()->GetAnalyzerTag(), bro_analyzer()->Conn(), - ${rec.is_orig}); + ODesc file_handle; + file_handle.Add(common.Description()); + file_handle.Add(i); - file_mgr->EndOfFile(fid); + string file_id = file_mgr->HashHandle(file_handle.Description()); + + file_mgr->DataIn(reinterpret_cast(cert.data()), + cert.length(), bro_analyzer()->GetAnalyzerTag(), + bro_analyzer()->Conn(), ${rec.is_orig}, file_id); + file_mgr->EndOfFile(file_id); } return true; %} From d3972afa97c86dedf2977caa03c1b9374eb43773 Mon Sep 17 00:00:00 2001 From: Mareq Date: Thu, 24 Apr 2014 16:40:57 +0100 Subject: [PATCH 036/136] Do not repeat hex-code of decoded quoted-printable. --- src/analyzer/protocol/mime/MIME.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/analyzer/protocol/mime/MIME.cc b/src/analyzer/protocol/mime/MIME.cc index f4e7d3981f..6f992c9256 100644 --- a/src/analyzer/protocol/mime/MIME.cc +++ b/src/analyzer/protocol/mime/MIME.cc @@ -1044,6 +1044,7 @@ void MIME_Entity::DecodeQuotedPrintable(int len, const char* data) { DataOctet((a << 4) + b); legal = 1; + i += 2; } } From d3b27eb0c1329f7def8e49dde6d2048d62fdd777 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Thu, 24 Apr 2014 10:47:57 -0500 Subject: [PATCH 037/136] Adapt HTTP partial content to cache file analysis IDs. The initial file ID I think is still ambiguous and/or depends on script-layer state tracking enough that it still needs to request a file ID via an event at first, but once that is assigned to an HTTP (MIME) entity, it never makes sense that it can change (so re-using a cached ID works). --- src/analyzer/protocol/http/HTTP.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/analyzer/protocol/http/HTTP.cc b/src/analyzer/protocol/http/HTTP.cc index bc0081ab52..feddeb00a9 100644 --- a/src/analyzer/protocol/http/HTTP.cc +++ b/src/analyzer/protocol/http/HTTP.cc @@ -243,10 +243,10 @@ int HTTP_Entity::Undelivered(int64_t len) return 0; if ( is_partial_content ) - file_mgr->Gap(body_length, len, + precomputed_file_id = file_mgr->Gap(body_length, len, http_message->MyHTTP_Analyzer()->GetAnalyzerTag(), http_message->MyHTTP_Analyzer()->Conn(), - http_message->IsOrig()); + http_message->IsOrig(), precomputed_file_id); else precomputed_file_id = file_mgr->Gap(body_length, len, http_message->MyHTTP_Analyzer()->GetAnalyzerTag(), @@ -306,15 +306,15 @@ void HTTP_Entity::SubmitData(int len, const char* buf) if ( is_partial_content ) { if ( send_size && instance_length > 0 ) - file_mgr->SetSize(instance_length, + precomputed_file_id = file_mgr->SetSize(instance_length, http_message->MyHTTP_Analyzer()->GetAnalyzerTag(), http_message->MyHTTP_Analyzer()->Conn(), - http_message->IsOrig()); + http_message->IsOrig(), precomputed_file_id); - file_mgr->DataIn(reinterpret_cast(buf), len, offset, + precomputed_file_id = file_mgr->DataIn(reinterpret_cast(buf), len, offset, http_message->MyHTTP_Analyzer()->GetAnalyzerTag(), http_message->MyHTTP_Analyzer()->Conn(), - http_message->IsOrig()); + http_message->IsOrig(), precomputed_file_id); offset += len; } From 9b7eb293f1aaee78a10b21dfd5b581ec268b9e80 Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Thu, 24 Apr 2014 12:05:21 -0700 Subject: [PATCH 038/136] Add documentation, consts and tests for the new events. This also fixes the heartbleed detector to work for encrypted attacks in this branch again. It stopped working, because the SSL analyzer now successfully detects established connections, and the scripts usually disable analyzing after that. (The heartbeat branch should not have been affected) --- scripts/base/protocols/ssl/consts.bro | 97 ++++++++-------- scripts/base/protocols/ssl/main.bro | 4 +- scripts/policy/protocols/ssl/heartbleed.bro | 5 +- src/analyzer/protocol/ssl/events.bif | 104 +++++++++++++++++- src/analyzer/protocol/ssl/ssl-analyzer.pac | 12 +- .../.stdout | 13 +++ .../notice-encrypted.log | 10 ++ .../notice-heartbleed-success.log | 11 ++ .../notice-heartbleed.log | 10 ++ .../btest/Traces/tls/chrome-34-google.trace | Bin 0 -> 11582 bytes .../tls/heartbleed-encrypted-success.pcap | Bin 0 -> 64480 bytes .../btest/Traces/tls/heartbleed-success.pcap | Bin 0 -> 39524 bytes testing/btest/Traces/tls/heartbleed.pcap | Bin 0 -> 22223 bytes .../protocols/ssl/tls-extension-events.test | 26 +++++ .../policy/protocols/ssl/heartbleed.bro | 13 +++ 15 files changed, 244 insertions(+), 61 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.protocols.ssl.tls-extension-events/.stdout create mode 100644 testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-encrypted.log create mode 100644 testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-heartbleed-success.log create mode 100644 testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-heartbleed.log create mode 100644 testing/btest/Traces/tls/chrome-34-google.trace create mode 100644 testing/btest/Traces/tls/heartbleed-encrypted-success.pcap create mode 100644 testing/btest/Traces/tls/heartbleed-success.pcap create mode 100644 testing/btest/Traces/tls/heartbleed.pcap create mode 100644 testing/btest/scripts/base/protocols/ssl/tls-extension-events.test create mode 100644 testing/btest/scripts/policy/protocols/ssl/heartbleed.bro diff --git a/scripts/base/protocols/ssl/consts.bro b/scripts/base/protocols/ssl/consts.bro index 1ccace102c..e60363e14c 100644 --- a/scripts/base/protocols/ssl/consts.bro +++ b/scripts/base/protocols/ssl/consts.bro @@ -14,15 +14,15 @@ export { [TLSv11] = "TLSv11", [TLSv12] = "TLSv12", } &default=function(i: count):string { return fmt("unknown-%d", i); }; - - ## Mapping between numeric codes and human readable strings for alert + + ## Mapping between numeric codes and human readable strings for alert ## levels. const alert_levels: table[count] of string = { [1] = "warning", [2] = "fatal", } &default=function(i: count):string { return fmt("unknown-%d", i); }; - - ## Mapping between numeric codes and human readable strings for alert + + ## Mapping between numeric codes and human readable strings for alert ## descriptions. const alert_descriptions: table[count] of string = { [0] = "close_notify", @@ -58,7 +58,7 @@ export { [115] = "unknown_psk_identity", [120] = "no_application_protocol", } &default=function(i: count):string { return fmt("unknown-%d", i); }; - + ## Mapping between numeric codes and human readable strings for SSL/TLS ## extensions. # More information can be found here: @@ -93,7 +93,50 @@ export { [35655] = "padding", [65281] = "renegotiation_info" } &default=function(i: count):string { return fmt("unknown-%d", i); }; - + + ## Mapping between numeric codes and human readable string for SSL/TLS elliptic curves. + # See http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8 + const ec_curves: table[count] of string = { + [1] = "sect163k1", + [2] = "sect163r1", + [3] = "sect163r2", + [4] = "sect193r1", + [5] = "sect193r2", + [6] = "sect233k1", + [7] = "sect233r1", + [8] = "sect239k1", + [9] = "sect283k1", + [10] = "sect283r1", + [11] = "sect409k1", + [12] = "sect409r1", + [13] = "sect571k1", + [14] = "sect571r1", + [15] = "secp160k1", + [16] = "secp160r1", + [17] = "secp160r2", + [18] = "secp192k1", + [19] = "secp192r1", + [20] = "secp224k1", + [21] = "secp224r1", + [22] = "secp256k1", + [23] = "secp256r1", + [24] = "secp384r1", + [25] = "secp521r1", + [26] = "brainpoolP256r1", + [27] = "brainpoolP384r1", + [28] = "brainpoolP512r1", + [0xFF01] = "arbitrary_explicit_prime_curves", + [0xFF02] = "arbitrary_explicit_char2_curves" + } &default=function(i: count):string { return fmt("unknown-%d", i); }; + + ## Mapping between numeric codes and human readable string for SSL/TLC EC point formats. + # See http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-9 + const ec_point_formats: table[count] of string = { + [0] = "uncompressed", + [1] = "ansiX962_compressed_prime", + [2] = "ansiX962_compressed_char2" + } &default=function(i: count):string { return fmt("unknown-%d", i); }; + # SSLv2 const SSLv20_CK_RC4_128_WITH_MD5 = 0x010080; const SSLv20_CK_RC4_128_EXPORT40_WITH_MD5 = 0x020080; @@ -458,8 +501,8 @@ export { const SSL_RSA_WITH_DES_CBC_MD5 = 0xFF82; const SSL_RSA_WITH_3DES_EDE_CBC_MD5 = 0xFF83; const TLS_EMPTY_RENEGOTIATION_INFO_SCSV = 0x00FF; - - ## This is a table of all known cipher specs. It can be used for + + ## This is a table of all known cipher specs. It can be used for ## detecting unknown ciphers and for converting the cipher spec ## constants into a human readable format. const cipher_desc: table[count] of string = { @@ -820,43 +863,5 @@ export { [SSL_RSA_WITH_3DES_EDE_CBC_MD5] = "SSL_RSA_WITH_3DES_EDE_CBC_MD5", [TLS_EMPTY_RENEGOTIATION_INFO_SCSV] = "TLS_EMPTY_RENEGOTIATION_INFO_SCSV", } &default=function(i: count):string { return fmt("unknown-%d", i); }; - - ## Mapping between the constants and string values for SSL/TLS errors. - const x509_errors: table[count] of string = { - [0] = "ok", - [1] = "unable to get issuer cert", - [2] = "unable to get crl", - [3] = "unable to decrypt cert signature", - [4] = "unable to decrypt crl signature", - [5] = "unable to decode issuer public key", - [6] = "cert signature failure", - [7] = "crl signature failure", - [8] = "cert not yet valid", - [9] = "cert has expired", - [10] = "crl not yet valid", - [11] = "crl has expired", - [12] = "error in cert not before field", - [13] = "error in cert not after field", - [14] = "error in crl last update field", - [15] = "error in crl next update field", - [16] = "out of mem", - [17] = "depth zero self signed cert", - [18] = "self signed cert in chain", - [19] = "unable to get issuer cert locally", - [20] = "unable to verify leaf signature", - [21] = "cert chain too long", - [22] = "cert revoked", - [23] = "invalid ca", - [24] = "path length exceeded", - [25] = "invalid purpose", - [26] = "cert untrusted", - [27] = "cert rejected", - [28] = "subject issuer mismatch", - [29] = "akid skid mismatch", - [30] = "akid issuer serial mismatch", - [31] = "keyusage no certsign", - [32] = "unable to get crl issuer", - [33] = "unhandled critical extension", - } &default=function(i: count):string { return fmt("unknown-%d", i); }; } diff --git a/scripts/base/protocols/ssl/main.bro b/scripts/base/protocols/ssl/main.bro index eb128483a4..e3c3320f74 100644 --- a/scripts/base/protocols/ssl/main.bro +++ b/scripts/base/protocols/ssl/main.bro @@ -159,7 +159,7 @@ event ssl_server_hello(c: connection, version: count, possible_ts: time, server_ c$ssl$cipher = cipher_desc[cipher]; } -event tls_extension_server_name(c: connection, is_orig: bool, names: string_vec) &priority=5 +event ssl_extension_server_name(c: connection, is_orig: bool, names: string_vec) &priority=5 { set_session(c); @@ -198,7 +198,7 @@ event connection_state_remove(c: connection) &priority=-5 event protocol_confirmation(c: connection, atype: Analyzer::Tag, aid: count) &priority=5 { - if ( atype == Analyzer::ANALYZER_SSL ) + if ( atype == Analyzer::ANALYZER_SSL ) { set_session(c); c$ssl$analyzer_id = aid; diff --git a/scripts/policy/protocols/ssl/heartbleed.bro b/scripts/policy/protocols/ssl/heartbleed.bro index dc38c66f73..dbf27ec63e 100644 --- a/scripts/policy/protocols/ssl/heartbleed.bro +++ b/scripts/policy/protocols/ssl/heartbleed.bro @@ -1,6 +1,9 @@ module Heartbleed; -# Please note - this is not well tested. Use at your own risk. +# Detect the TLS heartbleed attack. See http://heartbleed.com/ + +# Do not disable analyzers after detection - otherwhise we will not notice encrypted attacks +redef SSL::disable_analyzer_after_detection=F; redef record SSL::Info += { last_originator_heartbeat_request_size: count &optional; diff --git a/src/analyzer/protocol/ssl/events.bif b/src/analyzer/protocol/ssl/events.bif index 457d18ea39..5106552740 100644 --- a/src/analyzer/protocol/ssl/events.bif +++ b/src/analyzer/protocol/ssl/events.bif @@ -66,6 +66,8 @@ event ssl_server_hello%(c: connection, version: count, possible_ts: time, server ## information out of that as it can. This event provides access to any ## extensions either side sends as part of an extended *hello* message. ## +## Note that Bro offers a few more specialized events for a few extensions. +## ## c: The connection. ## ## is_orig: True if event is raised for originator side of the connection. @@ -77,16 +79,75 @@ event ssl_server_hello%(c: connection, version: count, possible_ts: time, server ## val: The raw extension value that was sent in the message. ## ## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello -## ssl_session_ticket_handshake +## ssl_session_ticket_handshake ssl_extension_ec_point_formats +## ssl_extension_elliptic_curves ssl_extension_application_layer_protocol_negotiation +## ssl_extension_server_name event ssl_extension%(c: connection, is_orig: bool, code: count, val: string%); -event tls_extension_ec_point_formats%(c: connection, is_orig: bool, point_formats: index_vec%); +## This TLS extension is defined in :rfc:`4492` and sent by the client in the initial +## handshake. It gives the list of elliptic curves supported by the client. +## +## c: The connection. +## +## is_orig: True if event is raised for originator side of the connection. +## +## curves: List of supported elliptic curves. +## +## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello +## ssl_session_ticket_handshake ssl_extension +## ssl_extension_ec_point_formats ssl_extension_application_layer_protocol_negotiation +## ssl_extension_server_name +event ssl_extension_elliptic_curves%(c: connection, is_orig: bool, curves: index_vec%); -event tls_extension_elliptic_curves%(c: connection, is_orig: bool, curves: index_vec%); +## This TLS extension is defined in :rfc:`4492` and sent by the client and/or server in the initial +## handshake. It gives the list of elliptic curve point formats supported by the client. +## +## c: The connection. +## +## is_orig: True if event is raised for originator side of the connection. +## +## point_formats: List of supported point formats. +## +## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello +## ssl_session_ticket_handshake ssl_extension +## ssl_extension_elliptic_curves ssl_extension_application_layer_protocol_negotiation +## ssl_extension_server_name +event ssl_extension_ec_point_formats%(c: connection, is_orig: bool, point_formats: index_vec%); -event tls_extension_application_layer_protocol_negotiation%(c: connection, is_orig: bool, protocols: string_vec%); +## This TLS extension is defined in draft-ietf-tls-applayerprotoneg and sent +## in the initial handshake. It contains the list of client supported application protocols +## by the client or the server, respectovely. +## +## At the moment it is mostly used to negotiate the use of SPDY / HTTP2-drafts. +## +## c: The connection. +## +## is_orig: True if event is raised for originator side of the connection. +## +## protocols: List of supported application layer protocols. +## +## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello +## ssl_session_ticket_handshake ssl_extension +## ssl_extension_elliptic_curves ssl_extension_ec_point_formats +## ssl_extension_server_name +event ssl_extension_application_layer_protocol_negotiation%(c: connection, is_orig: bool, protocols: string_vec%); -event tls_extension_server_name%(c: connection, is_orig: bool, names: string_vec%); +## This SSL/TLS extension is defined in :rfc:`3546` and sent by the client +## in the initial handshake. It contains the name of the server it is contacting. +## This information can be used by the server to choose the correct certificate for +## the host the client wants to contact. +## +## c: The connection. +## +## is_orig: True if event is raised for originator side of the connection. +## +## protocols: List of supported application layer protocols. +## +## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello +## ssl_session_ticket_handshake ssl_extension +## ssl_extension_elliptic_curves ssl_extension_ec_point_formats +## ssl_extension_application_layer_protocol_negotiation +event ssl_extension_server_name%(c: connection, is_orig: bool, names: string_vec%); ## Generated at the end of an SSL/TLS handshake. SSL/TLS sessions start with ## an unencrypted handshake, and Bro extracts as much information out of that @@ -147,6 +208,37 @@ event ssl_alert%(c: connection, is_orig: bool, level: count, desc: count%); ## ssl_alert event ssl_session_ticket_handshake%(c: connection, ticket_lifetime_hint: count, ticket: string%); +## Generated for SSL/TLS heartbeat messages that are sent before session encryption +## starts. Generally heartbeat messages should rarely be seen in normal TLS traffic. +## Heartbeats are described in :rfc:`6520`. +## +## c: The connection. +## +## length: length of the entire heartbeat message. +## +## heartbeat_type: type of the heartbeat message. Per RFC, 1 = request, 2 = response +## +## payload_length: length of the payload of the heartbeat message, according to packet field +## +## payload: payload contained in the heartbeat message. Size can differ from payload_length, +## if payload_length and actual packet length disagree. +## +## .. bro:see:: ssl_client_hello ssl_established ssl_extension ssl_server_hello +## ssl_alert ssl_encrypted_heartbeat +event ssl_heartbeat%(c: connection, is_orig: bool, length: count, heartbeat_type: count, payload_length: count, payload: string%); + +## Generated for SSL/TLS heartbeat messages that are sent after session encryption +## started. Generally heartbeat messages should rarely be seen in normal TLS traffic. +## Heartbeats are described in :rfc:`6520`. +## +## Note that :bro:id:`SSL::disable_analyzer_after_detection` has to be set to false. +## Otherwhise this event will never be thrown. +## +## c: The connection. +## +## length: length of the entire heartbeat message. +## +## .. bro:see:: ssl_client_hello ssl_established ssl_extension ssl_server_hello +## ssl_alert ssl_heartbeat event ssl_encrypted_heartbeat%(c: connection, is_orig: bool, length: count%); -event ssl_heartbeat%(c: connection, is_orig: bool, length: count, heartbeat_type: count, payload_length: count, payload: string%); diff --git a/src/analyzer/protocol/ssl/ssl-analyzer.pac b/src/analyzer/protocol/ssl/ssl-analyzer.pac index 043b2271ec..66224bf45a 100644 --- a/src/analyzer/protocol/ssl/ssl-analyzer.pac +++ b/src/analyzer/protocol/ssl/ssl-analyzer.pac @@ -228,7 +228,7 @@ refine connection SSL_Conn += { } } - BifEvent::generate_tls_extension_ec_point_formats(bro_analyzer(), bro_analyzer()->Conn(), + BifEvent::generate_ssl_extension_ec_point_formats(bro_analyzer(), bro_analyzer()->Conn(), ${rec.is_orig}, points); return true; @@ -245,7 +245,7 @@ refine connection SSL_Conn += { } } - BifEvent::generate_tls_extension_elliptic_curves(bro_analyzer(), bro_analyzer()->Conn(), + BifEvent::generate_ssl_extension_elliptic_curves(bro_analyzer(), bro_analyzer()->Conn(), ${rec.is_orig}, curves); return true; @@ -262,7 +262,7 @@ refine connection SSL_Conn += { } } - BifEvent::generate_tls_extension_application_layer_protocol_negotiation(bro_analyzer(), bro_analyzer()->Conn(), + BifEvent::generate_ssl_extension_application_layer_protocol_negotiation(bro_analyzer(), bro_analyzer()->Conn(), ${rec.is_orig}, plist); return true; @@ -278,18 +278,18 @@ refine connection SSL_Conn += { ServerName* servername = (*list)[i]; if ( servername->name_type() != 0 ) { - bro_analyzer()->Weird(fmt("Encountered unknown type in server name tls extension: %d", servername->name_type())); + bro_analyzer()->Weird(fmt("Encountered unknown type in server name ssl extension: %d", servername->name_type())); continue; } if ( servername->host_name() ) servers->Assign(j++, new StringVal(servername->host_name()->host_name().length(), (const char*) servername->host_name()->host_name().data())); else - bro_analyzer()->Weird("Empty server_name extension in tls connection"); + bro_analyzer()->Weird("Empty server_name extension in ssl connection"); } } - BifEvent::generate_tls_extension_server_name(bro_analyzer(), bro_analyzer()->Conn(), + BifEvent::generate_ssl_extension_server_name(bro_analyzer(), bro_analyzer()->Conn(), ${rec.is_orig}, servers); return true; diff --git a/testing/btest/Baseline/scripts.base.protocols.ssl.tls-extension-events/.stdout b/testing/btest/Baseline/scripts.base.protocols.ssl.tls-extension-events/.stdout new file mode 100644 index 0000000000..8305175edb --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ssl.tls-extension-events/.stdout @@ -0,0 +1,13 @@ +server_name, 192.168.4.149, 74.125.239.152, [google.de] +Curves, 192.168.4.149, 74.125.239.152 +secp256r1 +secp384r1 +secp521r1 +Point formats, 192.168.4.149, 74.125.239.152, T +uncompressed +ALPN, 192.168.4.149, 74.125.239.152, [spdy/3, spdy/3.1, http/1.1] +Point formats, 192.168.4.149, 74.125.239.152, F +uncompressed +ansiX962_compressed_prime +ansiX962_compressed_char2 +ALPN, 192.168.4.149, 74.125.239.152, [spdy/3.1] diff --git a/testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-encrypted.log b/testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-encrypted.log new file mode 100644 index 0000000000..863d8dd9c0 --- /dev/null +++ b/testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-encrypted.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path notice +#open 2014-04-24-19-05-00 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p fuid file_mime_type file_desc proto note msg sub src dst p n peer_descr actions suppress_for dropped remote_location.country_code remote_location.region remote_location.city remote_location.latitude remote_location.longitude +#types time string addr port addr port string string string enum enum string string addr addr port count string set[enum] interval bool string string string double double +1397169549.895057 CXWv6p3arKYeMETxOg 192.168.4.149 59676 107.170.241.107 443 - - - tcp Heartbleed::SSL_Heartbeat_Attack_Success An Encrypted TLS heartbleed attack was probably detected! First packet client record length 1, first packet server record length 32 - 192.168.4.149 107.170.241.107 443 - bro Notice::ACTION_LOG 3600.000000 F - - - - - +#close 2014-04-24-19-05-00 diff --git a/testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-heartbleed-success.log b/testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-heartbleed-success.log new file mode 100644 index 0000000000..9722e20655 --- /dev/null +++ b/testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-heartbleed-success.log @@ -0,0 +1,11 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path notice +#open 2014-04-24-18-30-54 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p fuid file_mime_type file_desc proto note msg sub src dst p n peer_descr actions suppress_for dropped remote_location.country_code remote_location.region remote_location.city remote_location.latitude remote_location.longitude +#types time string addr port addr port string string string enum enum string string addr addr port count string set[enum] interval bool string string string double double +1396976220.863714 CXWv6p3arKYeMETxOg 173.203.79.216 41459 107.170.241.107 443 - - - tcp Heartbleed::SSL_Heartbeat_Attack An TLS heartbleed attack was detected! Record length 16368, payload length 16365 - 173.203.79.216 107.170.241.107 443 - bro Notice::ACTION_LOG 3600.000000 F - - - - - +1396976220.918017 CXWv6p3arKYeMETxOg 173.203.79.216 41459 107.170.241.107 443 - - - tcp Heartbleed::SSL_Heartbeat_Attack_Success An TLS heartbleed attack detected before was probably exploited. Transmitted payload length in first packet: 16365 - 173.203.79.216 107.170.241.107 443 - bro Notice::ACTION_LOG 3600.000000 F - - - - - +#close 2014-04-24-18-30-54 diff --git a/testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-heartbleed.log b/testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-heartbleed.log new file mode 100644 index 0000000000..da376c79a0 --- /dev/null +++ b/testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-heartbleed.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path notice +#open 2014-04-24-18-29-46 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p fuid file_mime_type file_desc proto note msg sub src dst p n peer_descr actions suppress_for dropped remote_location.country_code remote_location.region remote_location.city remote_location.latitude remote_location.longitude +#types time string addr port addr port string string string enum enum string string addr addr port count string set[enum] interval bool string string string double double +1396973486.753913 CXWv6p3arKYeMETxOg 173.203.79.216 46592 162.219.2.166 443 - - - tcp Heartbleed::SSL_Heartbeat_Attack An TLS heartbleed attack was detected! Record length 16368, payload length 16365 - 173.203.79.216 162.219.2.166 443 - bro Notice::ACTION_LOG 3600.000000 F - - - - - +#close 2014-04-24-18-29-46 diff --git a/testing/btest/Traces/tls/chrome-34-google.trace b/testing/btest/Traces/tls/chrome-34-google.trace new file mode 100644 index 0000000000000000000000000000000000000000..e02d35a5f1f37a6f2525fe7b7465dc9c4f4cf36c GIT binary patch literal 11582 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

fLIN#~ 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 literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/tls/heartbleed-success.pcap b/testing/btest/Traces/tls/heartbleed-success.pcap new file mode 100644 index 0000000000000000000000000000000000000000..47a2bac1a3e69860dcff61ba86d805f26e5e9562 GIT binary patch literal 39524 zcmeI52~-nF8po@1K?30xK@fwWC@6F^C

_D5$6df`}*+AV>rfOoGTbDj>+Aj<++8 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 literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/tls/heartbleed.pcap b/testing/btest/Traces/tls/heartbleed.pcap new file mode 100644 index 0000000000000000000000000000000000000000..46e7935d18109d31e681d0037c8b0cb1a93fb57b GIT binary patch literal 22223 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 Date: Thu, 24 Apr 2014 12:36:05 -0700 Subject: [PATCH 039/136] Add very basic ocsp stapling support. This only allows access to the ocsp stapling response data. No verification or anything else at the moment. --- scripts/site/local.bro | 5 +++-- src/analyzer/protocol/ssl/events.bif | 14 ++++++++++++++ src/analyzer/protocol/ssl/ssl-analyzer.pac | 15 +++++++++++++++ src/analyzer/protocol/ssl/ssl-protocol.pac | 1 + .../.stdout | 1 + testing/btest/Traces/tls/ocsp-stapling.trace | Bin 0 -> 9427 bytes .../base/protocols/ssl/ocsp-stapling.test | 7 +++++++ 7 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.protocols.ssl.ocsp-stapling/.stdout create mode 100644 testing/btest/Traces/tls/ocsp-stapling.trace create mode 100644 testing/btest/scripts/base/protocols/ssl/ocsp-stapling.test diff --git a/scripts/site/local.bro b/scripts/site/local.bro index bb2cc73a53..afe1d9d4f2 100644 --- a/scripts/site/local.bro +++ b/scripts/site/local.bro @@ -81,5 +81,6 @@ # Detect SHA1 sums in Team Cymru's Malware Hash Registry. @load frameworks/files/detect-MHR -# Load heartbleed detection. Only superficially tested, might contain bugs. -@load policy/protocols/ssl/heartbleed +# Uncomment the following line to enable detection of the heartbleed attack. Enabling +# this might impact performance a bit. +# @load policy/protocols/ssl/heartbleed diff --git a/src/analyzer/protocol/ssl/events.bif b/src/analyzer/protocol/ssl/events.bif index 5106552740..f32649403b 100644 --- a/src/analyzer/protocol/ssl/events.bif +++ b/src/analyzer/protocol/ssl/events.bif @@ -214,6 +214,8 @@ event ssl_session_ticket_handshake%(c: connection, ticket_lifetime_hint: count, ## ## c: The connection. ## +## is_orig: True if event is raised for originator side of the connection. +## ## length: length of the entire heartbeat message. ## ## heartbeat_type: type of the heartbeat message. Per RFC, 1 = request, 2 = response @@ -236,9 +238,21 @@ event ssl_heartbeat%(c: connection, is_orig: bool, length: count, heartbeat_type ## ## c: The connection. ## +## is_orig: True if event is raised for originator side of the connection. +## ## length: length of the entire heartbeat message. ## ## .. bro:see:: ssl_client_hello ssl_established ssl_extension ssl_server_hello ## ssl_alert ssl_heartbeat event ssl_encrypted_heartbeat%(c: connection, is_orig: bool, length: count%); +## This event contains the OCSP response contained in a Certificate Status Request +## message, when the client requested OCSP stapling and the server supports it. See +## description in :rfc:`6066` +## +## c: The connection. +## +## is_orig: True if event is raised for originator side of the connection. +## +## response: OCSP data. +event ssl_stapled_ocsp%(c: connection, is_orig: bool, response: string%); diff --git a/src/analyzer/protocol/ssl/ssl-analyzer.pac b/src/analyzer/protocol/ssl/ssl-analyzer.pac index 66224bf45a..e9d29675c3 100644 --- a/src/analyzer/protocol/ssl/ssl-analyzer.pac +++ b/src/analyzer/protocol/ssl/ssl-analyzer.pac @@ -389,6 +389,17 @@ refine connection SSL_Conn += { return true; %} + function proc_certificate_status(rec : SSLRecord, status_type: uint8, response: bytestring) : bool + %{ + if ( status_type == 1 ) // ocsp + { + BifEvent::generate_ssl_stapled_ocsp(bro_analyzer(), + bro_analyzer()->Conn(), ${rec.is_orig}, + new StringVal(response.length(), (const char*) response.data())); + } + + return true; + %} }; refine typeattr Alert += &let { @@ -473,3 +484,7 @@ refine typeattr ApplicationLayerProtocolNegotiationExtension += &let { refine typeattr ServerNameExt += &let { proc : bool = $context.connection.proc_server_name(rec, server_names); }; + +refine typeattr CertificateStatus += &let { + proc : bool = $context.connection.proc_certificate_status(rec, status_type, response); +}; diff --git a/src/analyzer/protocol/ssl/ssl-protocol.pac b/src/analyzer/protocol/ssl/ssl-protocol.pac index 857bd01f26..a8b9975eb5 100644 --- a/src/analyzer/protocol/ssl/ssl-protocol.pac +++ b/src/analyzer/protocol/ssl/ssl-protocol.pac @@ -341,6 +341,7 @@ type Certificate(rec: SSLRecord) = record { type CertificateStatus(rec: SSLRecord) = record { status_type: uint8; # 1 = ocsp, everything else is undefined + length : uint24; response: bytestring &restofdata; }; diff --git a/testing/btest/Baseline/scripts.base.protocols.ssl.ocsp-stapling/.stdout b/testing/btest/Baseline/scripts.base.protocols.ssl.ocsp-stapling/.stdout new file mode 100644 index 0000000000..a8735f6d41 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ssl.ocsp-stapling/.stdout @@ -0,0 +1 @@ +F, 1995 diff --git a/testing/btest/Traces/tls/ocsp-stapling.trace b/testing/btest/Traces/tls/ocsp-stapling.trace new file mode 100644 index 0000000000000000000000000000000000000000..8b66f7288d11316bcea20d3ca91066cf167391c4 GIT binary patch literal 9427 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 literal 0 HcmV?d00001 diff --git a/testing/btest/scripts/base/protocols/ssl/ocsp-stapling.test b/testing/btest/scripts/base/protocols/ssl/ocsp-stapling.test new file mode 100644 index 0000000000..b50f04a92e --- /dev/null +++ b/testing/btest/scripts/base/protocols/ssl/ocsp-stapling.test @@ -0,0 +1,7 @@ +# @TEST-EXEC: bro -C -r $TRACES/tls/ocsp-stapling.trace %INPUT +# @TEST-EXEC: btest-diff .stdout + +event ssl_stapled_ocsp(c: connection, is_orig: bool, response: string) + { + print is_orig, |response|; + } From de0ce6deedd388de612365c085a1e4f427fbc2e0 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Thu, 24 Apr 2014 16:20:01 -0500 Subject: [PATCH 040/136] BIT-1156: Fix parsing of DNS TXT RRs w/ multiple character-strings. The "dns_TXT_reply" event now uses a "vector of strings" as the final parameter instead of just a "string" in order to support DNS TXT resource records that contain multiple character-strings. The format in which the TXT answers are logged by default is now changed to be a list of strings of the form `fmt("TXT %d %s", |str|, str)`, one for each character-string in the RR and delimited by a space (' ') character. --- scripts/base/protocols/dns/main.bro | 14 +++- src/analyzer/protocol/dns/DNS.cc | 65 +++++++++++++------ src/analyzer/protocol/dns/events.bif | 2 +- testing/btest/Baseline/core.ipv6-frag/dns.log | 8 +-- 4 files changed, 62 insertions(+), 27 deletions(-) diff --git a/scripts/base/protocols/dns/main.bro b/scripts/base/protocols/dns/main.bro index d7280602e6..83c9682e8c 100644 --- a/scripts/base/protocols/dns/main.bro +++ b/scripts/base/protocols/dns/main.bro @@ -382,9 +382,19 @@ event dns_A_reply(c: connection, msg: dns_msg, ans: dns_answer, a: addr) &priori hook DNS::do_reply(c, msg, ans, fmt("%s", a)); } -event dns_TXT_reply(c: connection, msg: dns_msg, ans: dns_answer, str: string) &priority=5 +event dns_TXT_reply(c: connection, msg: dns_msg, ans: dns_answer, strs: string_vec) &priority=5 { - hook DNS::do_reply(c, msg, ans, str); + local txt_strings: string = ""; + + for ( i in strs ) + { + if ( i > 0 ) + txt_strings += " "; + + txt_strings += fmt("TXT %d %s", |strs[i]|, strs[i]); + } + + hook DNS::do_reply(c, msg, ans, txt_strings); } event dns_AAAA_reply(c: connection, msg: dns_msg, ans: dns_answer, a: addr) &priority=5 diff --git a/src/analyzer/protocol/dns/DNS.cc b/src/analyzer/protocol/dns/DNS.cc index a97c7b8632..aee1e1b213 100644 --- a/src/analyzer/protocol/dns/DNS.cc +++ b/src/analyzer/protocol/dns/DNS.cc @@ -835,34 +835,59 @@ int DNS_Interpreter::ParseRR_HINFO(DNS_MsgInfo* msg, return 1; } +static StringVal* extract_char_string(analyzer::Analyzer* analyzer, + const u_char*& data, int& len, int& rdlen) + { + if ( rdlen <= 0 ) + return 0; + + uint8 str_size = data[0]; + --rdlen; + --len; + ++data; + + if ( str_size > rdlen ) + { + analyzer->Weird("DNS_TXT_char_str_past_rdlen"); + return 0; + } + + StringVal* rval = new StringVal(str_size, + reinterpret_cast(data)); + + rdlen -= str_size; + len -= str_size; + data += str_size; + return rval; + } + int DNS_Interpreter::ParseRR_TXT(DNS_MsgInfo* msg, const u_char*& data, int& len, int rdlength, const u_char* msg_start) { - int name_len = data[0]; - - char* name = new char[name_len]; - - memcpy(name, data+1, name_len); - - data += rdlength; - len -= rdlength; - - if ( dns_TXT_reply && ! msg->skip_event ) + if ( ! dns_TXT_reply || msg->skip_event ) { - val_list* vl = new val_list; - - vl->append(analyzer->BuildConnVal()); - vl->append(msg->BuildHdrVal()); - vl->append(msg->BuildAnswerVal()); - vl->append(new StringVal(name_len, name)); - - analyzer->ConnectionEvent(dns_TXT_reply, vl); + data += rdlength; + len -= rdlength; + return 1; } - delete [] name; + VectorVal* char_strings = new VectorVal(string_vec); + StringVal* char_string; - return 1; + while ( (char_string = extract_char_string(analyzer, data, len, rdlength)) ) + char_strings->Assign(char_strings->Size(), char_string); + + val_list* vl = new val_list; + + vl->append(analyzer->BuildConnVal()); + vl->append(msg->BuildHdrVal()); + vl->append(msg->BuildAnswerVal()); + vl->append(char_strings); + + analyzer->ConnectionEvent(dns_TXT_reply, vl); + + return rdlength == 0; } void DNS_Interpreter::SendReplyOrRejectEvent(DNS_MsgInfo* msg, diff --git a/src/analyzer/protocol/dns/events.bif b/src/analyzer/protocol/dns/events.bif index 520e32fe6d..efa0807fd1 100644 --- a/src/analyzer/protocol/dns/events.bif +++ b/src/analyzer/protocol/dns/events.bif @@ -376,7 +376,7 @@ event dns_MX_reply%(c: connection, msg: dns_msg, ans: dns_answer, name: string, ## dns_mapping_unverified dns_mapping_valid dns_message dns_query_reply ## dns_rejected dns_request non_dns_request dns_max_queries dns_session_timeout ## dns_skip_addl dns_skip_all_addl dns_skip_all_auth dns_skip_auth -event dns_TXT_reply%(c: connection, msg: dns_msg, ans: dns_answer, str: string%); +event dns_TXT_reply%(c: connection, msg: dns_msg, ans: dns_answer, strs: string_vec%); ## Generated for DNS replies of type *SRV*. For replies with multiple answers, ## an individual event of the corresponding type is raised for each. diff --git a/testing/btest/Baseline/core.ipv6-frag/dns.log b/testing/btest/Baseline/core.ipv6-frag/dns.log index 69aec7e222..5eede0a0e4 100644 --- a/testing/btest/Baseline/core.ipv6-frag/dns.log +++ b/testing/btest/Baseline/core.ipv6-frag/dns.log @@ -3,10 +3,10 @@ #empty_field (empty) #unset_field - #path dns -#open 2013-08-26-19-02-10 +#open 2014-04-24-20-25-19 #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto trans_id query qclass qclass_name qtype qtype_name rcode rcode_name AA TC RD RA Z answers TTLs rejected #types time string addr port addr port enum count string count string count string count string bool bool bool bool count vector[string] vector[interval] bool -1331084278.438444 CXWv6p3arKYeMETxOg 2001:470:1f11:81f:d138:5f55:6d4:1fe2 51850 2607:f740:b::f93 53 udp 3903 txtpadding_323.n1.netalyzr.icsi.berkeley.edu 1 C_INTERNET 16 TXT 0 NOERROR T F T F 0 This TXT record should be ignored 1.000000 F -1331084293.592245 CjhGID4nQcgTWjvg4c 2001:470:1f11:81f:d138:5f55:6d4:1fe2 51851 2607:f740:b::f93 53 udp 40849 txtpadding_3230.n1.netalyzr.icsi.berkeley.edu 1 C_INTERNET 16 TXT 0 NOERROR T F T F 0 This TXT record should be ignored 1.000000 F +1331084278.438444 CXWv6p3arKYeMETxOg 2001:470:1f11:81f:d138:5f55:6d4:1fe2 51850 2607:f740:b::f93 53 udp 3903 txtpadding_323.n1.netalyzr.icsi.berkeley.edu 1 C_INTERNET 16 TXT 0 NOERROR T F T F 0 TXT 33 This TXT record should be ignored TXT 21 As it is just padding TXT 136 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 1.000000 F +1331084293.592245 CjhGID4nQcgTWjvg4c 2001:470:1f11:81f:d138:5f55:6d4:1fe2 51851 2607:f740:b::f93 53 udp 40849 txtpadding_3230.n1.netalyzr.icsi.berkeley.edu 1 C_INTERNET 16 TXT 0 NOERROR T F T F 0 TXT 33 This TXT record should be ignored TXT 21 As it is just padding TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 189 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX TXT 192 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 1.000000 F 1331084298.593081 CjhGID4nQcgTWjvg4c 2001:470:1f11:81f:d138:5f55:6d4:1fe2 51851 2607:f740:b::f93 53 udp 40849 txtpadding_3230.n1.netalyzr.icsi.berkeley.edu 1 C_INTERNET 16 TXT - - F F T F 0 - - F -#close 2013-08-26-19-02-10 +#close 2014-04-24-20-25-20 From 3d22692b6e897c1935cb60a8890de8bb76ef2b47 Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Thu, 24 Apr 2014 14:45:06 -0700 Subject: [PATCH 041/136] Fix a few failing tests --- scripts/policy/protocols/ssl/heartbleed.bro | 7 +++++-- scripts/test-all-policy.bro | 1 + testing/btest/core/leaks/http-connect.bro | 2 +- testing/btest/core/leaks/x509_verify.bro | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/scripts/policy/protocols/ssl/heartbleed.bro b/scripts/policy/protocols/ssl/heartbleed.bro index dbf27ec63e..1e0fdcd98b 100644 --- a/scripts/policy/protocols/ssl/heartbleed.bro +++ b/scripts/policy/protocols/ssl/heartbleed.bro @@ -1,6 +1,9 @@ -module Heartbleed; +# Detect the TLS heartbleed attack. See http://heartbleed.com -# Detect the TLS heartbleed attack. See http://heartbleed.com/ +@load base/protocols/ssl +@load base/frameworks/notice + +module Heartbleed; # Do not disable analyzers after detection - otherwhise we will not notice encrypted attacks redef SSL::disable_analyzer_after_detection=F; diff --git a/scripts/test-all-policy.bro b/scripts/test-all-policy.bro index 895a9a8901..5c6ed286fb 100644 --- a/scripts/test-all-policy.bro +++ b/scripts/test-all-policy.bro @@ -85,6 +85,7 @@ @load protocols/ssh/software.bro @load protocols/ssl/expiring-certs.bro @load protocols/ssl/extract-certs-pem.bro +@load protocols/ssl/heartbleed.bro @load protocols/ssl/known-certs.bro @load protocols/ssl/log-hostcerts-only.bro #@load protocols/ssl/notary.bro diff --git a/testing/btest/core/leaks/http-connect.bro b/testing/btest/core/leaks/http-connect.bro index e9a47d00a2..fe42f3ec0a 100644 --- a/testing/btest/core/leaks/http-connect.bro +++ b/testing/btest/core/leaks/http-connect.bro @@ -5,7 +5,7 @@ # @TEST-REQUIRES: bro --help 2>&1 | grep -q mem-leaks # # @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run bro bro -b -m -r $TRACES/http/connect-with-smtp.trace %INPUT -# @TEST-EXEC: btest-bg-wait 15 +# @TEST-EXEC: btest-bg-wait 30 @load base/protocols/conn @load base/protocols/http diff --git a/testing/btest/core/leaks/x509_verify.bro b/testing/btest/core/leaks/x509_verify.bro index 426a95d2c2..f4a5ddc7d1 100644 --- a/testing/btest/core/leaks/x509_verify.bro +++ b/testing/btest/core/leaks/x509_verify.bro @@ -5,7 +5,7 @@ # @TEST-REQUIRES: bro --help 2>&1 | grep -q mem-leaks # # @TEST-EXEC: HEAP_CHECK_DUMP_DIRECTORY=. HEAPCHECK=local btest-bg-run bro bro -b -m -r $TRACES/tls/tls-expired-cert.trace %INPUT -# @TEST-EXEC: btest-bg-wait 15 +# @TEST-EXEC: btest-bg-wait 30 @load base/protocols/ssl From 9e6643e9d428ce0c9e0a2ba336013b9a56297036 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Thu, 24 Apr 2014 17:07:04 -0700 Subject: [PATCH 042/136] Updating submodule(s). [nomail] --- aux/broccoli | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aux/broccoli b/aux/broccoli index 04e6a7f591..561ccdd6ed 160000 --- a/aux/broccoli +++ b/aux/broccoli @@ -1 +1 @@ -Subproject commit 04e6a7f591817f060a781f21c12e1afce7eb1e16 +Subproject commit 561ccdd6edec4ac5540f3d5565aefb59e7510634 From 988ba2e897a5256defac18b32d1cde4ce2721116 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Thu, 24 Apr 2014 17:08:45 -0700 Subject: [PATCH 043/136] Add Java version to software framework BIT-1168 #merged --- CHANGES | 4 ++++ VERSION | 2 +- scripts/base/frameworks/software/main.bro | 7 +++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 37cfb13a64..b8f537e914 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,8 @@ +2.2-381 | 2014-04-24 17:08:45 -0700 + + * Add Java version to software framework. (Brian Little) + 2.2-379 | 2014-04-24 17:06:21 -0700 * Remove unused Val::attribs member. (Jon Siwek) diff --git a/VERSION b/VERSION index 523b625f56..ba398d78a0 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.2-379 +2.2-381 diff --git a/scripts/base/frameworks/software/main.bro b/scripts/base/frameworks/software/main.bro index c8f413a8f2..f5c9927126 100644 --- a/scripts/base/frameworks/software/main.bro +++ b/scripts/base/frameworks/software/main.bro @@ -287,6 +287,13 @@ function parse_mozilla(unparsed_version: string): Description if ( 2 in parts ) v = parse(parts[2])$version; } + else if ( / Java\/[0-9]\./ in unparsed_version ) + { + software_name = "Java"; + parts = split_all(unparsed_version, /Java\/[0-9\._]*/); + if ( 2 in parts ) + v = parse(parts[2])$version; + } return [$version=v, $unparsed_version=unparsed_version, $name=software_name]; } From bd64e52782eaf6a7f006d029a61f24f19a2ac9fa Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Thu, 24 Apr 2014 18:14:18 -0700 Subject: [PATCH 044/136] Fixing compiler warnings. --- src/analyzer/protocol/tcp/TCP_Endpoint.h | 3 ++- src/analyzer/protocol/tcp/TCP_Reassembler.cc | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/analyzer/protocol/tcp/TCP_Endpoint.h b/src/analyzer/protocol/tcp/TCP_Endpoint.h index 95186c583a..96cc497421 100644 --- a/src/analyzer/protocol/tcp/TCP_Endpoint.h +++ b/src/analyzer/protocol/tcp/TCP_Endpoint.h @@ -135,7 +135,8 @@ public: int NoDataAcked() const { uint64 ack = ToFullSeqSpace(ack_seq, ack_wraps); - return ack == StartSeqI64() || ack == StartSeqI64() + 1; + uint64 start = static_cast(StartSeqI64()); + return ack == start || ack == start + 1; } Connection* Conn() const; diff --git a/src/analyzer/protocol/tcp/TCP_Reassembler.cc b/src/analyzer/protocol/tcp/TCP_Reassembler.cc index 1fabfc5d73..053e8c8f60 100644 --- a/src/analyzer/protocol/tcp/TCP_Reassembler.cc +++ b/src/analyzer/protocol/tcp/TCP_Reassembler.cc @@ -376,7 +376,7 @@ void TCP_Reassembler::BlockInserted(DataBlock* start_block) TrimToSeq(last_reassem_seq); else if ( e->NoDataAcked() && tcp_max_initial_window && - e->Size() > tcp_max_initial_window ) + e->Size() > static_cast(tcp_max_initial_window) ) // We've sent quite a bit of data, yet none of it has // been acked. Presume that we're not seeing the peer's // acks (perhaps due to filtering or split routing) and @@ -465,7 +465,7 @@ int TCP_Reassembler::DataSent(double t, uint64 seq, int len, NewBlock(t, seq, len, data); if ( Endpoint()->NoDataAcked() && tcp_max_above_hole_without_any_acks && - NumUndeliveredBytes() > tcp_max_above_hole_without_any_acks ) + NumUndeliveredBytes() > static_cast(tcp_max_above_hole_without_any_acks) ) { tcp_analyzer->Weird("above_hole_data_without_any_acks"); ClearBlocks(); @@ -473,7 +473,7 @@ int TCP_Reassembler::DataSent(double t, uint64 seq, int len, } if ( tcp_excessive_data_without_further_acks && - NumUndeliveredBytes() > tcp_excessive_data_without_further_acks ) + NumUndeliveredBytes() > static_cast(tcp_excessive_data_without_further_acks) ) { tcp_analyzer->Weird("excessive_data_without_further_acks"); ClearBlocks(); From 597c373fa0b947ee2da2c5e4a65dcdf5f0c5b40e Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Sat, 26 Apr 2014 09:48:36 -0700 Subject: [PATCH 045/136] Log chosen curve when using ec cipher suite in TLS. --- scripts/base/protocols/ssl/main.bro | 9 + src/analyzer/protocol/ssl/events.bif | 20 +- src/analyzer/protocol/ssl/ssl-analyzer.pac | 13 + src/analyzer/protocol/ssl/ssl-defs.pac | 352 ++++++++++++++++++ src/analyzer/protocol/ssl/ssl-protocol.pac | 60 ++- .../ssl.log | 12 +- .../scripts.base.protocols.ssl.basic/ssl.log | 10 +- .../scripts.base.protocols.ssl.ecdhe/ssl.log | 10 + .../scripts.base.protocols.ssl.ecdhe/x509.log | 12 + .../ssl.log | 10 +- .../ssl.log | 10 +- .../ssl.log | 12 +- .../ssl.log | 12 +- testing/btest/Traces/tls/ecdhe.pcap | Bin 0 -> 7510 bytes .../scripts/base/protocols/ssl/ecdhe.test | 3 + 15 files changed, 505 insertions(+), 40 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.protocols.ssl.ecdhe/ssl.log create mode 100644 testing/btest/Baseline/scripts.base.protocols.ssl.ecdhe/x509.log create mode 100644 testing/btest/Traces/tls/ecdhe.pcap create mode 100644 testing/btest/scripts/base/protocols/ssl/ecdhe.test diff --git a/scripts/base/protocols/ssl/main.bro b/scripts/base/protocols/ssl/main.bro index e3c3320f74..f1315f8c85 100644 --- a/scripts/base/protocols/ssl/main.bro +++ b/scripts/base/protocols/ssl/main.bro @@ -19,6 +19,8 @@ export { version: string &log &optional; ## SSL/TLS cipher suite that the server chose. cipher: string &log &optional; + ## Elliptic curve the server chose when using ECDH/ECDHE. + curve: string &log &optional; ## Value of the Server Name Indicator SSL/TLS extension. It ## indicates the server name that the client was requesting. server_name: string &log &optional; @@ -159,6 +161,13 @@ event ssl_server_hello(c: connection, version: count, possible_ts: time, server_ c$ssl$cipher = cipher_desc[cipher]; } +event ssl_server_curve(c: connection, curve: count) &priority=5 + { + set_session(c); + + c$ssl$curve = ec_curves[curve]; + } + event ssl_extension_server_name(c: connection, is_orig: bool, names: string_vec) &priority=5 { set_session(c); diff --git a/src/analyzer/protocol/ssl/events.bif b/src/analyzer/protocol/ssl/events.bif index 555168e82f..54bb0715d2 100644 --- a/src/analyzer/protocol/ssl/events.bif +++ b/src/analyzer/protocol/ssl/events.bif @@ -58,7 +58,7 @@ event ssl_client_hello%(c: connection, version: count, possible_ts: time, client ## standardized as part of the SSL/TLS protocol. ## ## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_extension -## ssl_session_ticket_handshake x509_certificate +## ssl_session_ticket_handshake x509_certificate ssl_server_curve event ssl_server_hello%(c: connection, version: count, possible_ts: time, server_random: string, session_id: string, cipher: count, comp_method: count%); ## Generated for SSL/TLS extensions seen in an initial handshake. SSL/TLS @@ -97,7 +97,7 @@ event ssl_extension%(c: connection, is_orig: bool, code: count, val: string%); ## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello ## ssl_session_ticket_handshake ssl_extension ## ssl_extension_ec_point_formats ssl_extension_application_layer_protocol_negotiation -## ssl_extension_server_name +## ssl_extension_server_name ssl_server_curve event ssl_extension_elliptic_curves%(c: connection, is_orig: bool, curves: index_vec%); ## Generated for an SSL/TLS Supported Point Formats extension. This TLS extension @@ -114,9 +114,23 @@ event ssl_extension_elliptic_curves%(c: connection, is_orig: bool, curves: index ## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello ## ssl_session_ticket_handshake ssl_extension ## ssl_extension_elliptic_curves ssl_extension_application_layer_protocol_negotiation -## ssl_extension_server_name +## ssl_extension_server_name ssl_server_curve event ssl_extension_ec_point_formats%(c: connection, is_orig: bool, point_formats: index_vec%); +## Generated a named curve is chosen by the server for the SSL/TLS connection. The +## curve is sent by the server in the ServerKeyExchange message as defined in +## :rfc:`4492`, in case an ECDH or ECDHE cipher suite is chosen. +## +## c: The connection. +## +## point_formats: List of supported point formats. +## +## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello +## ssl_session_ticket_handshake ssl_extension +## ssl_extension_elliptic_curves ssl_extension_application_layer_protocol_negotiation +## ssl_extension_server_name +event ssl_server_curve%(c: connection, curve: count%); + ## Generated for an SSL/TLS Application-Layer Protocol Negotiation extension. ## This TLS extension is defined in draft-ietf-tls-applayerprotoneg and sent in ## the initial handshake. It contains the list of client supported application diff --git a/src/analyzer/protocol/ssl/ssl-analyzer.pac b/src/analyzer/protocol/ssl/ssl-analyzer.pac index 62300557da..071edf2eac 100644 --- a/src/analyzer/protocol/ssl/ssl-analyzer.pac +++ b/src/analyzer/protocol/ssl/ssl-analyzer.pac @@ -400,6 +400,15 @@ refine connection SSL_Conn += { return true; %} + + function proc_ec_server_key_exchange(rec: SSLRecord, curve_type: uint8, curve: uint16) : bool + %{ + if ( curve_type == NAMED_CURVE ) + BifEvent::generate_ssl_server_curve(bro_analyzer(), + bro_analyzer()->Conn(), curve); + + return true; + %} }; refine typeattr Alert += &let { @@ -488,3 +497,7 @@ refine typeattr ServerNameExt += &let { refine typeattr CertificateStatus += &let { proc : bool = $context.connection.proc_certificate_status(rec, status_type, response); }; + +refine typeattr EcServerKeyExchange += &let { + proc : bool = $context.connection.proc_ec_server_key_exchange(rec, curve_type, curve); +}; diff --git a/src/analyzer/protocol/ssl/ssl-defs.pac b/src/analyzer/protocol/ssl/ssl-defs.pac index 24827d3621..2b55e53b25 100644 --- a/src/analyzer/protocol/ssl/ssl-defs.pac +++ b/src/analyzer/protocol/ssl/ssl-defs.pac @@ -60,3 +60,355 @@ enum SSLExtensions { EXT_PADDING = 35655, EXT_RENEGOTIATION_INFO = 65281 }; + +enum ECCurveType { + EXPLICIT_PRIME = 1, + EXPLICIT_CHAR = 2, + NAMED_CURVE = 3 +}; + +enum TLSCiphers { + NO_CHOSEN_CIPHER = 0xFFFFFF, + TLS_NULL_WITH_NULL_NULL = 0x0000, + TLS_RSA_WITH_NULL_MD5 = 0x0001, + TLS_RSA_WITH_NULL_SHA = 0x0002, + TLS_RSA_EXPORT_WITH_RC4_40_MD5 = 0x0003, + TLS_RSA_WITH_RC4_128_MD5 = 0x0004, + TLS_RSA_WITH_RC4_128_SHA = 0x0005, + TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = 0x0006, + TLS_RSA_WITH_IDEA_CBC_SHA = 0x0007, + TLS_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x0008, + TLS_RSA_WITH_DES_CBC_SHA = 0x0009, + TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x000A, + TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x000B, + TLS_DH_DSS_WITH_DES_CBC_SHA = 0x000C, + TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = 0x000D, + TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x000E, + TLS_DH_RSA_WITH_DES_CBC_SHA = 0x000F, + TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = 0x0010, + TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x0011, + TLS_DHE_DSS_WITH_DES_CBC_SHA = 0x0012, + TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 0x0013, + TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x0014, + TLS_DHE_RSA_WITH_DES_CBC_SHA = 0x0015, + TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x0016, + TLS_DH_ANON_EXPORT_WITH_RC4_40_MD5 = 0x0017, + TLS_DH_ANON_WITH_RC4_128_MD5 = 0x0018, + TLS_DH_ANON_EXPORT_WITH_DES40_CBC_SHA = 0x0019, + TLS_DH_ANON_WITH_DES_CBC_SHA = 0x001A, + TLS_DH_ANON_WITH_3DES_EDE_CBC_SHA = 0x001B, + TLS_KRB5_WITH_DES_CBC_SHA = 0x001E, + TLS_KRB5_WITH_3DES_EDE_CBC_SHA = 0x001F, + TLS_KRB5_WITH_RC4_128_SHA = 0x0020, + TLS_KRB5_WITH_IDEA_CBC_SHA = 0x0021, + TLS_KRB5_WITH_DES_CBC_MD5 = 0x0022, + TLS_KRB5_WITH_3DES_EDE_CBC_MD5 = 0x0023, + TLS_KRB5_WITH_RC4_128_MD5 = 0x0024, + TLS_KRB5_WITH_IDEA_CBC_MD5 = 0x0025, + TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA = 0x0026, + TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA = 0x0027, + TLS_KRB5_EXPORT_WITH_RC4_40_SHA = 0x0028, + TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 = 0x0029, + TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 = 0x002A, + TLS_KRB5_EXPORT_WITH_RC4_40_MD5 = 0x002B, + TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F, + TLS_DH_DSS_WITH_AES_128_CBC_SHA = 0x0030, + TLS_DH_RSA_WITH_AES_128_CBC_SHA = 0x0031, + TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x0032, + TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033, + TLS_DH_ANON_WITH_AES_128_CBC_SHA = 0x0034, + TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035, + TLS_DH_DSS_WITH_AES_256_CBC_SHA = 0x0036, + TLS_DH_RSA_WITH_AES_256_CBC_SHA = 0x0037, + TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0x0038, + TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039, + TLS_DH_ANON_WITH_AES_256_CBC_SHA = 0x003A, + TLS_RSA_WITH_NULL_SHA256 = 0x003B, + TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C, + TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D, + TLS_DH_DSS_WITH_AES_128_CBC_SHA256 = 0x003E, + TLS_DH_RSA_WITH_AES_128_CBC_SHA256 = 0x003F, + TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = 0x0040, + TLS_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0041, + TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA = 0x0042, + TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0043, + TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA = 0x0044, + TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0045, + TLS_DH_ANON_WITH_CAMELLIA_128_CBC_SHA = 0x0046, + TLS_RSA_EXPORT1024_WITH_RC4_56_MD5 = 0x0060, + TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5 = 0x0061, + TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA = 0x0062, + TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA = 0x0063, + TLS_RSA_EXPORT1024_WITH_RC4_56_SHA = 0x0064, + TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA = 0x0065, + TLS_DHE_DSS_WITH_RC4_128_SHA = 0x0066, + TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067, + TLS_DH_DSS_WITH_AES_256_CBC_SHA256 = 0x0068, + TLS_DH_RSA_WITH_AES_256_CBC_SHA256 = 0x0069, + TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 = 0x006A, + TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B, + TLS_DH_ANON_WITH_AES_128_CBC_SHA256 = 0x006C, + TLS_DH_ANON_WITH_AES_256_CBC_SHA256 = 0x006D, + # draft-ietf-tls-openpgp-keys-06 + TLS_DHE_DSS_WITH_3DES_EDE_CBC_RMD = 0x0072, + TLS_DHE_DSS_WITH_AES_128_CBC_RMD = 0x0073, + TLS_DHE_DSS_WITH_AES_256_CBC_RMD = 0x0074, + TLS_DHE_RSA_WITH_3DES_EDE_CBC_RMD = 0x0077, + TLS_DHE_RSA_WITH_AES_128_CBC_RMD = 0x0078, + TLS_DHE_RSA_WITH_AES_256_CBC_RMD = 0x0079, + TLS_RSA_WITH_3DES_EDE_CBC_RMD = 0x007C, + TLS_RSA_WITH_AES_128_CBC_RMD = 0x007D, + TLS_RSA_WITH_AES_256_CBC_RMD = 0x007E, + # draft-chudov-cryptopro-cptls-04 + TLS_GOSTR341094_WITH_28147_CNT_IMIT = 0x0080, + TLS_GOSTR341001_WITH_28147_CNT_IMIT = 0x0081, + TLS_GOSTR341094_WITH_NULL_GOSTR3411 = 0x0082, + TLS_GOSTR341001_WITH_NULL_GOSTR3411 = 0x0083, + TLS_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0084, + TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA = 0x0085, + TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0086, + TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA = 0x0087, + TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0088, + TLS_DH_ANON_WITH_CAMELLIA_256_CBC_SHA = 0x0089, + TLS_PSK_WITH_RC4_128_SHA = 0x008A, + TLS_PSK_WITH_3DES_EDE_CBC_SHA = 0x008B, + TLS_PSK_WITH_AES_128_CBC_SHA = 0x008C, + TLS_PSK_WITH_AES_256_CBC_SHA = 0x008D, + TLS_DHE_PSK_WITH_RC4_128_SHA = 0x008E, + TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA = 0x008F, + TLS_DHE_PSK_WITH_AES_128_CBC_SHA = 0x0090, + TLS_DHE_PSK_WITH_AES_256_CBC_SHA = 0x0091, + TLS_RSA_PSK_WITH_RC4_128_SHA = 0x0092, + TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA = 0x0093, + TLS_RSA_PSK_WITH_AES_128_CBC_SHA = 0x0094, + TLS_RSA_PSK_WITH_AES_256_CBC_SHA = 0x0095, + TLS_RSA_WITH_SEED_CBC_SHA = 0x0096, + TLS_DH_DSS_WITH_SEED_CBC_SHA = 0x0097, + TLS_DH_RSA_WITH_SEED_CBC_SHA = 0x0098, + TLS_DHE_DSS_WITH_SEED_CBC_SHA = 0x0099, + TLS_DHE_RSA_WITH_SEED_CBC_SHA = 0x009A, + TLS_DH_ANON_WITH_SEED_CBC_SHA = 0x009B, + TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C, + TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D, + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E, + TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F, + TLS_DH_RSA_WITH_AES_128_GCM_SHA256 = 0x00A0, + TLS_DH_RSA_WITH_AES_256_GCM_SHA384 = 0x00A1, + TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 = 0x00A2, + TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 = 0x00A3, + TLS_DH_DSS_WITH_AES_128_GCM_SHA256 = 0x00A4, + TLS_DH_DSS_WITH_AES_256_GCM_SHA384 = 0x00A5, + TLS_DH_ANON_WITH_AES_128_GCM_SHA256 = 0x00A6, + TLS_DH_ANON_WITH_AES_256_GCM_SHA384 = 0x00A7, + TLS_PSK_WITH_AES_128_GCM_SHA256 = 0x00A8, + TLS_PSK_WITH_AES_256_GCM_SHA384 = 0x00A9, + TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 = 0x00AA, + TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 = 0x00AB, + TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 = 0x00AC, + TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 = 0x00AD, + TLS_PSK_WITH_AES_128_CBC_SHA256 = 0x00AE, + TLS_PSK_WITH_AES_256_CBC_SHA384 = 0x00AF, + TLS_PSK_WITH_NULL_SHA256 = 0x00B0, + TLS_PSK_WITH_NULL_SHA384 = 0x00B1, + TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 = 0x00B2, + TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 = 0x00B3, + TLS_DHE_PSK_WITH_NULL_SHA256 = 0x00B4, + TLS_DHE_PSK_WITH_NULL_SHA384 = 0x00B5, + TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 = 0x00B6, + TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 = 0x00B7, + TLS_RSA_PSK_WITH_NULL_SHA256 = 0x00B8, + TLS_RSA_PSK_WITH_NULL_SHA384 = 0x00B9, + TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BA, + TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BB, + TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BC, + TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BD, + TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BE, + TLS_DH_ANON_WITH_CAMELLIA_128_CBC_SHA256 = 0x00BF, + TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C0, + TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C1, + TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C2, + TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C3, + TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C4, + TLS_DH_ANON_WITH_CAMELLIA_256_CBC_SHA256 = 0x00C5, + # draft-bmoeller-tls-downgrade-scsv-01 + TLS_FALLBACK_SCSV = 0x5600, + # RFC 4492 + TLS_ECDH_ECDSA_WITH_NULL_SHA = 0xC001, + TLS_ECDH_ECDSA_WITH_RC4_128_SHA = 0xC002, + TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA = 0xC003, + TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA = 0xC004, + TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA = 0xC005, + TLS_ECDHE_ECDSA_WITH_NULL_SHA = 0xC006, + TLS_ECDHE_ECDSA_WITH_RC4_128_SHA = 0xC007, + TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA = 0xC008, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A, + TLS_ECDH_RSA_WITH_NULL_SHA = 0xC00B, + TLS_ECDH_RSA_WITH_RC4_128_SHA = 0xC00C, + TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA = 0xC00D, + TLS_ECDH_RSA_WITH_AES_128_CBC_SHA = 0xC00E, + TLS_ECDH_RSA_WITH_AES_256_CBC_SHA = 0xC00F, + TLS_ECDHE_RSA_WITH_NULL_SHA = 0xC010, + TLS_ECDHE_RSA_WITH_RC4_128_SHA = 0xC011, + TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA = 0xC012, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014, + TLS_ECDH_ANON_WITH_NULL_SHA = 0xC015, + TLS_ECDH_ANON_WITH_RC4_128_SHA = 0xC016, + TLS_ECDH_ANON_WITH_3DES_EDE_CBC_SHA = 0xC017, + TLS_ECDH_ANON_WITH_AES_128_CBC_SHA = 0xC018, + TLS_ECDH_ANON_WITH_AES_256_CBC_SHA = 0xC019, + TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA = 0xC01A, + TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA = 0xC01B, + TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA = 0xC01C, + TLS_SRP_SHA_WITH_AES_128_CBC_SHA = 0xC01D, + TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA = 0xC01E, + TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA = 0xC01F, + TLS_SRP_SHA_WITH_AES_256_CBC_SHA = 0xC020, + TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA = 0xC021, + TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA = 0xC022, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC024, + TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC025, + TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC026, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xC028, + TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 = 0xC029, + TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 = 0xC02A, + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B, + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C, + TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02D, + TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02E, + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030, + TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 = 0xC031, + TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 = 0xC032, + TLS_ECDHE_PSK_WITH_RC4_128_SHA = 0xC033, + TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA = 0xC034, + TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA = 0xC035, + TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA = 0xC036, + TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 = 0xC037, + TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 = 0xC038, + TLS_ECDHE_PSK_WITH_NULL_SHA = 0xC039, + TLS_ECDHE_PSK_WITH_NULL_SHA256 = 0xC03A, + TLS_ECDHE_PSK_WITH_NULL_SHA384 = 0xC03B, + # RFC 6209 + TLS_RSA_WITH_ARIA_128_CBC_SHA256 = 0xC03C, + TLS_RSA_WITH_ARIA_256_CBC_SHA384 = 0xC03D, + TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256 = 0xC03E, + TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384 = 0xC03F, + TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256 = 0xC040, + TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384 = 0xC041, + TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256 = 0xC042, + TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384 = 0xC043, + TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 = 0xC044, + TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 = 0xC045, + TLS_DH_ANON_WITH_ARIA_128_CBC_SHA256 = 0xC046, + TLS_DH_ANON_WITH_ARIA_256_CBC_SHA384 = 0xC047, + TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 = 0xC048, + TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 = 0xC049, + TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 = 0xC04A, + TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 = 0xC04B, + TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 = 0xC04C, + TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 = 0xC04D, + TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 = 0xC04E, + TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 = 0xC04F, + TLS_RSA_WITH_ARIA_128_GCM_SHA256 = 0xC050, + TLS_RSA_WITH_ARIA_256_GCM_SHA384 = 0xC051, + TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 = 0xC052, + TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 = 0xC053, + TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256 = 0xC054, + TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384 = 0xC055, + TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256 = 0xC056, + TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384 = 0xC057, + TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256 = 0xC058, + TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384 = 0xC059, + TLS_DH_ANON_WITH_ARIA_128_GCM_SHA256 = 0xC05A, + TLS_DH_ANON_WITH_ARIA_256_GCM_SHA384 = 0xC05B, + TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 = 0xC05C, + TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 = 0xC05D, + TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 = 0xC05E, + TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 = 0xC05F, + TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 = 0xC060, + TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 = 0xC061, + TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 = 0xC062, + TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 = 0xC063, + TLS_PSK_WITH_ARIA_128_CBC_SHA256 = 0xC064, + TLS_PSK_WITH_ARIA_256_CBC_SHA384 = 0xC065, + TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 = 0xC066, + TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 = 0xC067, + TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 = 0xC068, + TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 = 0xC069, + TLS_PSK_WITH_ARIA_128_GCM_SHA256 = 0xC06A, + TLS_PSK_WITH_ARIA_256_GCM_SHA384 = 0xC06B, + TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 = 0xC06C, + TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 = 0xC06D, + TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 = 0xC06E, + TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 = 0xC06F, + TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 = 0xC070, + TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 = 0xC071, + # RFC 6367 + TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC072, + TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC073, + TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC074, + TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC075, + TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC076, + TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC077, + TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 = 0xC078, + TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 = 0xC079, + TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC07A, + TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC07B, + TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC07C, + TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC07D, + TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC07E, + TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC07F, + TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256 = 0xC080, + TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384 = 0xC081, + TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 = 0xC082, + TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 = 0xC083, + TLS_DH_ANON_WITH_CAMELLIA_128_GCM_SHA256 = 0xC084, + TLS_DH_ANON_WITH_CAMELLIA_256_GCM_SHA384 = 0xC085, + TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC086, + TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC087, + TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC088, + TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC089, + TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC08A, + TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC08B, + TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 = 0xC08C, + TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 = 0xC08D, + TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 = 0xC08E, + TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 = 0xC08F, + TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 = 0xC090, + TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 = 0xC091, + TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 = 0xC092, + TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 = 0xC093, + TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC094, + TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC095, + TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC096, + TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC097, + TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC098, + TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC099, + TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 = 0xC09A, + TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 = 0xC09B, + # RFC 6655 + TLS_RSA_WITH_AES_128_CCM = 0xC09C, + TLS_RSA_WITH_AES_256_CCM = 0xC09D, + TLS_DHE_RSA_WITH_AES_128_CCM = 0xC09E, + TLS_DHE_RSA_WITH_AES_256_CCM = 0xC09F, + TLS_RSA_WITH_AES_128_CCM_8 = 0xC0A0, + TLS_RSA_WITH_AES_256_CCM_8 = 0xC0A1, + TLS_DHE_RSA_WITH_AES_128_CCM_8 = 0xC0A2, + TLS_DHE_RSA_WITH_AES_256_CCM_8 = 0xC0A3, + TLS_PSK_WITH_AES_128_CCM = 0xC0A4, + TLS_PSK_WITH_AES_256_CCM = 0xC0A5, + TLS_DHE_PSK_WITH_AES_128_CCM = 0xC0A6, + TLS_DHE_PSK_WITH_AES_256_CCM = 0xC0A7, + TLS_PSK_WITH_AES_128_CCM_8 = 0xC0A8, + TLS_PSK_WITH_AES_256_CCM_8 = 0xC0A9, + TLS_PSK_DHE_WITH_AES_128_CCM_8 = 0xC0AA, + TLS_PSK_DHE_WITH_AES_256_CCM_8 = 0xC0AB, + # draft-agl-tls-chacha20poly1305-02 + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCC13, + TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCC14, + TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCC15 +}; diff --git a/src/analyzer/protocol/ssl/ssl-protocol.pac b/src/analyzer/protocol/ssl/ssl-protocol.pac index a3729826c4..a44516dc6b 100644 --- a/src/analyzer/protocol/ssl/ssl-protocol.pac +++ b/src/analyzer/protocol/ssl/ssl-protocol.pac @@ -302,9 +302,11 @@ type ServerHello(rec: SSLRecord) = record { # of the following fields. ext_len: uint16[] &until($element == 0 || $element != 0); extensions : SSLExtension(rec)[] &until($input.length() == 0); +} &let { + cipher_set : bool = + $context.connection.set_cipher(cipher_suite[0]); }; - ###################################################################### # V2 Server Hello (SSLv2 2.6.) ###################################################################### @@ -351,11 +353,51 @@ type CertificateStatus(rec: SSLRecord) = record { # V3 Server Key Exchange Message (7.4.3.) ###################################################################### -# For now ignore details; just eat up complete message -type ServerKeyExchange(rec: SSLRecord) = record { - key : bytestring &restofdata &transient; +# Usually, the server key exchange does not contain any information +# that we are interested in. +# +# The one exception is when we are using an elliptic curve cipher suite. +# In this case, we can extract the final chosen cipher from here. +type ServerKeyExchange(rec: SSLRecord) = case $context.connection.chosen_cipher() of { + TLS_ECDH_ECDSA_WITH_NULL_SHA, + TLS_ECDH_ECDSA_WITH_RC4_128_SHA, + TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, + TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_NULL_SHA, + TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, + TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + TLS_ECDH_RSA_WITH_NULL_SHA, + TLS_ECDH_RSA_WITH_RC4_128_SHA, + TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, + TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDHE_RSA_WITH_NULL_SHA, + TLS_ECDHE_RSA_WITH_RC4_128_SHA, + TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + TLS_ECDH_ANON_WITH_NULL_SHA, + TLS_ECDH_ANON_WITH_RC4_128_SHA, + TLS_ECDH_ANON_WITH_3DES_EDE_CBC_SHA, + TLS_ECDH_ANON_WITH_AES_128_CBC_SHA, + TLS_ECDH_ANON_WITH_AES_256_CBC_SHA + -> ec_server_key_exchange : EcServerKeyExchange(rec); + + default + -> key : bytestring &restofdata &transient; }; +# For the moment, we really only are interested in the curve name. If it +# is not set (if the server sends explicit parameters), we do not bother. +# We also do not parse the actual signature data following the named curve. +type EcServerKeyExchange(rec: SSLRecord) = record { + curve_type: uint8; + curve: uint16; # only if curve_type = 3 + data: bytestring &restofdata &transient; +}; ###################################################################### # V3 Certificate Request (7.4.4.) @@ -501,14 +543,24 @@ refine connection SSL_Conn += { int client_state_; int server_state_; int record_layer_version_; + uint32 chosen_cipher_; %} %init{ server_state_ = STATE_CLEAR; client_state_ = STATE_CLEAR; record_layer_version_ = UNKNOWN_VERSION; + chosen_cipher_ = NO_CHOSEN_CIPHER; %} + function chosen_cipher() : int %{ return chosen_cipher_; %} + + function set_cipher(cipher: int64) : bool + %{ + chosen_cipher_ = cipher; + return true; + %} + function determine_ssl_record_layer(head0 : uint8, head1 : uint8, head2 : uint8, head3: uint8, head4: uint8) : int %{ diff --git a/testing/btest/Baseline/scripts.base.protocols.ftp.gridftp/ssl.log b/testing/btest/Baseline/scripts.base.protocols.ftp.gridftp/ssl.log index 3b04596f6f..5fb15d53ae 100644 --- a/testing/btest/Baseline/scripts.base.protocols.ftp.gridftp/ssl.log +++ b/testing/btest/Baseline/scripts.base.protocols.ftp.gridftp/ssl.log @@ -3,9 +3,9 @@ #empty_field (empty) #unset_field - #path ssl -#open 2014-03-13-20-45-24 -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher server_name session_id last_alert established cert_chain_fuids client_cert_chain_fuids subject issuer client_subject client_issuer -#types time string addr port addr port string string string string string bool vector[string] vector[string] string string string string -1348168976.508038 CXWv6p3arKYeMETxOg 192.168.57.103 60108 192.168.57.101 2811 TLSv10 TLS_RSA_WITH_AES_256_CBC_SHA - - - T FBtbj87tgpyeDSj31,F8TfgZ31c1dFu8Kt2k FVNYOh2BeQBb7MpCPe,FwjBou1e5DbpE0eOgk,FbYQmk4x4M4Bx3PZme CN=host/alpha,OU=simpleCA-alpha,OU=GlobusTest,O=Grid CN=Globus Simple CA,OU=simpleCA-alpha,OU=GlobusTest,O=Grid CN=917532944,CN=Jon Siwek,OU=local,OU=simpleCA-alpha,OU=GlobusTest,O=Grid CN=Jon Siwek,OU=local,OU=simpleCA-alpha,OU=GlobusTest,O=Grid -1348168976.551422 CjhGID4nQcgTWjvg4c 192.168.57.103 35391 192.168.57.101 55968 TLSv10 TLS_RSA_WITH_NULL_SHA - - - T F4SSqN31HDIrrH5Q8h,FJHp5Pf6VLQsRQK3,FHACqa3dX9BXRV2av,FNnDVT1NURRWeoLLN3 FFWYVj4BcvQb35WIaf,Fj16G835fnJgnVlKU6,FGONoc1Nj0Ka5zlxDa CN=932373381,CN=917532944,CN=Jon Siwek,OU=local,OU=simpleCA-alpha,OU=GlobusTest,O=Grid CN=917532944,CN=Jon Siwek,OU=local,OU=simpleCA-alpha,OU=GlobusTest,O=Grid CN=917532944,CN=Jon Siwek,OU=local,OU=simpleCA-alpha,OU=GlobusTest,O=Grid CN=Jon Siwek,OU=local,OU=simpleCA-alpha,OU=GlobusTest,O=Grid -#close 2014-03-13-20-45-24 +#open 2014-04-26-16-44-47 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name session_id last_alert established cert_chain_fuids client_cert_chain_fuids subject issuer client_subject client_issuer +#types time string addr port addr port string string string string string string bool vector[string] vector[string] string string string string +1348168976.508038 CXWv6p3arKYeMETxOg 192.168.57.103 60108 192.168.57.101 2811 TLSv10 TLS_RSA_WITH_AES_256_CBC_SHA - - - - T FBtbj87tgpyeDSj31,F8TfgZ31c1dFu8Kt2k FVNYOh2BeQBb7MpCPe,FwjBou1e5DbpE0eOgk,FbYQmk4x4M4Bx3PZme CN=host/alpha,OU=simpleCA-alpha,OU=GlobusTest,O=Grid CN=Globus Simple CA,OU=simpleCA-alpha,OU=GlobusTest,O=Grid CN=917532944,CN=Jon Siwek,OU=local,OU=simpleCA-alpha,OU=GlobusTest,O=Grid CN=Jon Siwek,OU=local,OU=simpleCA-alpha,OU=GlobusTest,O=Grid +1348168976.551422 CjhGID4nQcgTWjvg4c 192.168.57.103 35391 192.168.57.101 55968 TLSv10 TLS_RSA_WITH_NULL_SHA - - - - T F4SSqN31HDIrrH5Q8h,FJHp5Pf6VLQsRQK3,FHACqa3dX9BXRV2av,FNnDVT1NURRWeoLLN3 FFWYVj4BcvQb35WIaf,Fj16G835fnJgnVlKU6,FGONoc1Nj0Ka5zlxDa CN=932373381,CN=917532944,CN=Jon Siwek,OU=local,OU=simpleCA-alpha,OU=GlobusTest,O=Grid CN=917532944,CN=Jon Siwek,OU=local,OU=simpleCA-alpha,OU=GlobusTest,O=Grid CN=917532944,CN=Jon Siwek,OU=local,OU=simpleCA-alpha,OU=GlobusTest,O=Grid CN=Jon Siwek,OU=local,OU=simpleCA-alpha,OU=GlobusTest,O=Grid +#close 2014-04-26-16-44-47 diff --git a/testing/btest/Baseline/scripts.base.protocols.ssl.basic/ssl.log b/testing/btest/Baseline/scripts.base.protocols.ssl.basic/ssl.log index 455d8606e8..7834e74868 100644 --- a/testing/btest/Baseline/scripts.base.protocols.ssl.basic/ssl.log +++ b/testing/btest/Baseline/scripts.base.protocols.ssl.basic/ssl.log @@ -3,8 +3,8 @@ #empty_field (empty) #unset_field - #path ssl -#open 2014-03-13-20-45-46 -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher server_name session_id last_alert established cert_chain_fuids client_cert_chain_fuids subject issuer client_subject client_issuer -#types time string addr port addr port string string string string string bool vector[string] vector[string] string string string string -1335538392.319381 CXWv6p3arKYeMETxOg 192.168.1.105 62045 74.125.224.79 443 TLSv10 TLS_ECDHE_RSA_WITH_RC4_128_SHA ssl.gstatic.com - - T F6wfNWn8LR755SYo7,FJl60T1mOolaez9T0h (empty) CN=*.gstatic.com,O=Google Inc,L=Mountain View,ST=California,C=US CN=Google Internet Authority,O=Google Inc,C=US - - -#close 2014-03-13-20-45-46 +#open 2014-04-26-16-45-01 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name session_id last_alert established cert_chain_fuids client_cert_chain_fuids subject issuer client_subject client_issuer +#types time string addr port addr port string string string string string string bool vector[string] vector[string] string string string string +1335538392.319381 CXWv6p3arKYeMETxOg 192.168.1.105 62045 74.125.224.79 443 TLSv10 TLS_ECDHE_RSA_WITH_RC4_128_SHA secp256r1 ssl.gstatic.com - - T F6wfNWn8LR755SYo7,FJl60T1mOolaez9T0h (empty) CN=*.gstatic.com,O=Google Inc,L=Mountain View,ST=California,C=US CN=Google Internet Authority,O=Google Inc,C=US - - +#close 2014-04-26-16-45-01 diff --git a/testing/btest/Baseline/scripts.base.protocols.ssl.ecdhe/ssl.log b/testing/btest/Baseline/scripts.base.protocols.ssl.ecdhe/ssl.log new file mode 100644 index 0000000000..66ea42be70 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ssl.ecdhe/ssl.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ssl +#open 2014-04-26-16-39-57 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name session_id last_alert established cert_chain_fuids client_cert_chain_fuids subject issuer client_subject client_issuer +#types time string addr port addr port string string string string string string bool vector[string] vector[string] string string string string +1398529018.678827 CXWv6p3arKYeMETxOg 192.168.18.50 56981 74.125.239.97 443 TLSv12 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA secp256r1 - - - T FDy6ve1m58lwPRfhE9,FnGjwc1EVGk5x0WZk5,F2T07R1XZFCmeWafv2 (empty) CN=*.google.com,O=Google Inc,L=Mountain View,ST=California,C=US CN=Google Internet Authority G2,O=Google Inc,C=US - - +#close 2014-04-26-16-39-57 diff --git a/testing/btest/Baseline/scripts.base.protocols.ssl.ecdhe/x509.log b/testing/btest/Baseline/scripts.base.protocols.ssl.ecdhe/x509.log new file mode 100644 index 0000000000..e8813fb60a --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ssl.ecdhe/x509.log @@ -0,0 +1,12 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path x509 +#open 2014-04-26-16-39-57 +#fields ts id certificate.version certificate.serial certificate.subject certificate.issuer certificate.not_valid_before certificate.not_valid_after certificate.key_alg certificate.sig_alg certificate.key_type certificate.key_length certificate.exponent certificate.curve san.dns san.uri san.email san.ip basic_constraints.ca basic_constraints.path_len +#types time string count string string string time time string string string count string string vector[string] vector[string] vector[string] vector[addr] bool count +1398529018.711296 FDy6ve1m58lwPRfhE9 3 1E58FDC12DE4C703 CN=*.google.com,O=Google Inc,L=Mountain View,ST=California,C=US CN=Google Internet Authority G2,O=Google Inc,C=US 1397045108.000000 1404777600.000000 rsaEncryption sha1WithRSAEncryption rsa 2048 65537 - *.google.com,*.android.com,*.appengine.google.com,*.cloud.google.com,*.google-analytics.com,*.google.ca,*.google.cl,*.google.co.in,*.google.co.jp,*.google.co.uk,*.google.com.ar,*.google.com.au,*.google.com.br,*.google.com.co,*.google.com.mx,*.google.com.tr,*.google.com.vn,*.google.de,*.google.es,*.google.fr,*.google.hu,*.google.it,*.google.nl,*.google.pl,*.google.pt,*.googleapis.cn,*.googlecommerce.com,*.googlevideo.com,*.gstatic.com,*.gvt1.com,*.urchin.com,*.url.google.com,*.youtube-nocookie.com,*.youtube.com,*.youtubeeducation.com,*.ytimg.com,android.com,g.co,goo.gl,google-analytics.com,google.com,googlecommerce.com,urchin.com,youtu.be,youtube.com,youtubeeducation.com - - - F - +1398529018.711296 FnGjwc1EVGk5x0WZk5 3 023A69 CN=Google Internet Authority G2,O=Google Inc,C=US CN=GeoTrust Global CA,O=GeoTrust Inc.,C=US 1365174955.000000 1428160555.000000 rsaEncryption sha1WithRSAEncryption rsa 2048 65537 - - - - - T 0 +1398529018.711296 F2T07R1XZFCmeWafv2 3 12BBE6 CN=GeoTrust Global CA,O=GeoTrust Inc.,C=US OU=Equifax Secure Certificate Authority,O=Equifax,C=US 1021953600.000000 1534824000.000000 rsaEncryption sha1WithRSAEncryption rsa 2048 65537 - - - - - T - +#close 2014-04-26-16-39-57 diff --git a/testing/btest/Baseline/scripts.base.protocols.ssl.tls-1.2-handshake-failure/ssl.log b/testing/btest/Baseline/scripts.base.protocols.ssl.tls-1.2-handshake-failure/ssl.log index 88f3c2126e..082106e89e 100644 --- a/testing/btest/Baseline/scripts.base.protocols.ssl.tls-1.2-handshake-failure/ssl.log +++ b/testing/btest/Baseline/scripts.base.protocols.ssl.tls-1.2-handshake-failure/ssl.log @@ -3,8 +3,8 @@ #empty_field (empty) #unset_field - #path ssl -#open 2014-03-13-20-46-30 -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher server_name session_id last_alert established cert_chain_fuids client_cert_chain_fuids subject issuer client_subject client_issuer -#types time string addr port addr port string string string string string bool vector[string] vector[string] string string string string -1393957586.786031 CXWv6p3arKYeMETxOg 192.168.4.149 53525 74.125.239.37 443 - - - - handshake_failure F - - - - - - -#close 2014-03-13-20-46-30 +#open 2014-04-26-16-45-16 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name session_id last_alert established cert_chain_fuids client_cert_chain_fuids subject issuer client_subject client_issuer +#types time string addr port addr port string string string string string string bool vector[string] vector[string] string string string string +1393957586.786031 CXWv6p3arKYeMETxOg 192.168.4.149 53525 74.125.239.37 443 - - - - - handshake_failure F - - - - - - +#close 2014-04-26-16-45-16 diff --git a/testing/btest/Baseline/scripts.base.protocols.ssl.tls-1.2/ssl.log b/testing/btest/Baseline/scripts.base.protocols.ssl.tls-1.2/ssl.log index 0bb8b5810d..ab1345d0cc 100644 --- a/testing/btest/Baseline/scripts.base.protocols.ssl.tls-1.2/ssl.log +++ b/testing/btest/Baseline/scripts.base.protocols.ssl.tls-1.2/ssl.log @@ -3,8 +3,8 @@ #empty_field (empty) #unset_field - #path ssl -#open 2014-03-13-20-46-09 -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher server_name session_id last_alert established cert_chain_fuids client_cert_chain_fuids subject issuer client_subject client_issuer -#types time string addr port addr port string string string string string bool vector[string] vector[string] string string string string -1357328848.549370 CXWv6p3arKYeMETxOg 10.0.0.80 56637 68.233.76.12 443 TLSv12 TLS_RSA_WITH_RC4_128_MD5 - - - T FlnQzb2dJK4p9jXwmd,FaDzX22O4j3kFF6Jqg,F9Tsjm3OdCmGGw43Yh (empty) CN=*.taleo.net,OU=Comodo PremiumSSL Wildcard,OU=Web,O=Taleo Inc.,street=4140 Dublin Boulevard,street=Suite 400,L=Dublin,ST=CA,postalCode=94568,C=US CN=COMODO High-Assurance Secure Server CA,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB - - -#close 2014-03-13-20-46-09 +#open 2014-04-26-16-45-09 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name session_id last_alert established cert_chain_fuids client_cert_chain_fuids subject issuer client_subject client_issuer +#types time string addr port addr port string string string string string string bool vector[string] vector[string] string string string string +1357328848.549370 CXWv6p3arKYeMETxOg 10.0.0.80 56637 68.233.76.12 443 TLSv12 TLS_RSA_WITH_RC4_128_MD5 - - - - T FlnQzb2dJK4p9jXwmd,FaDzX22O4j3kFF6Jqg,F9Tsjm3OdCmGGw43Yh (empty) CN=*.taleo.net,OU=Comodo PremiumSSL Wildcard,OU=Web,O=Taleo Inc.,street=4140 Dublin Boulevard,street=Suite 400,L=Dublin,ST=CA,postalCode=94568,C=US CN=COMODO High-Assurance Secure Server CA,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB - - +#close 2014-04-26-16-45-09 diff --git a/testing/btest/Baseline/scripts.policy.protocols.ssl.known-certs/ssl.log b/testing/btest/Baseline/scripts.policy.protocols.ssl.known-certs/ssl.log index ec0a90929b..da805fd35d 100644 --- a/testing/btest/Baseline/scripts.policy.protocols.ssl.known-certs/ssl.log +++ b/testing/btest/Baseline/scripts.policy.protocols.ssl.known-certs/ssl.log @@ -3,9 +3,9 @@ #empty_field (empty) #unset_field - #path ssl -#open 2014-03-13-21-47-24 -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher server_name session_id last_alert established cert_chain_fuids client_cert_chain_fuids subject issuer client_subject client_issuer -#types time string addr port addr port string string string string string bool vector[string] vector[string] string string string string -1394747126.855035 CXWv6p3arKYeMETxOg 192.168.4.149 60623 74.125.239.129 443 TLSv12 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - - - T FlaIzV19yTmBYwWwc6,F0BeiV3cMsGkNML0P2,F6PfYi2WUoPdIJrhpg (empty) CN=*.google.com,O=Google Inc,L=Mountain View,ST=California,C=US CN=Google Internet Authority G2,O=Google Inc,C=US - - -1394747129.505622 CjhGID4nQcgTWjvg4c 192.168.4.149 60624 74.125.239.129 443 TLSv12 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - - - T FOye6a4kt8a7QChqw3,FytlLr3jOQenFAVtYi,FEmnxy4DGbxkmtQJS1 (empty) CN=*.google.com,O=Google Inc,L=Mountain View,ST=California,C=US CN=Google Internet Authority G2,O=Google Inc,C=US - - -#close 2014-03-13-21-47-24 +#open 2014-04-26-16-45-23 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name session_id last_alert established cert_chain_fuids client_cert_chain_fuids subject issuer client_subject client_issuer +#types time string addr port addr port string string string string string string bool vector[string] vector[string] string string string string +1394747126.855035 CXWv6p3arKYeMETxOg 192.168.4.149 60623 74.125.239.129 443 TLSv12 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - - - - T FlaIzV19yTmBYwWwc6,F0BeiV3cMsGkNML0P2,F6PfYi2WUoPdIJrhpg (empty) CN=*.google.com,O=Google Inc,L=Mountain View,ST=California,C=US CN=Google Internet Authority G2,O=Google Inc,C=US - - +1394747129.505622 CjhGID4nQcgTWjvg4c 192.168.4.149 60624 74.125.239.129 443 TLSv12 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - - - - T FOye6a4kt8a7QChqw3,FytlLr3jOQenFAVtYi,FEmnxy4DGbxkmtQJS1 (empty) CN=*.google.com,O=Google Inc,L=Mountain View,ST=California,C=US CN=Google Internet Authority G2,O=Google Inc,C=US - - +#close 2014-04-26-16-45-23 diff --git a/testing/btest/Baseline/scripts.policy.protocols.ssl.validate-certs/ssl.log b/testing/btest/Baseline/scripts.policy.protocols.ssl.validate-certs/ssl.log index 16fcee9111..7965e3be89 100644 --- a/testing/btest/Baseline/scripts.policy.protocols.ssl.validate-certs/ssl.log +++ b/testing/btest/Baseline/scripts.policy.protocols.ssl.validate-certs/ssl.log @@ -3,9 +3,9 @@ #empty_field (empty) #unset_field - #path ssl -#open 2014-03-13-21-53-03 -#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher server_name session_id last_alert established cert_chain_fuids client_cert_chain_fuids subject issuer client_subject client_issuer validation_status -#types time string addr port addr port string string string string string bool vector[string] vector[string] string string string string string -1394745602.951961 CXWv6p3arKYeMETxOg 192.168.4.149 60539 87.98.220.10 443 TLSv10 TLS_DHE_RSA_WITH_AES_256_CBC_SHA - - - T F1fX1R2cDOzbvg17ye,FqPEQR2eytAQybroyl (empty) CN=www.spidh.org,OU=COMODO SSL,OU=Domain Control Validated CN=COMODO SSL CA,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB - - certificate has expired -1394745618.791420 CjhGID4nQcgTWjvg4c 192.168.4.149 60540 122.1.240.204 443 TLSv10 TLS_RSA_WITH_AES_256_CBC_SHA - - - T F6NAbK127LhNBaEe5c,FDhmPt28vyXlGMTxP7,F0ROCKibhE1KntJ1h (empty) CN=www.tobu-estate.com,OU=Terms of use at www.verisign.com/rpa (c)05,O=TOBU RAILWAY Co.\,Ltd.,L=Sumida-ku,ST=Tokyo,C=JP CN=VeriSign Class 3 Secure Server CA - G3,OU=Terms of use at https://www.verisign.com/rpa (c)10,OU=VeriSign Trust Network,O=VeriSign\, Inc.,C=US - - ok -#close 2014-03-13-21-53-03 +#open 2014-04-26-16-45-32 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name session_id last_alert established cert_chain_fuids client_cert_chain_fuids subject issuer client_subject client_issuer validation_status +#types time string addr port addr port string string string string string string bool vector[string] vector[string] string string string string string +1394745602.951961 CXWv6p3arKYeMETxOg 192.168.4.149 60539 87.98.220.10 443 TLSv10 TLS_DHE_RSA_WITH_AES_256_CBC_SHA - - - - T F1fX1R2cDOzbvg17ye,FqPEQR2eytAQybroyl (empty) CN=www.spidh.org,OU=COMODO SSL,OU=Domain Control Validated CN=COMODO SSL CA,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB - - certificate has expired +1394745618.791420 CjhGID4nQcgTWjvg4c 192.168.4.149 60540 122.1.240.204 443 TLSv10 TLS_RSA_WITH_AES_256_CBC_SHA - - - - T F6NAbK127LhNBaEe5c,FDhmPt28vyXlGMTxP7,F0ROCKibhE1KntJ1h (empty) CN=www.tobu-estate.com,OU=Terms of use at www.verisign.com/rpa (c)05,O=TOBU RAILWAY Co.\,Ltd.,L=Sumida-ku,ST=Tokyo,C=JP CN=VeriSign Class 3 Secure Server CA - G3,OU=Terms of use at https://www.verisign.com/rpa (c)10,OU=VeriSign Trust Network,O=VeriSign\, Inc.,C=US - - ok +#close 2014-04-26-16-45-32 diff --git a/testing/btest/Traces/tls/ecdhe.pcap b/testing/btest/Traces/tls/ecdhe.pcap new file mode 100644 index 0000000000000000000000000000000000000000..e37df374e0271a643d49fea1c67e03e00a158a63 GIT binary patch literal 7510 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 literal 0 HcmV?d00001 diff --git a/testing/btest/scripts/base/protocols/ssl/ecdhe.test b/testing/btest/scripts/base/protocols/ssl/ecdhe.test new file mode 100644 index 0000000000..bd1bd2cb96 --- /dev/null +++ b/testing/btest/scripts/base/protocols/ssl/ecdhe.test @@ -0,0 +1,3 @@ +# @TEST-EXEC: bro -r $TRACES/tls/ecdhe.pcap %INPUT +# @TEST-EXEC: btest-diff ssl.log +# @TEST-EXEC: btest-diff x509.log From 24b63f5fc8f9526d902137813fabb692a5fd9478 Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Sat, 26 Apr 2014 09:53:18 -0700 Subject: [PATCH 046/136] Forgot a few ciphers in the EC list... --- src/analyzer/protocol/ssl/ssl-protocol.pac | 69 +++++++++++++++++++++- 1 file changed, 66 insertions(+), 3 deletions(-) diff --git a/src/analyzer/protocol/ssl/ssl-protocol.pac b/src/analyzer/protocol/ssl/ssl-protocol.pac index a44516dc6b..f84befe695 100644 --- a/src/analyzer/protocol/ssl/ssl-protocol.pac +++ b/src/analyzer/protocol/ssl/ssl-protocol.pac @@ -98,7 +98,7 @@ type ServerName() = record { name_type: uint8; # has to be 0 for host-name name: case name_type of { 0 -> host_name: ServerNameHostName; - default -> data : bytestring &restofdata; # unknown name + default -> data : bytestring &restofdata &transient; # unknown name }; }; @@ -119,7 +119,7 @@ type ServerNameExt(rec: SSLRecord) = record { # status_type: uint8; # 1 -> ocsp # req: case status_type of { # 1 -> ocsp_status_request: OcspStatusRequest(rec); -# default -> data : bytestring &restofdata; # unknown +# default -> data : bytestring &restofdata &transient; # unknown # }; #}; @@ -383,7 +383,70 @@ type ServerKeyExchange(rec: SSLRecord) = case $context.connection.chosen_cipher( TLS_ECDH_ANON_WITH_RC4_128_SHA, TLS_ECDH_ANON_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ANON_WITH_AES_128_CBC_SHA, - TLS_ECDH_ANON_WITH_AES_256_CBC_SHA + TLS_ECDH_ANON_WITH_AES_256_CBC_SHA, + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, + TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, + TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, + TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, + TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, + TLS_ECDHE_PSK_WITH_RC4_128_SHA, + TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA, + TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, + TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, + TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, + TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, + TLS_ECDHE_PSK_WITH_NULL_SHA, + TLS_ECDHE_PSK_WITH_NULL_SHA256, + TLS_ECDHE_PSK_WITH_NULL_SHA384, + TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256, + TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384, + TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256, + TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384, + TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256, + TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384, + TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256, + TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384, + TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384, + TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256, + TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384, + TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384, + TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256, + TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384, + TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256, + TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384, + TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, + TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, + TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, + TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, + TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, + TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, + TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256, + TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384, + TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, + TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, + TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, + TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, + TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, + TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, + TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256, + TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384, + TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, + TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 -> ec_server_key_exchange : EcServerKeyExchange(rec); default From b1a2bccdc747750a94c396b07119bb14fcb800c9 Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Sat, 26 Apr 2014 14:51:08 -0700 Subject: [PATCH 047/136] Add a few more ciphers Bro did not know at all so far. --- scripts/base/protocols/ssl/consts.bro | 8 ++++++++ src/analyzer/protocol/ssl/ssl-defs.pac | 4 ++++ src/analyzer/protocol/ssl/ssl-protocol.pac | 4 ++++ 3 files changed, 16 insertions(+) diff --git a/scripts/base/protocols/ssl/consts.bro b/scripts/base/protocols/ssl/consts.bro index e60363e14c..e1b366130f 100644 --- a/scripts/base/protocols/ssl/consts.bro +++ b/scripts/base/protocols/ssl/consts.bro @@ -487,6 +487,10 @@ export { const TLS_PSK_WITH_AES_256_CCM_8 = 0xC0A9; const TLS_PSK_DHE_WITH_AES_128_CCM_8 = 0xC0AA; const TLS_PSK_DHE_WITH_AES_256_CCM_8 = 0xC0AB; + const TLS_ECDHE_ECDSA_WITH_AES_128_CCM = 0xC0AC; + const TLS_ECDHE_ECDSA_WITH_AES_256_CCM = 0xC0AD; + const TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 = 0xC0AE; + const TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 = 0xC0AF; # draft-agl-tls-chacha20poly1305-02 const TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCC13; const TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCC14; @@ -850,6 +854,10 @@ export { [TLS_PSK_WITH_AES_256_CCM_8] = "TLS_PSK_WITH_AES_256_CCM_8", [TLS_PSK_DHE_WITH_AES_128_CCM_8] = "TLS_PSK_DHE_WITH_AES_128_CCM_8", [TLS_PSK_DHE_WITH_AES_256_CCM_8] = "TLS_PSK_DHE_WITH_AES_256_CCM_8", + [TLS_ECDHE_ECDSA_WITH_AES_128_CCM] = "TLS_ECDHE_ECDSA_WITH_AES_128_CCM", + [TLS_ECDHE_ECDSA_WITH_AES_256_CCM] = "TLS_ECDHE_ECDSA_WITH_AES_256_CCM", + [TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8] = "TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8", + [TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8] = "TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8", [TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256] = "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", [TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256] = "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", [TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256] = "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256", diff --git a/src/analyzer/protocol/ssl/ssl-defs.pac b/src/analyzer/protocol/ssl/ssl-defs.pac index 2b55e53b25..a4074443b9 100644 --- a/src/analyzer/protocol/ssl/ssl-defs.pac +++ b/src/analyzer/protocol/ssl/ssl-defs.pac @@ -407,6 +407,10 @@ enum TLSCiphers { TLS_PSK_WITH_AES_256_CCM_8 = 0xC0A9, TLS_PSK_DHE_WITH_AES_128_CCM_8 = 0xC0AA, TLS_PSK_DHE_WITH_AES_256_CCM_8 = 0xC0AB, + TLS_ECDHE_ECDSA_WITH_AES_128_CCM = 0xC0AC, + TLS_ECDHE_ECDSA_WITH_AES_256_CCM = 0xC0AD, + TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 = 0xC0AE, + TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 = 0xC0AF, # draft-agl-tls-chacha20poly1305-02 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCC13, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCC14, diff --git a/src/analyzer/protocol/ssl/ssl-protocol.pac b/src/analyzer/protocol/ssl/ssl-protocol.pac index f84befe695..e19fdb6aac 100644 --- a/src/analyzer/protocol/ssl/ssl-protocol.pac +++ b/src/analyzer/protocol/ssl/ssl-protocol.pac @@ -445,6 +445,10 @@ type ServerKeyExchange(rec: SSLRecord) = case $context.connection.chosen_cipher( TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384, TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, + TLS_ECDHE_ECDSA_WITH_AES_128_CCM, + TLS_ECDHE_ECDSA_WITH_AES_256_CCM, + TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, + TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 -> ec_server_key_exchange : EcServerKeyExchange(rec); From fb56b22cffdf8603404da367fac097b71b3bf36f Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Sat, 26 Apr 2014 23:48:47 -0700 Subject: [PATCH 048/136] Add DH support to SSL analyzer. When using DHE or DH-Anon, sever key parameters are now available in scriptland. Also add script to alert on weak certificate keys or weak dh-params. --- scripts/policy/protocols/ssl/weak-keys.bro | 90 +++++++++++++ scripts/test-all-policy.bro | 1 + src/analyzer/protocol/ssl/events.bif | 19 ++- src/analyzer/protocol/ssl/ssl-analyzer.pac | 17 +++ src/analyzer/protocol/ssl/ssl-protocol.pac | 121 +++++++++++++++++- .../scripts.base.protocols.ssl.dhe/.stdout | 1 + .../scripts.base.protocols.ssl.dhe/ssl.log | 10 ++ .../ssl.log | 8 +- .../notice-1.log | 12 ++ testing/btest/Traces/tls/dhe.pcap | Bin 0 -> 6929 bytes .../btest/scripts/base/protocols/ssl/dhe.test | 8 ++ .../policy/protocols/ssl/weak-keys.bro | 8 ++ 12 files changed, 288 insertions(+), 7 deletions(-) create mode 100644 scripts/policy/protocols/ssl/weak-keys.bro create mode 100644 testing/btest/Baseline/scripts.base.protocols.ssl.dhe/.stdout create mode 100644 testing/btest/Baseline/scripts.base.protocols.ssl.dhe/ssl.log create mode 100644 testing/btest/Baseline/scripts.policy.protocols.ssl.weak-keys/notice-1.log create mode 100644 testing/btest/Traces/tls/dhe.pcap create mode 100644 testing/btest/scripts/base/protocols/ssl/dhe.test create mode 100644 testing/btest/scripts/policy/protocols/ssl/weak-keys.bro diff --git a/scripts/policy/protocols/ssl/weak-keys.bro b/scripts/policy/protocols/ssl/weak-keys.bro new file mode 100644 index 0000000000..27cfb31554 --- /dev/null +++ b/scripts/policy/protocols/ssl/weak-keys.bro @@ -0,0 +1,90 @@ +##! Generate notices when SSL/TLS connections use certificates or DH parameters +##! that have potentially unsafe key lengths. + +@load base/protocols/ssl +@load base/frameworks/notice +@load base/utils/directions-and-hosts + +module SSL; + +export { + redef enum Notice::Type += { + ## Indicates that a server is using a potentially unsafe key. + SSL_Weak_Key, + }; + + ## The category of hosts you would like to be notified about which have + ## certificates that are going to be expiring soon. By default, these + ## notices will be suppressed by the notice framework for 1 day after + ## a particular certificate has had a notice generated. + ## Choices are: LOCAL_HOSTS, REMOTE_HOSTS, ALL_HOSTS, NO_HOSTS + const notify_weak_keys = LOCAL_HOSTS &redef; + + ## The minimal key length in bits that is considered to be safe. Any + ## shorter (non-EC) key lengths will trigger the notice. + const notify_minimal_key_length = 1024 &redef; + + ## Warn if the DH key length is smaller than the certificate key length. + ## This is potentially unsafe, because it gives a wrong impression of safety + ## due to the certificate key length. + ## However, it is very common and cannot be avoided in some settings (e.g. with + ## old jave clients). + const notify_dh_length_shorter_cert_length = T &redef; +} + +## We check key lengths only for DSA or RSA certificates. For others, we do +## not know what is safe (e.g. EC is safe even with very short key lengths). + +event ssl_established(c: connection) &priority=3 + { + # If there are no certificates or we are not interested in the server, just return. + if ( ! c$ssl?$cert_chain || |c$ssl$cert_chain| == 0 || + ! addr_matches_host(c$id$resp_h, notify_weak_keys) ) + return; + + local fuid = c$ssl$cert_chain_fuids[0]; + local cert = c$ssl$cert_chain[0]$x509$certificate; + if ( !cert?$key_type || !cert?$key_length ) + return; + if ( cert$key_type != "dsa" && cert$key_type != "rsa" ) + return; + + local key_length = cert$key_length; + + if ( key_length < notify_minimal_key_length ) + NOTICE([$note=SSL_Weak_Key, + $msg=fmt("Host uses weak certificate with %d bit key", key_length), + $conn=c, $suppress_for=1day, + $identifier=cat(c$id$orig_h, c$id$orig_p, key_length) + ]); + } + +event ssl_dh_server_params(c: connection, p: string, q: string, Ys: string) &priority=3 + { + if ( ! addr_matches_host(c$id$resp_h, notify_weak_keys) ) + return; + + local key_length = |Ys|*8; # key length in bits + if ( key_length < notify_minimal_key_length ) + NOTICE([$note=SSL_Weak_Key, + $msg=fmt("Host uses weak DH parameters with %d key bits", key_length), + $conn=c, $suppress_for=1day, + $identifier=cat(c$id$orig_h, c$id$orig_p, key_length) + ]); + + if ( notify_dh_length_shorter_cert_length && + c?$ssl && c$ssl?$cert_chain && |c$ssl$cert_chain| > 0 && c$ssl$cert_chain[0]?$x509 && + c$ssl$cert_chain[0]$x509?$certificate && c$ssl$cert_chain[0]$x509$certificate?$key_type && + ( c$ssl$cert_chain[0]$x509$certificate$key_type == "rsa" || + c$ssl$cert_chain[0]$x509$certificate$key_type == "dsa" ) ) + { + if ( c$ssl$cert_chain[0]$x509$certificate?$key_length && + c$ssl$cert_chain[0]$x509$certificate$key_length > key_length ) + NOTICE([$note=SSL_Weak_Key, + $msg=fmt("DH key length of %d bits is smaller certificate key length of %d bits", + key_length, c$ssl$cert_chain[0]$x509$certificate$key_length), + $conn=c, $suppress_for=1day, + $identifier=cat(c$id$orig_h, c$id$orig_p) + ]); + } + } diff --git a/scripts/test-all-policy.bro b/scripts/test-all-policy.bro index 5c6ed286fb..43dc6b9dce 100644 --- a/scripts/test-all-policy.bro +++ b/scripts/test-all-policy.bro @@ -90,6 +90,7 @@ @load protocols/ssl/log-hostcerts-only.bro #@load protocols/ssl/notary.bro @load protocols/ssl/validate-certs.bro +@load protocols/ssl/weak-keys.bro @load tuning/__load__.bro @load tuning/defaults/__load__.bro @load tuning/defaults/extracted_file_limits.bro diff --git a/src/analyzer/protocol/ssl/events.bif b/src/analyzer/protocol/ssl/events.bif index 54bb0715d2..46747ecb58 100644 --- a/src/analyzer/protocol/ssl/events.bif +++ b/src/analyzer/protocol/ssl/events.bif @@ -59,6 +59,7 @@ event ssl_client_hello%(c: connection, version: count, possible_ts: time, client ## ## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_extension ## ssl_session_ticket_handshake x509_certificate ssl_server_curve +## ssl_dh_server_params event ssl_server_hello%(c: connection, version: count, possible_ts: time, server_random: string, session_id: string, cipher: count, comp_method: count%); ## Generated for SSL/TLS extensions seen in an initial handshake. SSL/TLS @@ -117,7 +118,7 @@ event ssl_extension_elliptic_curves%(c: connection, is_orig: bool, curves: index ## ssl_extension_server_name ssl_server_curve event ssl_extension_ec_point_formats%(c: connection, is_orig: bool, point_formats: index_vec%); -## Generated a named curve is chosen by the server for the SSL/TLS connection. The +## Generated if a named curve is chosen by the server for the SSL/TLS connection. The ## curve is sent by the server in the ServerKeyExchange message as defined in ## :rfc:`4492`, in case an ECDH or ECDHE cipher suite is chosen. ## @@ -131,6 +132,22 @@ event ssl_extension_ec_point_formats%(c: connection, is_orig: bool, point_format ## ssl_extension_server_name event ssl_server_curve%(c: connection, curve: count%); +## Generated if a server uses a DH-anon or DHE cipher suite. This event contains +## the server DH parameters, which are sent in the ServerKeyExchange message as +## defined in :rfc:`5246`. +## +## c: The connection. +## +## p: The DH prime modulus. +## +## q: The DH generator. +## +## Ys: The server's DH public key. +## +## .. bro:see:: ssl_alert ssl_client_hello ssl_established ssl_server_hello +## ssl_session_ticket_handshake ssl_server_curve +event ssl_dh_server_params%(c: connection, p: string, q: string, Ys: string%); + ## Generated for an SSL/TLS Application-Layer Protocol Negotiation extension. ## This TLS extension is defined in draft-ietf-tls-applayerprotoneg and sent in ## the initial handshake. It contains the list of client supported application diff --git a/src/analyzer/protocol/ssl/ssl-analyzer.pac b/src/analyzer/protocol/ssl/ssl-analyzer.pac index 071edf2eac..ef1d862b87 100644 --- a/src/analyzer/protocol/ssl/ssl-analyzer.pac +++ b/src/analyzer/protocol/ssl/ssl-analyzer.pac @@ -409,6 +409,19 @@ refine connection SSL_Conn += { return true; %} + + function proc_dh_server_key_exchange(rec: SSLRecord, p: bytestring, g: bytestring, Ys: bytestring) : bool + %{ + BifEvent::generate_ssl_dh_server_params(bro_analyzer(), + bro_analyzer()->Conn(), + new StringVal(p.length(), (const char*) p.data()), + new StringVal(g.length(), (const char*) g.data()), + new StringVal(Ys.length(), (const char*) Ys.data()) + ); + + return true; + %} + }; refine typeattr Alert += &let { @@ -501,3 +514,7 @@ refine typeattr CertificateStatus += &let { refine typeattr EcServerKeyExchange += &let { proc : bool = $context.connection.proc_ec_server_key_exchange(rec, curve_type, curve); }; + +refine typeattr DhServerKeyExchange += &let { + proc : bool = $context.connection.proc_dh_server_key_exchange(rec, dh_p, dh_g, dh_Ys); +}; diff --git a/src/analyzer/protocol/ssl/ssl-protocol.pac b/src/analyzer/protocol/ssl/ssl-protocol.pac index e19fdb6aac..840aca4b84 100644 --- a/src/analyzer/protocol/ssl/ssl-protocol.pac +++ b/src/analyzer/protocol/ssl/ssl-protocol.pac @@ -356,8 +356,9 @@ type CertificateStatus(rec: SSLRecord) = record { # Usually, the server key exchange does not contain any information # that we are interested in. # -# The one exception is when we are using an elliptic curve cipher suite. -# In this case, we can extract the final chosen cipher from here. +# The exception is when we are using an ECDHE, DHE or DH-Anon suite. +# In this case, we can extract information about the chosen cipher from +# here. type ServerKeyExchange(rec: SSLRecord) = case $context.connection.chosen_cipher() of { TLS_ECDH_ECDSA_WITH_NULL_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, @@ -453,6 +454,109 @@ type ServerKeyExchange(rec: SSLRecord) = case $context.connection.chosen_cipher( TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 -> ec_server_key_exchange : EcServerKeyExchange(rec); + # DHE suites + TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, + TLS_DHE_DSS_WITH_DES_CBC_SHA, + TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, + TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, + TLS_DHE_RSA_WITH_DES_CBC_SHA, + TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, + TLS_DHE_DSS_WITH_AES_128_CBC_SHA, + TLS_DHE_RSA_WITH_AES_128_CBC_SHA, + TLS_DHE_DSS_WITH_AES_256_CBC_SHA, + TLS_DHE_RSA_WITH_AES_256_CBC_SHA, + TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, + TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, + TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, + TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA, + TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA, + TLS_DHE_DSS_WITH_RC4_128_SHA, + TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, + TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, + TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, + TLS_DHE_DSS_WITH_3DES_EDE_CBC_RMD, + TLS_DHE_DSS_WITH_AES_128_CBC_RMD, + TLS_DHE_DSS_WITH_AES_256_CBC_RMD, + TLS_DHE_RSA_WITH_3DES_EDE_CBC_RMD, + TLS_DHE_RSA_WITH_AES_128_CBC_RMD, + TLS_DHE_RSA_WITH_AES_256_CBC_RMD, + TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, + TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, + TLS_DHE_PSK_WITH_RC4_128_SHA, + TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, + TLS_DHE_PSK_WITH_AES_128_CBC_SHA, + TLS_DHE_PSK_WITH_AES_256_CBC_SHA, + TLS_DHE_DSS_WITH_SEED_CBC_SHA, + TLS_DHE_RSA_WITH_SEED_CBC_SHA, + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, + TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, + TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, + TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, + TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, + TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, + TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, + TLS_DHE_PSK_WITH_NULL_SHA256, + TLS_DHE_PSK_WITH_NULL_SHA384, + TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256, + TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, + TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256, + TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, + TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256, + TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384, + TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256, + TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384, + TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256, + TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384, + TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256, + TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384, + TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256, + TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384, + TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256, + TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384, + TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, + TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, + TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256, + TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384, + TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256, + TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384, + TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, + TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, + TLS_DHE_RSA_WITH_AES_128_CCM, + TLS_DHE_RSA_WITH_AES_256_CCM, + TLS_DHE_RSA_WITH_AES_128_CCM_8, + TLS_DHE_RSA_WITH_AES_256_CCM_8, + TLS_DHE_PSK_WITH_AES_128_CCM, + TLS_DHE_PSK_WITH_AES_256_CCM, + TLS_PSK_DHE_WITH_AES_128_CCM_8, + TLS_PSK_DHE_WITH_AES_256_CCM_8, + TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + # DH-anon suites + TLS_DH_ANON_EXPORT_WITH_RC4_40_MD5, + TLS_DH_ANON_WITH_RC4_128_MD5, + TLS_DH_ANON_EXPORT_WITH_DES40_CBC_SHA, + TLS_DH_ANON_WITH_DES_CBC_SHA, + TLS_DH_ANON_WITH_3DES_EDE_CBC_SHA, + TLS_DH_ANON_WITH_AES_128_CBC_SHA, + TLS_DH_ANON_WITH_AES_256_CBC_SHA, + TLS_DH_ANON_WITH_CAMELLIA_128_CBC_SHA, + TLS_DH_ANON_WITH_AES_128_CBC_SHA256, + TLS_DH_ANON_WITH_AES_256_CBC_SHA256, + TLS_DH_ANON_WITH_CAMELLIA_256_CBC_SHA, + TLS_DH_ANON_WITH_SEED_CBC_SHA, + TLS_DH_ANON_WITH_AES_128_GCM_SHA256, + TLS_DH_ANON_WITH_AES_256_GCM_SHA384, + TLS_DH_ANON_WITH_CAMELLIA_128_CBC_SHA256, + TLS_DH_ANON_WITH_CAMELLIA_256_CBC_SHA256, + TLS_DH_ANON_WITH_ARIA_128_CBC_SHA256, + TLS_DH_ANON_WITH_ARIA_256_CBC_SHA384, + TLS_DH_ANON_WITH_ARIA_128_GCM_SHA256, + TLS_DH_ANON_WITH_ARIA_256_GCM_SHA384, + TLS_DH_ANON_WITH_CAMELLIA_128_GCM_SHA256, + TLS_DH_ANON_WITH_CAMELLIA_256_GCM_SHA384 + # DH non-anon suites do not send a ServerKeyExchange + -> dh_server_key_exchange : DhServerKeyExchange(rec); + default -> key : bytestring &restofdata &transient; }; @@ -466,6 +570,19 @@ type EcServerKeyExchange(rec: SSLRecord) = record { data: bytestring &restofdata &transient; }; +# For both, dh_anon and dhe the ServerKeyExchange starts with a ServerDHParams +# structure. After that, they start to differ, but we do not care about that. +type DhServerKeyExchange(rec: SSLRecord) = record { + dh_p_length: uint16; + dh_p: bytestring &length=dh_p_length; + dh_g_length: uint16; + dh_g: bytestring &length=dh_g_length; + dh_Ys_length: uint16; + dh_Ys: bytestring &length=dh_Ys_length; + data: bytestring &restofdata &transient; +}; + + ###################################################################### # V3 Certificate Request (7.4.4.) ###################################################################### diff --git a/testing/btest/Baseline/scripts.base.protocols.ssl.dhe/.stdout b/testing/btest/Baseline/scripts.base.protocols.ssl.dhe/.stdout new file mode 100644 index 0000000000..c2cc676ec1 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ssl.dhe/.stdout @@ -0,0 +1 @@ +key length in bits, 1024 diff --git a/testing/btest/Baseline/scripts.base.protocols.ssl.dhe/ssl.log b/testing/btest/Baseline/scripts.base.protocols.ssl.dhe/ssl.log new file mode 100644 index 0000000000..652f3b3df7 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.ssl.dhe/ssl.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path ssl +#open 2014-04-27-00-52-03 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name session_id last_alert established cert_chain_fuids client_cert_chain_fuids subject issuer client_subject client_issuer +#types time string addr port addr port string string string string string string bool vector[string] vector[string] string string string string +1398558136.319509 CXWv6p3arKYeMETxOg 192.168.18.50 62277 162.219.2.166 443 TLSv12 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA - - - - T F6fLv13PBYz8MNqx68,F8cTDl1penwXxGu4K7 (empty) emailAddress=denicadmmail@arcor.de,CN=www.lilawelt.net,C=US CN=StartCom Class 1 Primary Intermediate Server CA,OU=Secure Digital Certificate Signing,O=StartCom Ltd.,C=IL - - +#close 2014-04-27-00-52-03 diff --git a/testing/btest/Baseline/scripts.policy.protocols.ssl.known-certs/ssl.log b/testing/btest/Baseline/scripts.policy.protocols.ssl.known-certs/ssl.log index da805fd35d..b09bd04350 100644 --- a/testing/btest/Baseline/scripts.policy.protocols.ssl.known-certs/ssl.log +++ b/testing/btest/Baseline/scripts.policy.protocols.ssl.known-certs/ssl.log @@ -3,9 +3,9 @@ #empty_field (empty) #unset_field - #path ssl -#open 2014-04-26-16-45-23 +#open 2014-04-27-06-48-05 #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p version cipher curve server_name session_id last_alert established cert_chain_fuids client_cert_chain_fuids subject issuer client_subject client_issuer #types time string addr port addr port string string string string string string bool vector[string] vector[string] string string string string -1394747126.855035 CXWv6p3arKYeMETxOg 192.168.4.149 60623 74.125.239.129 443 TLSv12 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - - - - T FlaIzV19yTmBYwWwc6,F0BeiV3cMsGkNML0P2,F6PfYi2WUoPdIJrhpg (empty) CN=*.google.com,O=Google Inc,L=Mountain View,ST=California,C=US CN=Google Internet Authority G2,O=Google Inc,C=US - - -1394747129.505622 CjhGID4nQcgTWjvg4c 192.168.4.149 60624 74.125.239.129 443 TLSv12 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - - - - T FOye6a4kt8a7QChqw3,FytlLr3jOQenFAVtYi,FEmnxy4DGbxkmtQJS1 (empty) CN=*.google.com,O=Google Inc,L=Mountain View,ST=California,C=US CN=Google Internet Authority G2,O=Google Inc,C=US - - -#close 2014-04-26-16-45-23 +1394747126.855035 CXWv6p3arKYeMETxOg 192.168.4.149 60623 74.125.239.129 443 TLSv12 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 secp256r1 - - - T FlaIzV19yTmBYwWwc6,F0BeiV3cMsGkNML0P2,F6PfYi2WUoPdIJrhpg (empty) CN=*.google.com,O=Google Inc,L=Mountain View,ST=California,C=US CN=Google Internet Authority G2,O=Google Inc,C=US - - +1394747129.505622 CjhGID4nQcgTWjvg4c 192.168.4.149 60624 74.125.239.129 443 TLSv12 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 secp256r1 - - - T FOye6a4kt8a7QChqw3,FytlLr3jOQenFAVtYi,FEmnxy4DGbxkmtQJS1 (empty) CN=*.google.com,O=Google Inc,L=Mountain View,ST=California,C=US CN=Google Internet Authority G2,O=Google Inc,C=US - - +#close 2014-04-27-06-48-05 diff --git a/testing/btest/Baseline/scripts.policy.protocols.ssl.weak-keys/notice-1.log b/testing/btest/Baseline/scripts.policy.protocols.ssl.weak-keys/notice-1.log new file mode 100644 index 0000000000..a8784bd8c8 --- /dev/null +++ b/testing/btest/Baseline/scripts.policy.protocols.ssl.weak-keys/notice-1.log @@ -0,0 +1,12 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path notice +#open 2014-04-27-06-41-50 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p fuid file_mime_type file_desc proto note msg sub src dst p n peer_descr actions suppress_for dropped remote_location.country_code remote_location.region remote_location.city remote_location.latitude remote_location.longitude +#types time string addr port addr port string string string enum enum string string addr addr port count string set[enum] interval bool string string string double double +1398558136.430417 CXWv6p3arKYeMETxOg 192.168.18.50 62277 162.219.2.166 443 - - - tcp SSL::SSL_Weak_Key Host uses weak DH parameters with 1024 key bits - 192.168.18.50 162.219.2.166 443 - bro Notice::ACTION_LOG 86400.000000 F - - - - - +1398558136.430417 CXWv6p3arKYeMETxOg 192.168.18.50 62277 162.219.2.166 443 - - - tcp SSL::SSL_Weak_Key DH key length of 1024 bits is smaller certificate key length of 2048 bits - 192.168.18.50 162.219.2.166 443 - bro Notice::ACTION_LOG 86400.000000 F - - - - - +1398558136.542637 CXWv6p3arKYeMETxOg 192.168.18.50 62277 162.219.2.166 443 - - - tcp SSL::SSL_Weak_Key Host uses weak certificate with 2048 bit key - 192.168.18.50 162.219.2.166 443 - bro Notice::ACTION_LOG 86400.000000 F - - - - - +#close 2014-04-27-06-41-50 diff --git a/testing/btest/Traces/tls/dhe.pcap b/testing/btest/Traces/tls/dhe.pcap new file mode 100644 index 0000000000000000000000000000000000000000..d5e034ef849d9b23bd713a69d6bcb69600ac3560 GIT binary patch literal 6929 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 literal 0 HcmV?d00001 diff --git a/testing/btest/scripts/base/protocols/ssl/dhe.test b/testing/btest/scripts/base/protocols/ssl/dhe.test new file mode 100644 index 0000000000..f41cb70fab --- /dev/null +++ b/testing/btest/scripts/base/protocols/ssl/dhe.test @@ -0,0 +1,8 @@ +# @TEST-EXEC: bro -r $TRACES/tls/dhe.pcap %INPUT +# @TEST-EXEC: btest-diff .stdout +# @TEST-EXEC: btest-diff ssl.log + +event ssl_dh_server_params(c: connection, p: string, q: string, Ys: string) + { + print "key length in bits", |Ys|*8; + } diff --git a/testing/btest/scripts/policy/protocols/ssl/weak-keys.bro b/testing/btest/scripts/policy/protocols/ssl/weak-keys.bro new file mode 100644 index 0000000000..ba07b6e647 --- /dev/null +++ b/testing/btest/scripts/policy/protocols/ssl/weak-keys.bro @@ -0,0 +1,8 @@ +# @TEST-EXEC: bro -r $TRACES/tls/dhe.pcap %INPUT +# @TEST-EXEC: mv notice.log notice-1.log +# @TEST-EXEC: btest-diff notice-1.log + +@load protocols/ssl/weak-keys + +redef SSL::notify_weak_keys = ALL_HOSTS; +redef SSL::notify_minimal_key_length = 4096; From ef5b021e77c04bcb1921b39dbffa975fc9722a4c Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Sun, 27 Apr 2014 00:09:00 -0700 Subject: [PATCH 049/136] Polish changes for ecdhe/dhe --- scripts/policy/protocols/ssl/weak-keys.bro | 30 +++++++++---------- src/analyzer/protocol/ssl/ssl-defs.pac | 2 +- src/analyzer/protocol/ssl/ssl-protocol.pac | 4 +-- .../{notice-1.log => notice.log} | 10 +++---- .../policy/protocols/ssl/weak-keys.bro | 3 +- 5 files changed, 24 insertions(+), 25 deletions(-) rename testing/btest/Baseline/scripts.policy.protocols.ssl.weak-keys/{notice-1.log => notice.log} (55%) diff --git a/scripts/policy/protocols/ssl/weak-keys.bro b/scripts/policy/protocols/ssl/weak-keys.bro index 27cfb31554..f8a7b504b3 100644 --- a/scripts/policy/protocols/ssl/weak-keys.bro +++ b/scripts/policy/protocols/ssl/weak-keys.bro @@ -10,7 +10,7 @@ module SSL; export { redef enum Notice::Type += { ## Indicates that a server is using a potentially unsafe key. - SSL_Weak_Key, + Weak_Key, }; ## The category of hosts you would like to be notified about which have @@ -52,10 +52,10 @@ event ssl_established(c: connection) &priority=3 local key_length = cert$key_length; if ( key_length < notify_minimal_key_length ) - NOTICE([$note=SSL_Weak_Key, + NOTICE([$note=Weak_Key, $msg=fmt("Host uses weak certificate with %d bit key", key_length), - $conn=c, $suppress_for=1day, - $identifier=cat(c$id$orig_h, c$id$orig_p, key_length) + $conn=c, $suppress_for=1day, + $identifier=cat(c$id$orig_h, c$id$orig_p, key_length) ]); } @@ -66,25 +66,25 @@ event ssl_dh_server_params(c: connection, p: string, q: string, Ys: string) &pri local key_length = |Ys|*8; # key length in bits if ( key_length < notify_minimal_key_length ) - NOTICE([$note=SSL_Weak_Key, - $msg=fmt("Host uses weak DH parameters with %d key bits", key_length), - $conn=c, $suppress_for=1day, - $identifier=cat(c$id$orig_h, c$id$orig_p, key_length) + NOTICE([$note=Weak_Key, + $msg=fmt("Host uses weak DH parameters with %d key bits", key_length), + $conn=c, $suppress_for=1day, + $identifier=cat(c$id$orig_h, c$id$orig_p, key_length) ]); if ( notify_dh_length_shorter_cert_length && c?$ssl && c$ssl?$cert_chain && |c$ssl$cert_chain| > 0 && c$ssl$cert_chain[0]?$x509 && c$ssl$cert_chain[0]$x509?$certificate && c$ssl$cert_chain[0]$x509$certificate?$key_type && - ( c$ssl$cert_chain[0]$x509$certificate$key_type == "rsa" || - c$ssl$cert_chain[0]$x509$certificate$key_type == "dsa" ) ) + ( c$ssl$cert_chain[0]$x509$certificate$key_type == "rsa" || + c$ssl$cert_chain[0]$x509$certificate$key_type == "dsa" ) ) { if ( c$ssl$cert_chain[0]$x509$certificate?$key_length && c$ssl$cert_chain[0]$x509$certificate$key_length > key_length ) - NOTICE([$note=SSL_Weak_Key, - $msg=fmt("DH key length of %d bits is smaller certificate key length of %d bits", - key_length, c$ssl$cert_chain[0]$x509$certificate$key_length), - $conn=c, $suppress_for=1day, - $identifier=cat(c$id$orig_h, c$id$orig_p) + NOTICE([$note=Weak_Key, + $msg=fmt("DH key length of %d bits is smaller certificate key length of %d bits", + key_length, c$ssl$cert_chain[0]$x509$certificate$key_length), + $conn=c, $suppress_for=1day, + $identifier=cat(c$id$orig_h, c$id$orig_p) ]); } } diff --git a/src/analyzer/protocol/ssl/ssl-defs.pac b/src/analyzer/protocol/ssl/ssl-defs.pac index a4074443b9..29eb1d1fb9 100644 --- a/src/analyzer/protocol/ssl/ssl-defs.pac +++ b/src/analyzer/protocol/ssl/ssl-defs.pac @@ -62,7 +62,7 @@ enum SSLExtensions { }; enum ECCurveType { - EXPLICIT_PRIME = 1, + EXPLICIT_PRIME = 1, EXPLICIT_CHAR = 2, NAMED_CURVE = 3 }; diff --git a/src/analyzer/protocol/ssl/ssl-protocol.pac b/src/analyzer/protocol/ssl/ssl-protocol.pac index 840aca4b84..af220f39de 100644 --- a/src/analyzer/protocol/ssl/ssl-protocol.pac +++ b/src/analyzer/protocol/ssl/ssl-protocol.pac @@ -566,7 +566,7 @@ type ServerKeyExchange(rec: SSLRecord) = case $context.connection.chosen_cipher( # We also do not parse the actual signature data following the named curve. type EcServerKeyExchange(rec: SSLRecord) = record { curve_type: uint8; - curve: uint16; # only if curve_type = 3 + curve: uint16; # only if curve_type = 3 (NAMED_CURVE) data: bytestring &restofdata &transient; }; @@ -739,7 +739,7 @@ refine connection SSL_Conn += { function chosen_cipher() : int %{ return chosen_cipher_; %} - function set_cipher(cipher: int64) : bool + function set_cipher(cipher: uint32) : bool %{ chosen_cipher_ = cipher; return true; diff --git a/testing/btest/Baseline/scripts.policy.protocols.ssl.weak-keys/notice-1.log b/testing/btest/Baseline/scripts.policy.protocols.ssl.weak-keys/notice.log similarity index 55% rename from testing/btest/Baseline/scripts.policy.protocols.ssl.weak-keys/notice-1.log rename to testing/btest/Baseline/scripts.policy.protocols.ssl.weak-keys/notice.log index a8784bd8c8..b44fb54b70 100644 --- a/testing/btest/Baseline/scripts.policy.protocols.ssl.weak-keys/notice-1.log +++ b/testing/btest/Baseline/scripts.policy.protocols.ssl.weak-keys/notice.log @@ -3,10 +3,10 @@ #empty_field (empty) #unset_field - #path notice -#open 2014-04-27-06-41-50 +#open 2014-04-27-07-15-32 #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p fuid file_mime_type file_desc proto note msg sub src dst p n peer_descr actions suppress_for dropped remote_location.country_code remote_location.region remote_location.city remote_location.latitude remote_location.longitude #types time string addr port addr port string string string enum enum string string addr addr port count string set[enum] interval bool string string string double double -1398558136.430417 CXWv6p3arKYeMETxOg 192.168.18.50 62277 162.219.2.166 443 - - - tcp SSL::SSL_Weak_Key Host uses weak DH parameters with 1024 key bits - 192.168.18.50 162.219.2.166 443 - bro Notice::ACTION_LOG 86400.000000 F - - - - - -1398558136.430417 CXWv6p3arKYeMETxOg 192.168.18.50 62277 162.219.2.166 443 - - - tcp SSL::SSL_Weak_Key DH key length of 1024 bits is smaller certificate key length of 2048 bits - 192.168.18.50 162.219.2.166 443 - bro Notice::ACTION_LOG 86400.000000 F - - - - - -1398558136.542637 CXWv6p3arKYeMETxOg 192.168.18.50 62277 162.219.2.166 443 - - - tcp SSL::SSL_Weak_Key Host uses weak certificate with 2048 bit key - 192.168.18.50 162.219.2.166 443 - bro Notice::ACTION_LOG 86400.000000 F - - - - - -#close 2014-04-27-06-41-50 +1398558136.430417 CXWv6p3arKYeMETxOg 192.168.18.50 62277 162.219.2.166 443 - - - tcp SSL::Weak_Key Host uses weak DH parameters with 1024 key bits - 192.168.18.50 162.219.2.166 443 - bro Notice::ACTION_LOG 86400.000000 F - - - - - +1398558136.430417 CXWv6p3arKYeMETxOg 192.168.18.50 62277 162.219.2.166 443 - - - tcp SSL::Weak_Key DH key length of 1024 bits is smaller certificate key length of 2048 bits - 192.168.18.50 162.219.2.166 443 - bro Notice::ACTION_LOG 86400.000000 F - - - - - +1398558136.542637 CXWv6p3arKYeMETxOg 192.168.18.50 62277 162.219.2.166 443 - - - tcp SSL::Weak_Key Host uses weak certificate with 2048 bit key - 192.168.18.50 162.219.2.166 443 - bro Notice::ACTION_LOG 86400.000000 F - - - - - +#close 2014-04-27-07-15-32 diff --git a/testing/btest/scripts/policy/protocols/ssl/weak-keys.bro b/testing/btest/scripts/policy/protocols/ssl/weak-keys.bro index ba07b6e647..42ef2ecc16 100644 --- a/testing/btest/scripts/policy/protocols/ssl/weak-keys.bro +++ b/testing/btest/scripts/policy/protocols/ssl/weak-keys.bro @@ -1,6 +1,5 @@ # @TEST-EXEC: bro -r $TRACES/tls/dhe.pcap %INPUT -# @TEST-EXEC: mv notice.log notice-1.log -# @TEST-EXEC: btest-diff notice-1.log +# @TEST-EXEC: btest-diff notice.log @load protocols/ssl/weak-keys From 7d0e5067c76ce5f3719cb203a1b692f78b64eecf Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Sun, 27 Apr 2014 16:25:32 -0700 Subject: [PATCH 050/136] fix broxygen errors --- scripts/policy/protocols/ssl/weak-keys.bro | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/policy/protocols/ssl/weak-keys.bro b/scripts/policy/protocols/ssl/weak-keys.bro index f8a7b504b3..a6f96bfd53 100644 --- a/scripts/policy/protocols/ssl/weak-keys.bro +++ b/scripts/policy/protocols/ssl/weak-keys.bro @@ -32,9 +32,9 @@ export { const notify_dh_length_shorter_cert_length = T &redef; } -## We check key lengths only for DSA or RSA certificates. For others, we do -## not know what is safe (e.g. EC is safe even with very short key lengths). - +# We check key lengths only for DSA or RSA certificates. For others, we do +# not know what is safe (e.g. EC is safe even with very short key lengths). +# event ssl_established(c: connection) &priority=3 { # If there are no certificates or we are not interested in the server, just return. From 4b059ea15ac6bba0c5189532bc1c749ec066b1c6 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 29 Apr 2014 12:44:53 -0500 Subject: [PATCH 051/136] Improve file analysis manager shutdown/cleanup. file_analysis::Manager's dtor now doesn't assume any more analysis progress can be made because too many of Bro's other subsystems are shutdown by that point. Any file analysis requests made after Terminate cannot be reliably processed. --- src/file_analysis/Manager.cc | 22 +++++++++++++++++++++- src/main.cc | 2 +- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/file_analysis/Manager.cc b/src/file_analysis/Manager.cc index 3f04ebfc2b..393dadfdc7 100644 --- a/src/file_analysis/Manager.cc +++ b/src/file_analysis/Manager.cc @@ -27,7 +27,22 @@ Manager::Manager() Manager::~Manager() { - Terminate(); + // Have to assume that too much of Bro has been shutdown by this point + // to do anything more than reclaim memory. + + File* f; + bool* b; + + IterCookie* it = id_map.InitForIteration(); + + while ( (f = id_map.NextEntry(it)) ) + delete f; + + it = ignored.InitForIteration(); + + while( (b = ignored.NextEntry(it)) ) + delete b; + delete magic_state; } @@ -58,10 +73,15 @@ void Manager::Terminate() HashKey* key; while ( id_map.NextEntry(key, it) ) + { keys.push_back(static_cast(key->Key())); + delete key; + } for ( size_t i = 0; i < keys.size(); ++i ) Timeout(keys[i], true); + + mgr.Drain(); } string Manager::HashHandle(const string& handle) const diff --git a/src/main.cc b/src/main.cc index cf1f82b1eb..10b66083a8 100644 --- a/src/main.cc +++ b/src/main.cc @@ -379,10 +379,10 @@ void terminate_bro() delete secondary_path; delete remote_serializer; delete analyzer_mgr; + delete file_mgr; delete log_mgr; delete plugin_mgr; delete thread_mgr; - delete file_mgr; delete reporter; reporter = 0; From d7d5497436f8b3bf6101adca4e1d2aa2c1113aa0 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 29 Apr 2014 15:26:19 -0500 Subject: [PATCH 052/136] Improve/standardize some malloc/realloc return val checks. --- src/file_analysis/analyzer/x509/X509.cc | 4 ++++ src/file_analysis/analyzer/x509/functions.bif | 4 ++++ src/logging/Manager.cc | 10 ++++++---- src/threading/BasicThread.cc | 2 +- src/util.cc | 4 ++-- 5 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/file_analysis/analyzer/x509/X509.cc b/src/file_analysis/analyzer/x509/X509.cc index 86f13f8760..c036fca7ed 100644 --- a/src/file_analysis/analyzer/x509/X509.cc +++ b/src/file_analysis/analyzer/x509/X509.cc @@ -184,6 +184,10 @@ void file_analysis::X509::ParseExtension(X509_EXTENSION* ex) // Use OPENSSL_malloc here. Using new or anything else can lead // to interesting, hard to debug segfaults. char *buffer = (char*) OPENSSL_malloc(length); + + if ( ! buffer ) + out_of_memory("X509::ParseExtension"); + BIO_read(bio, (void*)buffer, length); StringVal* ext_val = new StringVal(length, buffer); OPENSSL_free(buffer); diff --git a/src/file_analysis/analyzer/x509/functions.bif b/src/file_analysis/analyzer/x509/functions.bif index 00042d860a..e6ed138c74 100644 --- a/src/file_analysis/analyzer/x509/functions.bif +++ b/src/file_analysis/analyzer/x509/functions.bif @@ -82,6 +82,10 @@ function x509_get_certificate_string%(cert: opaque of x509, pem: bool &default=F int length = BIO_pending(bio); // use OPENSS_malloc here. Otherwhise, interesting problems will happen. char *buffer = (char*) OPENSSL_malloc(length); + + if ( ! buffer ) + out_of_memory("x509_get_certificate_string"); + BIO_read(bio, (void*) buffer, length); StringVal* ext_val = new StringVal(length, buffer); OPENSSL_free(buffer); diff --git a/src/logging/Manager.cc b/src/logging/Manager.cc index 8d833ddbc6..55e0fddb5a 100644 --- a/src/logging/Manager.cc +++ b/src/logging/Manager.cc @@ -537,17 +537,19 @@ bool Manager::TraverseRecord(Stream* stream, Filter* filter, RecordType* rt, filter->indices.push_back(new_indices); - filter->fields = (threading::Field**) + void* tmp = realloc(filter->fields, - sizeof(threading::Field*) * ++filter->num_fields); + sizeof(threading::Field*) * (filter->num_fields + 1)); - if ( ! filter->fields ) + if ( ! tmp ) { - --filter->num_fields; reporter->Error("out of memory in add_filter"); return false; } + ++filter->num_fields; + filter->fields = (threading::Field**) tmp; + TypeTag st = TYPE_VOID; if ( t->Tag() == TYPE_TABLE ) diff --git a/src/threading/BasicThread.cc b/src/threading/BasicThread.cc index 7f5dbfc56b..ffee21bc16 100644 --- a/src/threading/BasicThread.cc +++ b/src/threading/BasicThread.cc @@ -24,7 +24,7 @@ BasicThread::BasicThread() pthread = 0; buf_len = STD_FMT_BUF_LEN; - buf = (char*) malloc(buf_len); + buf = (char*) safe_malloc(buf_len); strerr_buffer = 0; diff --git a/src/util.cc b/src/util.cc index 6190067aa6..f5bbe9cf96 100644 --- a/src/util.cc +++ b/src/util.cc @@ -568,7 +568,7 @@ const char* fmt(const char* format, ...) static unsigned int buf_len = 1024; if ( ! buf ) - buf = (char*) malloc(buf_len); + buf = (char*) safe_malloc(buf_len); va_list al; va_start(al, format); @@ -578,7 +578,7 @@ const char* fmt(const char* format, ...) if ( (unsigned int) n >= buf_len ) { // Not enough room, grow the buffer. buf_len = n + 32; - buf = (char*) realloc(buf, buf_len); + buf = (char*) safe_realloc(buf, buf_len); // Is it portable to restart? va_start(al, format); From 636262d86591251e08110074074b04331854bef9 Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Wed, 30 Apr 2014 12:35:09 -0700 Subject: [PATCH 053/136] Correct a notice for heartbleed. The notice is thrown correctly, just the message conteined wrong values. --- scripts/policy/protocols/ssl/heartbleed.bro | 2 +- .../notice-encrypted.log | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/policy/protocols/ssl/heartbleed.bro b/scripts/policy/protocols/ssl/heartbleed.bro index c4842d6a0a..543430e156 100644 --- a/scripts/policy/protocols/ssl/heartbleed.bro +++ b/scripts/policy/protocols/ssl/heartbleed.bro @@ -106,7 +106,7 @@ event ssl_encrypted_heartbeat(c: connection, is_orig: bool, length: count) { NOTICE([$note=SSL_Heartbeat_Attack_Success, $msg=fmt("An Encrypted TLS heartbleed attack was probably detected! First packet client record length %d, first packet server record length %d", - c$ssl?$last_originator_heartbeat_request_size, c$ssl$last_originator_heartbeat_request_size), + c$ssl$last_originator_heartbeat_request_size, length), $conn=c, $identifier=c$uid # only throw once per connection ]); diff --git a/testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-encrypted.log b/testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-encrypted.log index 863d8dd9c0..dfe9dcec74 100644 --- a/testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-encrypted.log +++ b/testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-encrypted.log @@ -3,8 +3,8 @@ #empty_field (empty) #unset_field - #path notice -#open 2014-04-24-19-05-00 +#open 2014-04-30-19-34-39 #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p fuid file_mime_type file_desc proto note msg sub src dst p n peer_descr actions suppress_for dropped remote_location.country_code remote_location.region remote_location.city remote_location.latitude remote_location.longitude #types time string addr port addr port string string string enum enum string string addr addr port count string set[enum] interval bool string string string double double -1397169549.895057 CXWv6p3arKYeMETxOg 192.168.4.149 59676 107.170.241.107 443 - - - tcp Heartbleed::SSL_Heartbeat_Attack_Success An Encrypted TLS heartbleed attack was probably detected! First packet client record length 1, first packet server record length 32 - 192.168.4.149 107.170.241.107 443 - bro Notice::ACTION_LOG 3600.000000 F - - - - - -#close 2014-04-24-19-05-00 +1397169549.895057 CXWv6p3arKYeMETxOg 192.168.4.149 59676 107.170.241.107 443 - - - tcp Heartbleed::SSL_Heartbeat_Attack_Success An Encrypted TLS heartbleed attack was probably detected! First packet client record length 32, first packet server record length 16416 - 192.168.4.149 107.170.241.107 443 - bro Notice::ACTION_LOG 3600.000000 F - - - - - +#close 2014-04-30-19-34-39 From 385438d47c6ca263f664fe85fc41584ff4ade085 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Thu, 1 May 2014 13:04:34 -0500 Subject: [PATCH 054/136] Change X509 extension value parsing to not abort on malloc failures. Also comes with factoring that out in to it's own function and additional error check before using a return value from BIO_pending. --- src/file_analysis/analyzer/x509/X509.cc | 59 +++++++++++++++---- src/file_analysis/analyzer/x509/X509.h | 8 +++ src/file_analysis/analyzer/x509/functions.bif | 14 +---- 3 files changed, 57 insertions(+), 24 deletions(-) diff --git a/src/file_analysis/analyzer/x509/X509.cc b/src/file_analysis/analyzer/x509/X509.cc index c036fca7ed..162e154df9 100644 --- a/src/file_analysis/analyzer/x509/X509.cc +++ b/src/file_analysis/analyzer/x509/X509.cc @@ -159,6 +159,49 @@ RecordVal* file_analysis::X509::ParseCertificate(X509Val* cert_val) return pX509Cert; } +StringVal* file_analysis::X509::GetExtensionFromBIO(BIO* bio) + { + BIO_flush(bio); + ERR_clear_error(); + int length = BIO_pending(bio); + + if ( ERR_peek_error() != 0 ) + { + char tmp[120]; + ERR_error_string(ERR_get_error(), tmp); + reporter->Error("X509::GetExtensionFromBIO: %s", tmp); + BIO_free_all(bio); + return 0; + } + + if ( length == 0 ) + { + BIO_free_all(bio); + return new StringVal(""); + } + + // TODO: see about using regular malloc here, there were unknown problems + // using anything other than OPENSSL_malloc that need investigation. + char* buffer = (char*) OPENSSL_malloc(length); + + if ( ! buffer ) + { + // Just emit an error here and try to continue instead of aborting + // because it's unclear the length value is very reliable. + reporter->Error("X509::GetExtensionFromBIO malloc(%d) failed", length); + BIO_free_all(bio); + return 0; + } + + BIO_read(bio, (void*) buffer, length); + StringVal* ext_val = new StringVal(length, buffer); + + OPENSSL_free(buffer); + BIO_free_all(bio); + + return ext_val; + } + void file_analysis::X509::ParseExtension(X509_EXTENSION* ex) { char name[256]; @@ -178,20 +221,10 @@ void file_analysis::X509::ParseExtension(X509_EXTENSION* ex) if( ! X509V3_EXT_print(bio, ex, 0, 0)) M_ASN1_OCTET_STRING_print(bio,ex->value); - BIO_flush(bio); - int length = BIO_pending(bio); + StringVal* ext_val = GetExtensionFromBIO(bio); - // Use OPENSSL_malloc here. Using new or anything else can lead - // to interesting, hard to debug segfaults. - char *buffer = (char*) OPENSSL_malloc(length); - - if ( ! buffer ) - out_of_memory("X509::ParseExtension"); - - BIO_read(bio, (void*)buffer, length); - StringVal* ext_val = new StringVal(length, buffer); - OPENSSL_free(buffer); - BIO_free_all(bio); + if ( ! ext_val ) + ext_val = new StringVal(0, ""); RecordVal* pX509Ext = new RecordVal(BifType::Record::X509::Extension); pX509Ext->Assign(0, new StringVal(name)); diff --git a/src/file_analysis/analyzer/x509/X509.h b/src/file_analysis/analyzer/x509/X509.h index 8667d870b1..6a3e6393a3 100644 --- a/src/file_analysis/analyzer/x509/X509.h +++ b/src/file_analysis/analyzer/x509/X509.h @@ -37,6 +37,14 @@ public: static file_analysis::Analyzer* Instantiate(RecordVal* args, File* file) { return new X509(args, file); } + /** + * Retrieve an X509 extension value from an OpenSSL BIO to which it was + * written. + * @param bio the OpenSSL BIO to read. + * @return The X509 extension value. + */ + static StringVal* GetExtensionFromBIO(BIO* bio); + protected: X509(RecordVal* args, File* file); diff --git a/src/file_analysis/analyzer/x509/functions.bif b/src/file_analysis/analyzer/x509/functions.bif index e6ed138c74..176df53bdb 100644 --- a/src/file_analysis/analyzer/x509/functions.bif +++ b/src/file_analysis/analyzer/x509/functions.bif @@ -78,18 +78,10 @@ function x509_get_certificate_string%(cert: opaque of x509, pem: bool &default=F else i2d_X509_bio(bio, h->GetCertificate()); - BIO_flush(bio); - int length = BIO_pending(bio); - // use OPENSS_malloc here. Otherwhise, interesting problems will happen. - char *buffer = (char*) OPENSSL_malloc(length); + StringVal* ext_val = file_analysis::X509::GetExtensionFromBIO(bio); - if ( ! buffer ) - out_of_memory("x509_get_certificate_string"); - - BIO_read(bio, (void*) buffer, length); - StringVal* ext_val = new StringVal(length, buffer); - OPENSSL_free(buffer); - BIO_free_all(bio); + if ( ! ext_val ) + ext_val = new StringVal(""); return ext_val; %} From 5b9d190f2c3b7a7c91d877aa98044c59cce16385 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Thu, 1 May 2014 14:08:07 -0500 Subject: [PATCH 055/136] Fix missing "irc-dcc-data" service field from IRC DCC connections. --- scripts/base/protocols/irc/dcc-send.bro | 2 +- .../scripts.base.protocols.irc.basic/conn.log | 11 +++++++++++ testing/btest/scripts/base/protocols/irc/basic.test | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 testing/btest/Baseline/scripts.base.protocols.irc.basic/conn.log diff --git a/scripts/base/protocols/irc/dcc-send.bro b/scripts/base/protocols/irc/dcc-send.bro index d95eb97517..437724004a 100644 --- a/scripts/base/protocols/irc/dcc-send.bro +++ b/scripts/base/protocols/irc/dcc-send.bro @@ -76,7 +76,7 @@ event irc_dcc_message(c: connection, is_orig: bool, dcc_expected_transfers[address, p] = c$irc; } -event expected_connection_seen(c: connection, a: Analyzer::Tag) &priority=10 +event scheduled_analyzer_applied(c: connection, a: Analyzer::Tag) &priority=10 { local id = c$id; if ( [id$resp_h, id$resp_p] in dcc_expected_transfers ) diff --git a/testing/btest/Baseline/scripts.base.protocols.irc.basic/conn.log b/testing/btest/Baseline/scripts.base.protocols.irc.basic/conn.log new file mode 100644 index 0000000000..411e57f8ee --- /dev/null +++ b/testing/btest/Baseline/scripts.base.protocols.irc.basic/conn.log @@ -0,0 +1,11 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open 2014-05-01-19-07-07 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string bool count string count count count count set[string] +1311189318.898709 CjhGID4nQcgTWjvg4c 192.168.1.77 57655 209.197.168.151 1024 tcp irc-dcc-data 2.256935 124 42208 SF - 0 ShAdDaFf 28 1592 43 44452 (empty) +1311189164.064603 CXWv6p3arKYeMETxOg 192.168.1.77 57640 66.198.80.67 6667 tcp irc 178.237017 453 25404 S3 - 0 ShADdaf 63 3761 52 28194 (empty) +#close 2014-05-01-19-07-07 diff --git a/testing/btest/scripts/base/protocols/irc/basic.test b/testing/btest/scripts/base/protocols/irc/basic.test index 32358d12a4..618f4d9079 100644 --- a/testing/btest/scripts/base/protocols/irc/basic.test +++ b/testing/btest/scripts/base/protocols/irc/basic.test @@ -3,6 +3,7 @@ # @TEST-EXEC: bro -r $TRACES/irc-dcc-send.trace %INPUT # @TEST-EXEC: btest-diff irc.log +# @TEST-EXEC: btest-diff conn.log # dcc mime types are irrelevant to this test, so filter it out event bro_init() From 8b7d5a68b2e774aa83056889d6ed6814e8d6b1ec Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Thu, 1 May 2014 15:00:03 -0500 Subject: [PATCH 056/136] Fix reference counting for lookup_ID() usages. That function refs the ID before returning it, but callers were never assuming responsibility for that reference. --- src/Debug.cc | 6 ++++++ src/EventHandler.cc | 5 ++++- src/Func.cc | 1 + src/RuleMatcher.cc | 5 ++++- src/Type.cc | 1 + src/Var.cc | 20 ++++++++++++++++---- src/scan.l | 12 ++++++++++-- 7 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/Debug.cc b/src/Debug.cc index 94b8abf952..09e8810edb 100644 --- a/src/Debug.cc +++ b/src/Debug.cc @@ -192,6 +192,7 @@ static void parse_function_name(vector& result, string fullname = make_full_var_name(current_module.c_str(), s.c_str()); debug_msg("Function %s not defined.\n", fullname.c_str()); plr.type = plrUnknown; + Unref(id); return; } @@ -199,6 +200,7 @@ static void parse_function_name(vector& result, { debug_msg("Function %s not declared.\n", id->Name()); plr.type = plrUnknown; + Unref(id); return; } @@ -206,6 +208,7 @@ static void parse_function_name(vector& result, { debug_msg("Function %s declared but not defined.\n", id->Name()); plr.type = plrUnknown; + Unref(id); return; } @@ -216,9 +219,12 @@ static void parse_function_name(vector& result, { debug_msg("Function %s is a built-in function\n", id->Name()); plr.type = plrUnknown; + Unref(id); return; } + Unref(id); + Stmt* body = 0; // the particular body we care about; 0 = all if ( bodies.size() == 1 ) diff --git a/src/EventHandler.cc b/src/EventHandler.cc index a5dc62148a..2f0a19ccc0 100644 --- a/src/EventHandler.cc +++ b/src/EventHandler.cc @@ -39,7 +39,10 @@ FuncType* EventHandler::FType() if ( id->Type()->Tag() != TYPE_FUNC ) return 0; - return type = id->Type()->AsFuncType(); + type = id->Type()->AsFuncType(); + Unref(id); + + return type; } void EventHandler::SetLocalHandler(Func* f) diff --git a/src/Func.cc b/src/Func.cc index 11749a8a9c..1f3ac6f93c 100644 --- a/src/Func.cc +++ b/src/Func.cc @@ -475,6 +475,7 @@ BuiltinFunc::BuiltinFunc(built_in_func arg_func, const char* arg_name, type = id->Type()->Ref(); id->SetVal(new Val(this)); + Unref(id); } BuiltinFunc::~BuiltinFunc() diff --git a/src/RuleMatcher.cc b/src/RuleMatcher.cc index 5cea843c8d..ca08388b10 100644 --- a/src/RuleMatcher.cc +++ b/src/RuleMatcher.cc @@ -1286,7 +1286,10 @@ static Val* get_bro_val(const char* label) return 0; } - return id->ID_Val(); + Val* rval = id->ID_Val(); + Unref(id); + + return rval; } diff --git a/src/Type.cc b/src/Type.cc index 672153d957..b840fa98e3 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -1449,6 +1449,7 @@ void EnumType::CheckAndAddName(const string& module_name, const char* name, } else { + Unref(id); reporter->Error("identifier or enumerator value in enumerated type definition already exists"); SetError(); return; diff --git a/src/Var.cc b/src/Var.cc index 52754e3265..a34a0142eb 100644 --- a/src/Var.cc +++ b/src/Var.cc @@ -385,6 +385,7 @@ void begin_func(ID* id, const char* module_name, function_flavor flavor, if ( arg_id && ! arg_id->IsGlobal() ) arg_id->Error("argument name used twice"); + Unref(arg_id); arg_id = install_ID(arg_i->id, module_name, false, false); arg_id->SetType(arg_i->type->Ref()); } @@ -442,10 +443,13 @@ void end_func(Stmt* body, attr_list* attrs) Val* internal_val(const char* name) { ID* id = lookup_ID(name, GLOBAL_MODULE_NAME); + if ( ! id ) reporter->InternalError("internal variable %s missing", name); - return id->ID_Val(); + Val* rval = id->ID_Val(); + Unref(id); + return rval; } Val* internal_const_val(const char* name) @@ -457,13 +461,17 @@ Val* internal_const_val(const char* name) if ( ! id->IsConst() ) reporter->InternalError("internal variable %s is not constant", name); - return id->ID_Val(); + Val* rval = id->ID_Val(); + Unref(id); + return rval; } Val* opt_internal_val(const char* name) { ID* id = lookup_ID(name, GLOBAL_MODULE_NAME); - return id ? id->ID_Val() : 0; + Val* rval = id ? id->ID_Val() : 0; + Unref(id); + return rval; } double opt_internal_double(const char* name) @@ -503,6 +511,8 @@ ListVal* internal_list_val(const char* name) return 0; Val* v = id->ID_Val(); + Unref(id); + if ( v ) { if ( v->Type()->Tag() == TYPE_LIST ) @@ -528,7 +538,9 @@ BroType* internal_type(const char* name) if ( ! id ) reporter->InternalError("internal type %s missing", name); - return id->Type(); + BroType* rval = id->Type(); + Unref(id); + return rval; } Func* internal_func(const char* name) diff --git a/src/scan.l b/src/scan.l index 18233fb58a..7de38cbfbc 100644 --- a/src/scan.l +++ b/src/scan.l @@ -606,22 +606,30 @@ void do_atifdef(const char* id) { ++current_depth; - if ( ! lookup_ID(id, current_module.c_str()) ) + ID* i; + + if ( ! (i = lookup_ID(id, current_module.c_str())) ) { if_stack.append(current_depth); BEGIN(IGNORE); } + + Unref(i); } void do_atifndef(const char *id) { ++current_depth; - if ( lookup_ID(id, current_module.c_str()) ) + ID* i; + + if ( (i = lookup_ID(id, current_module.c_str())) ) { if_stack.append(current_depth); BEGIN(IGNORE); } + + Unref(i); } void do_atelse() From 83a15886a732e34219f594ffd9539e3999f213e7 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Thu, 1 May 2014 20:45:35 -0700 Subject: [PATCH 057/136] Updating CHANGES and NEWS for earlier X509 updates. BIT-1150 #merged --- CHANGES | 15 +++++++++++++-- NEWS | 3 +++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index 631e781d9a..e7a1cc9bef 100644 --- a/CHANGES +++ b/CHANGES @@ -207,8 +207,19 @@ 2.2-294 | 2014-03-30 22:08:25 +0200 - * TODO: x509 changes. (Bernhard Amann) - + * Rework and move X509 certificate processing from the SSL protocol + analyzer to a dedicated file analyzer. This will allow us to + examine X509 certificates from sources other than SSL in the + future. Furthermore, Bro now parses more fields and extensions + from the certificates (e.g. elliptic curve information, subject + alternative names, basic constraints). Certificate validation also + was improved, should be easier to use and exposes information like + the full verified certificate chain. (Bernhard Amann) + + This update changes the format of ssl.log and adds a new x509.log + with certificate information. Furthermore all x509 events and + handling functions have changed. + 2.2-271 | 2014-03-30 20:25:17 +0200 * Add unit tests covering vector/set/table ctors/inits. (Jon Siwek) diff --git a/NEWS b/NEWS index 9de61a2dc4..ac12931819 100644 --- a/NEWS +++ b/NEWS @@ -62,6 +62,9 @@ Changed Functionality event x509_extension(c: connection, is_orig: bool, cert: X509, ext: X509_extension_info); +- Generally, all x509 events and handling functions have changed their + signatures. + - Bro no longer special-cases SYN/FIN/RST-filtered traces by not reporting missing data. The old behavior can be reverted by redef'ing "detect_filtered_trace". From bf9bddd4fc8dce1053e0ec7f021c00effd5dc814 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Thu, 1 May 2014 21:05:17 -0700 Subject: [PATCH 058/136] Updating submodule(s). [nomail] --- aux/broctl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aux/broctl b/aux/broctl index 5266f45a68..c44ec9c13d 160000 --- a/aux/broctl +++ b/aux/broctl @@ -1 +1 @@ -Subproject commit 5266f45a6839ea9b6f1825ba0fd448a721cb42be +Subproject commit c44ec9c13d87b8589d6f1549b9c523130fcc2a39 From 3905b6fc70fe2c1948efdaf04e7154d83756de42 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Fri, 2 May 2014 12:09:06 -0500 Subject: [PATCH 059/136] Clean up base SNMP script. Mostly docs, some logic refactors. --- CHANGES | 14 +++++ VERSION | 2 +- scripts/base/protocols/snmp/main.bro | 82 ++++++++++++++++------------ 3 files changed, 62 insertions(+), 36 deletions(-) diff --git a/CHANGES b/CHANGES index e7a1cc9bef..b49fa5239c 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,18 @@ +2.2-409 | 2014-05-02 12:09:06 -0500 + + * Clean up and documentation for base SNMP script. (Jon Siwek) + + * Update base SNMP script to now produce a snmp.log. (Seth Hall) + + * Add DH support to SSL analyzer. When using DHE or DH-Anon, sever + key parameters are now available in scriptland. Also add script to + alert on weak certificate keys or weak dh-params. (Bernhard Amann) + + * Add a few more ciphers Bro did not know at all so far. (Bernhard Amann) + + * Log chosen curve when using ec cipher suite in TLS. (Bernhard Amann) + 2.2-397 | 2014-05-01 20:29:20 -0700 * Fix reference counting for lookup_ID() usages. (Jon Siwek) diff --git a/VERSION b/VERSION index 720c163a49..12e210c885 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.2-397 +2.2-409 diff --git a/scripts/base/protocols/snmp/main.bro b/scripts/base/protocols/snmp/main.bro index 1c92e73ce0..4921794408 100644 --- a/scripts/base/protocols/snmp/main.bro +++ b/scripts/base/protocols/snmp/main.bro @@ -1,45 +1,68 @@ -##! Enables analysis of SNMP datagrams. +##! Enables analysis and logging of SNMP datagrams. module SNMP; export { redef enum Log::ID += { LOG }; + ## Information tracked per SNMP session. type Info: record { + ## Timestamp of first packet belonging to the SNMP session. ts: time &log; + ## The unique ID for the connection. uid: string &log; + ## The connection's 5-tuple of addresses/ports (ports inherently + ## include transport protocol information) id: conn_id &log; + ## The amount of time between the first packet beloning to + ## the SNMP session and the latest one seen. duration: interval &log &default=0secs; - + ## The version of SNMP being used. version: string &log; + ## The community string of the first SNMP packet associated with + ## the session. This is used as part of SNMP's (v1 and v2c) + ## administrative/security framework. See :rfc:`1157` or :rfc:`1901`. community: string &log &optional; + ## The number of variable bindings in GetRequest/GetNextRequest PDUs + ## seen for the session. get_requests: count &log &default=0; + ## The number of variable bindings in GetBulkRequest PDUs seen for + ## the session. get_bulk_requests: count &log &default=0; + ## The number of variable bindings in GetResponse/Response PDUs seen + ## for the session. get_responses: count &log &default=0; - + ## The number of variable bindings in SetRequest PDUs seen for + ## the session. set_requests: count &log &default=0; + ## A system description of the SNMP responder endpoint. display_string: string &log &optional; + ## The time at which the SNMP responder endpoint claims it's been + ## up since. up_since: time &log &optional; }; - redef record connection += { - snmp: SNMP::Info &optional; - }; + ## Maps an SNMP version integer to a human readable string. + const version_map: table[count] of string = { + [0] = "1", + [1] = "2c", + [3] = "3", + } &redef &default="unknown"; + ## Event that can be handled to access the SNMP record as it is sent on + ## to the logging framework. global log_snmp: event(rec: Info); } +redef record connection += { + snmp: SNMP::Info &optional; +}; + const ports = { 161/udp, 162/udp }; redef likely_server_ports += { ports }; -const version_map = { - [0] = "1", - [1] = "2c", - [3] = "3", -}; - event bro_init() &priority=5 { Analyzer::register_for_ports(Analyzer::ANALYZER_SNMP, ports); @@ -50,17 +73,18 @@ function init_state(c: connection, h: SNMP::Header): Info { if ( ! c?$snmp ) { - c$snmp = Info($ts=network_time(), + c$snmp = Info($ts=network_time(), $uid=c$uid, $id=c$id, $version=version_map[h$version]); } local s = c$snmp; + if ( ! s?$community ) { if ( h?$v1 ) s$community = h$v1$community; - if ( h?$v2 ) + else if ( h?$v2 ) s$community = h$v2$community; } @@ -78,39 +102,30 @@ event connection_state_remove(c: connection) &priority=-5 event snmp_get_request(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::PDU) &priority=5 { local s = init_state(c, header); - for ( i in pdu$bindings ) - { - ++s$get_requests; - } + s$get_requests += |pdu$bindings|; } event snmp_get_bulk_request(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::BulkPDU) &priority=5 { local s = init_state(c, header); - for ( i in pdu$bindings ) - { - ++s$get_bulk_requests; - } + s$get_bulk_requests += |pdu$bindings|; } event snmp_get_next_request(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::PDU) &priority=5 { local s = init_state(c, header); - for ( i in pdu$bindings ) - { - ++s$get_requests; - } + s$get_requests += |pdu$bindings|; } event snmp_response(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::PDU) &priority=5 { local s = init_state(c, header); + s$get_responses += |pdu$bindings|; for ( i in pdu$bindings ) { - ++s$get_responses; - local binding = pdu$bindings[i]; + if ( binding$oid == "1.3.6.1.2.1.1.1.0" && binding$value?$octets ) c$snmp$display_string = binding$value$octets; else if ( binding$oid == "1.3.6.1.2.1.1.3.0" && binding$value?$unsigned ) @@ -124,10 +139,7 @@ event snmp_response(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNM event snmp_set_request(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::PDU) &priority=5 { local s = init_state(c, header); - for ( i in pdu$bindings ) - { - ++s$set_requests; - } + s$set_requests += |pdu$bindings|; } event snmp_trap(c: connection, is_orig: bool, header: SNMP::Header, pdu: SNMP::TrapPDU) &priority=5 @@ -165,6 +177,6 @@ event snmp_encrypted_pdu(c: connection, is_orig: bool, header: SNMP::Header) &pr init_state(c, header); } -event snmp_unknown_header_version(c: connection, is_orig: bool, version: count) &priority=5 - { - } +#event snmp_unknown_header_version(c: connection, is_orig: bool, version: count) &priority=5 +# { +# } From b15bbf4f333662374e5316af0b70ecc149f8ec65 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Fri, 2 May 2014 12:49:53 -0500 Subject: [PATCH 060/136] Replace an unneeded OPENSSL_malloc call. --- CHANGES | 4 ++++ VERSION | 2 +- src/file_analysis/analyzer/x509/X509.cc | 6 ++---- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGES b/CHANGES index b49fa5239c..9bb4bf6a70 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,8 @@ +2.2-410 | 2014-05-02 12:49:53 -0500 + + * Replace an unneeded OPENSSL_malloc call. (Jon Siwek) + 2.2-409 | 2014-05-02 12:09:06 -0500 * Clean up and documentation for base SNMP script. (Jon Siwek) diff --git a/VERSION b/VERSION index 12e210c885..861e91890f 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.2-409 +2.2-410 diff --git a/src/file_analysis/analyzer/x509/X509.cc b/src/file_analysis/analyzer/x509/X509.cc index 3cd886657b..debe38deaa 100644 --- a/src/file_analysis/analyzer/x509/X509.cc +++ b/src/file_analysis/analyzer/x509/X509.cc @@ -180,9 +180,7 @@ StringVal* file_analysis::X509::GetExtensionFromBIO(BIO* bio) return new StringVal(""); } - // TODO: see about using regular malloc here, there were unknown problems - // using anything other than OPENSSL_malloc that need investigation. - char* buffer = (char*) OPENSSL_malloc(length); + char* buffer = (char*) malloc(length); if ( ! buffer ) { @@ -196,7 +194,7 @@ StringVal* file_analysis::X509::GetExtensionFromBIO(BIO* bio) BIO_read(bio, (void*) buffer, length); StringVal* ext_val = new StringVal(length, buffer); - OPENSSL_free(buffer); + free(buffer); BIO_free_all(bio); return ext_val; From 99b13d3cfdd18e6d7b1df5507a3441af027d194a Mon Sep 17 00:00:00 2001 From: Daniel Thayer Date: Fri, 2 May 2014 16:57:55 -0500 Subject: [PATCH 061/136] Add a new section "Cluster Configuration" to the docs Added a new section that is intended as a how-to for configuring a Bro cluster (this section does not discuss cluster architecture or theory) that is aimed at beginners to Bro. Most of this content was moved here from the BroControl doc (which is now intended as more of a reference guide for more experienced users) and the load balancing FAQ on the website. --- doc/configuration/index.rst | 289 ++++++++++++++++++++++++++++++++++++ doc/index.rst | 1 + doc/quickstart/index.rst | 4 +- 3 files changed, 292 insertions(+), 2 deletions(-) create mode 100644 doc/configuration/index.rst diff --git a/doc/configuration/index.rst b/doc/configuration/index.rst new file mode 100644 index 0000000000..07b46c9d0d --- /dev/null +++ b/doc/configuration/index.rst @@ -0,0 +1,289 @@ + +.. _configuration: + +===================== +Cluster Configuration +===================== + +.. contents:: + +A *Bro Cluster* is a set of systems jointly analyzing the traffic of +a network link in a coordinated fashion. You can operate such a setup from +a central manager system easily using BroControl, because BroControl +hides much of the complexity of the multi-machine installation. + +This section gives examples of how to setup common cluster configurations +using BroControl (for a full reference on BroControl, see the +:doc:`BroControl <../components/broctl/README>` documentation). + + +Preparing to Setup a Cluster +============================ + +When setting up a cluster, the same user account (in this document, we refer +to this user as the "Bro user") must be set up on all hosts, and this user +must have ssh access from the manager to all machines in the cluster, +and it must work without being prompted for a password/passphrase (for +example, using ssh public key authentication). Finally, on the worker nodes, +this user must have access to the target network interface in promiscuous mode. + +Additionally, you need to have some storage available on all +hosts under the same path, which we will call the cluster's *prefix* path. +In this document, we refer to this directory as ```` (if you build +Bro from source, then ```` is the directory specified +with the ``--prefix`` configure option, or ``/usr/local/bro`` by default). +The Bro user must be able to either create this directory or, where it +already exists, must have write permission inside this directory +on all hosts. + +When trying to decide how to configure the Bro nodes, keep in mind that +there can be multiple Bro instances running on the same host. For example, +it's possible to run a proxy and the manager on the same host. However, it is +recommended to run workers on a different machine than the manager (because +workers can consume a lot of CPU resources). The maximum recommended +number of workers to run on a machine should be one or two less than +the number of CPU cores available on that machine. Using a load-balancing +method (such as PF_RING) along with CPU pinning can decrease the load on +the worker machines. + + +Basic Cluster Configuration +=========================== + +With all prerequisites in place, perform the following steps to setup +a Bro cluster (do this as the Bro user on the manager host only): + +- Edit the BroControl configuration file, ``/etc/broctl.cfg``, + and adjust any BroControl options that are needed for your environment. + Most likely you may want to adjust the value of the ``MailTo`` and + ``LogRotationInterval`` options. A complete reference of all BroControl + options can be found in the :doc:`BroControl <../components/broctl/README>` + documentation. + +- Edit the BroControl node configuration file, ``/etc/node.cfg`` + to define where manager, proxies, and workers are to run. For a cluster + configuration, you must comment-out (or remove) the standalone node + in that file, and either uncomment or add node entries for each node + in your cluster (manager, proxy, and workers). For example, if you wanted + to run four Bro nodes (two workers, one proxy, and a manager) on a cluster + consisting of three machines, your cluster configuration would look like + this:: + + [manager] + type=manager + host=10.0.0.10 + + [proxy-1] + type=proxy + host=10.0.0.10 + + [worker-1] + type=worker + host=10.0.0.11 + interface=eth0 + + [worker-2] + type=worker + host=10.0.0.12 + interface=eth0 + + For a complete reference of all options that are allowed in the ``node.cfg`` + file, see the :doc:`BroControl <../components/broctl/README>` documentation. + +- Edit the network configuration file ``/etc/networks.cfg``. This + file lists all of the networks which the cluster should consider as local + to the monitored environment. + +- Install workers and proxies using BroControl:: + + > broctl install + +- Some tasks need to be run on a regular basis. On the manager node, + insert a line like this into the crontab of the user running the + cluster:: + + 0-59/5 * * * * /bin/broctl cron + + (Note: if you are editing the system crontab instead of a user's own + crontab, then you need to also specify the user which the command + will be run as. The username must be placed after the time fields + and before the broctl command.) + + Note that on some systems (FreeBSD in particular), the default PATH + for cron jobs does not include the directories where bash and python + are installed (the symptoms of this problem would be that "broctl cron" + works when run directly by the user, but does not work from a cron job). + To solve this problem, you would either need to create symlinks + to bash and python in a directory that is in the default PATH for + cron jobs, or specify a new PATH in the crontab. + + +PF_RING Cluster Configuration +============================= + +`PF_RING `_ allows speeding up the +packet capture process by installing a new type of socket in Linux systems. +It supports 10Gbit hardware packet filtering using standard network adapters, +and user-space DNA (Direct NIC Access) for fast packet capture/transmission. + +Installing PF_RING +^^^^^^^^^^^^^^^^^^ +1. Download and install PF_RING for your system following the instructions + `here `_. The following + commands will install the PF_RING libraries and kernel module (replace + the version number 5.6.2 in this example with the version that you + downloaded):: + + cd /usr/src + tar xvzf PF_RING-5.6.2.tar.gz + cd PF_RING-5.6.2/userland/lib + ./configure --prefix=/opt/pfring + make install + + cd ../libpcap + ./configure --prefix=/opt/pfring + make install + + cd ../tcpdump-4.1.1 + ./configure --prefix=/opt/pfring + make install + + cd ../../kernel + make install + + modprobe pf_ring enable_tx_capture=0 min_num_slots=32768 + + Refer to the documentation for your Linux distribution on how to load the + pf_ring module at boot time. You will need to install the PF_RING + library files and kernel module on all of the workers in your cluster. + +2. Download the Bro source code. +3. Configure and install Bro using the following commands:: + + ./configure --with-pcap=/opt/pfring + make + make install + +4. Make sure Bro is correctly linked to the PF_RING libpcap libraries:: + + ldd /usr/local/bro/bin/bro | grep pcap + libpcap.so.1 => /opt/pfring/lib/libpcap.so.1 (0x00007fa6d7d24000) + +5. Configure BroControl to use PF_RING (explained below). +6. Run "broctl install" on the manager. This command will install Bro and + all required scripts to the other machines in your cluster. + +Using PF_RING +^^^^^^^^^^^^^ + +In order to use PF_RING, you need to specify the correct configuration +options for your worker nodes in BroControl's node configuration file. +Edit the ``node.cfg`` file and specify ``lb_method=pf_ring`` for each of +your worker nodes. Next, use the ``lb_procs`` node option to specify how +many Bro processes you'd like that worker node to run, and optionally pin +those processes to certain CPU cores with the ``pin_cpus`` option (CPU +numbering starts at zero). The correct ``pin_cpus`` setting to use is +dependent on your CPU architecture (Intel and AMD systems enumerate +processors in different ways). Using the wrong ``pin_cpus`` setting +can cause poor performance. Here is what a worker node entry should +look like when using PF_RING and CPU pinning:: + + [worker-1] + type=worker + host=10.0.0.50 + interface=eth0 + lb_method=pf_ring + lb_procs=10 + pin_cpus=2,3,4,5,6,7,8,9,10,11 + + +Using PF_RING+DNA with symmetric RSS +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +You must have a PF_RING+DNA license in order to do this. You can sniff +each packet only once. + +1. Load the DNA NIC driver (i.e. ixgbe) on each worker host. +2. Run "ethtool -L dna0 combined 10" (this will establish 10 RSS queues + on your NIC) on each worker host. You must make sure that you set the + number of RSS queues to the same as the number you specify for the + lb_procs option in the node.cfg file. +3. On the manager, configure your worker(s) in node.cfg:: + + [worker-1] + type=worker + host=10.0.0.50 + interface=dna0 + lb_method=pf_ring + lb_procs=10 + + +Using PF_RING+DNA with pfdnacluster_master +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +You must have a PF_RING+DNA license and a libzero license in order to do +this. You can load balance between multiple applications and sniff the +same packets multiple times with different tools. + +1. Load the DNA NIC driver (i.e. ixgbe) on each worker host. +2. Run "ethtool -L dna0 1" (this will establish 1 RSS queues on your NIC) + on each worker host. +3. Run the pfdnacluster_master command on each worker host. For example:: + + pfdnacluster_master -c 21 -i dna0 -n 10 + + Make sure that your cluster ID (21 in this example) matches the interface + name you specify in the node.cfg file. Also make sure that the number + of processes you're balancing across (10 in this example) matches + the lb_procs option in the node.cfg file. +4. If you are load balancing to other processes, you can use the + pfringdnafirstappinstance variable in broctl.cfg to set the first + application instance that Bro should use. For example, if you are running + pfdnacluster_master with "-n 10,4" you would set + pfringdnafirstappinstance=4. Unfortunately that's still a global setting + in broctl.cfg at the moment but we may change that to something you can + set in node.cfg eventually. +5. On the manager, configure your worker(s) in node.cfg:: + + [worker-1] + type=worker + host=10.0.0.50 + interface=dnacluster:21 + lb_method=pf_ring + lb_procs=10 + + +Using PF_RING ZC with zbalance_ipc +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +You must have a license for the ZC PF_RING-aware driver in order to do this. +You can load balance between multiple applications and sniff the +same packets multiple times with different tools. + +1. Load the ZC PF_RING-aware NIC driver (i.e. ixgbe) on each worker host. +2. Run "ethtool -L zc:eth0 1" (this will establish 1 RSS queues on your NIC) + on each worker host. +3. Run the zbalance_ipc command on each worker host. For example:: + + zbalance_ipc -c 21 -i zc:eth0 -n 10 + + Make sure that your cluster ID (21 in this example) matches the interface + name you specify in the node.cfg file. Also make sure that the number + of processes you're balancing across (10 in this example) matches + the lb_procs option in the node.cfg file. +4. If you are load balancing to other processes, you can use the + pfringdnafirstappinstance variable in broctl.cfg to set the first + application instance that Bro should use. For example, if you are running + zbalance_ipc with "-n 10,4" you would set + pfringdnafirstappinstance=4. Unfortunately that's still a global setting + in broctl.cfg at the moment but we may change that to something you can + set in node.cfg eventually. +5. On the manager, configure your worker(s) in node.cfg:: + + [worker-1] + type=worker + host=10.0.0.50 + interface=zc:eth0 + lb_method=pf_ring + lb_procs=10 + diff --git a/doc/index.rst b/doc/index.rst index bab3d49204..8d479d2a25 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -15,6 +15,7 @@ Introduction Section cluster/index.rst install/index.rst quickstart/index.rst + configuration/index.rst .. diff --git a/doc/quickstart/index.rst b/doc/quickstart/index.rst index a61d0cc71d..19add23bd4 100644 --- a/doc/quickstart/index.rst +++ b/doc/quickstart/index.rst @@ -25,8 +25,8 @@ BroControl is an interactive shell for easily operating/managing Bro installations on a single system or even across multiple systems in a traffic-monitoring cluster. This section explains how to use BroControl to manage a stand-alone Bro installation. For instructions on how to -configure a Bro cluster, see the documentation for :doc:`BroControl -<../components/broctl/README>`. +configure a Bro cluster, see the :doc:`Cluster Configuration +<../configuration/index>` documentation. A Minimal Starting Configuration -------------------------------- From 713fd2fbafde195a7aa508e145760990e0988977 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 6 May 2014 12:07:23 -0500 Subject: [PATCH 062/136] Fix new []/delete mismatch in ~Base64Converter. --- src/Base64.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Base64.cc b/src/Base64.cc index 50732534ab..e76621e634 100644 --- a/src/Base64.cc +++ b/src/Base64.cc @@ -104,7 +104,7 @@ Base64Converter::Base64Converter(analyzer::Analyzer* arg_analyzer, const string& Base64Converter::~Base64Converter() { if ( base64_table != default_base64_table ) - delete base64_table; + delete [] base64_table; } int Base64Converter::Decode(int len, const char* data, int* pblen, char** pbuf) From 965e4d421d66b79d9c8fa363b65f63955e93f583 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 6 May 2014 12:13:43 -0500 Subject: [PATCH 063/136] Fix buffer overlows in IP address masking logic. That could occur either in taking a zero-length mask on an IPv6 address (e.g. [fe80::]/0) or a reverse mask of length 128 on any address (e.g. via the remask_addr BuiltIn Function). --- src/IPAddr.cc | 58 +++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/src/IPAddr.cc b/src/IPAddr.cc index 7fd3755042..7ccc3dce07 100644 --- a/src/IPAddr.cc +++ b/src/IPAddr.cc @@ -1,5 +1,6 @@ // See the file "COPYING" in the main distribution directory for copyright. +#include #include #include #include "IPAddr.h" @@ -45,6 +46,14 @@ HashKey* BuildConnIDHashKey(const ConnID& id) return new HashKey(&key, sizeof(key)); } +static inline uint32_t bit_mask32(int bottom_bits) + { + if ( bottom_bits >= 32 ) + return 0xffffffff; + + return (((uint32_t) 1) << bottom_bits) - 1; + } + void IPAddr::Mask(int top_bits_to_keep) { if ( top_bits_to_keep < 0 || top_bits_to_keep > 128 ) @@ -53,25 +62,20 @@ void IPAddr::Mask(int top_bits_to_keep) return; } - uint32_t tmp[4]; - memcpy(tmp, in6.s6_addr, sizeof(in6.s6_addr)); + uint32_t mask_bits[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; + std::ldiv_t res = std::ldiv(top_bits_to_keep, 32); - int word = 3; - int bits_to_chop = 128 - top_bits_to_keep; + if ( res.quot < 4 ) + mask_bits[res.quot] = + htonl(mask_bits[res.quot] & ~bit_mask32(32 - res.rem)); - while ( bits_to_chop >= 32 ) - { - tmp[word] = 0; - --word; - bits_to_chop -= 32; - } + for ( unsigned int i = res.quot + 1; i < 4; ++i ) + mask_bits[i] = 0; - uint32_t w = ntohl(tmp[word]); - w >>= bits_to_chop; - w <<= bits_to_chop; - tmp[word] = htonl(w); + uint32_t* p = reinterpret_cast(in6.s6_addr); - memcpy(in6.s6_addr, tmp, sizeof(in6.s6_addr)); + for ( unsigned int i = 0; i < 4; ++i ) + p[i] &= mask_bits[i]; } void IPAddr::ReverseMask(int top_bits_to_chop) @@ -82,25 +86,19 @@ void IPAddr::ReverseMask(int top_bits_to_chop) return; } - uint32_t tmp[4]; - memcpy(tmp, in6.s6_addr, sizeof(in6.s6_addr)); + uint32_t mask_bits[4] = { 0, 0, 0, 0 }; + std::ldiv_t res = std::ldiv(top_bits_to_chop, 32); - int word = 0; - int bits_to_chop = top_bits_to_chop; + if ( res.quot < 4 ) + mask_bits[res.quot] = htonl(bit_mask32(32 - res.rem)); - while ( bits_to_chop >= 32 ) - { - tmp[word] = 0; - ++word; - bits_to_chop -= 32; - } + for ( unsigned int i = res.quot + 1; i < 4; ++i ) + mask_bits[i] = 0xffffffff; - uint32_t w = ntohl(tmp[word]); - w <<= bits_to_chop; - w >>= bits_to_chop; - tmp[word] = htonl(w); + uint32_t* p = reinterpret_cast(in6.s6_addr); - memcpy(in6.s6_addr, tmp, sizeof(in6.s6_addr)); + for ( unsigned int i = 0; i < 4; ++i ) + p[i] &= mask_bits[i]; } void IPAddr::Init(const std::string& s) From af3b87e100a89d29773f7c20cf7a6a4a632108d2 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 6 May 2014 12:36:02 -0500 Subject: [PATCH 064/136] Fix buffer over-reads in file_analysis::Manager::Terminate() --- src/file_analysis/Manager.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/file_analysis/Manager.cc b/src/file_analysis/Manager.cc index 393dadfdc7..3a7b799094 100644 --- a/src/file_analysis/Manager.cc +++ b/src/file_analysis/Manager.cc @@ -74,7 +74,8 @@ void Manager::Terminate() while ( id_map.NextEntry(key, it) ) { - keys.push_back(static_cast(key->Key())); + keys.push_back(string(static_cast(key->Key()), + key->Size())); delete key; } From 37b860d3252525d278943d83d46d874e55da39e3 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 6 May 2014 12:55:50 -0500 Subject: [PATCH 065/136] Fix new []/delete mismatch in input::reader::Raw::DoClose(). --- src/input/readers/Raw.cc | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/input/readers/Raw.cc b/src/input/readers/Raw.cc index 53469335a2..11976e2a11 100644 --- a/src/input/readers/Raw.cc +++ b/src/input/readers/Raw.cc @@ -67,12 +67,9 @@ void Raw::DoClose() if ( file != 0 ) CloseInput(); - if ( buf != 0 ) - { - // we still have output that has not been flushed. Throw away. - delete buf; - buf = 0; - } + // Just throw away output that has not been flushed. + delete [] buf; + buf = 0; if ( execute && childpid > 0 && kill(childpid, 0) == 0 ) { From 6277be6e606334263f18f5d86489564a6ff84dc3 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Tue, 6 May 2014 20:50:37 -0500 Subject: [PATCH 066/136] Fix memory leaks in X509 certificate parsing/verification. --- src/file_analysis/analyzer/x509/X509.cc | 11 +++++++++++ src/file_analysis/analyzer/x509/functions.bif | 18 +++++++++--------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/file_analysis/analyzer/x509/X509.cc b/src/file_analysis/analyzer/x509/X509.cc index debe38deaa..6e0f37e9c9 100644 --- a/src/file_analysis/analyzer/x509/X509.cc +++ b/src/file_analysis/analyzer/x509/X509.cc @@ -153,6 +153,8 @@ RecordVal* file_analysis::X509::ParseCertificate(X509Val* cert_val) unsigned int length = KeyLength(pkey); if ( length > 0 ) pX509Cert->Assign(9, new Val(length, TYPE_COUNT)); + + EVP_PKEY_free(pkey); } @@ -273,6 +275,7 @@ void file_analysis::X509::ParseBasicConstraints(X509_EXTENSION* ex) vl->append(pBasicConstraint); mgr.QueueEvent(x509_ext_basic_constraints, vl); + BASIC_CONSTRAINTS_free(constr); } else @@ -387,6 +390,7 @@ void file_analysis::X509::ParseSAN(X509_EXTENSION* ext) vl->append(GetFile()->GetVal()->Ref()); vl->append(sanExt); mgr.QueueEvent(x509_ext_subject_alternative_name, vl); + GENERAL_NAMES_free(altname); } StringVal* file_analysis::X509::KeyCurve(EVP_PKEY *key) @@ -442,13 +446,20 @@ unsigned int file_analysis::X509::KeyLength(EVP_PKEY *key) return 0; const EC_GROUP *group = EC_KEY_get0_group(key->pkey.ec); + if ( ! group ) + { // unknown ex-group + BN_free(ec_order); return 0; + } if ( ! EC_GROUP_get_order(group, ec_order, NULL) ) + { // could not get ec-group-order + BN_free(ec_order); return 0; + } unsigned int length = BN_num_bits(ec_order); BN_free(ec_order); diff --git a/src/file_analysis/analyzer/x509/functions.bif b/src/file_analysis/analyzer/x509/functions.bif index 176df53bdb..5d9242026e 100644 --- a/src/file_analysis/analyzer/x509/functions.bif +++ b/src/file_analysis/analyzer/x509/functions.bif @@ -179,7 +179,7 @@ function x509_verify%(certs: x509_opaque_vector, root_certs: table_string_of_str X509* x = ((file_analysis::X509Val*) sv)->GetCertificate(); if ( ! x ) { - sk_X509_pop(untrusted_certs); + sk_X509_free(untrusted_certs); builtin_error(fmt("No certificate in opaque in stack")); return x509_error_record(-1, "No certificate in opaque"); } @@ -203,6 +203,7 @@ function x509_verify%(certs: x509_opaque_vector, root_certs: table_string_of_str if ( ! chain ) { reporter->Error("Encountered valid chain that could not be resolved"); + sk_X509_pop_free(chain, X509_free); goto x509_verify_chainerror; } @@ -212,22 +213,21 @@ function x509_verify%(certs: x509_opaque_vector, root_certs: table_string_of_str for ( int i = 0; i < num_certs; i++ ) { X509* currcert = sk_X509_value(chain, i); - if ( !currcert ) - { - reporter->InternalError("OpenSSL returned null certificate"); - goto x509_verify_chainerror; - } - chainVector->Assign(i, new file_analysis::X509Val(currcert)); // X509Val takes ownership + if ( currcert ) + chainVector->Assign(i, new file_analysis::X509Val(currcert)); // X509Val takes ownership + else + reporter->InternalWarning("OpenSSL returned null certificate"); } + + sk_X509_free(chain); } x509_verify_chainerror: X509_STORE_CTX_cleanup(&csc); - if ( untrusted_certs ) - sk_X509_pop(untrusted_certs); + sk_X509_free(untrusted_certs); RecordVal* rrecord = new RecordVal(BifType::Record::X509::Result); From 4ea8a4e8ef451f4599f173a14103d8e9e9ade5d6 Mon Sep 17 00:00:00 2001 From: Jon Siwek Date: Wed, 7 May 2014 10:45:00 -0500 Subject: [PATCH 067/136] Change handling of atypical OpenSSL error case in x509 verification. --- src/file_analysis/analyzer/x509/functions.bif | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/file_analysis/analyzer/x509/functions.bif b/src/file_analysis/analyzer/x509/functions.bif index 5d9242026e..1fa81a0fd0 100644 --- a/src/file_analysis/analyzer/x509/functions.bif +++ b/src/file_analysis/analyzer/x509/functions.bif @@ -215,9 +215,17 @@ function x509_verify%(certs: x509_opaque_vector, root_certs: table_string_of_str X509* currcert = sk_X509_value(chain, i); if ( currcert ) - chainVector->Assign(i, new file_analysis::X509Val(currcert)); // X509Val takes ownership + // X509Val takes ownership of currcert. + chainVector->Assign(i, new file_analysis::X509Val(currcert)); else + { reporter->InternalWarning("OpenSSL returned null certificate"); + + for ( int j = i + 1; i < num_certs; ++j ) + X509_free(sk_X509_value(chain, j)); + + break; + } } sk_X509_free(chain); From 9014629a7d17b5c0b7f13108f349f3a3b0656c1b Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Thu, 8 May 2014 11:32:52 -0700 Subject: [PATCH 068/136] Let TLS analyzer fail better when no longer in sync with the data stream. The version field in each record-layer packet is now re-checked. --- src/analyzer/protocol/ssl/events.bif | 9 +++++---- src/analyzer/protocol/ssl/ssl-analyzer.pac | 5 ++--- src/analyzer/protocol/ssl/ssl-protocol.pac | 15 +++++++++++++++ 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/analyzer/protocol/ssl/events.bif b/src/analyzer/protocol/ssl/events.bif index 6f44165be4..e17d5ec477 100644 --- a/src/analyzer/protocol/ssl/events.bif +++ b/src/analyzer/protocol/ssl/events.bif @@ -265,9 +265,8 @@ event ssl_session_ticket_handshake%(c: connection, ticket_lifetime_hint: count, ## ssl_alert ssl_encrypted_heartbeat event ssl_heartbeat%(c: connection, is_orig: bool, length: count, heartbeat_type: count, payload_length: count, payload: string%); -## Generated for SSL/TLS heartbeat messages that are sent after session encryption -## started. Generally heartbeat messages should rarely be seen in normal TLS traffic. -## Heartbeats are described in :rfc:`6520`. +## Generated for SSL/TLS messages that are sent after session encryption +## started. ## ## Note that :bro:id:`SSL::disable_analyzer_after_detection` has to be set to false. ## Otherwhise this event will never be thrown. @@ -276,11 +275,13 @@ event ssl_heartbeat%(c: connection, is_orig: bool, length: count, heartbeat_type ## ## is_orig: True if event is raised for originator side of the connection. ## +## content type: message type as reported by TLS session layer +## ## length: length of the entire heartbeat message. ## ## .. bro:see:: ssl_client_hello ssl_established ssl_extension ssl_server_hello ## ssl_alert ssl_heartbeat -event ssl_encrypted_heartbeat%(c: connection, is_orig: bool, length: count%); +event ssl_encrypted_data%(c: connection, is_orig: bool, content_type: count, length: count%); ## This event contains the OCSP response contained in a Certificate Status Request ## message, when the client requested OCSP stapling and the server supports it. See diff --git a/src/analyzer/protocol/ssl/ssl-analyzer.pac b/src/analyzer/protocol/ssl/ssl-analyzer.pac index ef1d862b87..8d62245f6b 100644 --- a/src/analyzer/protocol/ssl/ssl-analyzer.pac +++ b/src/analyzer/protocol/ssl/ssl-analyzer.pac @@ -365,9 +365,8 @@ refine connection SSL_Conn += { bro_analyzer()->Conn()); } - if ( ${rec.content_type} == HEARTBEAT ) - BifEvent::generate_ssl_encrypted_heartbeat(bro_analyzer(), - bro_analyzer()->Conn(), ${rec.is_orig}, ${rec.length}); + BifEvent::generate_ssl_encrypted_data(bro_analyzer(), + bro_analyzer()->Conn(), ${rec.content_type}, ${rec.is_orig}, ${rec.length}); return true; %} diff --git a/src/analyzer/protocol/ssl/ssl-protocol.pac b/src/analyzer/protocol/ssl/ssl-protocol.pac index af220f39de..a31d257330 100644 --- a/src/analyzer/protocol/ssl/ssl-protocol.pac +++ b/src/analyzer/protocol/ssl/ssl-protocol.pac @@ -44,6 +44,8 @@ type SSLRecord(is_orig: bool) = record { }; length : int = case version of { + # fail analyzer if the packet cannot be recognized as TLS. + UNKNOWN_VERSION -> 0; SSLv20 -> (((head0 & 0x7f) << 8) | head1) - 3; default -> (head3 << 8) | head4; }; @@ -748,6 +750,19 @@ refine connection SSL_Conn += { function determine_ssl_record_layer(head0 : uint8, head1 : uint8, head2 : uint8, head3: uint8, head4: uint8) : int %{ + // re-check record layer version to be sure that we still are synchronized with + // the data stream + if ( record_layer_version_ != UNKNOWN_VERSION && record_layer_version_ != SSLv20 ) + { + uint16 version = (head1<<8) | head2; + if ( version != SSLv30 && version != TLSv10 && + version != TLSv11 && version != TLSv12 ) + { + bro_analyzer()->ProtocolViolation(fmt("Invalid version late in TLS connection. Packet reported version: %d", version)); + return UNKNOWN_VERSION; + } + } + if ( record_layer_version_ != UNKNOWN_VERSION ) return record_layer_version_; From 37dd3312564346bc2110c41270174b2ccded71a8 Mon Sep 17 00:00:00 2001 From: Robin Sommer Date: Thu, 8 May 2014 16:34:44 -0700 Subject: [PATCH 069/136] Updating submodule(s). [nomail] --- CHANGES | 24 ++++++++++++------------ VERSION | 2 +- aux/bro-aux | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/CHANGES b/CHANGES index 1d141ae3d5..68beb70ada 100644 --- a/CHANGES +++ b/CHANGES @@ -1,24 +1,24 @@ -2.2-424 | 2014-05-08 16:32:29 -0700 +2.2-425 | 2014-05-08 16:34:44 -0700 - * Fixing compiler warnings. (Robin Sommer) + * Fix reassembly of data w/ sizes beyond 32-bit capacities. (Jon Siwek) - * Update SNMP analyzer's DeliverPacket method signature. (Jon Siwek) - - * Fix reassembly of data w/ sizes beyond 32-bit capacities The main - change is that reassembly code (e.g. for TCP) now uses - int64/uint64 (signedness is situational) data types in place of - int types in order to support delivering data to analyzers that - pass 2GB thresholds. There's also changes in logic that accompany - the change in data types, e.g. to fix TCP sequence space - arithmetic inconsistencies. + Reassembly code (e.g. for TCP) now uses int64/uint64 (signedness + is situational) data types in place of int types in order to + support delivering data to analyzers that pass 2GB thresholds. + There's also changes in logic that accompany the change in data + types, e.g. to fix TCP sequence space arithmetic inconsistencies. Another significant change is in the Analyzer API: the *Packet and *Undelivered methods now use a uint64 in place of an int for the relative sequence space offset parameter. - Addresses BIT-348. (Jon Siwek) + Addresses BIT-348. + * Fixing compiler warnings. (Robin Sommer) + + * Update SNMP analyzer's DeliverPacket method signature. (Jon Siwek) + 2.2-417 | 2014-05-07 10:59:22 -0500 * Change handling of atypical OpenSSL error case in x509 verification. (Jon Siwek) diff --git a/VERSION b/VERSION index c43adf607d..ce1d2d112b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.2-424 +2.2-425 diff --git a/aux/bro-aux b/aux/bro-aux index 5c0043d587..6dfc648d22 160000 --- a/aux/bro-aux +++ b/aux/bro-aux @@ -1 +1 @@ -Subproject commit 5c0043d587314c57070e5362762e3e0f6408c2be +Subproject commit 6dfc648d22d234d2ba4b1cb0fc74cda2eb023d1e From f0b244b8b0a3525c38469985557029ebf14139fb Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Wed, 14 May 2014 15:42:27 -0700 Subject: [PATCH 070/136] Add new features from other branch to the heartbleed-detector (and clean them up). We should now quite reliably detect scans/attacks, even when encrypted and not succesful. --- scripts/policy/protocols/ssl/heartbleed.bro | 151 ++++++++++++++++-- src/analyzer/protocol/ssl/ssl-analyzer.pac | 2 +- .../notice-encrypted-short.log | 12 ++ .../notice-encrypted-success.log | 12 ++ .../notice-encrypted.log | 6 +- .../notice-heartbleed-success.log | 8 +- .../tls/heartbleed-encrypted-short.pcap | Bin 0 -> 4294 bytes .../Traces/tls/heartbleed-encrypted.pcap | Bin 0 -> 6117 bytes .../policy/protocols/ssl/heartbleed.bro | 10 +- 9 files changed, 179 insertions(+), 22 deletions(-) create mode 100644 testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-encrypted-short.log create mode 100644 testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-encrypted-success.log create mode 100644 testing/btest/Traces/tls/heartbleed-encrypted-short.pcap create mode 100644 testing/btest/Traces/tls/heartbleed-encrypted.pcap diff --git a/scripts/policy/protocols/ssl/heartbleed.bro b/scripts/policy/protocols/ssl/heartbleed.bro index 5c5333a7a2..63fc2e72c9 100644 --- a/scripts/policy/protocols/ssl/heartbleed.bro +++ b/scripts/policy/protocols/ssl/heartbleed.bro @@ -7,11 +7,11 @@ module Heartbleed; export { redef enum Notice::Type += { - ## Indicates that a host performing a heartbleed attack. + ## Indicates that a host performing a heartbleed attack or scan. SSL_Heartbeat_Attack, ## Indicates that a host performing a heartbleed attack was probably successful. SSL_Heartbeat_Attack_Success, - ## Indicates we saw heartbeat requests with odd length. Probably an attack. + ## Indicates we saw heartbeat requests with odd length. Probably an attack or scan. SSL_Heartbeat_Odd_Length, ## Indicates we saw many heartbeat requests without an reply. Might be an attack. SSL_Heartbeat_Many_Requests @@ -25,14 +25,76 @@ redef SSL::disable_analyzer_after_detection=F; redef record SSL::Info += { last_originator_heartbeat_request_size: count &optional; last_responder_heartbeat_request_size: count &optional; + originator_heartbeats: count &default=0; responder_heartbeats: count &default=0; + # Unencrypted connections - was an exploit attempt detected yet. heartbleed_detected: bool &default=F; - }; + + # Count number of appdata packages and bytes exchanged so far. + enc_appdata_packages: count &default=0; + enc_appdata_bytes: count &default=0; +}; + +# TLS content types: +const CHANGE_CIPHER_SPEC = 20; +const ALERT = 21; +const HANDSHAKE = 22; +const APPLICATION_DATA = 23; +const HEARTBEAT = 24; +const V2_ERROR = 300; +const V2_CLIENT_HELLO = 301; +const V2_CLIENT_MASTER_KEY = 302; +const V2_SERVER_HELLO = 304; + +type min_length: record { + cipher: pattern; + min_length: count; +}; + +global min_lengths: vector of min_length = vector(); +global min_lengths_tls11: vector of min_length = vector(); + +event bro_init() + { + # Minimum length a heartbeat packet must have for different cipher suites. + # Note - tls 1.1f and 1.0 have different lengths :( + # This should be all cipher suites usually supported by vulnerable servers. + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_AES_256_GCM_SHA384$/, $min_length=43]; + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_AES_128_GCM_SHA256$/, $min_length=43]; + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_256_CBC_SHA384$/, $min_length=96]; + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_256_CBC_SHA256$/, $min_length=80]; + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_256_CBC_SHA$/, $min_length=64]; + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_128_CBC_SHA256$/, $min_length=80]; + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_128_CBC_SHA$/, $min_length=64]; + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_3DES_EDE_CBC_SHA$/, $min_length=48]; + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_SEED_CBC_SHA$/, $min_length=64]; + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_IDEA_CBC_SHA$/, $min_length=48]; + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_DES_CBC_SHA$/, $min_length=48]; + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_DES40_CBC_SHA$/, $min_length=48]; + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_RC4_128_SHA$/, $min_length=39]; + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_RC4_128_MD5$/, $min_length=35]; + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_RC4_40_MD5$/, $min_length=35]; + min_lengths_tls11[|min_lengths_tls11|] = [$cipher=/_RC2_CBC_40_MD5$/, $min_length=48]; + min_lengths[|min_lengths|] = [$cipher=/_256_CBC_SHA$/, $min_length=48]; + min_lengths[|min_lengths|] = [$cipher=/_128_CBC_SHA$/, $min_length=48]; + min_lengths[|min_lengths|] = [$cipher=/_3DES_EDE_CBC_SHA$/, $min_length=40]; + min_lengths[|min_lengths|] = [$cipher=/_SEED_CBC_SHA$/, $min_length=48]; + min_lengths[|min_lengths|] = [$cipher=/_IDEA_CBC_SHA$/, $min_length=40]; + min_lengths[|min_lengths|] = [$cipher=/_DES_CBC_SHA$/, $min_length=40]; + min_lengths[|min_lengths|] = [$cipher=/_DES40_CBC_SHA$/, $min_length=40]; + min_lengths[|min_lengths|] = [$cipher=/_RC4_128_SHA$/, $min_length=39]; + min_lengths[|min_lengths|] = [$cipher=/_RC4_128_MD5$/, $min_length=35]; + min_lengths[|min_lengths|] = [$cipher=/_RC4_40_MD5$/, $min_length=35]; + min_lengths[|min_lengths|] = [$cipher=/_RC2_CBC_40_MD5$/, $min_length=40]; + } event ssl_heartbeat(c: connection, is_orig: bool, length: count, heartbeat_type: count, payload_length: count, payload: string) { + if ( ! c?$ssl ) + return; + if ( heartbeat_type == 1 ) { local checklength: count = (length<(3+16)) ? length : (length - 3 - 16); @@ -40,18 +102,27 @@ event ssl_heartbeat(c: connection, is_orig: bool, length: count, heartbeat_type: if ( payload_length > checklength ) { c$ssl$heartbleed_detected = T; - NOTICE([$note=SSL_Heartbeat_Attack, - $msg=fmt("An TLS heartbleed attack was detected! Record length %d, payload length %d", length, payload_length), + NOTICE([$note=Heartbleed::SSL_Heartbeat_Attack, + $msg=fmt("An TLS heartbleed attack was detected! Record length %d. Payload length %d", length, payload_length), $conn=c, $identifier=cat(c$uid, length, payload_length) ]); } + else if ( is_orig ) + { + NOTICE([$note=Heartbleed::SSL_Heartbeat_Attack, + $msg=fmt("Heartbeat request before encryption. Probable Scan without exploit attempt. Message length: %d. Payload length: %d", length, payload_length), + $conn=c, + $n=length, + $identifier=cat(c$uid, length) + ]); + } } if ( heartbeat_type == 2 && c$ssl$heartbleed_detected ) { - NOTICE([$note=SSL_Heartbeat_Attack_Success, - $msg=fmt("An TLS heartbleed attack detected before was probably exploited. Transmitted payload length in first packet: %d", payload_length), + NOTICE([$note=Heartbleed::SSL_Heartbeat_Attack_Success, + $msg=fmt("An TLS heartbleed attack detected before was probably exploited. Message length: %d. Payload length: %d", length, payload_length), $conn=c, $identifier=c$uid ]); @@ -65,9 +136,26 @@ event ssl_encrypted_heartbeat(c: connection, is_orig: bool, length: count) else ++c$ssl$responder_heartbeats; + local duration = network_time() - c$start_time; + + if ( c$ssl$enc_appdata_packages == 0 ) + NOTICE([$note=SSL_Heartbeat_Attack, + $msg=fmt("Heartbeat before ciphertext. Probable attack or scan. Length: %d, is_orig: %d", length, is_orig), + $conn=c, + $n=length, + $identifier=fmt("%s%s", c$uid, "early") + ]); + else if ( duration < 1min ) + NOTICE([$note=SSL_Heartbeat_Attack, + $msg=fmt("Heartbeat within first minute. Possible attack or scan. Length: %d, is_orig: %d, time: %d", length, is_orig, duration), + $conn=c, + $n=length, + $identifier=fmt("%s%s", c$uid, "early") + ]); + if ( c$ssl$originator_heartbeats > c$ssl$responder_heartbeats + 3 ) NOTICE([$note=SSL_Heartbeat_Many_Requests, - $msg=fmt("Seeing more than 3 heartbeat requests without replies from server. Possible attack. Client count: %d, server count: %d", c$ssl$originator_heartbeats, c$ssl$responder_heartbeats), + $msg=fmt("More than 3 heartbeat requests without replies from server. Possible attack. Client count: %d, server count: %d", c$ssl$originator_heartbeats, c$ssl$responder_heartbeats), $conn=c, $n=(c$ssl$originator_heartbeats-c$ssl$responder_heartbeats), $identifier=fmt("%s%d", c$uid, c$ssl$responder_heartbeats/1000) # re-throw every 1000 heartbeats @@ -75,7 +163,7 @@ event ssl_encrypted_heartbeat(c: connection, is_orig: bool, length: count) if ( c$ssl$responder_heartbeats > c$ssl$originator_heartbeats + 3 ) NOTICE([$note=SSL_Heartbeat_Many_Requests, - $msg=fmt("Server is sending more heartbleed responsed than requests were seen. Possible attack. Client count: %d, server count: %d", c$ssl$originator_heartbeats, c$ssl$responder_heartbeats), + $msg=fmt("Server sending more heartbeat responses than requests seen. Possible attack. Client count: %d, server count: %d", c$ssl$originator_heartbeats, c$ssl$responder_heartbeats), $conn=c, $n=(c$ssl$originator_heartbeats-c$ssl$responder_heartbeats), $identifier=fmt("%s%d", c$uid, c$ssl$responder_heartbeats/1000) # re-throw every 1000 heartbeats @@ -83,12 +171,38 @@ event ssl_encrypted_heartbeat(c: connection, is_orig: bool, length: count) if ( is_orig && length < 19 ) NOTICE([$note=SSL_Heartbeat_Odd_Length, - $msg=fmt("Heartbeat message smaller than minimum required length. Probable attack. Message length: %d", length), + $msg=fmt("Heartbeat message smaller than minimum required length. Probable attack or scan. Message length: %d. Cipher: %s. Time: %f", length, c$ssl$cipher, duration), $conn=c, $n=length, - $identifier=cat(c$uid, length) + $identifier=fmt("%s-weak-%d", c$uid, length) ]); + # Examine request lengths based on used cipher... + local min_length_choice: vector of min_length; + if ( (c$ssl$version == "TLSv11") || (c$ssl$version == "TLSv12") ) # tls 1.1+ have different lengths for CBC + min_length_choice = min_lengths_tls11; + else + min_length_choice = min_lengths; + + for ( i in min_length_choice ) + { + if ( min_length_choice[i]$cipher in c$ssl$cipher ) + { + if ( length < min_length_choice[i]$min_length ) + { + NOTICE([$note=SSL_Heartbeat_Odd_Length, + $msg=fmt("Heartbeat message smaller than minimum required length. Probable attack. Message length: %d. Required length: %d. Cipher: %s. Cipher match: %s", length, min_length_choice[i]$min_length, c$ssl$cipher, min_length_choice[i]$cipher), + $conn=c, + $n=length, + $identifier=fmt("%s-weak-%d", c$uid, length) + ]); + } + + break; + } + + } + if ( is_orig ) { if ( c$ssl?$last_responder_heartbeat_request_size ) @@ -105,8 +219,8 @@ event ssl_encrypted_heartbeat(c: connection, is_orig: bool, length: count) if ( c$ssl?$last_originator_heartbeat_request_size && c$ssl$last_originator_heartbeat_request_size < length ) { NOTICE([$note=SSL_Heartbeat_Attack_Success, - $msg=fmt("An Encrypted TLS heartbleed attack was probably detected! First packet client record length %d, first packet server record length %d", - c$ssl$last_originator_heartbeat_request_size, length), + $msg=fmt("An encrypted TLS heartbleed attack was probably detected! First packet client record length %d, first packet server record length %d. Time: %f", + c$ssl$last_originator_heartbeat_request_size, length, duration), $conn=c, $identifier=c$uid # only throw once per connection ]); @@ -119,3 +233,14 @@ event ssl_encrypted_heartbeat(c: connection, is_orig: bool, length: count) delete c$ssl$last_originator_heartbeat_request_size; } } + +event ssl_encrypted_data(c: connection, is_orig: bool, content_type: count, length: count) + { + if ( content_type == HEARTBEAT ) + event ssl_encrypted_heartbeat(c, is_orig, length); + else if ( (content_type == APPLICATION_DATA) && (length > 0) ) + { + ++c$ssl$enc_appdata_packages; + c$ssl$enc_appdata_bytes += length; + } + } diff --git a/src/analyzer/protocol/ssl/ssl-analyzer.pac b/src/analyzer/protocol/ssl/ssl-analyzer.pac index 8d62245f6b..2c242eb4cb 100644 --- a/src/analyzer/protocol/ssl/ssl-analyzer.pac +++ b/src/analyzer/protocol/ssl/ssl-analyzer.pac @@ -366,7 +366,7 @@ refine connection SSL_Conn += { } BifEvent::generate_ssl_encrypted_data(bro_analyzer(), - bro_analyzer()->Conn(), ${rec.content_type}, ${rec.is_orig}, ${rec.length}); + bro_analyzer()->Conn(), ${rec.is_orig}, ${rec.content_type}, ${rec.length}); return true; %} diff --git a/testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-encrypted-short.log b/testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-encrypted-short.log new file mode 100644 index 0000000000..a3812210d1 --- /dev/null +++ b/testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-encrypted-short.log @@ -0,0 +1,12 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path notice +#open 2014-05-14-22-40-47 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p fuid file_mime_type file_desc proto note msg sub src dst p n peer_descr actions suppress_for dropped remote_location.country_code remote_location.region remote_location.city remote_location.latitude remote_location.longitude +#types time string addr port addr port string string string enum enum string string addr addr port count string set[enum] interval bool string string string double double +1398954957.074664 CXWv6p3arKYeMETxOg 192.168.4.149 54233 162.219.2.166 4443 - - - tcp Heartbleed::SSL_Heartbeat_Attack Heartbeat before ciphertext. Probable attack or scan. Length: 32, is_orig: 1 - 192.168.4.149 162.219.2.166 4443 32 bro Notice::ACTION_LOG 3600.000000 F - - - - - +1398954957.074664 CXWv6p3arKYeMETxOg 192.168.4.149 54233 162.219.2.166 4443 - - - tcp Heartbleed::SSL_Heartbeat_Odd_Length Heartbeat message smaller than minimum required length. Probable attack. Message length: 32. Required length: 48. Cipher: TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA. Cipher match: /^?(_256_CBC_SHA$)$?/ - 192.168.4.149 162.219.2.166 4443 32 bro Notice::ACTION_LOG 3600.000000 F - - - - - +1398954957.145535 CXWv6p3arKYeMETxOg 192.168.4.149 54233 162.219.2.166 4443 - - - tcp Heartbleed::SSL_Heartbeat_Attack_Success An encrypted TLS heartbleed attack was probably detected! First packet client record length 32, first packet server record length 48. Time: 0.351035 - 192.168.4.149 162.219.2.166 4443 - bro Notice::ACTION_LOG 3600.000000 F - - - - - +#close 2014-05-14-22-40-47 diff --git a/testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-encrypted-success.log b/testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-encrypted-success.log new file mode 100644 index 0000000000..95960e7e5c --- /dev/null +++ b/testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-encrypted-success.log @@ -0,0 +1,12 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path notice +#open 2014-05-14-22-40-36 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p fuid file_mime_type file_desc proto note msg sub src dst p n peer_descr actions suppress_for dropped remote_location.country_code remote_location.region remote_location.city remote_location.latitude remote_location.longitude +#types time string addr port addr port string string string enum enum string string addr addr port count string set[enum] interval bool string string string double double +1397169549.882425 CXWv6p3arKYeMETxOg 192.168.4.149 59676 107.170.241.107 443 - - - tcp Heartbleed::SSL_Heartbeat_Attack Heartbeat before ciphertext. Probable attack or scan. Length: 32, is_orig: 1 - 192.168.4.149 107.170.241.107 443 32 bro Notice::ACTION_LOG 3600.000000 F - - - - - +1397169549.882425 CXWv6p3arKYeMETxOg 192.168.4.149 59676 107.170.241.107 443 - - - tcp Heartbleed::SSL_Heartbeat_Odd_Length Heartbeat message smaller than minimum required length. Probable attack. Message length: 32. Required length: 48. Cipher: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA. Cipher match: /^?(_256_CBC_SHA$)$?/ - 192.168.4.149 107.170.241.107 443 32 bro Notice::ACTION_LOG 3600.000000 F - - - - - +1397169549.895057 CXWv6p3arKYeMETxOg 192.168.4.149 59676 107.170.241.107 443 - - - tcp Heartbleed::SSL_Heartbeat_Attack_Success An encrypted TLS heartbleed attack was probably detected! First packet client record length 32, first packet server record length 16416. Time: 0.035413 - 192.168.4.149 107.170.241.107 443 - bro Notice::ACTION_LOG 3600.000000 F - - - - - +#close 2014-05-14-22-40-37 diff --git a/testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-encrypted.log b/testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-encrypted.log index dfe9dcec74..db96ffeeaf 100644 --- a/testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-encrypted.log +++ b/testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-encrypted.log @@ -3,8 +3,8 @@ #empty_field (empty) #unset_field - #path notice -#open 2014-04-30-19-34-39 +#open 2014-05-14-22-40-26 #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p fuid file_mime_type file_desc proto note msg sub src dst p n peer_descr actions suppress_for dropped remote_location.country_code remote_location.region remote_location.city remote_location.latitude remote_location.longitude #types time string addr port addr port string string string enum enum string string addr addr port count string set[enum] interval bool string string string double double -1397169549.895057 CXWv6p3arKYeMETxOg 192.168.4.149 59676 107.170.241.107 443 - - - tcp Heartbleed::SSL_Heartbeat_Attack_Success An Encrypted TLS heartbleed attack was probably detected! First packet client record length 32, first packet server record length 16416 - 192.168.4.149 107.170.241.107 443 - bro Notice::ACTION_LOG 3600.000000 F - - - - - -#close 2014-04-30-19-34-39 +1400106542.810248 CXWv6p3arKYeMETxOg 54.221.166.250 56323 162.219.2.166 443 - - - tcp Heartbleed::SSL_Heartbeat_Attack Heartbeat before ciphertext. Probable attack or scan. Length: 86, is_orig: 1 - 54.221.166.250 162.219.2.166 443 86 bro Notice::ACTION_LOG 3600.000000 F - - - - - +#close 2014-05-14-22-40-27 diff --git a/testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-heartbleed-success.log b/testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-heartbleed-success.log index 9722e20655..d96ddd42e1 100644 --- a/testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-heartbleed-success.log +++ b/testing/btest/Baseline/scripts.policy.protocols.ssl.heartbleed/notice-heartbleed-success.log @@ -3,9 +3,9 @@ #empty_field (empty) #unset_field - #path notice -#open 2014-04-24-18-30-54 +#open 2014-05-14-22-40-19 #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p fuid file_mime_type file_desc proto note msg sub src dst p n peer_descr actions suppress_for dropped remote_location.country_code remote_location.region remote_location.city remote_location.latitude remote_location.longitude #types time string addr port addr port string string string enum enum string string addr addr port count string set[enum] interval bool string string string double double -1396976220.863714 CXWv6p3arKYeMETxOg 173.203.79.216 41459 107.170.241.107 443 - - - tcp Heartbleed::SSL_Heartbeat_Attack An TLS heartbleed attack was detected! Record length 16368, payload length 16365 - 173.203.79.216 107.170.241.107 443 - bro Notice::ACTION_LOG 3600.000000 F - - - - - -1396976220.918017 CXWv6p3arKYeMETxOg 173.203.79.216 41459 107.170.241.107 443 - - - tcp Heartbleed::SSL_Heartbeat_Attack_Success An TLS heartbleed attack detected before was probably exploited. Transmitted payload length in first packet: 16365 - 173.203.79.216 107.170.241.107 443 - bro Notice::ACTION_LOG 3600.000000 F - - - - - -#close 2014-04-24-18-30-54 +1396976220.863714 CXWv6p3arKYeMETxOg 173.203.79.216 41459 107.170.241.107 443 - - - tcp Heartbleed::SSL_Heartbeat_Attack An TLS heartbleed attack was detected! Record length 16368. Payload length 16365 - 173.203.79.216 107.170.241.107 443 - bro Notice::ACTION_LOG 3600.000000 F - - - - - +1396976220.918017 CXWv6p3arKYeMETxOg 173.203.79.216 41459 107.170.241.107 443 - - - tcp Heartbleed::SSL_Heartbeat_Attack_Success An TLS heartbleed attack detected before was probably exploited. Message length: 16384. Payload length: 16365 - 173.203.79.216 107.170.241.107 443 - bro Notice::ACTION_LOG 3600.000000 F - - - - - +#close 2014-05-14-22-40-19 diff --git a/testing/btest/Traces/tls/heartbleed-encrypted-short.pcap b/testing/btest/Traces/tls/heartbleed-encrypted-short.pcap new file mode 100644 index 0000000000000000000000000000000000000000..91942d52bb89b4d0fcc4f3be706f2a78d48cd34c GIT binary patch literal 4294 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 literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/tls/heartbleed-encrypted.pcap b/testing/btest/Traces/tls/heartbleed-encrypted.pcap new file mode 100644 index 0000000000000000000000000000000000000000..dc32d689a2b0fa0ead4dc35f431e7a651c4786ce GIT binary patch literal 6117 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 TWuru)qF?G#7U**Om9GB*i_(ve literal 0 HcmV?d00001 diff --git a/testing/btest/scripts/policy/protocols/ssl/heartbleed.bro b/testing/btest/scripts/policy/protocols/ssl/heartbleed.bro index 4a980bb895..52137adbd0 100644 --- a/testing/btest/scripts/policy/protocols/ssl/heartbleed.bro +++ b/testing/btest/scripts/policy/protocols/ssl/heartbleed.bro @@ -6,8 +6,16 @@ # @TEST-EXEC: mv notice.log notice-heartbleed-success.log # @TEST-EXEC: btest-diff notice-heartbleed-success.log -# @TEST-EXEC: bro -C -r $TRACES/tls/heartbleed-encrypted-success.pcap %INPUT +# @TEST-EXEC: bro -C -r $TRACES/tls/heartbleed-encrypted.pcap %INPUT # @TEST-EXEC: mv notice.log notice-encrypted.log # @TEST-EXEC: btest-diff notice-encrypted.log +# @TEST-EXEC: bro -C -r $TRACES/tls/heartbleed-encrypted-success.pcap %INPUT +# @TEST-EXEC: mv notice.log notice-encrypted-success.log +# @TEST-EXEC: btest-diff notice-encrypted-success.log + +# @TEST-EXEC: bro -C -r $TRACES/tls/heartbleed-encrypted-short.pcap %INPUT +# @TEST-EXEC: mv notice.log notice-encrypted-short.log +# @TEST-EXEC: btest-diff notice-encrypted-short.log + @load protocols/ssl/heartbleed From 5bd0c3fcaffee977b4278e1b930a037774d07765 Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Wed, 14 May 2014 15:45:47 -0700 Subject: [PATCH 071/136] move tls content types from heartbleed to consts.bro. Seems better to put them there... --- scripts/base/protocols/ssl/consts.bro | 11 +++++++++++ scripts/policy/protocols/ssl/heartbleed.bro | 15 ++------------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/scripts/base/protocols/ssl/consts.bro b/scripts/base/protocols/ssl/consts.bro index e1b366130f..da8bb28151 100644 --- a/scripts/base/protocols/ssl/consts.bro +++ b/scripts/base/protocols/ssl/consts.bro @@ -15,6 +15,17 @@ export { [TLSv12] = "TLSv12", } &default=function(i: count):string { return fmt("unknown-%d", i); }; + ## TLS content types: + const CHANGE_CIPHER_SPEC = 20; + const ALERT = 21; + const HANDSHAKE = 22; + const APPLICATION_DATA = 23; + const HEARTBEAT = 24; + const V2_ERROR = 300; + const V2_CLIENT_HELLO = 301; + const V2_CLIENT_MASTER_KEY = 302; + const V2_SERVER_HELLO = 304; + ## Mapping between numeric codes and human readable strings for alert ## levels. const alert_levels: table[count] of string = { diff --git a/scripts/policy/protocols/ssl/heartbleed.bro b/scripts/policy/protocols/ssl/heartbleed.bro index 63fc2e72c9..12087f1fc8 100644 --- a/scripts/policy/protocols/ssl/heartbleed.bro +++ b/scripts/policy/protocols/ssl/heartbleed.bro @@ -37,17 +37,6 @@ redef record SSL::Info += { enc_appdata_bytes: count &default=0; }; -# TLS content types: -const CHANGE_CIPHER_SPEC = 20; -const ALERT = 21; -const HANDSHAKE = 22; -const APPLICATION_DATA = 23; -const HEARTBEAT = 24; -const V2_ERROR = 300; -const V2_CLIENT_HELLO = 301; -const V2_CLIENT_MASTER_KEY = 302; -const V2_SERVER_HELLO = 304; - type min_length: record { cipher: pattern; min_length: count; @@ -236,9 +225,9 @@ event ssl_encrypted_heartbeat(c: connection, is_orig: bool, length: count) event ssl_encrypted_data(c: connection, is_orig: bool, content_type: count, length: count) { - if ( content_type == HEARTBEAT ) + if ( content_type == SSL::HEARTBEAT ) event ssl_encrypted_heartbeat(c, is_orig, length); - else if ( (content_type == APPLICATION_DATA) && (length > 0) ) + else if ( (content_type == SSL::APPLICATION_DATA) && (length > 0) ) { ++c$ssl$enc_appdata_packages; c$ssl$enc_appdata_bytes += length; From 746c07372924db6d80e93a5553e7241c670d27d0 Mon Sep 17 00:00:00 2001 From: Bernhard Amann Date: Wed, 14 May 2014 15:53:26 -0700 Subject: [PATCH 072/136] Replace errors when parsing x509 certs with weirds (as requested by Seth). The one I did not replace is a malloc issue which I think really should raise an error. --- src/file_analysis/analyzer/x509/X509.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/file_analysis/analyzer/x509/X509.cc b/src/file_analysis/analyzer/x509/X509.cc index 6e0f37e9c9..23cccc6030 100644 --- a/src/file_analysis/analyzer/x509/X509.cc +++ b/src/file_analysis/analyzer/x509/X509.cc @@ -46,7 +46,7 @@ bool file_analysis::X509::EndOfFile() ::X509* ssl_cert = d2i_X509(NULL, &cert_char, cert_data.size()); if ( ! ssl_cert ) { - reporter->Error("Could not parse X509 certificate (fuid %s)", GetFile()->GetID().c_str()); + reporter->Weird(fmt("Could not parse X509 certificate (fuid %s)", GetFile()->GetID().c_str())); return false; } @@ -171,7 +171,7 @@ StringVal* file_analysis::X509::GetExtensionFromBIO(BIO* bio) { char tmp[120]; ERR_error_string_n(ERR_get_error(), tmp, sizeof(tmp)); - reporter->Error("X509::GetExtensionFromBIO: %s", tmp); + reporter->Weird(fmt("X509::GetExtensionFromBIO: %s", tmp)); BIO_free_all(bio); return 0; } @@ -279,7 +279,7 @@ void file_analysis::X509::ParseBasicConstraints(X509_EXTENSION* ex) } else - reporter->Error("Certificate with invalid BasicConstraint. fuid %s", GetFile()->GetID().c_str()); + reporter->Weird(fmt("Certificate with invalid BasicConstraint. fuid %s", GetFile()->GetID().c_str())); } void file_analysis::X509::ParseSAN(X509_EXTENSION* ext) @@ -289,7 +289,7 @@ void file_analysis::X509::ParseSAN(X509_EXTENSION* ext) GENERAL_NAMES *altname = (GENERAL_NAMES*)X509V3_EXT_d2i(ext); if ( ! altname ) { - reporter->Error("Could not parse subject alternative names. fuid %s", GetFile()->GetID().c_str()); + reporter->Weird(fmt("Could not parse subject alternative names. fuid %s", GetFile()->GetID().c_str())); return; } @@ -309,7 +309,7 @@ void file_analysis::X509::ParseSAN(X509_EXTENSION* ext) { if ( ASN1_STRING_type(gen->d.ia5) != V_ASN1_IA5STRING ) { - reporter->Error("DNS-field does not contain an IA5String. fuid %s", GetFile()->GetID().c_str()); + reporter->Weird(fmt("DNS-field does not contain an IA5String. fuid %s", GetFile()->GetID().c_str())); continue; } @@ -356,7 +356,7 @@ void file_analysis::X509::ParseSAN(X509_EXTENSION* ext) else { - reporter->Error("Weird IP address length %d in subject alternative name. fuid %s", gen->d.ip->length, GetFile()->GetID().c_str()); + reporter->Weird(fmt("Weird IP address length %d in subject alternative name. fuid %s", gen->d.ip->length, GetFile()->GetID().c_str())); continue; } } From d88f8d77cb35917a2fe341c87750f1e13a9c5260 Mon Sep 17 00:00:00 2001 From: Vlad Grigorescu Date: Thu, 15 May 2014 09:47:20 -0400 Subject: [PATCH 073/136] Move seq to uint64 to match recent changes in seq processing. --- src/analyzer/protocol/radius/RADIUS.cc | 2 +- src/analyzer/protocol/radius/RADIUS.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/analyzer/protocol/radius/RADIUS.cc b/src/analyzer/protocol/radius/RADIUS.cc index e88bd40083..a73ab49ce2 100644 --- a/src/analyzer/protocol/radius/RADIUS.cc +++ b/src/analyzer/protocol/radius/RADIUS.cc @@ -30,7 +30,7 @@ void RADIUS_Analyzer::Done() } void RADIUS_Analyzer::DeliverPacket(int len, const u_char* data, - bool orig, int seq, const IP_Hdr* ip, int caplen) + bool orig, uint64 seq, const IP_Hdr* ip, int caplen) { Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); diff --git a/src/analyzer/protocol/radius/RADIUS.h b/src/analyzer/protocol/radius/RADIUS.h index 85f8f197a6..c0548a4b6f 100644 --- a/src/analyzer/protocol/radius/RADIUS.h +++ b/src/analyzer/protocol/radius/RADIUS.h @@ -24,7 +24,7 @@ public: virtual void Done(); virtual void DeliverPacket(int len, const u_char* data, bool orig, - int seq, const IP_Hdr* ip, int caplen); + uint64 seq, const IP_Hdr* ip, int caplen); static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) From a3e00322a28eef5c6a573bfe52df802b0a7caf4a Mon Sep 17 00:00:00 2001 From: Vlad Grigorescu Date: Thu, 15 May 2014 11:18:00 -0400 Subject: [PATCH 074/136] Update test baselines. --- scripts/base/protocols/radius/main.bro | 15 +- .../Baseline/core.print-bpf-filters/output2 | 9 +- .../canonified_loaded_scripts.log | 9 +- .../canonified_loaded_scripts.log | 12 +- .../all-events.log | 224 +++++++++--------- .../smtp-events.log | 52 ++-- 6 files changed, 162 insertions(+), 159 deletions(-) diff --git a/scripts/base/protocols/radius/main.bro b/scripts/base/protocols/radius/main.bro index 0b73ecc257..ab4cf16361 100644 --- a/scripts/base/protocols/radius/main.bro +++ b/scripts/base/protocols/radius/main.bro @@ -1,10 +1,9 @@ ##! Implements base functionality for RADIUS analysis. Generates the radius.log file. -# Generated by binpac_quickstart - module RADIUS; @load ./consts.bro +@load base/utils/addrs export { redef enum Log::ID += { LOG }; @@ -77,9 +76,8 @@ event radius_message(c: connection, result: RADIUS::Message) info$id = c$id; } - switch ( result$code ) { - case 1: - # Acess-Request + switch ( RADIUS::msg_types[result$code] ) { + case "Access-Request": if ( result?$attributes ) { # User-Name if ( !info?$username && 1 in result$attributes ) @@ -95,12 +93,10 @@ event radius_message(c: connection, result: RADIUS::Message) info$connect_info = result$attributes[77][0]; } break; - case 2: - # Access-Accept + case "Access-Accept": info$result = "success"; break; - case 3: - # Access-Reject + case "Access-Reject": info$result = "failed"; break; } @@ -116,5 +112,6 @@ event radius_message(c: connection, result: RADIUS::Message) function expire(t: table[count] of Info, idx: count): interval { t[idx]$result = "unknown"; + Log::write(RADIUS::LOG, t[idx]); return 0secs; } \ No newline at end of file diff --git a/testing/btest/Baseline/core.print-bpf-filters/output2 b/testing/btest/Baseline/core.print-bpf-filters/output2 index f2825e6cb8..a803d83b91 100644 --- a/testing/btest/Baseline/core.print-bpf-filters/output2 +++ b/testing/btest/Baseline/core.print-bpf-filters/output2 @@ -2,6 +2,7 @@ 1 137 1 161 1 162 +1 1812 1 20000 1 21 1 2123 @@ -41,8 +42,8 @@ 1 992 1 993 1 995 -45 and -44 or -45 port +46 and +45 or +46 port 32 tcp -13 udp +14 udp diff --git a/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log b/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log index c25c854779..8128554281 100644 --- a/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log +++ b/testing/btest/Baseline/coverage.bare-load-baseline/canonified_loaded_scripts.log @@ -3,7 +3,7 @@ #empty_field (empty) #unset_field - #path loaded_scripts -#open 2014-04-08-22-38-18 +#open 2014-05-15-14-10-48 #fields name #types string scripts/base/init-bare.bro @@ -38,15 +38,16 @@ scripts/base/init-bare.bro build/scripts/base/bif/plugins/Bro_IRC.events.bif.bro build/scripts/base/bif/plugins/Bro_Login.events.bif.bro build/scripts/base/bif/plugins/Bro_Login.functions.bif.bro - build/scripts/base/bif/plugins/Bro_Modbus.events.bif.bro build/scripts/base/bif/plugins/Bro_MIME.events.bif.bro + build/scripts/base/bif/plugins/Bro_Modbus.events.bif.bro build/scripts/base/bif/plugins/Bro_NCP.events.bif.bro - build/scripts/base/bif/plugins/Bro_NetFlow.events.bif.bro build/scripts/base/bif/plugins/Bro_NetBIOS.events.bif.bro build/scripts/base/bif/plugins/Bro_NetBIOS.functions.bif.bro + build/scripts/base/bif/plugins/Bro_NetFlow.events.bif.bro build/scripts/base/bif/plugins/Bro_NTP.events.bif.bro build/scripts/base/bif/plugins/Bro_PIA.events.bif.bro build/scripts/base/bif/plugins/Bro_POP3.events.bif.bro + build/scripts/base/bif/plugins/Bro_RADIUS.events.bif.bro build/scripts/base/bif/plugins/Bro_RPC.events.bif.bro build/scripts/base/bif/plugins/Bro_SNMP.events.bif.bro build/scripts/base/bif/plugins/Bro_SMB.events.bif.bro @@ -106,4 +107,4 @@ scripts/base/init-bare.bro build/scripts/base/bif/broxygen.bif.bro scripts/policy/misc/loaded-scripts.bro scripts/base/utils/paths.bro -#close 2014-04-08-22-38-18 +#close 2014-05-15-14-10-48 diff --git a/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log b/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log index 488b74e111..03c299141c 100644 --- a/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log +++ b/testing/btest/Baseline/coverage.default-load-baseline/canonified_loaded_scripts.log @@ -3,7 +3,7 @@ #empty_field (empty) #unset_field - #path loaded_scripts -#open 2014-04-08-22-38-27 +#open 2014-05-15-14-12-26 #fields name #types string scripts/base/init-bare.bro @@ -38,15 +38,16 @@ scripts/base/init-bare.bro build/scripts/base/bif/plugins/Bro_IRC.events.bif.bro build/scripts/base/bif/plugins/Bro_Login.events.bif.bro build/scripts/base/bif/plugins/Bro_Login.functions.bif.bro - build/scripts/base/bif/plugins/Bro_Modbus.events.bif.bro build/scripts/base/bif/plugins/Bro_MIME.events.bif.bro + build/scripts/base/bif/plugins/Bro_Modbus.events.bif.bro build/scripts/base/bif/plugins/Bro_NCP.events.bif.bro - build/scripts/base/bif/plugins/Bro_NetFlow.events.bif.bro build/scripts/base/bif/plugins/Bro_NetBIOS.events.bif.bro build/scripts/base/bif/plugins/Bro_NetBIOS.functions.bif.bro + build/scripts/base/bif/plugins/Bro_NetFlow.events.bif.bro build/scripts/base/bif/plugins/Bro_NTP.events.bif.bro build/scripts/base/bif/plugins/Bro_PIA.events.bif.bro build/scripts/base/bif/plugins/Bro_POP3.events.bif.bro + build/scripts/base/bif/plugins/Bro_RADIUS.events.bif.bro build/scripts/base/bif/plugins/Bro_RPC.events.bif.bro build/scripts/base/bif/plugins/Bro_SNMP.events.bif.bro build/scripts/base/bif/plugins/Bro_SMB.events.bif.bro @@ -210,6 +211,9 @@ scripts/base/init-default.bro scripts/base/protocols/modbus/consts.bro scripts/base/protocols/modbus/main.bro scripts/base/protocols/pop3/__load__.bro + scripts/base/protocols/radius/__load__.bro + scripts/base/protocols/radius/main.bro + scripts/base/protocols/radius/consts.bro scripts/base/protocols/snmp/__load__.bro scripts/base/protocols/snmp/main.bro scripts/base/protocols/smtp/__load__.bro @@ -232,4 +236,4 @@ scripts/base/init-default.bro scripts/base/misc/find-checksum-offloading.bro scripts/base/misc/find-filtered-trace.bro scripts/policy/misc/loaded-scripts.bro -#close 2014-04-08-22-38-27 +#close 2014-05-15-14-12-26 diff --git a/testing/btest/Baseline/scripts.policy.misc.dump-events/all-events.log b/testing/btest/Baseline/scripts.policy.misc.dump-events/all-events.log index c964e793de..4ccfd356c9 100644 --- a/testing/btest/Baseline/scripts.policy.misc.dump-events/all-events.log +++ b/testing/btest/Baseline/scripts.policy.misc.dump-events/all-events.log @@ -1,62 +1,62 @@ 0.000000 bro_init 0.000000 filter_change_tracking 1254722767.492060 protocol_confirmation - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.0, service={^J^J}, addl=, hot=0, history=D, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.0, service={^J^J}, addl=, hot=0, history=D, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] [1] atype: enum = Analyzer::ANALYZER_DNS [2] aid: count = 3 1254722767.492060 ChecksumOffloading::check 1254722767.492060 filter_change_tracking 1254722767.492060 new_connection - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.0, service={^J^IDNS^J}, addl=, hot=0, history=D, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.0, service={^J^IDNS^J}, addl=, hot=0, history=D, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] 1254722767.492060 dns_message - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.0, service={^J^IDNS^J}, addl=, hot=0, history=D, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.0, service={^J^IDNS^J}, addl=, hot=0, history=D, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] [1] is_orig: bool = T [2] msg: dns_msg = [id=31062, opcode=0, rcode=0, QR=F, AA=F, TC=F, RD=T, RA=F, Z=0, num_queries=1, num_answers=0, num_auth=0, num_addl=0] [3] len: count = 34 1254722767.492060 dns_request - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.0, service={^J^IDNS^J}, addl=, hot=0, history=D, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=[ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=, qclass=, qclass_name=, qtype=, qtype_name=, rcode=, rcode_name=, AA=F, TC=F, RD=F, RA=F, Z=0, answers=, TTLs=, rejected=F, total_answers=, total_replies=, saw_query=F, saw_reply=F], dns_state=[pending_queries={^J^I[31062] = [initialized=T, vals={^J^I^I[0] = [ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=, qclass=, qclass_name=, qtype=, qtype_name=, rcode=, rcode_name=, AA=F, TC=F, RD=F, RA=F, Z=0, answers=, TTLs=, rejected=F, total_answers=, total_replies=, saw_query=F, saw_reply=F]^J^I}, settings=[max_len=], top=1, bottom=0, size=0]^J}, pending_replies={^J^J}], ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.0, service={^J^IDNS^J}, addl=, hot=0, history=D, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=[ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=, qclass=, qclass_name=, qtype=, qtype_name=, rcode=, rcode_name=, AA=F, TC=F, RD=F, RA=F, Z=0, answers=, TTLs=, rejected=F, total_answers=, total_replies=, saw_query=F, saw_reply=F], dns_state=[pending_queries={^J^I[31062] = [initialized=T, vals={^J^I^I[0] = [ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=, qclass=, qclass_name=, qtype=, qtype_name=, rcode=, rcode_name=, AA=F, TC=F, RD=F, RA=F, Z=0, answers=, TTLs=, rejected=F, total_answers=, total_replies=, saw_query=F, saw_reply=F]^J^I}, settings=[max_len=], top=1, bottom=0, size=0]^J}, pending_replies={^J^J}], ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] [1] msg: dns_msg = [id=31062, opcode=0, rcode=0, QR=F, AA=F, TC=F, RD=T, RA=F, Z=0, num_queries=1, num_answers=0, num_auth=0, num_addl=0] [2] query: string = mail.patriots.in [3] qtype: count = 1 [4] qclass: count = 1 1254722767.492060 dns_end - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.0, service={^J^IDNS^J}, addl=, hot=0, history=D, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=[ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=mail.patriots.in, qclass=1, qclass_name=C_INTERNET, qtype=1, qtype_name=A, rcode=, rcode_name=, AA=F, TC=F, RD=T, RA=F, Z=0, answers=, TTLs=, rejected=F, total_answers=, total_replies=, saw_query=F, saw_reply=F], dns_state=[pending_queries={^J^I[31062] = [initialized=T, vals={^J^I^I[0] = [ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=mail.patriots.in, qclass=1, qclass_name=C_INTERNET, qtype=1, qtype_name=A, rcode=, rcode_name=, AA=F, TC=F, RD=T, RA=F, Z=0, answers=, TTLs=, rejected=F, total_answers=, total_replies=, saw_query=F, saw_reply=F]^J^I}, settings=[max_len=], top=1, bottom=0, size=0]^J}, pending_replies={^J^J}], ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.0, service={^J^IDNS^J}, addl=, hot=0, history=D, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=[ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=mail.patriots.in, qclass=1, qclass_name=C_INTERNET, qtype=1, qtype_name=A, rcode=, rcode_name=, AA=F, TC=F, RD=T, RA=F, Z=0, answers=, TTLs=, rejected=F, total_answers=, total_replies=, saw_query=F, saw_reply=F], dns_state=[pending_queries={^J^I[31062] = [initialized=T, vals={^J^I^I[0] = [ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=mail.patriots.in, qclass=1, qclass_name=C_INTERNET, qtype=1, qtype_name=A, rcode=, rcode_name=, AA=F, TC=F, RD=T, RA=F, Z=0, answers=, TTLs=, rejected=F, total_answers=, total_replies=, saw_query=F, saw_reply=F]^J^I}, settings=[max_len=], top=1, bottom=0, size=0]^J}, pending_replies={^J^J}], ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] [1] msg: dns_msg = [id=31062, opcode=0, rcode=0, QR=F, AA=F, TC=F, RD=T, RA=F, Z=0, num_queries=1, num_answers=0, num_auth=0, num_addl=0] 1254722767.526085 dns_message - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=1, num_bytes_ip=62, flow_label=0], resp=[size=100, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.034025, service={^J^IDNS^J}, addl=, hot=0, history=Dd, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=[ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=mail.patriots.in, qclass=1, qclass_name=C_INTERNET, qtype=1, qtype_name=A, rcode=, rcode_name=, AA=F, TC=F, RD=T, RA=F, Z=0, answers=, TTLs=, rejected=F, total_answers=, total_replies=, saw_query=T, saw_reply=F], dns_state=[pending_queries={^J^I[31062] = [initialized=T, vals={^J^I^I[0] = [ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=mail.patriots.in, qclass=1, qclass_name=C_INTERNET, qtype=1, qtype_name=A, rcode=, rcode_name=, AA=F, TC=F, RD=T, RA=F, Z=0, answers=, TTLs=, rejected=F, total_answers=, total_replies=, saw_query=T, saw_reply=F]^J^I}, settings=[max_len=], top=1, bottom=0, size=0]^J}, pending_replies={^J^J}], ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=1, num_bytes_ip=62, flow_label=0], resp=[size=100, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.034025, service={^J^IDNS^J}, addl=, hot=0, history=Dd, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=[ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=mail.patriots.in, qclass=1, qclass_name=C_INTERNET, qtype=1, qtype_name=A, rcode=, rcode_name=, AA=F, TC=F, RD=T, RA=F, Z=0, answers=, TTLs=, rejected=F, total_answers=, total_replies=, saw_query=T, saw_reply=F], dns_state=[pending_queries={^J^I[31062] = [initialized=T, vals={^J^I^I[0] = [ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=mail.patriots.in, qclass=1, qclass_name=C_INTERNET, qtype=1, qtype_name=A, rcode=, rcode_name=, AA=F, TC=F, RD=T, RA=F, Z=0, answers=, TTLs=, rejected=F, total_answers=, total_replies=, saw_query=T, saw_reply=F]^J^I}, settings=[max_len=], top=1, bottom=0, size=0]^J}, pending_replies={^J^J}], ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] [1] is_orig: bool = F [2] msg: dns_msg = [id=31062, opcode=0, rcode=0, QR=T, AA=F, TC=F, RD=T, RA=T, Z=0, num_queries=1, num_answers=2, num_auth=2, num_addl=0] [3] len: count = 100 1254722767.526085 dns_CNAME_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=1, num_bytes_ip=62, flow_label=0], resp=[size=100, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.034025, service={^J^IDNS^J}, addl=, hot=0, history=Dd, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=[ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=mail.patriots.in, qclass=1, qclass_name=C_INTERNET, qtype=1, qtype_name=A, rcode=0, rcode_name=NOERROR, AA=F, TC=F, RD=T, RA=F, Z=0, answers=, TTLs=, rejected=F, total_answers=2, total_replies=4, saw_query=T, saw_reply=F], dns_state=[pending_queries={^J^J}, pending_replies={^J^J}], ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=1, num_bytes_ip=62, flow_label=0], resp=[size=100, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.034025, service={^J^IDNS^J}, addl=, hot=0, history=Dd, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=[ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=mail.patriots.in, qclass=1, qclass_name=C_INTERNET, qtype=1, qtype_name=A, rcode=0, rcode_name=NOERROR, AA=F, TC=F, RD=T, RA=F, Z=0, answers=, TTLs=, rejected=F, total_answers=2, total_replies=4, saw_query=T, saw_reply=F], dns_state=[pending_queries={^J^J}, pending_replies={^J^J}], ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] [1] msg: dns_msg = [id=31062, opcode=0, rcode=0, QR=T, AA=F, TC=F, RD=T, RA=T, Z=0, num_queries=1, num_answers=2, num_auth=2, num_addl=0] [2] ans: dns_answer = [answer_type=1, query=mail.patriots.in, qtype=5, qclass=1, TTL=3.0 hrs 27.0 secs] [3] name: string = patriots.in 1254722767.526085 dns_A_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=1, num_bytes_ip=62, flow_label=0], resp=[size=100, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.034025, service={^J^IDNS^J}, addl=, hot=0, history=Dd, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=[ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=mail.patriots.in, qclass=1, qclass_name=C_INTERNET, qtype=1, qtype_name=A, rcode=0, rcode_name=NOERROR, AA=F, TC=F, RD=T, RA=T, Z=0, answers=[patriots.in], TTLs=[3.0 hrs 27.0 secs], rejected=F, total_answers=2, total_replies=4, saw_query=T, saw_reply=F], dns_state=[pending_queries={^J^J}, pending_replies={^J^J}], ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=1, num_bytes_ip=62, flow_label=0], resp=[size=100, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.034025, service={^J^IDNS^J}, addl=, hot=0, history=Dd, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=[ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=mail.patriots.in, qclass=1, qclass_name=C_INTERNET, qtype=1, qtype_name=A, rcode=0, rcode_name=NOERROR, AA=F, TC=F, RD=T, RA=T, Z=0, answers=[patriots.in], TTLs=[3.0 hrs 27.0 secs], rejected=F, total_answers=2, total_replies=4, saw_query=T, saw_reply=F], dns_state=[pending_queries={^J^J}, pending_replies={^J^J}], ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] [1] msg: dns_msg = [id=31062, opcode=0, rcode=0, QR=T, AA=F, TC=F, RD=T, RA=T, Z=0, num_queries=1, num_answers=2, num_auth=2, num_addl=0] [2] ans: dns_answer = [answer_type=1, query=patriots.in, qtype=1, qclass=1, TTL=3.0 hrs 28.0 secs] [3] a: addr = 74.53.140.153 1254722767.526085 dns_end - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=1, num_bytes_ip=62, flow_label=0], resp=[size=100, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.034025, service={^J^IDNS^J}, addl=, hot=0, history=Dd, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=[ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=mail.patriots.in, qclass=1, qclass_name=C_INTERNET, qtype=1, qtype_name=A, rcode=0, rcode_name=NOERROR, AA=F, TC=F, RD=T, RA=T, Z=0, answers=[patriots.in, 74.53.140.153], TTLs=[3.0 hrs 27.0 secs, 3.0 hrs 28.0 secs], rejected=F, total_answers=2, total_replies=4, saw_query=T, saw_reply=F], dns_state=[pending_queries={^J^J}, pending_replies={^J^J}], ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], orig=[size=34, state=1, num_pkts=1, num_bytes_ip=62, flow_label=0], resp=[size=100, state=1, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.49206, duration=0.034025, service={^J^IDNS^J}, addl=, hot=0, history=Dd, uid=CXWv6p3arKYeMETxOg, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=[ts=1254722767.49206, uid=CXWv6p3arKYeMETxOg, id=[orig_h=10.10.1.4, orig_p=56166/udp, resp_h=10.10.1.1, resp_p=53/udp], proto=udp, trans_id=31062, query=mail.patriots.in, qclass=1, qclass_name=C_INTERNET, qtype=1, qtype_name=A, rcode=0, rcode_name=NOERROR, AA=F, TC=F, RD=T, RA=T, Z=0, answers=[patriots.in, 74.53.140.153], TTLs=[3.0 hrs 27.0 secs, 3.0 hrs 28.0 secs], rejected=F, total_answers=2, total_replies=4, saw_query=T, saw_reply=F], dns_state=[pending_queries={^J^J}, pending_replies={^J^J}], ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] [1] msg: dns_msg = [id=31062, opcode=0, rcode=0, QR=T, AA=F, TC=F, RD=T, RA=T, Z=0, num_queries=1, num_answers=2, num_auth=2, num_addl=0] 1254722767.529046 new_connection - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.529046, duration=0.0, service={^J^J}, addl=, hot=0, history=, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], resp=[size=0, state=0, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.529046, duration=0.0, service={^J^J}, addl=, hot=0, history=, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] 1254722767.875996 connection_established - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=0, state=4, num_pkts=1, num_bytes_ip=48, flow_label=0], resp=[size=0, state=4, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.529046, duration=0.34695, service={^J^J}, addl=, hot=0, history=Sh, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=0, state=4, num_pkts=1, num_bytes_ip=48, flow_label=0], resp=[size=0, state=4, num_pkts=0, num_bytes_ip=0, flow_label=0], start_time=1254722767.529046, duration=0.34695, service={^J^J}, addl=, hot=0, history=Sh, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] 1254722768.219663 smtp_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=0, state=4, num_pkts=2, num_bytes_ip=88, flow_label=0], resp=[size=181, state=4, num_pkts=1, num_bytes_ip=48, flow_label=0], start_time=1254722767.529046, duration=0.690617, service={^J^J}, addl=, hot=0, history=ShAd, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=0, state=4, num_pkts=2, num_bytes_ip=88, flow_label=0], resp=[size=181, state=4, num_pkts=1, num_bytes_ip=48, flow_label=0], start_time=1254722767.529046, duration=0.690617, service={^J^J}, addl=, hot=0, history=ShAd, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=, smtp_state=, socks=, ssh=, syslog=] [1] is_orig: bool = F [2] code: count = 220 [3] cmd: string = > @@ -64,7 +64,7 @@ [5] cont_resp: bool = T 1254722768.219663 smtp_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=0, state=4, num_pkts=2, num_bytes_ip=88, flow_label=0], resp=[size=181, state=4, num_pkts=1, num_bytes_ip=48, flow_label=0], start_time=1254722767.529046, duration=0.690617, service={^J^J}, addl=, hot=0, history=ShAd, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=220 xc90.websitewelcome.com ESMTP Exim 4.69 #1 Mon, 05 Oct 2009 01:05:54 -0500 , path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=F, entity=, fuids=[]], smtp_state=[helo=, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=0, state=4, num_pkts=2, num_bytes_ip=88, flow_label=0], resp=[size=181, state=4, num_pkts=1, num_bytes_ip=48, flow_label=0], start_time=1254722767.529046, duration=0.690617, service={^J^J}, addl=, hot=0, history=ShAd, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=220 xc90.websitewelcome.com ESMTP Exim 4.69 #1 Mon, 05 Oct 2009 01:05:54 -0500 , path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=F, entity=, fuids=[]], smtp_state=[helo=, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = F [2] code: count = 220 [3] cmd: string = > @@ -72,7 +72,7 @@ [5] cont_resp: bool = T 1254722768.219663 smtp_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=0, state=4, num_pkts=2, num_bytes_ip=88, flow_label=0], resp=[size=181, state=4, num_pkts=1, num_bytes_ip=48, flow_label=0], start_time=1254722767.529046, duration=0.690617, service={^J^J}, addl=, hot=0, history=ShAd, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=220 We do not authorize the use of this system to transport unsolicited, , path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=F, entity=, fuids=[]], smtp_state=[helo=, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=0, state=4, num_pkts=2, num_bytes_ip=88, flow_label=0], resp=[size=181, state=4, num_pkts=1, num_bytes_ip=48, flow_label=0], start_time=1254722767.529046, duration=0.690617, service={^J^J}, addl=, hot=0, history=ShAd, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=220 We do not authorize the use of this system to transport unsolicited, , path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=F, entity=, fuids=[]], smtp_state=[helo=, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = F [2] code: count = 220 [3] cmd: string = > @@ -80,18 +80,18 @@ [5] cont_resp: bool = F 1254722768.224809 protocol_confirmation - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=2, num_bytes_ip=88, flow_label=0], resp=[size=181, state=4, num_pkts=2, num_bytes_ip=269, flow_label=0], start_time=1254722767.529046, duration=0.695763, service={^J^J}, addl=, hot=0, history=ShAdD, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=220 and/or bulk e-mail., path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=F, entity=, fuids=[]], smtp_state=[helo=, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=2, num_bytes_ip=88, flow_label=0], resp=[size=181, state=4, num_pkts=2, num_bytes_ip=269, flow_label=0], start_time=1254722767.529046, duration=0.695763, service={^J^J}, addl=, hot=0, history=ShAdD, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=220 and/or bulk e-mail., path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=F, entity=, fuids=[]], smtp_state=[helo=, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] atype: enum = Analyzer::ANALYZER_SMTP [2] aid: count = 7 1254722768.224809 smtp_request - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=2, num_bytes_ip=88, flow_label=0], resp=[size=181, state=4, num_pkts=2, num_bytes_ip=269, flow_label=0], start_time=1254722767.529046, duration=0.695763, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdD, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=220 and/or bulk e-mail., path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=F, entity=, fuids=[]], smtp_state=[helo=, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=2, num_bytes_ip=88, flow_label=0], resp=[size=181, state=4, num_pkts=2, num_bytes_ip=269, flow_label=0], start_time=1254722767.529046, duration=0.695763, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdD, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=220 and/or bulk e-mail., path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=F, entity=, fuids=[]], smtp_state=[helo=, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = T [2] command: string = EHLO [3] arg: string = GP 1254722768.566183 smtp_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=3, num_bytes_ip=137, flow_label=0], resp=[size=318, state=4, num_pkts=3, num_bytes_ip=309, flow_label=0], start_time=1254722767.529046, duration=1.037137, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=220 and/or bulk e-mail., path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=3, num_bytes_ip=137, flow_label=0], resp=[size=318, state=4, num_pkts=3, num_bytes_ip=309, flow_label=0], start_time=1254722767.529046, duration=1.037137, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=220 and/or bulk e-mail., path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = F [2] code: count = 250 [3] cmd: string = EHLO @@ -99,7 +99,7 @@ [5] cont_resp: bool = T 1254722768.566183 smtp_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=3, num_bytes_ip=137, flow_label=0], resp=[size=318, state=4, num_pkts=3, num_bytes_ip=309, flow_label=0], start_time=1254722767.529046, duration=1.037137, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 xc90.websitewelcome.com Hello GP [122.162.143.157], path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=3, num_bytes_ip=137, flow_label=0], resp=[size=318, state=4, num_pkts=3, num_bytes_ip=309, flow_label=0], start_time=1254722767.529046, duration=1.037137, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 xc90.websitewelcome.com Hello GP [122.162.143.157], path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = F [2] code: count = 250 [3] cmd: string = EHLO @@ -107,7 +107,7 @@ [5] cont_resp: bool = T 1254722768.566183 smtp_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=3, num_bytes_ip=137, flow_label=0], resp=[size=318, state=4, num_pkts=3, num_bytes_ip=309, flow_label=0], start_time=1254722767.529046, duration=1.037137, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 SIZE 52428800, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=3, num_bytes_ip=137, flow_label=0], resp=[size=318, state=4, num_pkts=3, num_bytes_ip=309, flow_label=0], start_time=1254722767.529046, duration=1.037137, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 SIZE 52428800, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = F [2] code: count = 250 [3] cmd: string = EHLO @@ -115,7 +115,7 @@ [5] cont_resp: bool = T 1254722768.566183 smtp_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=3, num_bytes_ip=137, flow_label=0], resp=[size=318, state=4, num_pkts=3, num_bytes_ip=309, flow_label=0], start_time=1254722767.529046, duration=1.037137, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 PIPELINING, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=3, num_bytes_ip=137, flow_label=0], resp=[size=318, state=4, num_pkts=3, num_bytes_ip=309, flow_label=0], start_time=1254722767.529046, duration=1.037137, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 PIPELINING, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = F [2] code: count = 250 [3] cmd: string = EHLO @@ -123,7 +123,7 @@ [5] cont_resp: bool = T 1254722768.566183 smtp_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=3, num_bytes_ip=137, flow_label=0], resp=[size=318, state=4, num_pkts=3, num_bytes_ip=309, flow_label=0], start_time=1254722767.529046, duration=1.037137, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 AUTH PLAIN LOGIN, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=3, num_bytes_ip=137, flow_label=0], resp=[size=318, state=4, num_pkts=3, num_bytes_ip=309, flow_label=0], start_time=1254722767.529046, duration=1.037137, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 AUTH PLAIN LOGIN, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = F [2] code: count = 250 [3] cmd: string = EHLO @@ -131,7 +131,7 @@ [5] cont_resp: bool = T 1254722768.566183 smtp_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=3, num_bytes_ip=137, flow_label=0], resp=[size=318, state=4, num_pkts=3, num_bytes_ip=309, flow_label=0], start_time=1254722767.529046, duration=1.037137, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 STARTTLS, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=9, state=4, num_pkts=3, num_bytes_ip=137, flow_label=0], resp=[size=318, state=4, num_pkts=3, num_bytes_ip=309, flow_label=0], start_time=1254722767.529046, duration=1.037137, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 STARTTLS, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = F [2] code: count = 250 [3] cmd: string = EHLO @@ -139,13 +139,13 @@ [5] cont_resp: bool = F 1254722768.568729 smtp_request - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=21, state=4, num_pkts=3, num_bytes_ip=137, flow_label=0], resp=[size=318, state=4, num_pkts=4, num_bytes_ip=486, flow_label=0], start_time=1254722767.529046, duration=1.039683, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 HELP, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=21, state=4, num_pkts=3, num_bytes_ip=137, flow_label=0], resp=[size=318, state=4, num_pkts=4, num_bytes_ip=486, flow_label=0], start_time=1254722767.529046, duration=1.039683, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 HELP, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = T [2] command: string = AUTH [3] arg: string = LOGIN 1254722768.911081 smtp_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=21, state=4, num_pkts=4, num_bytes_ip=189, flow_label=0], resp=[size=336, state=4, num_pkts=4, num_bytes_ip=486, flow_label=0], start_time=1254722767.529046, duration=1.382035, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 HELP, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=21, state=4, num_pkts=4, num_bytes_ip=189, flow_label=0], resp=[size=336, state=4, num_pkts=4, num_bytes_ip=486, flow_label=0], start_time=1254722767.529046, duration=1.382035, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 HELP, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = F [2] code: count = 334 [3] cmd: string = AUTH @@ -153,13 +153,13 @@ [5] cont_resp: bool = F 1254722768.911655 smtp_request - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=51, state=4, num_pkts=4, num_bytes_ip=189, flow_label=0], resp=[size=336, state=4, num_pkts=5, num_bytes_ip=544, flow_label=0], start_time=1254722767.529046, duration=1.382609, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=334 VXNlcm5hbWU6, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=51, state=4, num_pkts=4, num_bytes_ip=189, flow_label=0], resp=[size=336, state=4, num_pkts=5, num_bytes_ip=544, flow_label=0], start_time=1254722767.529046, duration=1.382609, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=334 VXNlcm5hbWU6, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = T [2] command: string = ** [3] arg: string = Z3VycGFydGFwQHBhdHJpb3RzLmlu 1254722769.253544 smtp_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=51, state=4, num_pkts=5, num_bytes_ip=259, flow_label=0], resp=[size=354, state=4, num_pkts=5, num_bytes_ip=544, flow_label=0], start_time=1254722767.529046, duration=1.724498, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=334 VXNlcm5hbWU6, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=51, state=4, num_pkts=5, num_bytes_ip=259, flow_label=0], resp=[size=354, state=4, num_pkts=5, num_bytes_ip=544, flow_label=0], start_time=1254722767.529046, duration=1.724498, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=334 VXNlcm5hbWU6, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = F [2] code: count = 334 [3] cmd: string = AUTH_ANSWER @@ -167,13 +167,13 @@ [5] cont_resp: bool = F 1254722769.254118 smtp_request - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=69, state=4, num_pkts=5, num_bytes_ip=259, flow_label=0], resp=[size=354, state=4, num_pkts=6, num_bytes_ip=602, flow_label=0], start_time=1254722767.529046, duration=1.725072, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=334 UGFzc3dvcmQ6, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=69, state=4, num_pkts=5, num_bytes_ip=259, flow_label=0], resp=[size=354, state=4, num_pkts=6, num_bytes_ip=602, flow_label=0], start_time=1254722767.529046, duration=1.725072, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=334 UGFzc3dvcmQ6, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = T [2] command: string = ** [3] arg: string = cHVuamFiQDEyMw== 1254722769.613798 smtp_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=69, state=4, num_pkts=6, num_bytes_ip=317, flow_label=0], resp=[size=384, state=4, num_pkts=6, num_bytes_ip=602, flow_label=0], start_time=1254722767.529046, duration=2.084752, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=334 UGFzc3dvcmQ6, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=69, state=4, num_pkts=6, num_bytes_ip=317, flow_label=0], resp=[size=384, state=4, num_pkts=6, num_bytes_ip=602, flow_label=0], start_time=1254722767.529046, duration=2.084752, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=334 UGFzc3dvcmQ6, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = F [2] code: count = 235 [3] cmd: string = AUTH_ANSWER @@ -181,13 +181,13 @@ [5] cont_resp: bool = F 1254722769.614414 smtp_request - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=105, state=4, num_pkts=6, num_bytes_ip=317, flow_label=0], resp=[size=384, state=4, num_pkts=7, num_bytes_ip=672, flow_label=0], start_time=1254722767.529046, duration=2.085368, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=235 Authentication succeeded, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=105, state=4, num_pkts=6, num_bytes_ip=317, flow_label=0], resp=[size=384, state=4, num_pkts=7, num_bytes_ip=672, flow_label=0], start_time=1254722767.529046, duration=2.085368, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=235 Authentication succeeded, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = T [2] command: string = MAIL [3] arg: string = FROM: 1254722769.956765 smtp_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=105, state=4, num_pkts=7, num_bytes_ip=393, flow_label=0], resp=[size=392, state=4, num_pkts=7, num_bytes_ip=672, flow_label=0], start_time=1254722767.529046, duration=2.427719, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=235 Authentication succeeded, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=105, state=4, num_pkts=7, num_bytes_ip=393, flow_label=0], resp=[size=392, state=4, num_pkts=7, num_bytes_ip=672, flow_label=0], start_time=1254722767.529046, duration=2.427719, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=235 Authentication succeeded, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = F [2] code: count = 250 [3] cmd: string = MAIL @@ -195,13 +195,13 @@ [5] cont_resp: bool = F 1254722769.957250 smtp_request - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=144, state=4, num_pkts=7, num_bytes_ip=393, flow_label=0], resp=[size=392, state=4, num_pkts=8, num_bytes_ip=720, flow_label=0], start_time=1254722767.529046, duration=2.428204, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 OK, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=144, state=4, num_pkts=7, num_bytes_ip=393, flow_label=0], resp=[size=392, state=4, num_pkts=8, num_bytes_ip=720, flow_label=0], start_time=1254722767.529046, duration=2.428204, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto=, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 OK, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = T [2] command: string = RCPT [3] arg: string = TO: 1254722770.319708 smtp_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=144, state=4, num_pkts=8, num_bytes_ip=472, flow_label=0], resp=[size=406, state=4, num_pkts=8, num_bytes_ip=720, flow_label=0], start_time=1254722767.529046, duration=2.790662, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 OK, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=144, state=4, num_pkts=8, num_bytes_ip=472, flow_label=0], resp=[size=406, state=4, num_pkts=8, num_bytes_ip=720, flow_label=0], start_time=1254722767.529046, duration=2.790662, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 OK, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = F [2] code: count = 250 [3] cmd: string = RCPT @@ -209,16 +209,16 @@ [5] cont_resp: bool = F 1254722770.320203 smtp_request - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=150, state=4, num_pkts=8, num_bytes_ip=472, flow_label=0], resp=[size=406, state=4, num_pkts=9, num_bytes_ip=774, flow_label=0], start_time=1254722767.529046, duration=2.791157, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 Accepted, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=150, state=4, num_pkts=8, num_bytes_ip=472, flow_label=0], resp=[size=406, state=4, num_pkts=9, num_bytes_ip=774, flow_label=0], start_time=1254722767.529046, duration=2.791157, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 Accepted, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] [1] is_orig: bool = T [2] command: string = DATA [3] arg: string = 1254722770.320203 mime_begin_entity - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=150, state=4, num_pkts=8, num_bytes_ip=472, flow_label=0], resp=[size=406, state=4, num_pkts=9, num_bytes_ip=774, flow_label=0], start_time=1254722767.529046, duration=2.791157, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 Accepted, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=150, state=4, num_pkts=8, num_bytes_ip=472, flow_label=0], resp=[size=406, state=4, num_pkts=9, num_bytes_ip=774, flow_label=0], start_time=1254722767.529046, duration=2.791157, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 Accepted, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=0], socks=, ssh=, syslog=] 1254722770.661679 smtp_reply - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=150, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=9, num_bytes_ip=774, flow_label=0], start_time=1254722767.529046, duration=3.132633, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 Accepted, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=150, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=9, num_bytes_ip=774, flow_label=0], start_time=1254722767.529046, duration=3.132633, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=250 Accepted, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] [1] is_orig: bool = F [2] code: count = 354 [3] cmd: string = DATA @@ -226,286 +226,286 @@ [5] cont_resp: bool = F 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from=, to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=FROM, value="Gurpartap Singh" ] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from="Gurpartap Singh" , to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from="Gurpartap Singh" , to=, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=TO, value=] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=, in_reply_to=, subject=, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=SUBJECT, value=SMTP] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=DATE, value=Mon, 5 Oct 2009 11:36:07 +0530] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=MESSAGE-ID, value=<000301ca4581$ef9e57f0$cedb07d0$@in>] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=MIME-VERSION, value=1.0] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=CONTENT-TYPE, value=multipart/mixed;^Iboundary="----=_NextPart_000_0004_01CA45B0.095693F0"] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=X-MAILER, value=Microsoft Office Outlook 12.0] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=THREAD-INDEX, value=AcpFgem9BvjjZEDeR1Kh8i+hUyVo0A==] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=CONTENT-LANGUAGE, value=en-us] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=X-CR-HASHEDPUZZLE, value=SeA= AAR2 ADaH BpiO C4G1 D1gW FNB1 FPkR Fn+W HFCP HnYJ JO7s Kum6 KytW LFcI LjUt;1;cgBhAGoAXwBkAGUAbwBsADIAMAAwADIAaQBuAEAAeQBhAGgAbwBvAC4AYwBvAC4AaQBuAA==;Sosha1_v1;7;{CAA37F59-1850-45C7-8540-AA27696B5398};ZwB1AHIAcABhAHIAdABhAHAAQABwAGEAdAByAGkAbwB0AHMALgBpAG4A;Mon, 05 Oct 2009 06:06:01 GMT;UwBNAFQAUAA=] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=X-CR-PUZZLEID, value={CAA37F59-1850-45C7-8540-AA27696B5398}] 1254722770.692743 mime_begin_entity - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=1], socks=, ssh=, syslog=] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=2], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=2], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=CONTENT-TYPE, value=multipart/alternative;^Iboundary="----=_NextPart_001_0005_01CA45B0.095693F0"] 1254722770.692743 mime_begin_entity - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=2], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=2], socks=, ssh=, syslog=] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=CONTENT-TYPE, value=text/plain;^Icharset="us-ascii"] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=CONTENT-TRANSFER-ENCODING, value=7bit] 1254722770.692743 get_file_handle [0] tag: enum = Analyzer::ANALYZER_SMTP - [1] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] + [1] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] [2] is_orig: bool = F 1254722770.692743 mime_end_entity - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] 1254722770.692743 get_file_handle [0] tag: enum = Analyzer::ANALYZER_SMTP - [1] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] + [1] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] [2] is_orig: bool = T 1254722770.692743 file_new - [0] f: fa_file = [id=Fel9gs4OtNEV6gUJZ5, parent_id=, source=SMTP, is_orig=F, conns={^J^I[[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp]] = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^I^ISMTP^J^I}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^I^J^I}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^I^J^I}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=]^J}, last_active=1254722770.692743, seen_bytes=0, total_bytes=, missing_bytes=0, overflow_bytes=0, timeout_interval=2.0 mins, bof_buffer_size=1024, bof_buffer=Hello^M^J^M^J ^M^J^M^JI send u smtp pcap file ^M^J^M^JFind the attachment^M^J^M^J ^M^J^M^JGPS^M^J^M^J^M^J, mime_type=text/plain, mime_types=[[strength=-20, mime=text/plain]], info=, u2_events=] + [0] f: fa_file = [id=Fel9gs4OtNEV6gUJZ5, parent_id=, source=SMTP, is_orig=F, conns={^J^I[[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp]] = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^I^ISMTP^J^I}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^I^J^I}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^I^J^I}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=]^J}, last_active=1254722770.692743, seen_bytes=0, total_bytes=, missing_bytes=0, overflow_bytes=0, timeout_interval=2.0 mins, bof_buffer_size=1024, bof_buffer=Hello^M^J^M^J ^M^J^M^JI send u smtp pcap file ^M^J^M^JFind the attachment^M^J^M^J ^M^J^M^JGPS^M^J^M^J^M^J, mime_type=text/plain, mime_types=[[strength=-20, mime=text/plain]], info=, u2_events=] 1254722770.692743 file_over_new_connection - [0] f: fa_file = [id=Fel9gs4OtNEV6gUJZ5, parent_id=, source=SMTP, is_orig=F, conns={^J^I[[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp]] = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^I^ISMTP^J^I}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^I^J^I}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^I^J^I}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=]^J}, last_active=1254722770.692743, seen_bytes=0, total_bytes=, missing_bytes=0, overflow_bytes=0, timeout_interval=2.0 mins, bof_buffer_size=1024, bof_buffer=Hello^M^J^M^J ^M^J^M^JI send u smtp pcap file ^M^J^M^JFind the attachment^M^J^M^J ^M^J^M^JGPS^M^J^M^J^M^J, mime_type=text/plain, mime_types=[[strength=-20, mime=text/plain]], info=[ts=1254722770.692743, fuid=Fel9gs4OtNEV6gUJZ5, tx_hosts={^J^J}, rx_hosts={^J^J}, conn_uids={^J^J}, source=SMTP, depth=0, analyzers={^J^J}, mime_type=text/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=] - [1] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] + [0] f: fa_file = [id=Fel9gs4OtNEV6gUJZ5, parent_id=, source=SMTP, is_orig=F, conns={^J^I[[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp]] = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^I^ISMTP^J^I}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^I^J^I}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^I^J^I}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=]^J}, last_active=1254722770.692743, seen_bytes=0, total_bytes=, missing_bytes=0, overflow_bytes=0, timeout_interval=2.0 mins, bof_buffer_size=1024, bof_buffer=Hello^M^J^M^J ^M^J^M^JI send u smtp pcap file ^M^J^M^JFind the attachment^M^J^M^J ^M^J^M^JGPS^M^J^M^J^M^J, mime_type=text/plain, mime_types=[[strength=-20, mime=text/plain]], info=[ts=1254722770.692743, fuid=Fel9gs4OtNEV6gUJZ5, tx_hosts={^J^J}, rx_hosts={^J^J}, conn_uids={^J^J}, source=SMTP, depth=0, analyzers={^J^J}, mime_type=text/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=] + [1] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=, fuids=[]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] [2] is_orig: bool = F 1254722770.692743 file_state_remove - [0] f: fa_file = [id=Fel9gs4OtNEV6gUJZ5, parent_id=, source=SMTP, is_orig=F, conns={^J^I[[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp]] = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^I^ISMTP^J^I}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^I^J^I}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^I^J^I}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=, fuids=[Fel9gs4OtNEV6gUJZ5]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=]^J}, last_active=1254722770.692743, seen_bytes=79, total_bytes=, missing_bytes=0, overflow_bytes=0, timeout_interval=2.0 mins, bof_buffer_size=1024, bof_buffer=Hello^M^J^M^J ^M^J^M^JI send u smtp pcap file ^M^J^M^JFind the attachment^M^J^M^J ^M^J^M^JGPS^M^J^M^J^M^J, mime_type=text/plain, mime_types=[[strength=-20, mime=text/plain]], info=[ts=1254722770.692743, fuid=Fel9gs4OtNEV6gUJZ5, tx_hosts={^J^I74.53.140.153^J}, rx_hosts={^J^I10.10.1.4^J}, conn_uids={^J^ICjhGID4nQcgTWjvg4c^J}, source=SMTP, depth=3, analyzers={^J^J}, mime_type=text/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=] + [0] f: fa_file = [id=Fel9gs4OtNEV6gUJZ5, parent_id=, source=SMTP, is_orig=F, conns={^J^I[[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp]] = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^I^ISMTP^J^I}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^I^J^I}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^I^J^I}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=, fuids=[Fel9gs4OtNEV6gUJZ5]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=]^J}, last_active=1254722770.692743, seen_bytes=79, total_bytes=, missing_bytes=0, overflow_bytes=0, timeout_interval=2.0 mins, bof_buffer_size=1024, bof_buffer=Hello^M^J^M^J ^M^J^M^JI send u smtp pcap file ^M^J^M^JFind the attachment^M^J^M^J ^M^J^M^JGPS^M^J^M^J^M^J, mime_type=text/plain, mime_types=[[strength=-20, mime=text/plain]], info=[ts=1254722770.692743, fuid=Fel9gs4OtNEV6gUJZ5, tx_hosts={^J^I74.53.140.153^J}, rx_hosts={^J^I10.10.1.4^J}, conn_uids={^J^ICjhGID4nQcgTWjvg4c^J}, source=SMTP, depth=3, analyzers={^J^J}, mime_type=text/plain, filename=, duration=0 secs, local_orig=, is_orig=F, seen_bytes=0, total_bytes=, missing_bytes=0, overflow_bytes=0, timedout=F, parent_fuid=, md5=, sha1=, sha256=, x509=, extracted=], u2_events=] 1254722770.692743 get_file_handle [0] tag: enum = Analyzer::ANALYZER_SMTP - [1] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=, fuids=[Fel9gs4OtNEV6gUJZ5]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] + [1] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=, fuids=[Fel9gs4OtNEV6gUJZ5]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] [2] is_orig: bool = F 1254722770.692743 mime_begin_entity - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=, fuids=[Fel9gs4OtNEV6gUJZ5]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=, fuids=[Fel9gs4OtNEV6gUJZ5]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=3], socks=, ssh=, syslog=] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[Fel9gs4OtNEV6gUJZ5]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=4], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[Fel9gs4OtNEV6gUJZ5]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=4], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=CONTENT-TYPE, value=text/html;^Icharset="us-ascii"] 1254722770.692743 mime_one_header - [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[Fel9gs4OtNEV6gUJZ5]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=4], socks=, ssh=, syslog=] + [0] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=1610, state=4, num_pkts=9, num_bytes_ip=518, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.163697, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[Fel9gs4OtNEV6gUJZ5]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=4], socks=, ssh=, syslog=] [1] h: mime_header_rec = [name=CONTENT-TRANSFER-ENCODING, value=quoted-printable] 1254722770.692786 get_file_handle [0] tag: enum = Analyzer::ANALYZER_SMTP - [1] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=3070, state=4, num_pkts=10, num_bytes_ip=2018, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.16374, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[Fel9gs4OtNEV6gUJZ5]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=4], socks=, ssh=, syslog=] + [1] c: connection = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=3070, state=4, num_pkts=10, num_bytes_ip=2018, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.16374, service={^J^ISMTP^J}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, radius=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^J}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^J}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[Fel9gs4OtNEV6gUJZ5]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=4], socks=, ssh=, syslog=] [2] is_orig: bool = F 1254722770.692786 file_new - [0] f: fa_file = [id=Ft4M3f2yMvLlmwtbq9, parent_id=, source=SMTP, is_orig=F, conns={^J^I[[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp]] = [id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], orig=[size=3070, state=4, num_pkts=10, num_bytes_ip=2018, flow_label=0], resp=[size=462, state=4, num_pkts=10, num_bytes_ip=870, flow_label=0], start_time=1254722767.529046, duration=3.16374, service={^J^I^ISMTP^J^I}, addl=, hot=0, history=ShAdDa, uid=CjhGID4nQcgTWjvg4c, tunnel=, dpd=, conn=, extract_orig=F, extract_resp=F, dhcp=, dnp3=, dns=, dns_state=, ftp=, ftp_data_reuse=F, ssl=, http=, http_state=, irc=, modbus=, snmp=, smtp=[ts=1254722768.219663, uid=CjhGID4nQcgTWjvg4c, id=[orig_h=10.10.1.4, orig_p=1470/tcp, resp_h=74.53.140.153, resp_p=25/tcp], trans_depth=1, helo=GP, mailfrom=, rcptto={^J^I^I^J^I}, date=Mon, 5 Oct 2009 11:36:07 +0530, from="Gurpartap Singh" , to={^J^I^I^J^I}, reply_to=, msg_id=<000301ca4581$ef9e57f0$cedb07d0$@in>, in_reply_to=, subject=SMTP, x_originating_ip=, first_received=, second_received=, last_reply=354 Enter message, ending with "." on a line by itself, path=[74.53.140.153, 10.10.1.4], user_agent=Microsoft Office Outlook 12.0, process_received_from=T, has_client_activity=T, entity=[filename=], fuids=[Fel9gs4OtNEV6gUJZ5]], smtp_state=[helo=GP, messages_transferred=0, pending_messages=, mime_depth=4], socks=, ssh=, syslog=]^J}, last_active=1254722770.692786, seen_bytes=0, total_bytes=, missing_bytes=0, overflow_bytes=0, timeout_interval=2.0 mins, bof_buffer_size=1024, bof_buffer=^M^J^M^J^M^J^M^J^M^J