2021-04-28 01:22 AM
Hello.
Could anybody help my with cef parser customization?
I have an issue of getting necessary value-to-meta from this cef-log:
Apr 19 15:09:54 hostname Appname: CEF:0|SWIFT|Alliance Access|1.1.11|BSA-3113|Operator Modified with Password|Medium|cn1=123456789 cn1Label=Event Sequence ID cs1=aaabbb cs1Label=Instance UUID cs2=1111-2222 cs2Label=Correlation ID cat=Data msg=Operator Alexander : Modified with password.\n Modification details :\n\nAuthentication method \= Local (added)\nAuthentication method \= Password and TOTP (removed)\n suid=Oper dvchost=hostname dvc=192.168.1.1 dvcmac=11:22:33:aa:bb:cc deviceProcessName=Appname src=192.168.1.2 dtz=Europe/Paris rt=123456789 outcome=Success
So, I need to get data Operator Alexander to be parsed into, for example, ec_subject.
So I've written next cef-custom.xml:
2021-04-30 04:22 PM - edited 2021-05-06 12:55 PM
6MAY: EDITED lua parser to remove the bad arguments in the nw.getPayload function
I've fielded this type of ask from a number of different customers recently, and the only solution we can offer at this time (especially for CEF logs) is to extract this type of information via custom lua parser.
And just for some details on why this is the only solution...
The first consideration in writing the lua parser for these situations is how to trigger (or callback) the lua. We don't want this lua parser to trigger on unrelated logs, as that will have a negative performance impact on the log decoder. So the best way I have found to ensure custom lua parsers fire only against the logs that I want, is to:
There's lots of resources online that you can use to write and understand lua...some of which are... (https://community.rsa.com/t5/rsa-netwitness-platform-threat/a-treatise-on-writing-packet-parsers-for-the-rsa-netwitness/ta-p/568861; https://www.lua.org/manual/5.1/; https://replit.com/languages/lua).
Here's what that lua parser could look like:
local parserName = "swift_alliance_access_cef_lua"
local parserVersion = "2021.04.30"
--[[
This parser requires a custom meta key.
Log Decoder:
cef-custom.xml
<VendorProducts>
<Vendor2Device vendor="Aruba Networks" product="ClearPass" device="swift_alliance_access" group="Analysis"/>
</VendorProducts>
<ExtensionKey cefName="msg" metaName="msg">
<device2meta device="swift_alliance_access" metaName="custom_msg_temp"/>
</ExtensionKey>
table-map-custom.xml
<mapping envisionName="custom_msg_temp" nwName="custom_msg_temp" flags="Transient" format="Text"/>
--]]
local cefCustomLua = nw.createParser(parserName, "swift_alliance_access_cef_lua -- parse out substrings from swift_alliance_access CEF logs.")
-- register the meta keys to add new values to
cefCustomLua:setKeys({
nwlanguagekey.create("ec.subject"),
})
function cefCustomLua:extractInfo(token,first,last)
--set the pattern we want to match against with a capture group to return the substring value we are looking for
local patternMatch = "msg=(.-) : Modified with password"
local logPayload = nw.getPayload()
-- start a "try/catch" block (error trapping)
local status, err = pcall(function()
if logPayload then
local rawLog = logPayload:tostring()
--ensure we have the raw log and that it is a string
if rawLog ~= nil and type(rawLog) == "string" then
local valueMatch = string.match(rawLog, patternMatch)
--ensure we matched the substring, and if we did create our meta
if valueMatch ~= nil then
nw.createMeta(self.keys["ec.subject"], valueMatch)
end
end
end
end, logPayload) -- end "try/catch" block
debugParser = false -- set debug mode for this parser
if not status and debugParser then
-- if we have an error in the parsing, write it to /var/log/messages with a string we can grep against
nw.logFailure("swift_alliance_access_cef_lua error: " .. tostring(err))
end
end
-- look for the existence of meta keys OR look for specific text in the raw session/log
cefCustomLua:setCallbacks({
[nwlanguagekey.create("custom_msg_temp")] = cefCustomLua.extractInfo,
})
And a quick look at the result of the pattern match:
2021-04-30 04:22 PM - edited 2021-05-06 12:55 PM
6MAY: EDITED lua parser to remove the bad arguments in the nw.getPayload function
I've fielded this type of ask from a number of different customers recently, and the only solution we can offer at this time (especially for CEF logs) is to extract this type of information via custom lua parser.
And just for some details on why this is the only solution...
The first consideration in writing the lua parser for these situations is how to trigger (or callback) the lua. We don't want this lua parser to trigger on unrelated logs, as that will have a negative performance impact on the log decoder. So the best way I have found to ensure custom lua parsers fire only against the logs that I want, is to:
There's lots of resources online that you can use to write and understand lua...some of which are... (https://community.rsa.com/t5/rsa-netwitness-platform-threat/a-treatise-on-writing-packet-parsers-for-the-rsa-netwitness/ta-p/568861; https://www.lua.org/manual/5.1/; https://replit.com/languages/lua).
Here's what that lua parser could look like:
local parserName = "swift_alliance_access_cef_lua"
local parserVersion = "2021.04.30"
--[[
This parser requires a custom meta key.
Log Decoder:
cef-custom.xml
<VendorProducts>
<Vendor2Device vendor="Aruba Networks" product="ClearPass" device="swift_alliance_access" group="Analysis"/>
</VendorProducts>
<ExtensionKey cefName="msg" metaName="msg">
<device2meta device="swift_alliance_access" metaName="custom_msg_temp"/>
</ExtensionKey>
table-map-custom.xml
<mapping envisionName="custom_msg_temp" nwName="custom_msg_temp" flags="Transient" format="Text"/>
--]]
local cefCustomLua = nw.createParser(parserName, "swift_alliance_access_cef_lua -- parse out substrings from swift_alliance_access CEF logs.")
-- register the meta keys to add new values to
cefCustomLua:setKeys({
nwlanguagekey.create("ec.subject"),
})
function cefCustomLua:extractInfo(token,first,last)
--set the pattern we want to match against with a capture group to return the substring value we are looking for
local patternMatch = "msg=(.-) : Modified with password"
local logPayload = nw.getPayload()
-- start a "try/catch" block (error trapping)
local status, err = pcall(function()
if logPayload then
local rawLog = logPayload:tostring()
--ensure we have the raw log and that it is a string
if rawLog ~= nil and type(rawLog) == "string" then
local valueMatch = string.match(rawLog, patternMatch)
--ensure we matched the substring, and if we did create our meta
if valueMatch ~= nil then
nw.createMeta(self.keys["ec.subject"], valueMatch)
end
end
end
end, logPayload) -- end "try/catch" block
debugParser = false -- set debug mode for this parser
if not status and debugParser then
-- if we have an error in the parsing, write it to /var/log/messages with a string we can grep against
nw.logFailure("swift_alliance_access_cef_lua error: " .. tostring(err))
end
end
-- look for the existence of meta keys OR look for specific text in the raw session/log
cefCustomLua:setCallbacks({
[nwlanguagekey.create("custom_msg_temp")] = cefCustomLua.extractInfo,
})
And a quick look at the result of the pattern match:
2021-05-04 12:42 AM
Hello.
Thank you for such detailed answer, I'll try to follow your recomendation.
2021-05-04 07:08 AM - edited 2021-05-04 07:30 AM
1) get this error after I've added .lua, table-map-custom, cef-custom and after reload nwlogdecoder service.
May 4 11:03:23 rsanw-decoder-1 NwLogDecoder[6492]: [Parse] [warning] Parser Log Parser registered for meta custom_meta_swift which returned an error: The language key 'custom_meta_swift' exceeds the maximum size of 16
2) Still get no ec.subject in Investigate for swift_alliance_access device.
My cef-custom.xml =
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<DEVICEMESSAGES>
<VERSION
xml="56"
checksum="3b5201ea5d3517e275d5d356eac552a2"
revision="149"
device="2.0" />
<ExtensionKey cefName="msg" metaName="msg">
<device2meta device="swift_alliance_access" metaName="custom_meta_swift"/>
</ExtensionKey>
<VendorProducts>
<Vendor2Device vendor="SWIFT" product="Alliance Access" device="swift_alliance_access" group="Analysis"/>
</VendorProducts>
</DEVICEMESSAGES>
local parserName = "swift_alliance_access_cef_lua"
local parserVersion = "2021.04.30"
--[[
This parser requires a custom meta key.
Log Decoder:
cef-custom.xml
<VendorProducts>
<Vendor2Device vendor="Aruba Networks" product="ClearPass" device="swift_alliance_access" group="Analysis"/>
</VendorProducts>
<ExtensionKey cefName="msg" metaName="msg">
<device2meta device="swift_alliance_access" metaName="custom_msg_temp"/>
</ExtensionKey>
table-map-custom.xml
<mapping envisionName="custom_msg_temp" nwName="custom_msg_temp" flags="Transient" format="Text"/>
--]]
local cefCustomLua = nw.createParser(parserName, "swift_alliance_access_cef_lua")
-- register the meta keys to add new values to
cefCustomLua:setKeys({
nwlanguagekey.create("ec.subject"),
})
function cefCustomLua:extractInfo(token,first,last)
--set the pattern we want to match against with a capture group to return the substring value we are looking for
local patternMatch = "msg=(.-) :"
local logPayload = nw.getPayload(first, last)
-- start a "try/catch" block (error trapping)
local status, err = pcall(function()
if logPayload then
local rawLog = logPayload:tostring()
--ensure we have the raw log and that it is a string
if rawLog ~= nil and type(rawLog) == "string" then
local valueMatch = string.match(rawLog, patternMatch)
--ensure we matched the substring, and if we did create our meta
if valueMatch ~= nil then
nw.createMeta(self.keys["ec.subject"], valueMatch)
end
end
end
end, logPayload) -- end "try/catch" block
debugParser = false -- set debug mode for this parser
if not status and debugParser then
-- if we have an error in the parsing, write it to /var/log/messages with a string we can grep against
nw.logFailure("swift_alliance_access_cef_lua error: " .. tostring(err))
end
end
-- look for the existence of meta keys OR look for specific text in the raw session/log
cefCustomLua:setCallbacks({
[nwlanguagekey.create("custom_msg_temp")] = cefCustomLua.extractInfo,
})
table-map-custom:
<mapping envisionName="custom_meta_swift" nwName="custom_meta_swift" flags="Transient" format="Text"/>
2021-05-04 11:59 AM - edited 2021-05-04 12:02 PM
@MaximMarchenko I see two immediate issues here.
First, the error message "The language key 'custom_meta_swift' exceeds the maximum size of 16" is telling you that custom_meta_swift is too long for a metakey name. NW has a hard limit for metakey name lengths of 16 bytes/characters, and custom_meta_swift is 1 character too long. That will need to be changed to a shorter metakey name.
Second, that shorter metakey name will need to be the same within your table-map-custom and the lua parser's setCallbacks function (the red boxes in this screen shot):
2021-05-04 11:35 PM - edited 2021-05-05 04:49 AM
Yes, stupid copy-paste mistake, sorry.
Now I get such errors, regarding Lua itself:
May 5 03:27:47 NwLogDecoder[26404]: [Lua] [failure] LUA_ERRRUN: [string "swift_alliance_access_cef_lua.lua"]:33: bad argument #2 to 'getPayload' (number expected, got string)
May 5 03:27:47 NwLogDecoder[26404]: [Lua] [failure] Throw in function void nw::LuaState::ecall(int, int)Dynamic exception type: boost::exception_detail::clone_impl<nw::LuaError>std::exception::what: LUA_ERRRUN: [string "swift_alliance_access_cef_lua.lua"]:33: bad argument #2 to 'getPayload' (number expected, got string)[boost::errinfo_at_line_*] = 200
May 5 03:28:20 NwLogDecoder[26404]: [Lua] [failure] LUA_ERRRUN: [string "swift_alliance_access_cef_lua.lua"]:33: bad argument #2 to 'getPayload' (number expected, got string)
May 5 03:28:20 NwLogDecoder[26404]: [Lua] [failure] Throw in function void nw::LuaState::ecall(int, int)Dynamic exception type: boost::exception_detail::clone_impl<nw::LuaError>std::exception::what: LUA_ERRRUN: [string "swift_alliance_access_cef_lua.lua"]:33: bad argument #2 to 'getPayload' (number expected, got string)[boost::errinfo_at_line_*] = 200
Previously I've done following:
I've changed my cef-custom.xml to this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<DEVICEMESSAGES>
<VERSION
xml="56"
checksum="3b5201ea5d3517e275d5d356eac552a2"
revision="149"
device="2.0" />
<ExtensionKey cefName="msg" metaName="msg">
<device2meta device="swift_alliance_access" metaName="custom_meta_swt"/>
</ExtensionKey>
<VendorProducts>
<Vendor2Device vendor="SWIFT" product="Alliance Access" device="swift_alliance_access" group="Analysis"/>
</VendorProducts>
</DEVICEMESSAGES>
I've changed lua:
# cat swift_alliance_access_cef_lua.lua
local parserName = "swift_alliance_access_cef_lua"
local parserVersion = "2021.04.30"
local cefCustomLua = nw.createParser(parserName, "swift_alliance_access_cef_lua")
-- register the meta keys to add new values to
cefCustomLua:setKeys({
nwlanguagekey.create("ec.subject"),
})
function cefCustomLua:extractInfo(token,first,last)
--set the pattern we want to match against with a capture group to return the substring value we are looking for
local patternMatch = "msg=(.-) :"
local logPayload = nw.getPayload(first, last)
-- start a "try/catch" block (error trapping)
local status, err = pcall(function()
if logPayload then
local rawLog = logPayload:tostring()
--ensure we have the raw log and that it is a string
if rawLog ~= nil and type(rawLog) == "string" then
local valueMatch = string.match(rawLog, patternMatch)
--ensure we matched the substring, and if we did create our meta
if valueMatch ~= nil then
nw.createMeta(self.keys["ec.subject"], valueMatch)
end
end
end
end, logPayload) -- end "try/catch" block
debugParser = false -- set debug mode for this parser
if not status and debugParser then
-- if we have an error in the parsing, write it to /var/log/messages with a string we can grep against
nw.logFailure("swift_alliance_access_cef_lua error: " .. tostring(err))
end
end
-- look for the existence of meta keys OR look for specific text in the raw session/log
cefCustomLua:setCallbacks({
[nwlanguagekey.create("custom_meta_swt")] = cefCustomLua.extractInfo,
})
And my table-map-custom:
<mapping envisionName="custom_meta_swt" nwName="custom_meta_swt" flags="Transient" format="Text"/>
Then I've restarted Decoder service via UI and reload parsers via cli:
NwConsole -c login localhost:56002:ssl admin password -c decoder/parsers reload
2021-05-05 10:50 AM
Ahh, sorry about that, looks like I had my own stupid copy-paste mistake. Its a simple fix, just have to remove the arguments from the nw.getPayload() function on line 33:
local logPayload = nw.getPayload()
...and that's it. I should have run through this fully the first time - would have prevented me from posting that incorrectly.
2021-05-05 10:54 AM
Oh, one more thing - when you upload the lua parser via the UI, it automatically reloads the parsers (which includes picking up your changes to cef-custom.xml and table-map-custom.xml), so there's no need to run an additional reload command or to restart the log decoder service.
2021-05-06 02:14 AM
Now it works, thank you a lot!