Documentation

 

 

Introduction

Use this guide to create queries in the Splunk Dashboard, which generate a visual representation of SecureAuth IdP logon activity, threat activity, realm utilization, and overall system health.

If using Splunk Enterprise or Splunk Cloud, then download the SecureAuth Splunk Dashboard App, which provides unprecedented user access visibility into enterprise resources such as VPN and ADC, cloud application access as well as on-premises applications out-of-the-box.

Prerequisites

1. Have SecureAuth IdP 8.1.1+

NOTE: SecureAuth IdP 8.2+ supports the use of the application, while version 8.1.1 supports only the manually-entered sample queries

2. Have Splunk (on-premises or cloud version)

NOTE: SecureAuth IdP queries were tested against Splunk version 6.2.3

3. Configure the Logs Tab to enable Syslog
 

Logs Tab Configuration Steps
Log Options

 

1. Set the Log Instance ID to an identifiable name, displayed on Splunk

2. Select Syslog from the Audit Logs options

Syslog

 

3. Set the Syslog Server to the Syslog IP Address

4. Set the Syslog Port to the Port being used, e.g. 514

5. Select RFC5424 from the Syslog RFC Spec dropdown

6. Set the Private Enterprise Number (PEN) to the PEN of the Syslog server (Splunk is 27389)

Click Save once the configurations have been completed and before leaving the Logs page to avoid losing changes

The Sample Queries vary based on the SecureAuth IdP version

Select the correct version range, and follow the specific instructions

Sample Queries
  • Manual Field Extractions were not used for these examples
  • Exclude debug logs if they are logged to Syslog (NOT Category>DEBUG)
  • Images are sample / recommended visual outputs, but can be designed as preferred
Base Queries

successful_api_logins

EventID=60503 ApiResponseStatus=Authenticated

successful_user_logins

((EventID=20990 TrxResult=*Success*) OR EventID=91220) NOT DestinationSiteUrl="Authorized/WSFedProvider.aspx"

successful_ws_logins

("Password is validated" Version="8.*" [search EventID="40601" WSTrustUserNameSecurityTokenHandler Version="8.*" | fields RequestID])) OR (DestinationSiteUrl="Authorized/WSFedProvider.aspx" EventID=20990)

successful_logins

secureauth_successful_api_logins OR secureauth_successful_user_logins OR secureauth_successful_ws_logins

failed_api_logins

(EventID=60202 OR EventID=60502 OR EventID=60602 OR (EventID=60102 NOT ApiResponseStatus="found"))

failed_user_logins

(EventID=20990 (TrxResult!=*Success* OR Succeed=False) NOT DestinationSiteUrl="Authorized/WSFedProvider.aspx")

failed_logins

secureauth_failed_user_logins OR secureauth_failed_api_logins

Login Activity

logins_by_external_location

secureauth_successful_user_logins | stats count by UserHostAddress | iplocation UserHostAddress | eval Country=if(Country=="", "N/A", Country) | eval Region=if(Region=="", Country, Region) | eval City=if(City=="",Country, City)

frequent_user_logins

secureauth_successful_user_logins | eval lower_user_id = lower(UserID) | stats count by lower_user_id | sort -count | eventstats sum(count) as total | eval percent=round(count*100/total,2) | fields - total | rename count as Logins, lower_user_id as "User ID", percent as Percent

admin_console_logins

EventID=19501 | stats count by UserID | sort -count | eventstats sum(count) as total | eval percent=round(count*100/total,2) | fields - total | rename count as Logins, UserID as "User ID", percent as Percent

logins_by_operating_system

secureauth_successful_user_logins | lookup user_agents http_user_agent as UserAgent | stats count by ua_os_family | sort -count | eventstats sum(count) as total | eval percent=round(count*100/total,2) | fields - total | rename count as Logins, ua_os_family as "Operating System", percent as Percent

logins_by_browser

secureauth_successful_user_logins | lookup user_agents http_user_agent as UserAgent | stats count by ua_family | sort -count | eventstats sum(count) as total | eval percent=round(count*100/total,2) | fields - total | rename count as Logins, ua_family as Browser, percent as Percent

logins_by_realm

secureauth_successful_user_logins | stats count by Realm | sort -count | eventstats sum(count) as total | eval percent=round(count*100/total,2) | fields - total | rename count as Logins, percent as Percent

logins_by_ip_address

secureauth_successful_user_logins | stats count by UserHostAddress | sort -count | eventstats sum(count) as total | eval percent=round(count*100/total,2) | fields - total | rename count as Logins, UserHostAddress as "Source IP", percent as Percent

