-
-
Save norandom/f3d5006b858c77810e63 to your computer and use it in GitHub Desktop.
suricata 2.0.10 URL comparer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- url comparision Lua script for suricata | |
-- author: marius - at - because-security.com | |
-- rule: | |
-- # Compare URLs with a black list | |
-- alert tcp any any -> any any (msg:"CUSTOM BAD url"; luajit:bad_urls.lua; sid:1;) | |
-- file: | |
-- some folder: bad_urls.txt: | |
-- http:/foo.bar/malware.exe | |
-- http://www.blala/malware123.exe | |
-- this gets called during rule parsing | |
function init (args) | |
local needs = {} | |
needs["payload"] = tostring(true) | |
return needs | |
end | |
-- this gets executed one time once per thread at init | |
-- read urls from file and keep them in a table | |
local url_file = io.open("/etc/suricata/rules/bad_urls.txt", "r"); | |
arr = {} | |
for line in url_file:lines() do | |
table.insert (arr, line); | |
end | |
url_file:close() | |
-- define our protocol methods | |
http_methods = { "GET", "POST", "PUT", "OPTIONS" } | |
-- this is a matcher function | |
function match(args) | |
a = tostring(args["payload"]) | |
if #a > 0 then | |
-- primitive protocol detection on ASCII | |
local file = io.open("/var/log/suricata/bad_urls_dbg.log", "a") | |
local http_method = string.match(a, '^([%l%u]+)%s+') | |
for _, v in ipairs(http_methods) do | |
if v == http_method then | |
http = true | |
file:write("http: " .. "yes" .. "\n") | |
file:flush() | |
end | |
end | |
if http then | |
local http_request = split(a, "\r?\n") | |
if http_request[1] and http_request[2] then | |
uri = string.match(http_request[1], "^GET%s+(.+)%sHTTP") | |
host = string.match(http_request[2], "^Host:%s+(.+)") | |
file:flush() | |
end | |
if uri and host then | |
url = host .. uri | |
file:write("url: " .. url .. "\n") | |
file:flush() | |
end | |
if url and uri and host then | |
local verbose = true | |
if verbose then | |
-- file:write("http req: " .. http_request[1] .. "\n") | |
file:write("uri: " .. uri .. "\n") | |
file:write("host: " .. host .. "\n") | |
file:write("url: " .. "http://" .. url .. "\n") | |
file:flush() | |
end | |
for _, v in ipairs(arr) do | |
if v:find(host .. uri) then | |
file:write("BAD URL match " .. host .. uri .. " vs " .. v .. "\n") | |
file:flush() | |
file:close() | |
return 1 | |
end | |
end | |
end | |
file:flush() | |
file:close() | |
end | |
end | |
return 0 | |
end | |
-- split function to get http requests line by line | |
function split(str, delim) | |
local result,pat,lastPos = {},"(.-)" .. delim .. "()",1 | |
for part, pos in string.gfind(str, pat) do | |
table.insert(result, part); lastPos = pos | |
end | |
table.insert(result, string.sub(str, lastPos)) | |
return result | |
end | |
return 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment