If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

Building your own IDS tripwire.

Overview

In this article I will be looking at how to build a tripwire into your webserver. The examples that I give here are using IIS / ASP / MSSQL, but the theory remains vitually unchanged for any webserver / ISAPI langauge / SQL database combination. The concepts covered in this tutorial are just as applicable to an Apache / PHP / MySQL platform as they are to a Microsoft one. (Thanks to Jethro for confirming that for me!)

The only 100% secure webserver is one with port 80 closed, but if you intend to host a public web service that just isn't possible. My objective here was to provide an additional layer of security in handling requests received by my webserver by providing a simple means of logging any attempts to interfere with or abuse my webserver.

These sort of intrusions are not repelled by your a firewall because they attack a port that, on a webserver, is open by design. The sort of exploits can include office extension scans, traversal scans, buffer overflow exploits, mail script attacks and SQL injection, all of which use your own web service against you. Without some sort of filter to detect such attempts the webmaster of a busy site can quite happily spend entire days trolling through logs.

You can also use the information collected to prepare abuse reports for a users ISP. See my earlier tut on Hunting down skript kiddies for more details.

What is a tripwire?

In this context of this document a tripwire refers to a mechanism by which you can flag suspicious events in your web log file. The simplest way of doing this is by using an SQL datasource to store the web logs. Then, using SQL statements, we have the ability to apply SQL filters to webserver log information and pull out information relating to potential intruders.

Configuring SQL logging

The process for enababling SQL logging on IIS is as follows:
1...Create an SQL Datasource in MSSQL. I will refer to this database as the WebLog Database
2...Create a table within the WebLog database called InternetLog using the script below
3...Create an ODBC datasouce (via the control panel) pointing to the WebLog Databse called Weblog
4...Set the logging options in the site properties of the MMC to SQL logging
5...Configure the service to save data to the Weblog ODBC Datasource in the table of Internetlog

You can repeat actions 4 and 5 for each of the web services that you wish to monitor, or alternatively set this up as the default propeties for your master website and all subsequently created site will inherit this characteristic.

The InternetLog Table

You can create the InternetLog table described above by running the following script against the WebLog database in iSQL or WiniSQL. This creates all of the fields of correct type and length required by IIS SQL logging.

Restart your webserver from the command prompt with the NET START|STOP w3svc command.
Once your webserver has restarted, if you did everything right, you should now be able to see a new record created in this log for each hit received by your site. If you are using Apache please refer to your product documentation as to what fields are required for SQL logging.

Filtering the web log

I decided that I would filter suspect records out to a seperate table, called intruder log for analisys by an operator. This IntruderLog table should have the same fields, types and lengths as the InternetLog table described above. The secondary reason for this was so that the operator was not working on the live data. The primary reason for this design choice however was that on my system the data in the InternetLog is parsed to provide customer site statistics (which I intend to cover in a later tutorial - bear with me - there's method in my madness ).

I also decided that my tripwire should do the following:
1...Maintain a list of suspect IP addresses that an operator was currently monitoring
2...Allow the removal of IP addresses from the monitoring list without deleting the actual log entries from the IntruderLog' table
3...Operator to be able to analyse this information via a web browser.

The IntruderIP list described above has a couple of benefits. First I can stop monitoring an IP without deleting the log entries, but, secondly, if I do stop monitoring an IP, and that IP returns the system will flag up not only their current log, but also their previous visits aswell. You can use this information to profile your attackers, their capabilities and next likley move.

I actually get SQL Server Agent to run this job at timed intervals, but you could just as simply write a Pearl or WSH script to use with the AT command to schedule the execution of this SQL filter.

This filter is a fairly basic one, but I'm not going into a lesson in SQL in this tut. If you want to impliment this type of system in a production enviroment you should consider the sorts of things you want to track and write your own 'filter'.

The premise for the following filter is based on the fact that most web style attacks (especially traversal scanners and SQL injection techniques) create dirty logs. Most, if not all of these attempts will cause at least some errors in the server logs. I have therefore based my filter around finding users that have created error and dropping their entire transaction history to the IntruderLog Table.

--Build new Intruder IP list from
--Existing list and new data
--This function ensures that
--there are no duplicate IPs
--in the Intruder IP list.

--Clear the Tempoary IP list
delete from tempIP

--**This bit is the Filter!!
--Insert all the IPs of browsers with:
--Requests with return codes other that 200 (ok) and 302 (redirected)
--GET Requests with parameters or POST requests
--from the InternetLog file to the TempIP table

INSERT INTO tempip ( IP )
SELECT ClientHost AS IP
FROM Internetlog
where ((parameters <> '-' ) or (operation='post'))
and servicestatus <> '200'
and servicestatus <> '302'
GROUP BY ClientHost

--Copy all the existing monitored
--IPs into the TempIP table

INSERT INTO tempip ( IP )
SELECT IntruderIP AS IP
FROM IntruderIP
GROUP BY IntruderIP

--Delete the old monitored list
delete from IntruderIP

--Create a new IntruderIP list based on
--grouped new and old data
INSERT INTO IntruderIP ( IntruderIP )
SELECT ip AS IntruderIP
FROM tempip
GROUP BY ip

--Cleaning up the IntruderLog Table:
--Last I heard there aren't any remote explots for images
--so we ignore requests for this type of file
DELETE from intruderlog
where right(rtrim(target),3) = 'gif'
or right(rtrim(target),3) = 'jpg'
or right(rtrim(target),4) = 'jpeg'
or right(rtrim(target),3) = 'png'
or right(rtrim(target),3) = 'bmp'

Creating a web based monitoring system

Ok - so now we our filter set up to run every x minutes using either a script with the AT command or using the SQL Server Agent, we want to create a new table and fill it with some information about the sites that we are monitoring. This is so as to make this information availible to the operator alongside the IntruderLog information via a web based interface. To do this I used one more lookup table to list the site host name against its service tag. I called this table SVC. It looks like this:

I use another script to maintain the information in this table, but again, that's for another tutorial. For now lets just assume that we maintain this list manually, so that it contains the relevant information about our web services.

The Code!

Now I just need a script that brings all this information together for the operator. Here we go... I decided to link the IP addresses contained in the IntruderIP table directly to samspade so the operator doesn't have to think too much . Again, this is an ASP script, but would be fairly simle to write in any ISAPI lauguage.

Ok. Thats all for now... In my next IIS/SQL article I intend to show you what happens to the rest of the information in the InternetLog table and publish the code for my simple stats package, but as I say - I'll save that for another day

The only 100% secure webserver is one with port 80 closed, but if you intend to host a public web service that just isn't possible.

Well, thats not completely true. You could set up your server to listen on port 8000 instead. Then, configure your router to send all port 80 requests on to port 8000.... Not that it would make any difference at all, but port 80 would be closed and the machine still isn't "100% secure"

ntsa> Shouldn't you say "computers are very succpetible to attacks"? Anyway, this was really good timing, because I am just starting to relearn tripwire. I used it back in 97 for a test project, but put it aside. Now I have to relearn it. It's an excellent program and has a LOT more uses then just watching a web server. I am using it on a linux machine that doesn't even have a web server installed on it.

Nice, but you should escape those asp request parameters (ip param) before passing them in sql queries (ie: doubling quotes...). You wouldn't want your code to become its own sql injection vulnerability !