orphaned_second_factor_logins

EventID=20100 BrowserSession=* BROWSER_REGISTRATION_METHOD | stats count by BrowserSession UserID UserHostAddress Realm | search count=1 | fields - count BrowserSession | stats count by UserID, UserHostAddress, Realm | sort -count | rename UserID as "User ID", count as "Logins", UserHostAddress as "Source IP"

Login Failures

failed_counts

EventID=20990 (TrxResult="SecurityViolation_ExceededMaxOTPAttempts" OR TrxResult="Incorrect_FingerPrint_Check_Password" OR TrxResult="Incorrect_Kiosk_Check_Password" OR TrxResult="Incorrect_Standard_Check_Password" OR TrxResult="Incorrect_User" OR TrxResult="Incorrect_UserPassword" OR TrxResult="SECURITYVIOLATION_*") | rex field=TrxResult "(?[^_]+)$" | stats count(UserID) as total, dc(eval(if(reason=="Password" OR reason=="UserPassword",UserID,NULL))) as Password, dc(eval(if(reason=="User",UserID,NULL))) as User, dc(eval(if(reason=="ExceededMaxOTPAttempts" OR reason=="ExceededMaxPasswordAttempts",UserID,NULL))) as ExceededMaxAttempts

failed_logins_by_external_location

secureauth_failed_user_logins | stats count by UserHostAddress | iplocation UserHostAddress | eval Country=if(Country=="", "N/A", Country) | eval Region=if(Region=="", Country, Region) | eval City=if(City=="",Country, City)

login_attempts_from_blocked_countries

(EventID=92310 OR EventID=92320) (whitelisted_ip=false OR blacklisted_ip=true) | fillnull value=NULL UserID | rename whitelisted_country as country blacklisted_country as country | stats count by UserHostAddress, UserID | iplocation UserHostAddress | eval Country=if(Country=="", "N/A", Country) | eval Region=if(Region=="", Country, Region) | eval City=if(City=="",Country, City)

failed_login_reasons_over_time

secureauth_failed_user_logins | lookup trx_lookup TrxResult | eval reason=coalesce(Definition, TrxResult) | timechart count by reason

denied_login_requests_by_user

secureauth_failed_user_logins TrxResult=Denied_Browser_RegistrionMethod_AcceptDeny_LoginRequest | stats count by UserID, Realm | sort -count

failed_passwords

EventID=20990 (TrxResult="SecurityViolation_ExceededMaxOTPAttempts" OR TrxResult="Incorrect_FingerPrint_Check_Password" OR TrxResult="Incorrect_Kiosk_Check_Password" OR TrxResult="Incorrect_Standard_Check_Password" OR TrxResult="Incorrect_User" OR TrxResult="Incorrect_UserPassword" OR TrxResult="SECURITYVIOLATION_*") | rex field=TrxResult "(?[^_]+)$" | stats count(eval(reason=="Password")) as Password count(eval(reason=="User")) as User count(eval(if(reason=="ExceededMaxOTPAttempts" OR reason=="ExceededMaxPasswordAttempts",UserID,NULL))) as ExceededMaxAttempts by UserID

invalid_user_ids

EventID=20990 (TrxResult="SecurityViolation_ExceededMaxOTPAttempts" OR TrxResult="Incorrect_FingerPrint_Check_Password" OR TrxResult="Incorrect_Kiosk_Check_Password" OR TrxResult="Incorrect_Standard_Check_Password" OR TrxResult="Incorrect_User" OR TrxResult="Incorrect_UserPassword" OR TrxResult="SECURITYVIOLATION_*") | rex field=TrxResult "(?[^_]+)$" | stats count(eval(reason=="Password")) as Password count(eval(reason=="User")) as User count(eval(if(reason=="ExceededMaxOTPAttempts" OR reason=="ExceededMaxPasswordAttempts",UserID,NULL))) as ExceededMaxAttempts by UserID

exceeded_max_login_attempts

EventID=20990 (TrxResult="SecurityViolation_ExceededMaxOTPAttempts" OR TrxResult="Incorrect_FingerPrint_Check_Password" OR TrxResult="Incorrect_Kiosk_Check_Password" OR TrxResult="Incorrect_Standard_Check_Password" OR TrxResult="Incorrect_User" OR TrxResult="Incorrect_UserPassword" OR TrxResult="SECURITYVIOLATION_*") | rex field=TrxResult "(?[^_]+)$" | stats count(eval(reason=="Password")) as Password count(eval(reason=="User")) as User count(eval(if(reason=="ExceededMaxOTPAttempts" OR reason=="ExceededMaxPasswordAttempts",UserID,NULL))) as ExceededMaxAttempts by UserID

