Hello!
I am attempting to use BRO to decode back-end SOAP interactions. I have a script to assemble the HTTP bodies, and I am able to log SOAP elements from the HTTP body events. My problem is that the back-end uses persistent connections, and I end up missing transactions whenever I re-start BRO. The decoder is never triggered because the connection already exists.
I’m uninterested in the TCP handshake, I just need to capture the HTTP protocol to a specific back-end server-address and port.
##! This script reassembles full HTTP bodies and raises an event with the
##!
##! complete contents.
module HTTP;
export {
Flag that indicates whether to hook request bodies.
const hook_request_bodies = T &redef;
Flag that indicates whether to hook reply bodies.
const hook_reply_bodies = T &redef;
The pattern applies
const hook_host_pattern = /.*/ &redef;
Do not buffer more than this amount of bytes per HTTP message.
##const max_body_size = 50000000;
const max_body_size = 500000;
}
Users write a handler for this event to process the current HTTP body.
global http_body: event(c: connection, is_orig: bool,
data: string, size: count);
type body_info: record {
data: string;
size: count;
};
global bodies: table[string, bool] of body_info;
function notify_and_remove_body(c: connection, is_orig: bool)
{
local info = bodies[c$uid, is_orig];
event http_body(c, is_orig, info$data, info$size);
delete bodies[c$uid, is_orig];
}
event http_begin_entity(c: connection, is_orig: bool)
{
if ( (is_orig && ! hook_request_bodies) ||
(! is_orig && ! hook_reply_bodies) )
return;
if ( hook_host_pattern !in c$http$host )
return;
local info: body_info;
info$data = “”;
info$size = 0;
bodies[c$uid, is_orig] = info;
FIXME: Type inference should work here, but it doesn’t.
#bodies[c$uid, is_orig] = [“”, 0];
}
event http_entity_data(c: connection, is_orig: bool, length: count,
data: string)
{
if ( [c$uid, is_orig] !in bodies )
return;
local info = bodies[c$uid, is_orig];
info$data += data;
info$size += length;
if ( info$size < max_body_size )
return;
notify_and_remove_body(c, is_orig);
}
event http_end_entity(c: connection, is_orig: bool)
{
if ( [c$uid, is_orig] !in bodies )
return;
notify_and_remove_body(c, is_orig);
}
Cheers!
Marc Giannoni