In Boss Of The Soc Version 1(2015)
Outbound communication has been detected from the web server
192.168.250.70
toprankglassinebracket.jumpingcrab.com
.
We need to identify the request packet associated with this outbound activity.
Use foreach
to iterate through all fields, extracting domain values into temp_domain_addr
using rex
command.
Then, store them into domain_addr
if there's no same value, and separate domain_addr
into each domain using the split
command for identification
index=* dest_ip=192.168.250.70 OR dest=192.168.250.70 sourcetype IN ("fgt_utm", "stream:http", "suricata") "prankglassinebracket.jumpingcrab.com"
| eval domain_addr=""
| foreach *
[ rex field=<<FIELD>> "(?:https*://)*(?P<temp_domain_addr>[\w\-0-9]+?\.[\w\-0-9]+?\.[\w\-0-9]+(?:\:\d+)*)"
| eval temp_domain_addr=if(isnull(temp_domain_addr), "", temp_domain_addr)
| eval domain_addr=if(like(domain_addr, "%".temp_domain_addr."%"), domain_addr, domain_addr.";".temp_domain_addr)]
| eval domain_addr=split(domain_addr, ";")
| mvexpand domain_addr
| stats values(sourcetype) values(dest_ip) c by domain_addr
index="index" "src" "dest"
| bin span=3m _time
| eval src_ip = if(isnull(src_ip), if(isnull(src), s_ip, src), src_ip)
| eval src_port = if(isnull(src_port), s_port, src_port)
| eval dest_ip = if(isnull(dest_ip), if(isnull(dest), d_ip, dest), dest_ip)
| eval dest_port = if(isnull(dest_port), d_port, dest_port)
| stats values(*) as * c by _time src_ip src_port
| eval src_port = mvindex(src_port, 0, 4)
| eval dest_port = mvindex(dest_port, 0, 4)
| table _time sourcetype src_ip src_port dest_ip dest_port
| sort _time
Additionally, if you add specified fields, you can visibly trace the change in its value, such as:
Basic search
| bin span=10m _time
| rename http.* as sc_http_*
| rename *{} as *_
| rename alert.* as alert_*
| eval time=strftime(_time, "%Y-%m-%d %H-%M")
| eval src_ip = if(isnull(src_ip), if(isnull(src), s_ip, src), src_ip)
| eval src_ip = if(src_ip="192.168.250.100" or c_ip="192.168.250.100", "192.168.250.100", src_ip)
| eval src_port = if(isnull(src_port), s_port, src_port)
| eval dest_ip = if(isnull(dest_ip), if(isnull(dest), d_ip, dest), dest_ip)
| eval dest_ip = if(src_ip="192.168.250.100", dest_ip, "192.168.250.100")
| eval dest_port = if(isnull(dest_port), d_port, dest_port)
| eval site = if(like(sourcetype, "suricata") and like(event_type, "http"), sc_http_hostname, site)
| eval uri = if(like(sourcetype, "suricata") and like(event_type, "http"), url, uri)
| eval filename = if(isnull(filename), "None", filename)
| eval command_ = if(isnull(command_), "None", command_)
| eval answer = if(isnull(answer), "None", answer) | eval record_type = if(isnull(record_type), "None", record_type) | eval query = if(isnull(query), if(isnull(hostname_), "None", hostname_), query)
| mvexpand command_
| mvexpand answer
| mvexpand query
| mvexpand record_type
| strcat "[" command_ "] " filename smb_status
| strcat http_method " " site uri " -> " status HTTP_request
| strcat "[" record_type "] " query " -> " answer dns_qr
| eval sourcetype=case(like(sourcetype, "suricata"), sourcetype." : ".event_type, 1=1, sourcetype)
| stats values(*) as * c by _time src_ip dest_ip sourcetype
| eval src_port = mvindex(src_port, 0, 4)
| eval dest_port = mvindex(dest_port, 0, 4)
| eval info = if(like(sourcetype, "stream:http") or (like(sourcetype, "suricata%") and (like(event_type, "http") or like(event_type, "fileinfo"))), HTTP_request, "")
| eval info = if(like(sourcetype, "stream:dns"), dns_qr, info)
| eval signature = if(like(sourcetype, "suricata%") and like(event_type, "alert"), alert_signature, "")
| eval info = if(like(sourcetype, "stream:smb") , smb_status, info)
| table time sourcetype signature info src_ip src_port dest_ip dest_port
| sort time
It will display information about a HTTP traffic and a DNS Query, in addition to the previous showed fields src
, dest
, and sourcetype
:
index=* sourcetype IN ("suricata" "fgt_utm" "iis" "stream:http")
| rename *{} as *_temp
| rename tag::* as tag_*
| eval sourcetype=if(like(sourcetype, "%suricata%"), "suricata_".event_type, sourcetype)
| stats values(*) as * by sourcetype
| foreach *
[ eval <<FIELD>>=mvindex(<<FIELD>>, 0, 0)]
| transpose 0 header_field=sourcetype
| fillnull value=" "
If you are dealing with a single field, type the following command:
Basic search
| fieldsummary
| search values!="[]"
| fields field values
| rex field=values max_match=0 "\{\"value\":\"(?<extract_values>[^\"]+)\""
| fields field extract_values
| eval extract_values=mvdedup(extract_values)
As a reference, you can check the categories of sourcetypes using the command metadata
as follows:
| metadata type=sourcetypes index=botsv1
| stats values(sourcetype)
If uri
field exists, you can examine the names and values of all URL parameter to trace a brute force attack as follows:
"site"
| rex field=uri "\/.+?\?(?P<prs>.+)"
| search prs=*
| eval prs=split(prs, "&")
| where mvcount(prs)>1 ``` If there's only one parameter, the likelihood of a brute force attack is low```
| stats c by prs
| eval temp = split(prs, "=")
| eval pr_n=mvindex(temp,0)
| eval pr_v=mvindex(temp,1)
| stats values(pr_v) as pr_v c by pr_n
"site" "method" "src_content"
| rex field="src_content" "(?P<matched>[^&=]+\=[^&=]*(?:\&[^&=]+\=[^&=]*)+)" | where not isnull(matched) | sort -c
| stats values("src_content") as "src_content" c by matched
| eval matched=split(matched, "&")
| mvexpand matched
| eval temp = split(matched, "=")
| eval matched_n=mvindex(temp, 0)
| eval matched_v=mvindex(temp, 1)
| stats values(matched_v) as matched_v by matched_n
| where mvcount(matched_v)>10
| eval matched_v=mvindex(matched_v, 0, 9)
basic search
| stats latest(_time) as time_login by cs_username
| join cs_username
[ search index=iis a_action=event_status cs_username=*
| stats latest(_time) as time_finish by cs_username ]
| eval difference=time_finish-time_login
| eval difference=strftime(difference,"%d-%m-%Y %H:%M:%S")
"exe file"
| rename *{} as *_brace
| rename tag::* as tag__*
| eval check_length = 0
| eval check_values = ""
| foreach *
[ eval check_length = if(len(<<FIELD>>)=32, 1, check_length)
| eval check_values=if(len(<<FIELD>>)=32, check_values."; ".<<FIELD>>, check_values)]
| search check_length=1
| rename "*: *" AS *_*
reverse
command only affects the order of results, not which events are returned by the search.