-
-
Save Bsebring/ec10519ecc272c69be08e82d4b3626af to your computer and use it in GitHub Desktop.
#!/usr/bin/env lua | |
-- Tells Suricata to only execute this script if the | |
-- packet triggered an alert | |
function init (args) | |
local needs = {} | |
needs["type"] = "packet" | |
needs["filter"] = "alerts" | |
return needs | |
end | |
-- Setting up the log files to use | |
function setup (args) | |
-- The first log will be used to determine if the report | |
-- was a success or a failure. | |
filename = SCLogPath() .. "/" .. "abuseipdb_alert_reports.log" | |
file = assert(io.open(filename, "a")) | |
-- The second log is a custom log set up for debugging your alerts | |
filename2 = SCLogPath() .. "/" .. "abuseipdb_custom_debug.log" | |
file2 = assert(io.open(filename2, "a")) | |
SCLogInfo("Report to AbuseIPDB " .. filename) | |
count = 0 | |
end | |
-- Function that reports to AbuseIPDB and logs | |
-- the reports to the specified file | |
function log(args) | |
local https = require("ssl.https"); | |
local ltn12 = require("ltn12") | |
local url = require("socket.url") | |
-- Grab data from packet to use in post request | |
local ipver, srcip, dstip, proto, sp, dp = SCPacketTuple() | |
-- Grab timestamp | |
local timestring = SCPacketTimeString() | |
local class, prio = SCRuleClass() | |
local surCategory = "15" | |
-- Assigning AbuseIPDB category based on Suricata Rule classification | |
if string.match(class, "web application") then | |
file2:write("Message: " .. SCRuleMsg() .. " Class: " .. class .. " matched to category 21\n") | |
surCategory = "21" | |
elseif string.match(class, "user") or string.match(class, "administrator") then | |
file2:write("Message: " .. SCRuleMsg() .. " Class: " .. class .. " matched to category 18\n") | |
surCategory = "18" | |
elseif string.match(class, "suspicious username") or string.match(class, "default username") then | |
file2:write("Message: " .. SCRuleMsg() .. " Class: " .. class .. " matched to categories 18, 22\n") | |
surCategory = "18,22" | |
elseif (string.match(class, "rpc") or string.match(class, "Network scan") or string.match(class, "Information Leak")) then | |
file2:write("Message: " .. SCRuleMsg() .. " Class: " .. class .. " matched to category 14\n") | |
surCategory = "14" | |
elseif string.match(class, "Denial of Service") then | |
file2:write("Message: " .. SCRuleMsg() .. " Class: " .. class .. " matched to category 4\n") | |
surCategory = "4" | |
else | |
file2:write("Message: " .. SCRuleMsg() .. " Class: " .. class .. " matched to category 15\n") | |
surCategory = "15" | |
end | |
if string.match(SCRuleMsg(), "SQL INJECTION") then | |
file2:write("Message: " .. SCRuleMsg() .. " Class: " .. class .. " category 16 added\n") | |
surCategory = surCategory .. ",16" | |
end | |
-- Setting up the post request. | |
comment = timestring .. " " .. srcip .. " Protocol: " .. proto .. " " .. SCRuleMsg() | |
commentE = url.escape(comment) | |
local path = "https://api.abuseipdb.com/api/v2/report?ip=" .. srcip .. "&comment=" .. commentE .. "&categories=" | |
local body = { | |
categories = "18,22", | |
["ip"] = srcip | |
} | |
local response_body = {} | |
-- Set up the response request. | |
local res, code, response_headers = https.request({ | |
url = path .. surCategory, | |
method = "POST", | |
headers = | |
{ | |
["Accept"] = "Application/json", | |
["Key"] = "$YOUR_API_KEY", | |
["Content-Length"] = #body, | |
}, | |
protocol = "tlsv1", | |
source = ltn12.source.string(tostring(body)), | |
sink = ltn12.sink.table(response_body) | |
}) | |
if code == 200 then | |
file:write ("\nReport " .. count .. " Success! " .. comment .. " " .. table.concat(response_body)) | |
else | |
file:write ("\nReport " .. count .. " FAILED!" .. timestring .. " Error Code: " .. code .. " Category: " .. surCategory) | |
end | |
file:flush() | |
file2:flush() | |
count = count + 1 | |
end | |
-- Cleans up, and closes the log files | |
function deinit (args) | |
SCLogInfo ("Reports Logged: " .. count); | |
io.close(file) | |
io.close(file2) | |
end |
I have question, the default rate limit for API is 3000, how do I obtain the json value for this, so that I can display it in my script. I see the documentation only explained about the header error code. Is there a specific json value? Also is there an API key to test the maximum rate ?
I have question, the default rate limit for API is 3000, how do I obtain the json value for this, so that I can display it in my script. I see the documentation only explained about the header error code. Is there a specific json value? Also is there an API key to test the maximum rate ?
We do have the X-RateLimit-Limit
header that returns your daily limit, as well as one that returns the number of daily requests remaining.
Not really sure what you mean by the last question, we do all of our testing with the maximum limit.
We also offer a trial on our premium subscription.
Hello,
Nice script, but needs a counter (per IP) or timer 15 minutes) to prevent send the same ip report multiple times. You must wait at least 15 minutes for report for the same IP.
Here's my case: if some stupid IP makes a multiple attack:
Message: ATTACK [PTsecurity] Unimplemented Trans2 Sub-Command code. Possible ETERNALBLUE (WannaCry, Petya) tool Class: Attempted Administrator Privilege Gain matched to category 15
For every line (even repeated) the script sent the attack every time to AbuseIPDB, and finally gets a Error Code 429
Report 2217 FAILED!03/07/2021-20:53:29.728015 Error Code: 429 Category: 15
May I add?
elseif string.match(class, "Attempted Administrator Privilege Gain") then
return
Context:
I'm runing a Honeypot on port 445 (SMB)
Same happens with other duplicate rules:
Message: GPL NETBIOS SMB-DS IPC$ share access Class: Generic Protocol Command Decode matched to category 15
Any ideas?
Respond myself:
Here is the solution using "threshold" /etc/suricata/threshold.config
threshold gen_id 1, sig_id 2102465, type both, track by_src, count 1, seconds 3600
Where sig_id is the rule.
Documentation:
https://suricata.readthedocs.io/en/suricata-6.0.2/configuration/global-thresholds.html#threshold-event-filter
https://suricata.readthedocs.io/en/suricata-6.0.2/rules/thresholding.html
Thank you in advance.
I had to change protocol version to "tlsv1_2" at line 85 to make it work
Thank you very much for adding this bit of information, I will verify that this works on our end and update the script accordingly.