top_browsers

secureauth_failed_user_logins | stats count by UserAgent | lookup user_agents http_user_agent as UserAgent | fields + ua_family count | stats sum(count) as count by ua_family | sort -count | eventstats sum(count) as total | eval percent = round(count*100/total,2) | table ua_family count percent | rename count as Failures UserID as "User ID" percent as Percent ua_family as Browser

geovelocity_violations

EventID=92300 UserHostAddress=* "geo-velocity" UserHostAddress!="10.0.0.0/8" UserHostAddress!="172.16.0.0/12" UserHostAddress!="192.168.0.0/16" UserHostAddress!="169.254.0.0/16" | streamstats current=f last(UserHostAddress) as new_addr last(_time) as time_of_change by UserID | where UserHostAddress!=new_addr | rename UserHostAddress as prev_addr | search "result: false" | iplocation prefix=prev_ prev_addr | iplocation prefix=new_ new_addr | table time_of_change, UserID, prev_addr, prev_Country, new_addr, new_Country | sort - time_of_change | convert ctime(time_of_change) as Time | table Time UserID prev_addr prev_Country new_addr new_Country | rename prev_addr as "Previous IP" prev_Country as "Previous Country" new_addr as "New IP" new_Country as "New Country" UserID as "User ID"

threats

"Check IP Risk 'ge" AE_IP_threatType=* AE_IP_threatType!=0 AE_IP_RiskScore!=0 | stats count by UserHostAddress, UserID, Realm, AE_IP_threatType, AE_IP_threatCategory | lookup threatType_lookup threatScore AS AE_IP_threatType OUTPUT threatType | lookup threatCategory_lookup AE_IP_threatCategory OUTPUT threatCategory | sort -count | table UserHostAddress, UserID, Realm, threatType, threatCategory, count | rename UserHostAddress as "Source IP", UserID as "User ID", threatType as "Source", threatCategory as "Category", count as Failures

Realm Utilization

total_logins

EventID=20990 TrxResult=*Success* | stats count sparkline(count) as utilization by Realm | eventstats sum(count) as total | eval Percent=round(count*100/total,2) | fields - total | sort -count | table Realm utilization count Percent | rename Realm as "Realm Name" utilization as "Utilization Over Time" count as "Total Logins"

second_factor_utilization

EventID=20990 | eval auth_type=case(AuthRegMethod=="NONE" AND AllowedTokens=="BROWSERFINGERPRINT" AND (AuthGuiMode=="0" OR AuthGuiMode=="2" OR AuthGuiMode=="3" OR AuthGuiMode=="4" OR AuthGuiMode=="5" OR AuthGuiMode=="6" OR AuthGuiMode=="9"), "DFP", AuthRegMethod!="NONE", AuthRegMethod) | chart count by auth_type | sort -count | rename count as Count auth_type as Authentication

digital_fingerprint_utilization

EventID=20990 (AuthRegMethod="NONE" AND AllowedTokens="BROWSERFINGERPRINT" AND (AuthGuiMode="0" OR AuthGuiMode="2" OR AuthGuiMode="3" OR AuthGuiMode="4" OR AuthGuiMode="5" OR AuthGuiMode="6" OR AuthGuiMode="9")) | stats count by Realm | sort -count | rename count as Count

top_realms_with_long_page_response_times

EventID=90040 | timechart avg(duration) as Seconds by Realm

data_store_response_time

((EventID=52010 "Retrieved user profile data") OR (EventID=52020 "Found the user for retrieving user's profile")) | stats min(_time) as min_time max(_time) as max_time by RequestID Realm | eval duration=(max_time-min_time )| rename min_time to _time | timechart max(duration) as Seconds by Realm

page_response_time_in_seconds

EventID=90040 Realm=* | stats min(duration) as Minimum, avg(duration) as Average, max(duration) as Maximum by Realm | sort -Average

Appliance Utilization

total_logins

EventID=90010 | stats count by host | sort -count | eventstats sum(count) as total | eval percent=round(count*100/total,2) | fields - total | rename host as Appliance count as Logins percent as Percent

average_page_load_time

EventID=90040 | timechart avg(duration) by host

page_load_time

EventID=90040 | stats min(duration) as Minimum, avg(duration) as Average, max(duration) as Maximum by host

appliance_errors_over_time

Category=ERROR NOT EventID=51102 NOT EventID=51003 NOT EventID=52001 | fillnull value=NULL Realm | search $realm$ | timechart useother=f count by host

API Activity

