# This extracts user IDs from a login URI. It's likely this will extract from most websites but could require some adjustments # Most likely to the amount of content pulled. The UID attempts twice for two different styles of UID parameters # and then logs a failure and inserts a UID-NULL value for a fail safe. # This has now been extended to handle our SSN and DOB page for enrollment. To ensure the SSN and DOB are not passed # but still accurately/uniquely tracked, we hash the value with sha256 and take a snippet. # Since SHA256 is consistent if the values are consistent, we will see the same hash for the same values # thus tracking/brute force prevention can take place. # Dependencies: TIP_Univ iRule / XXX_LOGIN_URI R8L_BAD_IP DataGroup # !!!R8L_GOOD_UID must have UID-NULL added to avoid banning unextractable usernames!!! when HTTP_REQUEST priority 630 { ######TroubleShooting Headers ###### log local0. "TIP: $tip EdgeIP: [IP::client_addr] VIP: [virtual name] - True-Client-IP Header value: [HTTP::header True-Client-IP]" # Set Login Pages set login_page XXX_LOGIN_URI set buri [HTTP::path] # HTTP protocol methods that is used by the login form set method [HTTP::method] # 0 - NONE, 1 - LOW, 2 - MEDIUM, 3 - VERBOSE set BAIU_LOG_LVL 1 # Set user cookie as SID/JSESSIONID set sid [string range [HTTP::cookie TLFREPLAYID] 0 32 ] set jsid [string range [HTTP::cookie AKAMTMXSID] 0 18 ] # set jsid [string range [HTTP::cookie JSESSIONID_AUTHENTICATION] 52 75 ] if {$tip ne ""} { # Only process matched uris & allow specific IPs/UIDs if { ( [class match $tip equals R8L_GOOD_IP ] ) } { if { $BAIU_LOG_LVL >= 3 } {log local0. "NO_MATCH: IP: $tip EdgeIP: [IP::client_addr] VIP: [virtual name] SID: $sid~$jsid ~ IP Whitelisted"} return } if { ( not [class match [HTTP::uri] equals XXX_LOGIN_URI ] ) and ( not [class match $tip equals R8L_BAD_IP ] ) } { if { $BAIU_LOG_LVL >= 3 } { log local0. "RETURN: IP: $tip EdgeIP: [IP::client_addr] VIP: [virtual name] SID: $sid~$jsid Returning from irule---no match on URI or IP found" } return } HTTP::collect 100 # Log the debug message if collect is enabled if { $BAIU_LOG_LVL >= 3 }{log local0. "$tip Collecting HTTP payload"} } } # Got the data, parse them and generate the syslog message when HTTP_REQUEST_DATA priority 631 { if {$tip ne ""} { # # Debug Payload Extraction # if { $BAIU_LOG_LVL >= 4 } {log local0. "PAYLOAD: [HTTP::payload]"} # Attempt to extract wp-login.php UID i.e. log # Pull username if present if {$method == "POST" && [HTTP::uri] equals "/wp-login.php" } { # Log the debug message if trace is enabled. Could be dangerous capturing all HTTP payload with single syslog line. if { $BAIU_LOG_LVL >= 4 }{log local0. "INSPECTPAYLOAD: IP: $tip EdgeIP: [IP::client_addr] VIP: [virtual name] SID: $sid~$jsid UID: $waf_uid URI: [HTTP::uri] ~ Collected request data: [HTTP::payload]"} # Extract log UID from wordpress from payload set waf_uid [ string trim [ string range [ findstr [string map {\x2D\x2D\x2D\x2D\x2D \x26} [string map {\x22 \x26} [string trim [HTTP::payload] ] ] ] log 4 & ] 0 20 ] ] # Insert UID Header #HTTP::header insert "lws" WAF-UID $waf_uid # Log UID success event if { $BAIU_LOG_LVL >= 2 } { log local0. "UIDSUCCESS: IP: $tip EdgeIP: [IP::client_addr] VIP: [virtual name] SID: $sid~$jsid UID: $waf_uid URI: [HTTP::uri] ~ UID=$waf_uid" } } # Pull SSN from DOB and hash if SSNandDOB page is called if {$method == "POST" && [HTTP::uri] equals "/public/authentication/enroll/ssndobandlastname" } { # Log the debug message if trace is enabled. Could be dangerous capturing all HTTP payload with single syslog line. if { $BAIU_LOG_LVL >= 4 }{log local0. "INSPECTPAYLOAD: IP: $tip EdgeIP: [IP::client_addr] VIP: [virtual name] SID: $sid~$jsid UID: $waf_uid URI: [HTTP::uri] ~ Collected request data: [HTTP::payload]"} # Extract SSN from payload (1st attempt) binary scan [ sha256 [ string trim [ string range [ findstr [ string map {\x22\x2C\x22 \x26} [string map {\x22\x3A\x22 \x3D} [string map {\x22\x2C\x22\x64\x6F\x62\x22\x3A\x22 \x5F} [string trim [HTTP::payload] ] ] ] ] lastFourSsn 12 & ] 0 15 ] ] ] H* hex set waf_uid [ string range [string toupper $hex] 0 32 ] # Insert UID Header # #HTTP::header insert "lws" WAF-UID $waf_uid # Log UID success event if { $BAIU_LOG_LVL >= 2 } { log local0. "UIDSUCCESS: IP: $tip EdgeIP: [IP::client_addr] VIP: [virtual name] SID: $sid~$jsid UID: $waf_uid URI: [HTTP::uri] ~ UID=$waf_uid" } # Extract SSN from payload (2nd attempt) if {$waf_uid equals "" } { binary scan [ sha256 [ string trim [ string range [ findstr [ string map {\x22\x2C\x22 \x26} [string map {\x22\x3A\x22 \x3D} [string map {\x22\x2C\x22\x64\x6F\x62\x22\x3A\x22 \x5F} [string trim [HTTP::payload] ] ] ] ] ssn 4 & ] 0 22 ] ] ] H* hex set waf_uid [ string range [string toupper $hex] 0 32 ] # Insert UID Header # #HTTP::header insert "lws" WAF-UID $waf_uid # Log UID success event if { $BAIU_LOG_LVL >= 2 } { log local0. "UIDSUCCESS: IP: $tip EdgeIP: [IP::client_addr] VIP: [virtual name] SID: $sid~$jsid UID: $waf_uid URI: [HTTP::uri] ~ UID=$waf_uid" } } } # Pull username if present if {$method == "POST" && [HTTP::uri] equals "/public/authentication/securelogin/authenticate" } { # Log the debug message if trace is enabled. Could be dangerous capturing all HTTP payload with single syslog line. if { $BAIU_LOG_LVL >= 4 }{log local0. "INSPECTPAYLOAD: IP: $tip EdgeIP: [IP::client_addr] VIP: [virtual name] SID: $sid~$jsid UID: $waf_uid URI: [HTTP::uri] ~ Collected request data: [HTTP::payload]"} # Extract Ushttps://192.168.169.5/tmui/Control/jspmap/tmui/locallb/rule/properties.jsp?name=/Common/XXX_030_UIDExtractAllSites_AddHeader_BAIUv2.2er ID from payload (1st attempt) set waf_uid [ string trim [ string range [ findstr [string map {\x2D\x2D\x2D\x2D\x2D \x26} [string map {\x22 \x26} [string trim [HTTP::payload] ] ] ] userId 7 & ] 0 20 ] ] # Insert UID Header # #HTTP::header insert "lws" WAF-UID $waf_uid # Log UID success event if { $BAIU_LOG_LVL >= 2 } { log local0. "UIDSUCCESS: IP: $tip EdgeIP: [IP::client_addr] VIP: [virtual name] SID: $sid~$jsid UID: $waf_uid URI: [HTTP::uri] ~ UID=$waf_uid" } # Username not found with "userId" parameter try username if { $waf_uid equals "" } { # Pull username if present if {$method == "POST" } { # Log the debug message if trace is enabled. Could be dangerous capturing all HTTP payload with single syslog line. if { $BAIU_LOG_LVL >= 4 }{log local0. "INSPECTPAYLOAD: IP: $tip EdgeIP: [IP::client_addr] VIP: [virtual name] SID: $sid~$jsid UID: $waf_uid URI: [HTTP::uri] ~ Collected request data: [HTTP::payload]"} # Extract userId from payload (2nd attempt) set waf_uid [ string trim [ string range [ findstr [string map {\x2D\x2D\x2D\x2D\x2D \x26} [string map {\x22 \x26} [string trim [HTTP::payload] ] ] ] username 9 & ] 0 20 ] ] # Insert UID Header # # HTTP::header insert "lws" WAF-UID $waf_uid # Log UID success event if { $BAIU_LOG_LVL >= 2 } { log local0. "UIDSUCCESS: IP: $tip EdgeIP: [IP::client_addr] VIP: [virtual name] SID: $sid~$jsid UID: $waf_uid URI: [HTTP::uri] ~ UID=$waf_uid" } } } # Username still not set so attempt XML style extraction for USERID value if { $waf_uid equals "" } { # Pull username if present if {$method == "POST" } { # Log the debug message if trace is enabled. Could be dangerous capturing all HTTP payload with single syslog line. if { $BAIU_LOG_LVL >= 4 }{log local0. "INSPECTPAYLOAD: IP: $tip EdgeIP: [IP::client_addr] VIP: [virtual name] SID: $sid~$jsid UID: $waf_uid URI: [HTTP::uri] ~ Collected request data: [HTTP::payload]"} # Extract USERID from payload (2nd attempt) set waf_uid [ string trim [ string range [ findstr [string map {\x2D\x2D\x2D\x2D\x2D \x26} [string map {\x22 \x26} [string trim [HTTP::payload] ] ] ] USERID 8 > ] 0 20 ] ] # Insert UID Header # #HTTP::header insert "lws" WAF-UID $waf_uid # Log UID success event if { $BAIU_LOG_LVL >= 2 } { log local0. "UIDSUCCESS: IP: $tip EdgeIP: [IP::client_addr] VIP: [virtual name] SID: $sid~$jsid UID: $waf_uid URI: [HTTP::uri] ~ UID=$waf_uid" } } } } # If User ID still not found then write UID-NULL if { $waf_uid equals "" && ( [class match $buri equals XXX_LOGIN_URI ] ) } { set waf_uid UID-NULL #HTTP::header insert "lws" WAF-UID UID-NULL if { $BAIU_LOG_LVL >= 2 } { log local0. "UIDFAIL: IP: $tip EdgeIP: [IP::client_addr] VIP: [virtual name] SID: $sid~$jsid UID: $waf_uid URI: [HTTP::uri] ~ UID=$waf_uid" } } } HTTP::release }