Friday, February 26, 2010

How To Get The Installed Software List Of All The Computers In Your Network

How To Get The Installed Software List Of All The Computers In Your Network

by cawan – cawan[at]ieee.org

It is important to monitor the installed software list of all the computers in a network to detect unauthorized the installation of pirated software. However, there is no simple tool to do this job. So, we will discuss a simple method to implement this feature by using batch files. The batch files will be put in the DC and run there because DC has authorized access to all the computers in the network. Here, we assume all the computers are Windows box that logged in to the DC. Hence, the DC can perform file copy from/to all the clients, as well as starting a scheduled task in all the clients.

All right, the first question is about how to get the list of installed software in a computer. Somebody advocates parsing dedicated inf file in certain folder from %windir%. However, this is not a good solution because the folder name is varied to the service pack and update versions of the windows. The ideal solution would be to export the registry entries from [hklm\software\microsoft\windows\currentversion\uninstall]. So, by executing the command like “reg export hklm\software\microsoft\windows\currentversion\uninstall list.reg”, we can get a file named “list.reg” which contains all the installed software names inside. Well, now we know how to get the list of installed software already, then the second question is about how to let all the computers in the network to run this command and generate individual “list.reg” respectively. I propose to use task scheduler service of windows for the purpose. So, from the DC, we can use the command like “at \\CLIENT_IP TIME /i COMMAND” to do our job. Now, let start to write our simple batch files. First, we create a “run.bat” with the content as “reg export hklm\software\microsoft\windows\currentversion\uninstall list.reg”. After that, we create a “put.bat” with the following contents,

//////////////////////////put.bat/////////////////////////
copy run.bat \\%1\c$\windows\system32
at \\%1 %2 /i run.bat
/////////////////////////////////////////////////////////

Then, to run the “put.bat”, we create a “startput.bat” with the following contents,

//////////////////////////startput.bat////////////////////
for /f %%a in ('type IP.txt') do call put.bat %%a %1
////////////////////////////////////////////////////////

So, the “startput.bat” will read the IP entries in “IP.txt” line-by-line and call “put.bat” to copy “run.bat” into those computers with its IP included in “IP.txt”, and finally creates a scheduled task in all of them respectively to run the “run.bat” at some time. For example, at 08:30, we execute “startput.bat 8:40” in DC to distribute “run.bat” to all the computers and each of them will run the “run.bat” after 10 minutes later (at 8:40) and generate a “list.reg” which contains the list of installed software. There is a little issue regarding how to generate the “IP.txt” with all the valid IPs as windows box. For this case, we can use fscan to grab the IPs with port 139 or 445 is opened.

Now, we have all the computers with individual “list.reg”, the question now is about how to get all those distributed “list.reg” and put into the DC with a filename which can represent the clients such as “192.168.1.100.txt”, “192.168.1.101.txt” and so on. Let us create two batch files, with the names of “get.bat” and “startget.bat” to do the job. Their contents are shown below,

//////////////////////////get.bat/////////////////////////
copy \\%1\c$\windows\system32\list.reg .\%1.txt
/////////////////////////////////////////////////////////

//////////////////////////startget.bat////////////////////
for /f %%a in ('type IP.txt') do call get.bat %%a
////////////////////////////////////////////////////////

So, by executing “startget.bat” at the DC, we can get a list of files named with individual IP addresses in “IP.txt” which contains the installed software list respectively in our local folder. The contents of the installed software list are majority repeated because those entries in [hklm\software\microsoft\windows\currentversion\uninstall] contain subkeys. Thus, we need to use tools such as grep tool for windows which is mentioned in last post to extract and generate a unique list of installed software for individual computer. For any further queries, please feel free to contact me.

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.

Saturday, January 23, 2010

How To Downgrade The Firmware Version of Siemens S450 SIP Handset

How To Downgrade The Firmware Version of Siemens S450 SIP Handset

by cawan - cawan[at]ieee.org

Lets ask two questions first...

1. Why we need to do so?
Because the new firmware cannot work well! (dropout, connection lost on call, self-reboot...)

2. why need to write a long article to talk about how to downgrade the S450 firmware?
Because S450 do not allow user to downgrade the firmware version once it is being upgraded to the latest version. In other words, if our phone cannot work well once getting upgraded, it cannot be reverted.

Lets start the story from here.

First of all, we need to know how to download and save a local copy of S450 firmware from gigaset.com. Lets start from studying the web directory structure of gigaset.com.

By gathering and analizing the sniffed packets with ethereal to the communication between S450 and gigaset.com, the web directory structure of gigaset.com can be summarized as below.

Lets say http://gigaset.com/chagall/2/14/ is an image path of a specific version of firmware. Then it has a master directory file with the name of master.bin to show the baselines directory of the firmware with the name of baselines.com. By reading the baselines.bin, we can get know the exact filename of the firmware version to download. Lets have an example,

a) Get into http://gigaset.com/chagall/2/14/
b) Get the master directory file - master.bin with http://gigaset.com/chagall/2/14/master.bin
c) Read the master.bin, and get baselines.bin which is stated in master.bin
d) Get the baselines.bin with http://gigaset.com/chagall/2/14/baselines.bin
e) Read the baselines.bin and get the filename(s) of the firmware, for my example, it is chagall083_02.bin
f) Get the firmware file with http://gigaset.com/chagall/2/14/chagall083_02.bin

Now, lets have a look to the naming convention of the S450 firmware, as shown below,

