All Apps and Add-ons

Anomalous Exchange sender daily_bytes dashboard?

nick405060
Motivator

Does anyone have a dashboard that displays anomalies for Exchange daily_bytes by sender? Looking for possible exfil through Exchange.

0 Karma
1 Solution

nick405060
Motivator

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"));
     });
 });

View solution in original post

0 Karma

nick405060
Motivator

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"));
     });
 });
0 Karma

nick405060
Motivator

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
0 Karma
Get Updates on the Splunk Community!

Enterprise Security Content Update (ESCU) | New Releases

In September, the Splunk Threat Research Team had two releases of new security content via the Enterprise ...

New in Observability - Improvements to Custom Metrics SLOs, Log Observer Connect & ...

The latest enhancements to the Splunk observability portfolio deliver improved SLO management accuracy, better ...

Improve Data Pipelines Using Splunk Data Management

  Register Now   This Tech Talk will explore the pipeline management offerings Edge Processor and Ingest ...