/usr/share/modsecurity-crs/lua/arachni_integration.lua is in modsecurity-crs 2.2.8-1.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | --
-- Include Arachni RPC client code
--
require "client"
--
-- Call main ModSecurity Lua function
--
function main()
--
-- Set the remote Arachni RPC host
--
arachni_host = '192.168.168.128'
--
-- Extract Request Data
--
host = m.getvar("REQUEST_HEADERS.host")
m.log(4, "Arachni: Host: " .. host)
request_filename = m.getvar("REQUEST_FILENAME")
m.log(4, "Arachni: Filename: " .. request_filename)
url_to_scan = "http://" .. host .. request_filename
m.log(4, "Arachni: URL to scan is: " .. url_to_scan)
request_method = m.getvar("REQUEST_METHOD")
m.log(4, "Arachni: Request Method is: " .. request_method)
--
-- Convert ModSecurity ARGS data into a local table called args
--
ARGS = {}
ARGS = m.getvars("ARGS")
args = {}
for k,v in pairs(ARGS) do
name = v["name"];
name = string.gsub(name, "ARGS:(.*)", "%1")
value = v["value"];
m.log(4, "Arachni: Arg Name: " ..name.. " and Value: " ..value.. ".");
args[name] = value
end
local yaml_args = yaml.dump ( args )
m.log(4, "Arachni: Updated ARGS table is: " .. yaml_args)
--
-- Convert ModSecrity COOKIE data into a local table called cookies_table
--
COOKIES = {}
COOKIES = m.getvars("REQUEST_COOKIES")
cookies_table = {}
for k,v in pairs(COOKIES) do
name = v["name"];
name = string.gsub(name, "REQUEST_COOKIES:(.*)", "%1")
value = v["value"];
m.log(4, "Arachni: Cookie Name: " ..name.. " and Value: " ..value.. ".");
cookies_table[name] = value
end
local yaml_cookies = yaml.dump ( cookies_table )
m.log(4, "Arachni: Updated Cookies table is: " .. yaml_cookies)
--
-- Initiate Arachni RPC Dispatchers
--
dispatcher = ArachniRPCClient:new( { host = arachni_host, port = 7331 } )
instance_info = dispatcher:call( 'dispatcher.dispatch' )
--
-- Check to see if we have previously initiated a scan for the resource
--
-- If we have not, then we will contact the Dispatcher and start a scan
--
local arachni_scan_initiated = m.getvar("RESOURCE.arachni_scan_initiated")
if arachni_scan_initiated == nil then
--
-- Set the host to match the remote Dispatcher
--
instance = ArachniRPCClient:new({
host = arachni_host,
port = instance_info.port,
token = instance_info.token
})
opts = {
url = url_to_scan,
audit_links = true,
audit_forms = true,
audit_cookies = true,
-- only audit the stuff passed to vector feed
link_count_limit = 0,
cookies = cookies_table
}
instance:call( 'modules.load', { 'xss', 'sqli', 'path_traversal' } )
vectors = {}
-- add a form var (for POST params)
table.insert( vectors, {
type = 'form',
method = request_method,
action = url_to_scan,
inputs = args
})
local yaml_vectors = yaml.dump( vectors )
m.log(4, "Arachni: Yaml output of vectors is: " .. yaml_vectors)
plugins = {
vector_feed = {
vectors = vectors
}
}
instance:call( 'plugins.load', plugins )
instance:call( 'opts.set', opts )
instance:call( 'framework.run' )
--
-- Save the Dispatcher port/token data to pull the report later
--
m.setvar("RESOURCE.arachni_scan_initiated", "1")
m.setvar("RESOURCE.arachni_instance_info_port", instance_info.port)
m.setvar("RESOURCE.arachni_instance_info_token", instance_info.token)
return ("Arachni: Scan Initiated. Exiting")
else
--
-- If we have previously initiated a scan, we will now check for a report
--
m.log(4, "Arachni: Previous scan was initiated, checking scan status.")
local instance_info_port = m.getvar("RESOURCE.arachni_instance_info_port")
local instance_info_token = m.getvar("RESOURCE.arachni_instance_info_token")
m.log(4, "Arachni: Port info: " .. instance_info_port .. " and Token info: " .. instance_info_token)
instance = ArachniRPCClient:new({
host = arachni_host,
port = instance_info_port,
token = instance_info_token
})
if instance:call( 'framework.busy?' ) then
m.log(4, "Arachni: Scan still in progress, framework is busy. Exiting.")
return ("Arachni scan still in progress, framework is busy. Exiting.")
else
m.log(4, "Arachni: Scan completed - calling for report.")
local results = instance:call( 'framework.issues_as_hash' )
yaml_results = yaml.dump( results )
m.log(4, "Arachni: Yaml Results: " .. yaml_results)
for k,v in pairs(results) do
name = v["name"];
value = v["value"];
if ( v["mod_name"] == "XSS" ) then
local XssVulnParams = m.getvar("RESOURCE.xss_vulnerable_params")
if not (XssVulnParams) then
m.log(4, "Arachni: Vulnerability Identified for Parameter: \"" .. v["var"] .. "\", Vulnerability Type: \"" .. v["mod_name"] .. "\"")
m.setvar("RESOURCE.xss_vulnerable_params", v["var"])
else
local CheckArgInXssVulnParams = string.find(XssVulnParams, v["var"])
if (CheckArgInXssVulnParams) then
m.log(4, "Arachni: Arg Name: " .. v["var"] .. " already in XSS Vuln list.")
else
m.log(4, "Arachni: Vulnerability Identified for Parameter: \"" .. v["var"] .. "\", Vulnerability Type: \"" .. v["mod_name"] .. "\"")
XssVulnParams = XssVulnParams .. ", " .. v["var"]
m.setvar("RESOURCE.xss_vulnerable_params", XssVulnParams)
end
end
end
if ( v["mod_name"] == "SQLInjection" ) then
local SQLiVulnParams = m.getvar("RESOURCE.sqli_vulnerable_params")
if not (SQLiVulnParams) then
m.log(4, "Arachni: Vulnerability Identified for Parameter: \"" .. v["var"] .. "\", Vulnerability Type: \"" .. v["mod_name"] .. "\"")
m.setvar("RESOURCE.sqli_vulnerable_params", v["var"])
else
local CheckArgInSQLiVulnParams = string.find(SQLiVulnParams, v["var"])
if (CheckArgInSQLiVulnParams) then
m.log(4, "Arachni: Arg Name: " .. v["var"] .. " already in SQLi Vuln list.")
else
m.log(4, "Arachni: Vulnerability Identified for Parameter: \"" .. v["var"] .. "\", Vulnerability Type: \"" .. v["mod_name"] .. "\"")
SQLiVulnParams = SQLiVulnParams .. ", " .. v["var"]
m.setvar("RESOURCE.sqli_vulnerable_params", SQLiVulnParams)
end
end
end
end
instance:call( 'service.shutdown' )
m.setvar("RESOURCE.arachni_scan_completed", "1")
return ("Arachni: Done")
end
end
end
|