Wednesday, February 17, 2010

How To Provide Time Scheduled Actions For m0n0wall

How To Provide Time Scheduled Actions For m0n0wall

by cawan - cawan[at]ieee.org

m0n0wall is a version of free embedded firewall which is based on FreeBSD. It has very outstanding performance in providing packet filtering based on the rules with conditions of protocol (TCP, UDP, ICMP…), source / destination IP address, source / destination port range, and etc. However, it is lacking the capability to enable or disable dedicated rule by time scheduler. Thus, it is not so flexible when being adopted in office environment. For example, if we want to block a few of the URLs (e.g. facebook.com, youtube.com…) from 9:00 am to 1:00 pm, and 2:00 pm to 8:00 pm, then it is a little bit trouble to change appropriate rules on the m0n0wall at those specific times manually. Then, the issue of providing an automatic solution arose and this is the reason to have this article.

Let us assume that we have a rule in m0n0wall to decide those URLs getting blocked or not by enable or disable the rule. So, now, we need to know exactly the packets of communication from the browser to the m0n0wall. After that, we can replay the packets to toggle the rule accordingly. I use ethereal to capture the packets for analysis purposes. First of all, to get access to the admin page, we need to login. Then, we get to Firewall->Rules->LAN to enable or disable the rule. Finally, we need to click “Apply Changes” button to enforce the setting on m0n0wall. While doing analysis on the packets being captured, I found that each packet uses “Authorization: Basic” once authenticated to get full access to the m0n0wall. There is a hash value generated which is appending to the end of “Authorization: Basic” to represent the validity of the authentication. For my case, it is “Authorization: Basic YWRtaW46c3VuZGVuYWl0”. On the other hand, there is no dedicated packet to enable or disable the rule. Instead, it is only a single packet to toggle the rule, if the rule is current enabled, then after toggle, it become disabled, and vice versa. For my case, the so called toggle packet is shown as below,

GET /firewall_rules.php?if=lan&act=toggle&id=15 HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/msword, application/vnd.ms-powerpoint, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, */*
Referer: http://192.168.1.254/firewall_rules.php?if=lan
Accept-Language: zh-cn
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
Host: 192.168.1.254
Connection: Keep-Alive
Authorization: Basic YWRtaW46c3VuZGVuYWl0

Again, please note that the last line of “Authorization: Basic YWRtaW46c3VuZGVuYWl0” is appended to fool the m0n0wall to assume it is an authenticated packet. In other words, by sending this packet to m0n0wall, the m0n0wall will toggle the rule immediately. However, the story is yet to finish. We need to emulate the click event to the “Apply Changes” button to enforce the rule. Otherwise, the rule will just seem to be toggled but actually not. The “Apply Change” event is represented by the following packet,

POST /firewall_rules.php HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/msword, application/vnd.ms-powerpoint, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, */*
Referer: http://192.168.1.254/firewall_rules.php?if=lan
Accept-Language: zh-cn
Content-Type: application/x-www-form-urlencoded
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
Host: 192.168.1.254
Content-Length: 26
Connection: Keep-Alive
Cache-Control: no-cache
Authorization: Basic YWRtaW46c3VuZGVuYWl0

apply=Apply+changes&if=lan


Well, the “Apply Change” event use POST instead of GET in toggle action. After the “Apply Change”, m0n0wall checks the current rules status by using packet as below,

GET /firewall_rules.php?if=lan HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/msword, application/vnd.ms-powerpoint, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, */*
Referer: http://192.168.1.254/firewall_rules.php
Accept-Language: zh-cn
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
Host: 192.168.1.254
Connection: Keep-Alive
Authorization: Basic YWRtaW46c3VuZGVuYWl0


All right, now we already understand the mechanism of m0n0wall to perform rule checking, toggling, and applying the changes. So, we can create 2 script files to block and unblock the network, by enabling and disabling the dedicated rule in m0n0wall. I am using a Windows XP box to do this job, and I write 2 batch files for it, block.bat and unblock.bat, as shown below,

/////////////////block.bat/////////////////

nc -v -n 192.168.1.254 80 <> checkstring.txt
find "gray" checkstring.txt
if errorlevel == 1 goto notfound
goto found
:found
nc -v -n 192.168.1.254 80 <> nul
nc -v -n 192.168.1.254 80 <> nul
echo block completed!
goto end
:notfound
echo already blocked!
:end
nc -v -n 192.168.1.254 80 <> checkstring.txt
net send 192.168.1.158 System_Blocked

///////////////////////////////////////////////

/////////////////unblock.bat/////////////////

nc -v -n 192.168.1.254 80 <> checkstring.txt
find "gray" checkstring.txt
if errorlevel == 1 goto notfound
goto found
:notfound
nc -v -n 192.168.1.254 80 <> nul
nc -v -n 192.168.1.254 80 <> nul
echo unblock completed!
goto end
:found
echo already unblocked!
:end
nc -v -n 192.168.1.254 80 <> checkstring.txt
net send 192.168.1.158 System_Unblocked

///////////////////////////////////////////////

The “test.txt” in the batch files contains the packet to perform rule checking. For “toggle1.txt” and “toggle2.txt”, they are representing the packets of rule toggling and applying change, respectively. In order to filter the return result, I use grep tool for Windows to get the line with “block dns”, and use Windows default find.exe to search for the word of “gray”. Other than that, everything is very straight forward. Now, you just launch your windows tasks scheduler and make it calls block.bat and unblock.bat at specific times, then a time scheduled action for m0n0wall is considered done. If you have any further queries, please feel free to contact me.

No comments:

Post a Comment