chagall083_02.bin -> v02083
chagall072_01.bin -> v01072
chagall184_02.bin -> v02184
chagall191_02.bin -> v02191
chagall214_02.bin -> v02214 <- Latest Firmware at 23-Jan-2010 We can get a list of the firmware version for S450 from the following site, http://gigaset.com/shc/0,1935,hq_en_0_123868_rArNrNrNrN_variation%253A-5_pageType%253Adownloads_imagePos%253A0,00.html

So, now, we already know how to get the exact filename of the firmware version that we are looking for. For example, if we need to get the firmware version of v02214, then the correct filename should be chagall214_02.bin. So, we can try to download the firmware directly. For chagall214_02.bin (v02214), it should be http://gigaset.com/chagall/2/chagall214_02.bin, and for chagall191_02.bin (v02191), it should be http://gigaset.com/chagall/2/chagall191_02.bin instead.

May be someone will ask why chagall083_02.bin (v02083) is located at http://gigaset.com/chagall/2/14/chagall083_02.bin but not http://gigaset.com/chagall/2/chagall083_02.bin? This is because http://gigaset.com/chagall/2/ only stores a few of the most recent firmware version, and all the older version will be moved into a deeper path such as /14 in our example. So, once the firmware version is moved into the deeper path, then we need to recursively traverse into the gigaset web directory to get the desired firmware file with appropriate baselines.bin file.

Lets start to have a look to the methods to upgrade S450 firmware into the latest version.

1. From handset: Setting->Base->Software Upgrade

2. From Web: (using Siemens Gigaset site)

Goto Setting->Miscellaneous->Firmware Upgrade
In "Data Server" the default is "gigaset.com/chagall/"
In "User Defined Firmware" put "http://gigaset.com/chagall/2/chagall214_02.bin"
Then click "Upgrade Firmware"

3. From Web: (using own local web site)

Goto Setting->Miscellaneous->Firmware Upgrade
In "Data Server" the default is "gigaset.com/chagall/" (no need to change this, it is for self-healing purpose)
In "User Defined Firmware" put "http://192.168.1.1/chagall214_02.bin" (we put chagall214_02.bin into the root directory of http://192.168.1.1/) .
Then click "Upgrade Firmware"

We have mentioned about the term of self-healing above, then what is it? The Siemens S450 has the ability to perform so called self-healing once the firmware spoilt due to the incomplete firmware upgrade process. It will based on the default setting of the S450 to connect Siemens Gigaset site (as stated in the "Data Server" column) to download the latest firmware automatically. However, if the "User Defined Firmware" is specified with a valid URL (such as "http://192.168.1.1/chagall214_02.bin"), then it will override the "Data Server" in order to get the latest firmware instead. As additional info, if "User Defined Firmware" is left blank or not specified correctly, then S450 will use port 20 to transfer the latest firmware from gigaset site. So, for those S450 installed in NAT, it is necessary to set port forwarding of port 20 to the S450 IP address at the router and also allow port 20 at the firewall to enable self-healing from gigaset site.

Well, now, we reach to the most crucial part of this article - how to downgrade the firmware version. For my case, I use firmware version v02191 for some times with no error. However, once I upgrade the firmware version into v02214, my S450 totally cannot call into Asterisk server or Barix Annuncicom in peer-to-peer mode. Everytime I initiate a call, it keeps showing "Connection Lost" and stop then. When I enable to show Status, I keep getting "IP Status Code:701"...So, now I really need to have my v02191 back! Then I try to fill in "http://gigaset.com/chagall/2/chagall191_02.bin" in "User Defied Firmware" and click "Upgrade Firmware" button, it shows a message box with "Firmware Upgrade Not Possible: Latest firmware version is already installed." and the upgrade process stopped. Then, I download the chagall191_02.bin and put it in the root directory of my local web server and start the upgrade process again with "http://192.168.1.1/chagall191_02.bin", I got the same error. After that, I tried to rename the file into chagall999_02.bin, I got the same error too.

After having some packet analysis with ethereal, I get know my S450 will get a chunk of data from chagall191_02.bin first before showing the error message box and stop the firmware upgrade process. So, it is very obvious the S450 should has some kind of "version checking" mechanism to the chagall191_02.bin file. By performing hexadecimal file compare to the chagall191_02.bin and chagall214_02.bin, there are not many bytes are in different for the chunk that is transfer from my web server to the S450. In very quickly, I found that at offset 0x200, chagall191_02.bin is 0xBF (191 in decimal) and chagall214_02.bin is 0xD6 (214 in decimal). Now, I can just "fool" the S450 to assume the chagall191_02.bin (v02191) as v02255 by changing the 0xBF of chagall191_02.bin at offset 0x200 to 0xff. Then I try to "upgrade" the new "v02255" firmware again. This time, I get a message box with "Firmware update started. The device will be disconnected and this interface terminated. The device will then shut down and restart. Once completed, you may start the interface again.", and I can see the upgrade process is started from ethereal. Once the upgrade process is completed, I just turn off and turn on the power again to restart the S450. Then, I try to access the S450 with my browser but it has not response! Then it seems the S450 got some kind of checksum to ensure the data integrity of the firmware. After that, I try to ping the S450 and I can get response from it (I assume the bootstrap of the S450 is always exist to support self-healing). So now I replace the edited chagall191_02.bin with the original one at my web server. Then I restart my S450 again. From ethereal, I can see my S450 is downloading the original chagall191_02.bin from my web server, in other words, the so called "firmware downgrade" process is just started! Once completed, I restart my S450 again and get access to it from my web browser. Finally, I get get into it and when I click into the "Status", it shows the firmware version is 0219100000. So, my firmware downgrade process is completed.

So, this is the whole process of firmware downgrade of Siemens S450 Sip handset. Please take you own risk to practice all the steps as mentioned above. For any further queries, please contact me.