From d04b022d155aefe38ca68be34dccc805c47a08d8 Mon Sep 17 00:00:00 2001 From: deepshikha-s Date: Tue, 20 Sep 2022 15:00:34 +0530 Subject: [PATCH 1/2] Resolved errors --- plugin/machine-learning-after.conf | 15 +- plugin/machine-learning-after.conf.disabled | 32 +++++ plugin/machine-learning-client.lua | 13 +- plugin/machine-learning-client.lua.save | 113 +++++++++++++++ plugin/machine-learning-config.conf | 1 + plugin/machine-learning-file.lua | 150 ++++++++++++++++++++ 6 files changed, 314 insertions(+), 10 deletions(-) create mode 100644 plugin/machine-learning-after.conf.disabled create mode 100644 plugin/machine-learning-client.lua.save create mode 100644 plugin/machine-learning-file.lua diff --git a/plugin/machine-learning-after.conf b/plugin/machine-learning-after.conf index 8980c93..69efb95 100644 --- a/plugin/machine-learning-after.conf +++ b/plugin/machine-learning-after.conf @@ -39,7 +39,7 @@ SecRule TX:ANOMALY_SCORE "@lt %{tx.machine-learning-plugin_inbound_anomaly_score phase:2,\ pass,\ nolog,\ - ctl:ruleRemoveById=9516120-9516310-9516320,\ + ctl:ruleRemoveById=9516310-9516320,\ ver:'machine-learning-plugin/1.0.0'" # This rule checks if the anomaly score exceeds inbound_anomaly_score_threshold @@ -53,8 +53,11 @@ SecRule TX:ANOMALY_SCORE "@ge %{tx.machine-learning-plugin_inbound_anomaly_score msg:'Anomaly Score Exceeded (Total Score: %{TX.ANOMALY_SCORE}) - ML kicked in.',\ tag:'anomaly-evaluation',\ ver:'machine-learning-plugin/1.0.0',\ - severity:'CRITICAL'" - SecRuleScript machine-learning-client.lua + severity:'CRITICAL', \ + chain,\ + setvar:'tx.machine-learning-plugin_inbound_anomaly_score=%{tx.anomaly_score}', \ + setvar:'tx.machine-learning-plugin_inbound_ml_status=%{tx.machine-learning-plugin_inbound_ml_status}'" + SecRuleScript machine-learning-client.lua # This rule calls the ml model which generates an anomaly score. # Based on this score the model gives a status deny or pass (0 or 1). @@ -64,14 +67,14 @@ SecAction \ phase:2,\ pass,\ t:none,\ - msg:'ML kicked in for evaluation.',\ + msg:'ML kicked in for evaluation. %{tx.machine-learning-plugin_inbound_ml_status}',\ tag:'anomaly-evaluation',\ ver:'machine-learning-plugin/1.0.0',\ severity:'NOTICE'" SecRuleScript machine-learning-client.lua # This rule checks the status of the ML model and makes a decision to pass. -SecRule TX:INBOUND_ML_STATUS "@eq %{tx.machine-learning-plugin_inbound_ml_pass_flag} " \ +SecRule TX:MACHINE-LEARNING-PLUGIN_INBOUND_ML_STATUS "@eq %{tx.machine-learning-plugin_inbound_ml_pass_flag} " \ "id:9516310,\ phase:2,\ pass,\ @@ -83,7 +86,7 @@ SecRule TX:INBOUND_ML_STATUS "@eq %{tx.machine-learning-plugin_inbound_ml_pass_f severity:'NOTICE'" # This rule checks the status of the ML model and makes a decision to deny. -SecRule TX:INBOUND_ML_STATUS "@eq %{tx.machine-learning-plugin_inbound_ml_deny_flag} " \ +SecRule TX:MACHINE-LEARNING-PLUGIN_INBOUND_ML_STATUS "@eq %{tx.machine-learning-plugin_inbound_ml_deny_flag} " \ "id:9516320,\ phase:2,\ deny,\ diff --git a/plugin/machine-learning-after.conf.disabled b/plugin/machine-learning-after.conf.disabled new file mode 100644 index 0000000..1f94d04 --- /dev/null +++ b/plugin/machine-learning-after.conf.disabled @@ -0,0 +1,32 @@ +# ------------------------------------------------------------------------ +# OWASP ModSecurity Core Rule Set Plugin +# Copyright (c) 2021-2022 Core Rule Set project. All rights reserved. +# +# The OWASP ModSecurity Core Rule Set plugins are distributed under +# Apache Software License (ASL) version 2 +# Please see the enclosed LICENSE file for full details. +# ------------------------------------------------------------------------ + +# OWASP CRS Plugin +# Plugin name: machine-learning +# Plugin description: +# Rule ID block base: 9,516,000 - 9,516,999 +# Plugin version: 1.0.0 + +# Documentation can be found here: +# https://github.com/coreruleset/machine-learning-plugin + +SecRule TX:ANOMALY_SCORE "@ge %{tx.inbound_anomaly_score_threshold}" \ + "id:9516110,\ + phase:2,\ + deny,\ + t:none,\ + msg:'Inbound Anomaly Score Exceeded (Total Score: %{TX.ANOMALY_SCORE})',\ + tag:'anomaly-evaluation',\ + ver:'machine-learning-plugin/1.0.0',\ + severity:'CRITICAL',\ + chain" + SecRule TX:0 "@inspectFile machine-learning-client.lua" \ + "t:none,\ + msg:'machine learning Anomaly Score: %{tx.anomaly_score}',\ + setvar:'tx.inbound_anomaly_score=%{tx.anomaly_score}'" diff --git a/plugin/machine-learning-client.lua b/plugin/machine-learning-client.lua index ec96836..ba6229c 100644 --- a/plugin/machine-learning-client.lua +++ b/plugin/machine-learning-client.lua @@ -83,7 +83,7 @@ function main() ["Content-Length"] = #body } local source = ltn12.source.string(body) - local client, code, headers, status = http.request{ + local client, code, headers, score = http.request{ url=ml_server_url, method='POST', source=source, @@ -91,18 +91,23 @@ function main() sink = ltn12.sink.table(respbody) } respbody = table.concat(respbody) - + m.log(1, "Client "..client.." Code "..code.."..".." Score "..score) + m.log(1, "Respbody "..respbody) -- Processing the result if client == nil then m.log(2, 'The server is unreachable ') end if code == 401 then m.log(1,'Anomaly found by ML') + m.setvar("TX.machine-learning-plugin_inbound_anomaly_score", score) end if code == 200 then inbound_ml_result = 1 + m.setvar("TX.machine-learning-plugin_inbound_anomaly_score", score) + m.setvar("TX.machine-learning-plugin_inbound_ml_status", inbound_ml_result) end - m.setvar("TX.machine-learning-plugin_inbound_ml_anomaly_score", respbody) - m.setvar("TX.machine-learning-plugin_inbound_ml_status", inbound_ml_result) + --m.setvar("TX.machine-learning-plugin_inbound_anomaly_score", score) + --m.setvar("TX.machine-learning-plugin_inbound_ml_status", inbound_ml_result) + --m.log(1, "Status "..TX.machine-learning-plugin_inbound_ml_status) return inbound_ml_result end diff --git a/plugin/machine-learning-client.lua.save b/plugin/machine-learning-client.lua.save new file mode 100644 index 0000000..75f502c --- /dev/null +++ b/plugin/machine-learning-client.lua.save @@ -0,0 +1,113 @@ +-- This is a driver code to point to different ML servers and models +-- and seek ml_inbound_status using such models +-- this ml driver is invoked by machine-learning-plugin-after.conf +-- currently most of this code is from https://github.com/coreruleset/coreruleset/pull/2067/files + +function main() + -- Variable Declarations: + -- setting the machine learning server URL + pcall(require, "m") + local ml_server_url = m.getvar("TX.machine-learning-plugin_ml_server_url") + -- initialising the variable to return the machine learning pass or block status + local inbound_ml_result = 0 + -- Importing libraries + local ltn12 = require("ltn12") + local http = require("socket.http") + -- Initialising variables + local method = m.getvar("REQUEST_METHOD") + local path = m.getvar("REQUEST_FILENAME") + local hour = m.getvar("TIME_HOUR") + local day = m.getvar("TIME_DAY") + local args = m.getvars("ARGS") + local files = m.getvars("FILES") + local filesizes = m.getvars("FILES_SIZES") + local args_str = "{}" + local filesstr = "{}" + local filesizestr = "{}" + local body = " " + local respbody = {} + -- Parsing the tables and logging + if args ~= nil then + args_str = "{" + for k,v in pairs(args) do + name = v["name"] + value = v["value"] + value = value:gsub('"', "$#$") + args_str = args_str..'"'..name..'":"'..value..'",' + end + if #args == 0 then + args_str = "{}" + else + args_str = string.sub(args_str, 1, -2) + args_str = args_str.."}" + end + end + + if files ~= nil then + filesstr = "{" + for k,v in pairs(files) do + name = v["name"] + value = v["value"] + value = value:gsub('"', "$#$") + filesstr = filesstr..'"'..name..'":"'..value..'",' + end + if #files == 0 then + filesstr = "{}" + else + filesstr = string.sub(filesstr, 1, -2) + filesstr = filesstr.."}" + end + end + + if filesizes ~= nil then + filesizestr = "{" + for k,v in pairs(filesizes) do + name = v["name"] + value = v["value"] + value = value:gsub('"', "$#$") + filesizestr = filesizestr..'"'..name..'":"'..value..'",' + end + if #filesizes == 0 then + filesizestr = "{}" + else + filesizestr = string.sub(filesizestr, 1, -2) + filesizestr = filesizestr.."}" + end + end + + -- Construct http request for the ml server + --body = "method="..method.."&path="..path.."&args="..args_str.."&files="..filesstr.."&sizes="..filesizestr.."&hour="..hour.."&day="..day + body = string.format("method=%s&path=%s&args=%s&files=%s&sizes=%s&hour=%s&day=%s", method, path, args_str, filesstr, filesizestr, hour, day) + headers = { + ["Content-Type"] = "application/x-www-form-urlencoded"; + ["Content-Length"] = #body + } + local source = ltn12.source.string(body) + local client, code, headers, score = http.request{ + url=ml_server_url, + method='POST', + source=source, + headers=headers, + sink = ltn12.sink.table(respbody) + } + m.log(1, "Respbody "..respbody) + respbody = table.concat(respbody) + m.log(1, "Client "..client.." Code "..code.."..".." Score "..score) +-- Processing the result + if client == nil then + m.log(2, 'The server is unreachable ') + end + if code == 401 then + m.log(1,'Anomaly found by ML') + m.setvar("TX.machine-learning-plugin_inbound_anomaly_score", score) + end + if code == 200 then + inbound_ml_result = 1 + m.setvar("TX.machine-learning-plugin_inbound_anomaly_score", score) + m.setvar("TX.machine-learning-plugin_inbound_ml_status", inbound_ml_result) + end + --m.setvar("TX.machine-learning-plugin_inbound_anomaly_score", score) + --m.setvar("TX.machine-learning-plugin_inbound_ml_status", inbound_ml_result) + --m.log(1, "Status "..TX.machine-learning-plugin_inbound_ml_status) + return inbound_ml_result +end diff --git a/plugin/machine-learning-config.conf b/plugin/machine-learning-config.conf index 2089473..66d2abb 100644 --- a/plugin/machine-learning-config.conf +++ b/plugin/machine-learning-config.conf @@ -63,5 +63,6 @@ SecAction \ setvar:'tx.machine-learning-plugin_inbound_ml_pass_flag=1',\ setvar:'tx.machine-learning-plugin_inbound_ml_deny_flag=0',\ setvar:'tx.machine-learning-plugin_inbound_ml_anomaly_score=0',\ + setvar:'tx.machine-learning-plugin_inbound_anomaly_score=0',\ setvar:'tx.machine-learning-plugin_inbound_ml_threshold=0', \ setvar:'tx.machine-learning-plugin_ml_server_url=http://127.0.0.1:5000/'" diff --git a/plugin/machine-learning-file.lua b/plugin/machine-learning-file.lua new file mode 100644 index 0000000..7842386 --- /dev/null +++ b/plugin/machine-learning-file.lua @@ -0,0 +1,150 @@ +--import urllib.request +--import urllib.parse +-- This is like a driver code to point to different ML servers and models +-- and seek ml_inbound_status using such models +-- this ml driver is invoked by machine-learning-plugin-after.conf if +-- the anomaly score exceeds the threshold + +-- currently most of this code is from https://github.com/coreruleset/coreruleset/pull/2067/files + +-- set your machine learning server URL +local ml_server_url = 'http://127.0.0.1:5000/' +-- local variable for inbound_ml_status update. By default it must be zero +local inbound_ml_result = 0 +local ltn12 = require("ltn12") +local http = require("socket.http") +local respbody = {} +file_name, error = io.open("/home/deepshikha/Desktop/testfile.txt", 'r') +print(" "..error) +function main() + local method = m.getvar("REQUEST_METHOD") + local path = m.getvar("REQUEST_FILENAME") + local hour = m.getvar("TIME_HOUR") + local day = m.getvar("TIME_DAY") + local args = m.getvars("ARGS") + local args_str = "{}" + local reqbody = m.getvar("REQUEST_CONTENT_TYPE") + local reqbodyl = m.getvar("REQUEST_BODY_LENGTH") + local req_data = {} + req_data["req_protocol"] = m.getvar("REQUEST_PROTOCOL") + req_data["req_uri"] = m.getvar("REQUEST_URI") + req_data["req_method"] = m.getvar("REQUEST_METHOD") + req_data["req_unique_id"] = m.getvar("UNIQUE_ID") + req_data["file_name"] = m.getvar("REQUEST_FILENAME") + req_data["base_name"] = m.getvar("REQUEST_BASENAME") + req_data["headers_name"] = m.getvar("REQUEST_HEADERS_NAMES") + local rea_header = {} + -- req_header["req_header_content_type"] = m.getvar("CONTENT_TYPE") + -- req_header["req_header_content_type"] = m.getvar("REQUEST_HEADERS:Content-Type") + -- req_header["req_header_content_length"] = m.getvar("REQUEST_HEADERS:Content-Length") + + -- m.log(1, "RequestHeaderContentType: " ..req_header["req_header_content_type"]) + -- m.log(1, "RequestHeaderContentLength: " ..req_header["req_header_content_length"]) + + -- local content_length = m.getvar("CONTENT_LENGTH") + -- local req_length = tonumber(m.getvar("CONTENT_LENGTH")) + + -- Start: this will not be in phase 1. Move this to -after.conf script or create new rule for phase2 + -- local req_body = {} + -- req_body["req_body"] = m.getvar("REQUEST_BODY") + -- req_body["req_body_length"] = m.getvar("REQUEST_BODY_LENGTH") + -- m.log(1, "RequestBody: " ..req_body["req_body"]) + -- m.log(1, "RequestBodyLength: " ..req_body["req_body_length"]) + -- local req_body = m.getvar("REQUEST_BODY","urlDecodeUni") + -- End: this will not be in phase 1. Move this to after script + m.log(1, "Inside before lua script") + m.log(1, "RequestProtocol: " ..req_data["req_protocol"]) + m.log(1, "RequestURI: " ..req_data["req_uri"]) + m.log(1, "RequestMethod: " ..req_data["req_method"]) + m.log(1, "RequestUniqueID: " ..req_data["req_unique_id"]) + m.log(1, "RequestFilename: " ..req_data["file_name"]) + m.log(1, "RequestBasename: " ..req_data["base_name"]) + m.log(1, "RequestHeadersName: " ..req_data["headers_name"]) + m.log(1, "body " ..reqbody) + m.log(1, "length "..reqbodyl) + local data = {} + data["unique_id"] = m.getvar("UNIQUE_ID") + data["protocol"] = m.getvar("REQUEST_PROTOCOL") + data["uri"] = m.getvar("REQUEST_URI") + + if m.getvar("REQUEST_BODY") then + data["body"] = m.getvar("REQUEST_BODY") + else + data["body"] = "" + end + + m.log(1, "id "..data["unique_id"]) + m.log(1, "protocol "..data["protocol"]) + m.log(1, "uri "..data["uri"]) + + -- transform the args array into a string following JSON format + --function json() + if args ~= nil then + args_str = "{" + for k,v in pairs(args) do + name = v["name"] + value = v["value"] + value = value:gsub('"', "$#$") + args_str = args_str..'"'..name..'":"'..value..'",' + end + if #args == 0 then + args_str = "{}" + else + args_str = string.sub(args_str, 1, -2) + args_str = args_str.."}" + end + end + --end + -- construct http request for the ml server + local body = "method="..method.."&path="..path.."&args="..args_str.."&hour="..hour.."&day="..day + local headers = { + ["Content-Type"] = "multipart/form-data"; + ["Content-Length"] = #body + } + --lines = {} + --lines = file:lines() + --print("Contents of file:"); + --for line in lines do + --print("\t" ..line) + --end + a = {} + if file_name then + io.input(file_name) + --a = io.read("*all") + a = file_name:lines() + m.log(1, "File contents"..a) + source = ltn12.source.file(file_name) + else + m.log(1, "File could not be opened "..error) + end + --local source = ltn12.source.file(io.open('/home/deepshikha/Desktop/testfile.txt')) + if not source then + m.log(1, "source error") + else + m.log(1, "Sending http request from lua") + local client, code, headers, status = http.request{ + url=ml_server_url, + method='POST', + source=source, + headers=headers, + sink = ltn12.sink.table(respbody) + } + respbody = table.concat(respbody) + end + if client == nil then + m.log(1, 'The server is unreachable \n') + end + + if code == 401 then + inbound_ml_result = 0 + m.log(1,'Anomaly found by ML') + end + + if code == 200 then + inbound_ml_result = 1 + end + m.setvar("TX.inbound_ml_anomaly_score", respbody) + m.setvar("TX.inbound_ml_status", inbound_ml_result) + return inbound_ml_result + +end From 3b2f6db75a7bcc727af6f98656e3a0a10f68b15e Mon Sep 17 00:00:00 2001 From: deepshikha-s Date: Tue, 20 Sep 2022 15:01:47 +0530 Subject: [PATCH 2/2] Resolving errors --- plugin/machine-learning-after.conf.disabled | 32 ----- plugin/machine-learning-client.lua.save | 113 --------------- plugin/machine-learning-file.lua | 150 -------------------- 3 files changed, 295 deletions(-) delete mode 100644 plugin/machine-learning-after.conf.disabled delete mode 100644 plugin/machine-learning-client.lua.save delete mode 100644 plugin/machine-learning-file.lua diff --git a/plugin/machine-learning-after.conf.disabled b/plugin/machine-learning-after.conf.disabled deleted file mode 100644 index 1f94d04..0000000 --- a/plugin/machine-learning-after.conf.disabled +++ /dev/null @@ -1,32 +0,0 @@ -# ------------------------------------------------------------------------ -# OWASP ModSecurity Core Rule Set Plugin -# Copyright (c) 2021-2022 Core Rule Set project. All rights reserved. -# -# The OWASP ModSecurity Core Rule Set plugins are distributed under -# Apache Software License (ASL) version 2 -# Please see the enclosed LICENSE file for full details. -# ------------------------------------------------------------------------ - -# OWASP CRS Plugin -# Plugin name: machine-learning -# Plugin description: -# Rule ID block base: 9,516,000 - 9,516,999 -# Plugin version: 1.0.0 - -# Documentation can be found here: -# https://github.com/coreruleset/machine-learning-plugin - -SecRule TX:ANOMALY_SCORE "@ge %{tx.inbound_anomaly_score_threshold}" \ - "id:9516110,\ - phase:2,\ - deny,\ - t:none,\ - msg:'Inbound Anomaly Score Exceeded (Total Score: %{TX.ANOMALY_SCORE})',\ - tag:'anomaly-evaluation',\ - ver:'machine-learning-plugin/1.0.0',\ - severity:'CRITICAL',\ - chain" - SecRule TX:0 "@inspectFile machine-learning-client.lua" \ - "t:none,\ - msg:'machine learning Anomaly Score: %{tx.anomaly_score}',\ - setvar:'tx.inbound_anomaly_score=%{tx.anomaly_score}'" diff --git a/plugin/machine-learning-client.lua.save b/plugin/machine-learning-client.lua.save deleted file mode 100644 index 75f502c..0000000 --- a/plugin/machine-learning-client.lua.save +++ /dev/null @@ -1,113 +0,0 @@ --- This is a driver code to point to different ML servers and models --- and seek ml_inbound_status using such models --- this ml driver is invoked by machine-learning-plugin-after.conf --- currently most of this code is from https://github.com/coreruleset/coreruleset/pull/2067/files - -function main() - -- Variable Declarations: - -- setting the machine learning server URL - pcall(require, "m") - local ml_server_url = m.getvar("TX.machine-learning-plugin_ml_server_url") - -- initialising the variable to return the machine learning pass or block status - local inbound_ml_result = 0 - -- Importing libraries - local ltn12 = require("ltn12") - local http = require("socket.http") - -- Initialising variables - local method = m.getvar("REQUEST_METHOD") - local path = m.getvar("REQUEST_FILENAME") - local hour = m.getvar("TIME_HOUR") - local day = m.getvar("TIME_DAY") - local args = m.getvars("ARGS") - local files = m.getvars("FILES") - local filesizes = m.getvars("FILES_SIZES") - local args_str = "{}" - local filesstr = "{}" - local filesizestr = "{}" - local body = " " - local respbody = {} - -- Parsing the tables and logging - if args ~= nil then - args_str = "{" - for k,v in pairs(args) do - name = v["name"] - value = v["value"] - value = value:gsub('"', "$#$") - args_str = args_str..'"'..name..'":"'..value..'",' - end - if #args == 0 then - args_str = "{}" - else - args_str = string.sub(args_str, 1, -2) - args_str = args_str.."}" - end - end - - if files ~= nil then - filesstr = "{" - for k,v in pairs(files) do - name = v["name"] - value = v["value"] - value = value:gsub('"', "$#$") - filesstr = filesstr..'"'..name..'":"'..value..'",' - end - if #files == 0 then - filesstr = "{}" - else - filesstr = string.sub(filesstr, 1, -2) - filesstr = filesstr.."}" - end - end - - if filesizes ~= nil then - filesizestr = "{" - for k,v in pairs(filesizes) do - name = v["name"] - value = v["value"] - value = value:gsub('"', "$#$") - filesizestr = filesizestr..'"'..name..'":"'..value..'",' - end - if #filesizes == 0 then - filesizestr = "{}" - else - filesizestr = string.sub(filesizestr, 1, -2) - filesizestr = filesizestr.."}" - end - end - - -- Construct http request for the ml server - --body = "method="..method.."&path="..path.."&args="..args_str.."&files="..filesstr.."&sizes="..filesizestr.."&hour="..hour.."&day="..day - body = string.format("method=%s&path=%s&args=%s&files=%s&sizes=%s&hour=%s&day=%s", method, path, args_str, filesstr, filesizestr, hour, day) - headers = { - ["Content-Type"] = "application/x-www-form-urlencoded"; - ["Content-Length"] = #body - } - local source = ltn12.source.string(body) - local client, code, headers, score = http.request{ - url=ml_server_url, - method='POST', - source=source, - headers=headers, - sink = ltn12.sink.table(respbody) - } - m.log(1, "Respbody "..respbody) - respbody = table.concat(respbody) - m.log(1, "Client "..client.." Code "..code.."..".." Score "..score) --- Processing the result - if client == nil then - m.log(2, 'The server is unreachable ') - end - if code == 401 then - m.log(1,'Anomaly found by ML') - m.setvar("TX.machine-learning-plugin_inbound_anomaly_score", score) - end - if code == 200 then - inbound_ml_result = 1 - m.setvar("TX.machine-learning-plugin_inbound_anomaly_score", score) - m.setvar("TX.machine-learning-plugin_inbound_ml_status", inbound_ml_result) - end - --m.setvar("TX.machine-learning-plugin_inbound_anomaly_score", score) - --m.setvar("TX.machine-learning-plugin_inbound_ml_status", inbound_ml_result) - --m.log(1, "Status "..TX.machine-learning-plugin_inbound_ml_status) - return inbound_ml_result -end diff --git a/plugin/machine-learning-file.lua b/plugin/machine-learning-file.lua deleted file mode 100644 index 7842386..0000000 --- a/plugin/machine-learning-file.lua +++ /dev/null @@ -1,150 +0,0 @@ ---import urllib.request ---import urllib.parse --- This is like a driver code to point to different ML servers and models --- and seek ml_inbound_status using such models --- this ml driver is invoked by machine-learning-plugin-after.conf if --- the anomaly score exceeds the threshold - --- currently most of this code is from https://github.com/coreruleset/coreruleset/pull/2067/files - --- set your machine learning server URL -local ml_server_url = 'http://127.0.0.1:5000/' --- local variable for inbound_ml_status update. By default it must be zero -local inbound_ml_result = 0 -local ltn12 = require("ltn12") -local http = require("socket.http") -local respbody = {} -file_name, error = io.open("/home/deepshikha/Desktop/testfile.txt", 'r') -print(" "..error) -function main() - local method = m.getvar("REQUEST_METHOD") - local path = m.getvar("REQUEST_FILENAME") - local hour = m.getvar("TIME_HOUR") - local day = m.getvar("TIME_DAY") - local args = m.getvars("ARGS") - local args_str = "{}" - local reqbody = m.getvar("REQUEST_CONTENT_TYPE") - local reqbodyl = m.getvar("REQUEST_BODY_LENGTH") - local req_data = {} - req_data["req_protocol"] = m.getvar("REQUEST_PROTOCOL") - req_data["req_uri"] = m.getvar("REQUEST_URI") - req_data["req_method"] = m.getvar("REQUEST_METHOD") - req_data["req_unique_id"] = m.getvar("UNIQUE_ID") - req_data["file_name"] = m.getvar("REQUEST_FILENAME") - req_data["base_name"] = m.getvar("REQUEST_BASENAME") - req_data["headers_name"] = m.getvar("REQUEST_HEADERS_NAMES") - local rea_header = {} - -- req_header["req_header_content_type"] = m.getvar("CONTENT_TYPE") - -- req_header["req_header_content_type"] = m.getvar("REQUEST_HEADERS:Content-Type") - -- req_header["req_header_content_length"] = m.getvar("REQUEST_HEADERS:Content-Length") - - -- m.log(1, "RequestHeaderContentType: " ..req_header["req_header_content_type"]) - -- m.log(1, "RequestHeaderContentLength: " ..req_header["req_header_content_length"]) - - -- local content_length = m.getvar("CONTENT_LENGTH") - -- local req_length = tonumber(m.getvar("CONTENT_LENGTH")) - - -- Start: this will not be in phase 1. Move this to -after.conf script or create new rule for phase2 - -- local req_body = {} - -- req_body["req_body"] = m.getvar("REQUEST_BODY") - -- req_body["req_body_length"] = m.getvar("REQUEST_BODY_LENGTH") - -- m.log(1, "RequestBody: " ..req_body["req_body"]) - -- m.log(1, "RequestBodyLength: " ..req_body["req_body_length"]) - -- local req_body = m.getvar("REQUEST_BODY","urlDecodeUni") - -- End: this will not be in phase 1. Move this to after script - m.log(1, "Inside before lua script") - m.log(1, "RequestProtocol: " ..req_data["req_protocol"]) - m.log(1, "RequestURI: " ..req_data["req_uri"]) - m.log(1, "RequestMethod: " ..req_data["req_method"]) - m.log(1, "RequestUniqueID: " ..req_data["req_unique_id"]) - m.log(1, "RequestFilename: " ..req_data["file_name"]) - m.log(1, "RequestBasename: " ..req_data["base_name"]) - m.log(1, "RequestHeadersName: " ..req_data["headers_name"]) - m.log(1, "body " ..reqbody) - m.log(1, "length "..reqbodyl) - local data = {} - data["unique_id"] = m.getvar("UNIQUE_ID") - data["protocol"] = m.getvar("REQUEST_PROTOCOL") - data["uri"] = m.getvar("REQUEST_URI") - - if m.getvar("REQUEST_BODY") then - data["body"] = m.getvar("REQUEST_BODY") - else - data["body"] = "" - end - - m.log(1, "id "..data["unique_id"]) - m.log(1, "protocol "..data["protocol"]) - m.log(1, "uri "..data["uri"]) - - -- transform the args array into a string following JSON format - --function json() - if args ~= nil then - args_str = "{" - for k,v in pairs(args) do - name = v["name"] - value = v["value"] - value = value:gsub('"', "$#$") - args_str = args_str..'"'..name..'":"'..value..'",' - end - if #args == 0 then - args_str = "{}" - else - args_str = string.sub(args_str, 1, -2) - args_str = args_str.."}" - end - end - --end - -- construct http request for the ml server - local body = "method="..method.."&path="..path.."&args="..args_str.."&hour="..hour.."&day="..day - local headers = { - ["Content-Type"] = "multipart/form-data"; - ["Content-Length"] = #body - } - --lines = {} - --lines = file:lines() - --print("Contents of file:"); - --for line in lines do - --print("\t" ..line) - --end - a = {} - if file_name then - io.input(file_name) - --a = io.read("*all") - a = file_name:lines() - m.log(1, "File contents"..a) - source = ltn12.source.file(file_name) - else - m.log(1, "File could not be opened "..error) - end - --local source = ltn12.source.file(io.open('/home/deepshikha/Desktop/testfile.txt')) - if not source then - m.log(1, "source error") - else - m.log(1, "Sending http request from lua") - local client, code, headers, status = http.request{ - url=ml_server_url, - method='POST', - source=source, - headers=headers, - sink = ltn12.sink.table(respbody) - } - respbody = table.concat(respbody) - end - if client == nil then - m.log(1, 'The server is unreachable \n') - end - - if code == 401 then - inbound_ml_result = 0 - m.log(1,'Anomaly found by ML') - end - - if code == 200 then - inbound_ml_result = 1 - end - m.setvar("TX.inbound_ml_anomaly_score", respbody) - m.setvar("TX.inbound_ml_status", inbound_ml_result) - return inbound_ml_result - -end