Feature #7847
openrules: extend byte_extract named variables for use in other keywords/transformations such as xor
Description
We have seen several cases in which a packet is XOR'd with a single byte and this byte can be found at X offset. Currently, the only solution for detection (aside from Lua) is to write a signature for that XOR key which is incredibly static.
We are asking for byte_extract & xor support so that we can specify the location of the XOR key, extract it and store it in a named variable, and then use that extracted byte with the XOR transformation.
ex.
http.request_body; byte_extract:1,0,xor_key; xor:xor_key; content:"infected";
I suspect this becomes more difficult because we would now need to tell the XOR transformation that we are only interested in part of the buffer instead of the whole buffer. Maybe we'd also need the ability to tell the XOR transformation where to begin processing data with an offset value?
http.request_body; byte_extract:1,0,xor_key; xor:offset 1,xor_key; content:"infected";
Files
Updated by Victor Julien about 1 month ago
- Subject changed from extend byte_extract named variables for use in other keywords/transformations such as xor to rules: extend byte_extract named variables for use in other keywords/transformations such as xor
Can you share a case like this, ideally with the a lua script to do the same if you have that?
Updated by Victor Julien about 1 month ago
- Related to Feature #6831: rules: support extraction of bytes of non-numeric values added
Updated by Victor Julien about 1 month ago
- Related to Feature #7321: rules: cross buffer byte_* keyword support added
Updated by James Emery-Callcott 11 days ago
- File xor_packet_test.pcap xor_packet_test.pcap added
I sure can. Here is a Lua script that extracts the 5th byte from the payload, which is always a random XOR key and then uses it to decrypt the bytes following.
Generic rule used in this test case:
alert tcp any any -> any any (msg:"ET OISF XOR Lua demonstration"; flow:established,to_server; lua:xor1.lua; classtype:misc-activity; rev:1; sid:1;)
Demo PCAP attached.
function manual_xor(a, b)
local result = 0
local bit = 1
while a > 0 or b > 0 do
local bit_a = a % 2
local bit_b = b % 2
if bit_a ~= bit_b then
result = result + bit
end
a = math.floor(a / 2)
b = math.floor(b / 2)
bit = bit * 2
end
return result
end
function init(args)
local needs = {}
needs["payload"] = tostring(true)
return needs
end
function match(args)
local payload = args["payload"]
if not payload then
return 0
end
if #payload < 6 then
return 0
end
local byte1 = payload:byte(1)
local byte2 = payload:byte(2)
local byte3 = payload:byte(3)
local byte4 = payload:byte(4)
if byte1 ~= 0x00 or byte2 ~= 0x00 or byte3 ~= 0x04 or byte4 ~= 0x01 then
return 0
end
local xor_key = payload:byte(5)
local encrypted_data = payload:sub(6)
local decrypted = ""
for i = 1, #encrypted_data do
local encrypted_byte = encrypted_data:byte(i)
local decrypted_byte = manual_xor(encrypted_byte, xor_key)
decrypted = decrypted .. string.char(decrypted_byte)
end
local traffic_found = string.find(decrypted:lower(), "traffic")
if traffic_found then
SCLogInfo("XOR Traffic Detected - 'traffic' keyword found!")
SCLogInfo("XOR Key: 0x" .. string.format("%02x", xor_key))
SCLogInfo("Decrypted Message: " .. decrypted)
SCLogInfo("Payload Length: " .. #encrypted_data .. " bytes")
SCLogInfo("Validation Method: Keyword 'traffic' found at position " .. traffic_found)
return 1
end
return 0
end
Victor Julien wrote in #note-2:
Can you share a case like this, ideally with the a lua script to do the same if you have that?
Updated by Victor Julien 8 days ago
Thanks @jcallcott, I created 2 SV tests for this example to make it easier to analyze it: https://github.com/OISF/suricata-verify/pull/2862
Updated by Victor Julien 7 days ago
- Status changed from New to Assigned
- Assignee changed from OISF Dev to Jeff Lucovsky
- Target version changed from TBD to 9.0.0-beta1