Does anyone have a dashboard that displays anomalies for Exchange daily_bytes by sender? Looking for possible exfil through Exchange.
Yes. This is a run anywhere dashboard if you have Exchange set up; just replace MYDOMAIN
<dashboard script="button_submit_mail_anomalies.js">
<label>Anomalies</label>
<row>
<panel>
<html depends="$hide$">
<style>
#submit_button{
width:80px !important;
}
#submit_button div[data-component="splunk-core:/splunkjs/mvc/components/LinkList"]{
width:80px !important;
}
#submit_button button{
padding: 6px 15px !important;
border-radius: 3px !important;
font-weight: 500 !important;
background-color: #5cc05c !important;
border: transparent !important;
color: #fff !important;
}
#submit_button button:hover{
background-color: #40a540 !important;
border-color: transparent !important;
}
</style>
</html>
<input type="time" token="TIMERANGE1">
<label>Time Range (STDEV Baseline):</label>
<default>
<earliest>-30d</earliest>
</default>
<change>
<eval token="earliest_epoch_onChange">case(isnum($TIMERANGE1.earliest$), $TIMERANGE1.earliest$, $TIMERANGE1.earliest$=="now", time(), $TIMERANGE1.earliest$="", 0, true(), relative_time(time(), $TIMERANGE1.earliest$))</eval>
<eval token="latest_epoch_onChange">case(isnum($TIMERANGE1.latest$), $TIMERANGE1.latest$, $TIMERANGE1.latest$=="now", time(), true(), relative_time(time(), $TIMERANGE1.latest$))</eval>
</change>
</input>
<input type="time" token="TIMERANGE2">
<label>Time Range (Results Filter):</label>
<default>
<earliest>@w0</earliest>
</default>
<change>
<eval token="earliest_epoch_FILTER_onChange">case(isnum($TIMERANGE2.earliest$), $TIMERANGE2.earliest$, $TIMERANGE2.earliest$=="now", time(), $TIMERANGE2.earliest$="", 0, true(), relative_time(time(), $TIMERANGE2.earliest$))</eval>
<eval token="latest_epoch_FILTER_onChange">case(isnum($TIMERANGE2.latest$), $TIMERANGE2.latest$, $TIMERANGE2.latest$=="now", time(), true(), relative_time(time(), $TIMERANGE2.latest$))</eval>
</change>
</input>-->
<input type="link" id="submit_button">
<label></label>
<choice value="submit">Submit</choice>
</input>
</panel>
</row>
<search id="base">
<query>
index=msexchange event_id=AGENTINFO sender_domain=MYDOMAIN.com | stats sum(total_bytes) as daily_bytes by sender,date_mday,date_month,date_year | eventstats avg(daily_bytes) as average stdev(daily_bytes) as sdev by sender | eval num_sdevs=(daily_bytes-average)/sdev | eval trigger="$submit_trigger$"
</query>
<earliest>$earliest_epoch$</earliest>
<latest>$latest_epoch$</latest>
</search>
<row>
<panel>
<input type="text" token="search">
<label>Filter results by email:</label>
<default>*</default>
</input>
<table>
<title>Top 100 Anomalous Senders by Daily Bytes</title>
<search base="base" id="base2">
<query>
eval time=strptime(date_mday." ".date_month." ".date_year,"%d %B %Y") | where time >="$earliest_epoch_FILTER$" AND time <="$latest_epoch_FILTER$" |
sort 0 - num_sdevs | head 100 | search sender="$search$" | table sender date_mday date_month date_year daily_bytes average sdev num_sdevs
</query>
</search>
<option name="wrap">true</option>
<option name="rowNumbers">false</option>
<option name="drilldown">none</option>
<option name="dataOverlayMode">none</option>
<option name="count">25</option>
</table>
</panel>
</row>
<row>
<panel>
<table>
<title>Repeat Senders in Top 100</title>
<search base="base2">
<query>
eventstats count by sender | where count >1 | table sender date_mday date_month date_year daily_bytes average sdev num_sdevs
</query>
</search>
<option name="wrap">true</option>
<option name="rowNumbers">false</option>
<option name="drilldown">none</option>
<option name="dataOverlayMode">none</option>
<option name="count">5</option>
</table>
</panel>
</row>
</dashboard>
JS:
require([
'jquery',
'splunkjs/mvc',
'splunkjs/mvc/simplexml/ready!'
], function($,mvc){
var submittedTokens = mvc.Components.get("submitted");
$("#submit_button").click(function(){
submittedTokens.set("submit_trigger", ""+Math.random());
submittedTokens.set("earliest_epoch",submittedTokens.get("earliest_epoch_onChange"));
submittedTokens.set("latest_epoch",submittedTokens.get("latest_epoch_onChange"));
submittedTokens.set("earliest_epoch_FILTER",submittedTokens.get("earliest_epoch_FILTER_onChange"));
submittedTokens.set("latest_epoch_FILTER",submittedTokens.get("latest_epoch_FILTER_onChange"));
});
});
Yes. This is a run anywhere dashboard if you have Exchange set up; just replace MYDOMAIN
<dashboard script="button_submit_mail_anomalies.js">
<label>Anomalies</label>
<row>
<panel>
<html depends="$hide$">
<style>
#submit_button{
width:80px !important;
}
#submit_button div[data-component="splunk-core:/splunkjs/mvc/components/LinkList"]{
width:80px !important;
}
#submit_button button{
padding: 6px 15px !important;
border-radius: 3px !important;
font-weight: 500 !important;
background-color: #5cc05c !important;
border: transparent !important;
color: #fff !important;
}
#submit_button button:hover{
background-color: #40a540 !important;
border-color: transparent !important;
}
</style>
</html>
<input type="time" token="TIMERANGE1">
<label>Time Range (STDEV Baseline):</label>
<default>
<earliest>-30d</earliest>
</default>
<change>
<eval token="earliest_epoch_onChange">case(isnum($TIMERANGE1.earliest$), $TIMERANGE1.earliest$, $TIMERANGE1.earliest$=="now", time(), $TIMERANGE1.earliest$="", 0, true(), relative_time(time(), $TIMERANGE1.earliest$))</eval>
<eval token="latest_epoch_onChange">case(isnum($TIMERANGE1.latest$), $TIMERANGE1.latest$, $TIMERANGE1.latest$=="now", time(), true(), relative_time(time(), $TIMERANGE1.latest$))</eval>
</change>
</input>
<input type="time" token="TIMERANGE2">
<label>Time Range (Results Filter):</label>
<default>
<earliest>@w0</earliest>
</default>
<change>
<eval token="earliest_epoch_FILTER_onChange">case(isnum($TIMERANGE2.earliest$), $TIMERANGE2.earliest$, $TIMERANGE2.earliest$=="now", time(), $TIMERANGE2.earliest$="", 0, true(), relative_time(time(), $TIMERANGE2.earliest$))</eval>
<eval token="latest_epoch_FILTER_onChange">case(isnum($TIMERANGE2.latest$), $TIMERANGE2.latest$, $TIMERANGE2.latest$=="now", time(), true(), relative_time(time(), $TIMERANGE2.latest$))</eval>
</change>
</input>-->
<input type="link" id="submit_button">
<label></label>
<choice value="submit">Submit</choice>
</input>
</panel>
</row>
<search id="base">
<query>
index=msexchange event_id=AGENTINFO sender_domain=MYDOMAIN.com | stats sum(total_bytes) as daily_bytes by sender,date_mday,date_month,date_year | eventstats avg(daily_bytes) as average stdev(daily_bytes) as sdev by sender | eval num_sdevs=(daily_bytes-average)/sdev | eval trigger="$submit_trigger$"
</query>
<earliest>$earliest_epoch$</earliest>
<latest>$latest_epoch$</latest>
</search>
<row>
<panel>
<input type="text" token="search">
<label>Filter results by email:</label>
<default>*</default>
</input>
<table>
<title>Top 100 Anomalous Senders by Daily Bytes</title>
<search base="base" id="base2">
<query>
eval time=strptime(date_mday." ".date_month." ".date_year,"%d %B %Y") | where time >="$earliest_epoch_FILTER$" AND time <="$latest_epoch_FILTER$" |
sort 0 - num_sdevs | head 100 | search sender="$search$" | table sender date_mday date_month date_year daily_bytes average sdev num_sdevs
</query>
</search>
<option name="wrap">true</option>
<option name="rowNumbers">false</option>
<option name="drilldown">none</option>
<option name="dataOverlayMode">none</option>
<option name="count">25</option>
</table>
</panel>
</row>
<row>
<panel>
<table>
<title>Repeat Senders in Top 100</title>
<search base="base2">
<query>
eventstats count by sender | where count >1 | table sender date_mday date_month date_year daily_bytes average sdev num_sdevs
</query>
</search>
<option name="wrap">true</option>
<option name="rowNumbers">false</option>
<option name="drilldown">none</option>
<option name="dataOverlayMode">none</option>
<option name="count">5</option>
</table>
</panel>
</row>
</dashboard>
JS:
require([
'jquery',
'splunkjs/mvc',
'splunkjs/mvc/simplexml/ready!'
], function($,mvc){
var submittedTokens = mvc.Components.get("submitted");
$("#submit_button").click(function(){
submittedTokens.set("submit_trigger", ""+Math.random());
submittedTokens.set("earliest_epoch",submittedTokens.get("earliest_epoch_onChange"));
submittedTokens.set("latest_epoch",submittedTokens.get("latest_epoch_onChange"));
submittedTokens.set("earliest_epoch_FILTER",submittedTokens.get("earliest_epoch_FILTER_onChange"));
submittedTokens.set("latest_epoch_FILTER",submittedTokens.get("latest_epoch_FILTER_onChange"));
});
});
P.S. I also have an alert for this:
[bytes_anomalies]
action.email = 1
action.email.cc = DELETED
action.email.include.search = 1
action.email.include.trigger = 1
action.email.include.trigger_time = 1
action.email.inline = 1
action.email.message.alert = Machine learning algorithm monitoring possible Exchange data exfil by internal senders.\
\
This alert is ran twice daily at 5AM (producing results since 12AM the previous day) and 5PM PST (producing results since 12AM the current day) with a STDEV baseline of 30 days. Total_bytes over 200MB AND num_sdevs over 4.0 alerted on only.
action.email.sendcsv = 1
action.email.sendresults = 1
action.email.subject = Splunk Alert: Exchange daily_bytes Anomaly Detection ($result.spl_id$)
action.email.to = DELETED
alert.suppress = 0
alert.track = 0
counttype = number of events
cron_schedule = 0 5,17 * * *
dispatch.earliest_time = -30d@d
dispatch.latest_time = now
display.general.type = statistics
display.page.search.tab = statistics
enableSched = 1
quantity = 0
relation = greater than
request.ui_dispatch_app = DELETED
request.ui_dispatch_view = search
search = index=msexchange event_id=AGENTINFO sender_domain=DELETED.com | stats sum(total_bytes) as daily_bytes by sender,date_mday,date_month,date_year | eventstats avg(daily_bytes) as average stdev(daily_bytes) as sdev by sender | eval num_sdevs=(daily_bytes-average)/sdev | \
eval time=strptime(date_mday." ".date_month." ".date_year,"%d %B %Y") | where time >= relative_time(now(),"-12h@d") AND daily_bytes >= 200000000 AND num_sdevs >= 4.0 | sort 0 - num_sdevs | eval spl_id=strftime(now(),"SPL%m%d%y_%H%M") | table spl_id sender date_mday date_month date_year daily_bytes average sdev num_sdevs