api_requests

(EventID=60203 OR EventID=60301 OR EventID=60201) ApiResponseStatus=Valid | stats count | lookup int2word int as count | fields word

api_requests_by_realm

EventID=60203 ApiResponseStatus=Valid | stats count sparkline(count) as utilization by Realm | eventstats sum(count) as total | eval Percent=round(count*100/total,2) | fields - total | sort -count | table Realm utilization count Percent | rename Realm as "Realm Name" utilization as "Utilization Over Time" count as "Total Logins"

failed_login_reasons_over_time

EventID=60203 ApiResponseStatus=Invalid ApiResponseMessage=* | rex field=ApiResponseMessage "^(?P.+?)( '|.$)" | timechart count by reason

request_types

(EventID=60201 OR EventID=60301) | chart count by AuthRequestType | sort -count | eval AuthRequestType=upper(AuthRequestType) | rename AuthRequestType as Request

adaptive_engine_api_responses

EventID=60503 ApiResponseStatus=* | timechart count by ApiResponseStatus

device_recognition_responses

((EventID=60402 Message=*) OR (EventID=60603 ApiResponseStatus=*)) | eval tmp=case(EventID=60402 AND Message="ok", "Mobile DFP Pass",EventID=60402 AND Message!="ok", "Mobile DFP Failed",EventID=60603,ApiResponseStatus) | stats count by tmp | eval tmp=replace(upper(tmp),"_"," ") | rename tmp as "Device Recognition Responses" count as Count | sort -Count

threats

EventID=60302 | stats count by UserHostAddress, UserID, Realm, AE_IP_threatType, AE_IP_threatCategory | lookup threatType_lookup threatScore AS AE_IP_threatType OUTPUT threatType | lookup threatCategory_lookup AE_IP_threatCategory OUTPUT threatCategory | sort -count | table UserHostAddress, UserID, Realm, threatType, threatCategory, count | rename UserHostAddress as "Source IP", UserID as "User ID", threatType as "Source", threatCategory as "Category", count as Failures

Sample Queries

  • Manual Field Extractions were not used for these examples
  • Exclude debug logs if they are logged to Syslog (NOT "Category>DEBUG)
Logins by Geo-location and IP Address

Logins by Geo-location

ID90010 | table UserHostAddress | stats count by UserHostAddress | iplocation UserHostAddress | geostats latfield=lat longfield=lon sum(count) as count by UserHostAddress globallimit=0

Access by Country

ID90010 | table UserHostAddress | stats count by UserHostAddress | iplocation UserHostAddress | stats count by Country

Logon Attempts from Banned Countries

ID92320 AND "is not in specified countries, result: false"  | stats count by Country

IP Risk Hits by User

ID92100 ",65," OR ",66," OR ",67," OR ",68," OR ",69," OR ",70," OR ",71," OR ",72," OR ",73," OR ",74," OR ",75," OR ",76," OR ",77," OR ",78," OR ",79," OR ",80," OR ",81," OR  ",82," OR ",83," OR ",84," OR ",85," OR  ",86," OR ",87," OR ",88," OR ",89," OR  ",90," OR ",91," OR ",92," OR ",93," OR  ",94," OR ",95," OR ",96," OR ",97," OR  ",98," OR ",99," OR ",100,"  | stats by UserID

Login Failures

Failed Passwords

Incorrect_FingerPrint_Check_Password OR Incorrect_Kiosk_Check_Password OR Incorrect_Standard_Check_Password | chart count by UserID

Invalid User IDs

Incorrect_User | chart count by UserID

Geo-velocity Violation Events

ID92300 "geo-velocity" "result: false"  | chart count by UserID

Exceeded Max Login Attempts

ID20990 SECURITYVIOLATION_* NOT SECURITYVIOLATION_X509 NOT SECURITYVIOLATION_X509_CONTINUE | chart count by UserID

Realm Utilization

Total Logins by Realm

((ID20990 TrxResult=*Success*) OR ID91220) | chart count by Realm

Second Factor Utilization

ID20990 AuthRegMethod!=NONE | chart limit=20 count by AuthRegMethod

Appliance Utilization

Total Logins – by Appliance

ID90010 | timechart count by host

Appliance Errors Over Time

Category=ERROR  NOT ID51102 NOT ID51003 NOT ID52001 | timechart count

Login Activity

Frequent Logins – Top 10

ID51080 | chart count by UserID | sort - count | head 10

Web Admin Logins

ID19501 | stats count by UserID | sort -count | eventstats sum(count) as total

Credential Provider Logins

ID91220 | chart count

  • No labels