I created these dashboards for splunk to detect some attacks:
Apache Error Log Monitoring Dashboard
<form version="1.1" theme="dark"> <label>Apache Error Log Monitoring Dashboard</label> <description>Monitors Apache error logs for potential security events and path traversal attempts</description> <fieldset submitButton="false" autoRun="true"></fieldset> <row> <panel> <title>Amount Of Errors Over Time</title> <chart> <search> <query>source="/var/log/apache2/error.log" sourcetype="apache_error" | eval mytime=strftime(_time,"%Y-%m-%d %H:%M") | stats count as error_count by mytime | sort -error_count </query> <earliest>-24h</earliest> <latest>now</latest> </search> <option name="charting.chart">pie</option> <option name="charting.drilldown">none</option> </chart> </panel> <panel> <title>Error Activity Over Time</title> <chart> <search> <query>source="/var/log/apache2/error.log" sourcetype="apache_error" | timechart span=5m count by host</query> <earliest>-24h</earliest> <latest>now</latest> </search> <option name="charting.chart">line</option> <option name="charting.drilldown">none</option> <option name="charting.legend.placement">bottom</option> </chart> </panel> </row> <row> <panel> <title>Path Traversal Attempts</title> <table> <search> <query>source="/var/log/apache2/error.log" sourcetype="apache_error" "AH00126: Invalid URI" OR "/../" OR ".." OR "%2E%2E" | rex field=_raw "GET (?<request_path>[^ ]+) HTTP" | table _time client request_path | sort -_time</query> <earliest>-24h</earliest> <latest>now</latest> </search> <option name="drilldown">none</option> </table> </panel> </row> <row> <panel> <title>Admin Page Probing</title> <chart> <search> <query>source="/var/log/apache2/error.log" sourcetype="apache_error" "admin" OR "administrator" OR "login" OR "cp" OR "controlpanel" | rex field=_raw "script '(?<requested_script>[^']+)'" | stats count by requested_script | sort -count</query> <earliest>-24h</earliest> <latest>now</latest> </search> <option name="charting.chart">bar</option> <option name="charting.drilldown">none</option> <option name="charting.chart.stackMode">default</option> <option name="charting.legend.placement">bottom</option> </chart> </panel> </row> <row> <panel> <title>Top Client IPs</title> <chart> <search> <query>source="/var/log/apache2/error.log" sourcetype="apache_error" | rex field=_raw "\[client (?<client_ip>[^\:]+)\:(?<client_port>\d+)\]" | stats count by client_ip | sort -count</query> <earliest>-24h</earliest> <latest>now</latest> </search> <option name="charting.chart">column</option> <option name="charting.drilldown">none</option> </chart> </panel> <panel> <title>Process IDs with Errors</title> <chart> <search> <query>source="/var/log/apache2/error.log" sourcetype="apache_error" | rex field=_raw "\[pid (?<process_id>\d+)\]" | stats count by process_id | sort -count</query> <earliest>-24h</earliest> <latest>now</latest> </search> <option name="charting.chart">pie</option> <option name="charting.drilldown">none</option> </chart> </panel> </row> <row> <panel> <title>Recent Critical Events</title> <table> <search> <query>source="/var/log/apache2/error.log" sourcetype="apache_error" "Invalid URI" OR "/etc/shadow" OR "/etc/passwd" OR "../" OR "%2E%2E" OR "/.." | rex field=_raw "GET (?<request_path>[^ ]+)" | rex field=_raw "\[client (?<client_ip>[^\:]+)\:(?<client_port>\d+)\]" | table _time client_ip request_path | sort -_time</query> <earliest>-24h</earliest> <latest>now</latest> </search> <option name="count">10</option> <option name="drilldown">none</option> </table> </panel> </row> <row> <panel> <title>Search for Suspicious Activity</title> <input type="text" token="search_term" searchWhenChanged="true"> <label>Search Term</label> <default>shadow</default> </input> <table> <search> <query>source="/var/log/apache2/error.log" sourcetype="apache_error" "$search_term$" | table _time _raw | sort -_time</query> <earliest>-24h</earliest> <latest>now</latest> </search> <option name="count">5</option> <option name="drilldown">none</option> </table> </panel> </row> </form>
Path Traversal Attempts
<form version="1.1" theme="dark"> <label>Path Traversal Attempts</label> <description></description> <row> <panel> <title>Top Missing Scripts</title> <chart> <search> <query>index=main sourcetype=apache_error "not found or unable to stat" | rex field=_raw "script '(?<script_path>[^']+)' not found" | stats count by script_path | sort -count</query> </search> <option name="charting.chart">bar</option> <option name="charting.legend.placement">right</option> <option name="height">250</option> </chart> </panel> <panel> <title>Path Traversal Attempts</title> <chart> <search> <query>index=main sourcetype=apache_error "Invalid URI" | regex _raw="(\.\./){2,}" | stats count by host, source, _time | sort -_time</query> </search> <option name="charting.chart">column</option> <option name="height">250</option> </chart> </panel> </row> <row> <panel> <title>Recent PHP Errors</title> <table> <search> <query>index=main sourcetype=apache_error "php7:error" | rex field=_raw "script '(?<script>[^']+)' not found" | table _time, script, client, host</query> </search> <option name="count">10</option> </table> </panel> <panel> <title>Uncommon Events</title> <table> <search> <query>index=main sourcetype=apache_error | rare _raw | table _time, _raw</query> </search> <option name="count">10</option> </table> </panel> </row> </form>
SSH Brute Force Attack Dashboard
<dashboard version="1.1" theme="light"> <label>SSH Brute Force Attack Dashboard</label> <description>Monitor and detect SSH brute force activities in real time</description> <row> <panel> <title>SSH Login Attempts Over Time</title> <chart> <search> <query> index=* sourcetype="auth" | search "ssh*" AND ("Failed password" OR "authentication failure" OR "Invalid user") | bucket span=1m _time | stats count as login_attempts by _time </query> <earliest>-24h@h</earliest> <latest>now</latest> </search> <option name="charting.chart">line</option> </chart> </panel> <panel> <title>Top Attacking IPs</title> <chart> <search> <query> index=* sourcetype="auth" | search "ssh*" AND ("Failed password" OR "authentication failure" OR "Invalid user") | eval src_ip=coalesce(src_ip, source_ip, src, clientip, rhost) | stats count by src_ip | sort -count | head 10 </query> <earliest>-24h@h</earliest> <latest>now</latest> </search> <option name="charting.chart">bar</option> </chart> </panel> </row> <row> <panel> <title>Top Targeted Usernames</title> <chart> <search> <query> index=* sourcetype="auth" | search "ssh*" AND ("Failed password" OR "authentication failure" OR "Invalid user") | rex field=_raw "(?:for|user)\s+(?:invalid user\s+)?(?<user>\w+)" | stats count by user | sort -count | head 10 </query> <earliest>-24h@h</earliest> <latest>now</latest> </search> <option name="charting.chart">pie</option> </chart> </panel> <panel> <title>Success vs Failure Attempts</title> <chart> <search> <query> index="*" sourcetype="auth" "ssh*" | eval status=case( like(_raw, "%Accepted password%"), "Success", like(_raw, "%Failed password%") OR like(_raw, "%authentication failure%") OR like(_raw, "%Invalid user%"), "Failure" ) | stats count by status </query> <earliest>-24h@h</earliest> <latest>now</latest> </search> <option name="charting.chart">pie</option> </chart> </panel> </row> <row> <panel> <title>Detailed SSH Brute Force Attempts</title> <table> <search> <query> index=* sourcetype="auth" | search "ssh*" AND ("Failed password" OR "authentication failure" OR "Invalid user") | rex field=_raw "(?:for|user)\s+(?:invalid user\s+)?(?<user>\w+)" | eval src_ip=coalesce(src_ip, source_ip, src, clientip, rhost) | table _time, src_ip, user, host, _raw </query> <earliest>-24h@h</earliest> <latest>now</latest> </search> </table> </panel> </row> </dashboard>
Top comments (0)