Splunk Queries for Detecting Anomalous URIs in Web Traffic

Prior to having a presence on the network, attackers are unlikely to be able to disguise web shell traffic as typical traffic for a targeted web server. In these cases, requests to the web shell are likely to have an unusual user agent string. In some environments, the attacker’s IP address may also appear uncharacteristic for typical network traffic. The queries below can highlight URIs requested by unusual user agents and client IP addresses. Administrators are encouraged to tailor these queries to individual environments including targeting individual web applications or servers rather than running the query for an entire network. In rare cases, certain web applications may generate unique URIs per request which would limit the effectiveness of these queries.

QUERY TO IDENTIFY URIs ACCESSED BY FEW USER AGENTS AND IP ADDRESSES

TIP: Unlike benign URIs, web shell URIs are likely to have few user agents

sourcetype=”access_combined”
| fillnull value=- ‘comment(“Fill all empty fields with -”)’
| search status>=”200″ status <“300” uri!=- clientip!=- `comment(“Only successful codes 200-299, eliminate blank URIs and client IPs”)`
| stats min(_time) as start max(_time) as stop dc(useragent) as dc_user_agent values(useragent) as values_user_agent dc(clientip) as dc_src values(clientip) as values_src count by uri `comment(“Find first and last time the grouping was found, number of distinct User Agent strings and IP addresses used to access that URI”)` | convert ctime(start) ctime(stop) `comment(“Convert the times to a readable format”)`
| search dc_src<=5 OR dc_user_agent<=5 `comment(“Only URIs with <=5 unique user agents or IP addresses”)` | table start stop uri dc_user_agent values_user_agent dc_src values_src


sourcetype=”iis”
| fillnull value=- ‘comment(“Fill all empty fields with -”)’
| search sc_status>=”200″ sc_status <“300” cs_uri_stem!=- c_ip!=- `comment(“Only successful codes 200-299, eliminate blank URIs and client IPs”)`
| stats min(_time) as start max(_time) as stop dc(cs_User_Agent) as dc_user_agent values(cs_User_Agent) as values_user_agent dc(c_ip) as dc_src values(c_ip) as values_src count by cs_uri_stem `comment(“Find first and last time the grouping was found, number of distinct User Agent strings and IP addresses used to access that URI”)`
| convert ctime(start) ctime(stop) `comment(“Convert the times to a readable format”)`
| search dc_src<=5 OR dc_user_agent<=5 `comment(“Only URIs with <=5 unique user agents or IP addresses”)` | table start stop cs_uri_stem dc_user_agent values_user_agent dc_src values_src

QUERY TO IDENTIFY USER AGENTS UNCOMMON FOR A TARGET WEB SERVER

TIP: Particularly for internal web applications, uncommon user agents can indicate web shell activity

sourcetype=”access_combined”
| fillnull value=- ‘comment(“Fill all empty fields with -”)’
| search status>=”200″ status <“300” ` comment(“Only successful codes 200-299”)`
| stats count by useragent `comment(“Group User Agent strings to determine frequency”)`
| sort + count `comment(“Sort count in ascending order”)`
| head 10 `comment(“Limit results to top 10. This can be changed to see more or fewer results”)`


sourcetype=”iis” sc_status>=”200″ AND sc_status<“300” ` comment(“Only successful codes 200-299”)` | fillnull value=- ‘comment(“Fill all empty fields with -”)’
| search sc_status>=”200″ sc_status <“300” `comment(“Only successful codes 200-299”)`
| stats count by cs_User_Agent `comment(“Group User Agent strings to determine frequency”)`

| sort + count `comment(“Sort count in ascending order”)`
| head 10 `comment(“Limit results to top 10. This can be changed to see more or fewer results”)`

QUERY TO IDENTIFY URIs WITH AN UNCOMMON HTTP REFERER

TIP: Web shell URIs are likely to have uncommon HTTP referees

sourcetype=”access_combined”
| fillnull value=- ‘comment(“Fill all empty fields with – (needed to make blank referer fields searchable)”)’
| search status>=”200″ status <“300” `comment(“Only successful codes 200-299”)`
| stats dc(uri) as dc_URIs values(uri) as All_URIs count by referer `comment(“Counts number of times each URI request is associated with a unique referer”)`
| table referer, All_URIs, dc_URIs
| sort + dc_URIs `comment(“Sort count in ascending order”)`
| head 10 `comment(“Limit results to top 10. This can be changed to see more or fewer results”)`


sourcetype=” iis”
| fillnull value=- ‘comment(“Fill all empty fields with – (needed to make blank referer fields searchable)”)’
| search sc_status>=”200″ sc_status<“300” `comment(“Only successful codes 200-299”)`
| stats dc(cs_uri_stem) as dc_URIs values(cs_uri_stem) as All_URIs count by cs_Referer `comment(“Counts number of times each URI request is associated with a unique referer”)`
| table cs_Referer, All_URIs, dc_URIs
| sort + dc_URIs `comment(“Sort count in ascending order”)`
| head 10 `comment(“Limit results to top 10. This can be changed to see more or fewer results”)`

QUERY TO IDENTIFY URIs MISSING AN HTTP REFERER

TIP: Web shell URIs are likely to have missing HTTP referrers

sourcetype=”access_combined”
| fillnull value=- ‘comment(“Fill all empty fields with – (needed to make blank referer fields searchable)”)’
| search status>=”200” status<”300” referrer=- uri!=”/” `comment(“Only successful codes 200-299 and blank referrer not from root webpage”)
| stats count by referer, uri `comment(“Counts number of times each URI request is associated with a unique referer”)`
| table uri, count
| sort – count `comment(“Sort count in descending order”)`
| head 10 `comment(“Limit results to top 10. This can be changed to add more or fewer results”)`


sourcetype=”iis”
| fillnull value=- ‘comment(“Fill all empty fields with – (needed to make blank referer fields searchable)”)’
| search sc_status>=”200″ sc_status<“300″ sc_Referer=- cs_uri_stem!=”/” `comment(“Only looking for successful status codes 200-299 and blank referer not from the root webpage”)`
| stats count by cs_Referer, cs_uri_stem `comment(“Counts number of times each URI request is associated with a unique referer”)`
| table cs_uri_stem, count
| sort – count `comment(“Sort count in descending order”)`
| head 10 `comment(“Limit results to top 10. This can be changed to add more or fewer results”)`

Write a Review

Your email address will not be published. Required fields are marked *