Bro monitoring HTTP traffic
@ (tutorial) [Bro]
Bro can log all HTTP traffic from the network to the Http.log file, which can be used for analysis or auditing
First we introduce the structure of the Http.log file.
Then we describe how to analyze and monitor HTTP traffic through bro
structure of the HTTP log
Http.log summarizes all bro monitored HTTP requests and responses, which are the first columns of Http.log
TS |
UID |
Orig_h |
orig_p |
Resp_h |
resp_p |
13116234.8 |
Hsh4uv8kvjq |
192.168.1.100 |
52303 |
192.150.187.43 |
80 |
Each single line is started with a timestamp, UID, connection Information 4 tuples (source address and port, destination address and Port)
The rest of the information describes in detail the activities that occurred
Method |
Host |
URI |
referrer |
user_agent |
GET |
bro.org |
- |
|
<...>Chrome/12.0.742.122<...> |
Network administrators and security engineers can use this log file to observe network activity and analyze anomalies
To learn more about how Bro analyzes HTTP traffic, you can refer to Scripts/base/protocols/http/main.bro
Reconnaissance Proxy Server
Proxy servers often provide access to the server for devices that do not have access, and some unauthenticated proxy servers should be considered a threat.
what the proxy server's traffic should be
Typically, the communication between the client and the proxy server should look like this:
Request:get http://bro.org/HTTP/1.1
reply:http/1.0 OK
The difference between this and the client server direct communication is that the request for direct communication should not have an "http" string, so this can be used to determine that this is a proxy server
We can write a script to handle the http_reply detection GET/HTTP request
Event Http_reply (C:connection,version:string,code:count, reson:string)
{
if (/^[hh][tt][pp]:/in C$heep$uri && C$http$status_code = =)
print fmt ("A local server is acting as an open proxy:%s", c$id$resp_h);
}
We detect that the request contains a "GET/http" return status of "OK" data to judge
But the HTTP protocol is more than a state of OK, we can extend this script to achieve more rigorous judgment
Module HTTP;
Export {
Global Success_status_codes:set[count] = {$
,
201,
202,
203,
204,
205,
206,
207,
208,
226,
304
};
}
Event Http_reply (c:connection, version:string, Code:count, reason:string)
{
if (/^[hh][tt][tt][pp]:/in C$h Ttp$uri &&
C$http$status_code in http::success_status_codes)
print FMT ("A local server was acting as an Open proxy:%s ", c$id$resp_h);
}
Next, we need to make sure that the agent is part of our local network
@load base/utils/site
redef site::local_nets + = {192.168.0.0/16};
Module HTTP;
Export {
Global Success_status_codes:set[count] = {$
,
201,
202,
203,
204,
205,
206,
207,
208,
226,
304
};
}
Event Http_reply (c:connection, version:string, Code:count, reason:string)
{
if (site::is_local_addr (c$id$ Resp_h) &&
/^[hh][tt][tt][pp]:/in C$http$uri &&
C$http$status_code in Http::success_ Status_codes)
print FMT ("A local server is acting as an open proxy:%s", c$id$resp_h);
}
Finally, our goal is to send an alarm message when the agent service is detected.
@load base/utils/site @load base/frameworks/notice redef site::local_nets + = {192.168.0.0/16
};
Module HTTP;
Export {redef enum Notice::type + = {Open_proxy};
Global Success_status_codes:set[count] = {200, 201, 202, 203, 204, 205,
206, 207, 208, 226, 304}; } Event Http_reply (C:connection, version:string, Code:count, reason:string) {if (Site::is_local_addr (c$id$r Esp_h) &&/^[hh][tt][tt][pp]:/in C$http$uri && C$http$status_code in Http::success_stat Us_codes) NOTICE ([$note =http::open_proxy, $msg =fmt ("A local server is acting as an Open Proxy:%s
", C$id$resp_h), $conn =c, $identifier =cat (C$id$resp_h),
$suppress _for=1day]); }
We've defined a new notification Tag:open_proxy
Once the notification is triggered, it will suppress one day
This notification is only written in the Notice.log file and can be configured via email
Check File
Usually files are transmitted over the HTTP protocol, and in most cases these files are harmless, but some executable programs are hidden from them, and we can copy them through the file analysis framework.
Global Mime_to_ext:table[string] of string = {
["application/x-dosexec"] = "EXE",
["text/plain"] = "txt",
[ "Image/jpeg"] = "jpg",
["image/png"] = "png",
["text/html"] = "html",
};
Event File_sniff (F:fa_file, Meta:fa_metadata)
{
if (f$source! = "HTTP")
return;
if (! Meta $mime _type)
return;
if (Meta$mime_type!in mime_to_ext)
return;
Local fname = FMT ("%s-%s.%s", F$source, F$id, Mime_to_ext[meta$mime_type]);
Print FMT ("Extracting file%s", fname);
Files::add_analyzer (f, files::analyzer_extract, [$extract _filename=fname]);
}
Here the "mime_to_ext" table has 2 functions, defines the file types to be parsed, and the MIME type
parsed files are saved under the Extract_files folder