Archive for the ‘IPS’ Category

ModSecurity: rule for latest Tikiwiki vulnerability

Wednesday, September 6th, 2006

A few days ago a new vulnerability was reported in Tikiwiki 1.9.x, the software I use for the Vuurmuur Wiki. Luckily, the Snort.org Community rules quickly had a rule for detecting the attack. Because I also run ModSecurity on the webserver, i wanted to have protection there as well. This rule should block the attack:

SecFilterSelective POST_PAYLOAD “jhot.php” “log,deny,status:403,msg:’LOCAL tikiwiki jhot.php attempt’”

Let’s see if I ever get a hit on it. An update for Tikiwiki as been released, so that should fix the issue completely.

ModSecurity: rules against comment spam

Wednesday, August 23rd, 2006

Lately the wiki of my Vuurmuur project has been receiving quite a lot of comment spam. Although removing the spam manually is boring work, i still don’t really mind the spam, because it enables me to practice with ModSecurity rules to fight it off. So far, the spam seems to be following a pattern, in which the spam is posted by bots, and has the same general layout for longer periods of time. That makes it worthwhile to spend time on creating rules against it. Yesterday a new type of spam emerged on the wiki. The following audit_log is for one of them. I had to slightly edit it for layout reasons.

–9075cb7a-A–
[22/Aug/2006:20:20:46 +0200] SPO4w5FhwZUAADItDEgAAAAC 195.225.177.131 34189 192.168.1.101 80
–9075cb7a-B–
POST /tiki/tiki-index.php HTTP/1.1
Host: wiki.vuurmuur.org
Referer: http://wiki.vuurmuur.org/tiki/tiki-index.php?page=Vuurmuur
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)
Content-Length: 1304
Content-Type: application/x-www-form-urlencoded

–9075cb7a-C–
page=Vuurmuur&cols=60&comments_sort_mode=points_desc&
comments_parentId=0&rows=6&comments_postComment=
post&comments_threshold=0&comments_threadId=0&
comments_data=Chevrolet+-+%5BURL%3Dhttp%3A%2F%2F
canonprnbf.kickme.to%2F+%5D+Chevrolet+%5B%2FURL%5D+
home+based+businesses+-+%5BURL%3Dhttp%3A%2F%2F
1964cadulj.blog.kataweb.it%2F1964cadulj%2Findex-home-
based-businesses.html+%5D+home+based+businesses+
%5B%2FURL%5D+diet+pills+-+%5BURL%3Dhttp%3A%2F%2F
aemerge4li.web1000.com%2Findex-diet-pills.html+%5D+diet+
pills+%5B%2FURL%5D+Cash+Advance+-+%5BURL%3D
http%3A%2F%2Fseamlesmnp.su.pl%2F+%5D+Cash+Advance
+%5B%2FURL%5D+Azithromycin+-+%5BURL%3D
http%3A%2F%2Fthelacefab7ne.kickme.to%2F+%5D+
Azithromycin+%5B%2FURL%5D+allergy+-+%5BURL%3D
http%3A%2F%2Fgeo.ya.com%2Faeggcelpzg%2Findex-
allergy.html+%5D+allergy+%5B%2FURL%5D+Cash+Advance+
-+%5BURL%3Dhttp%3A%2F%2Faofficeuov.ir.pl%2F+%5D+
Cash+Advance+%5B%2FURL%5D+free+games+-+%5BURL
%3Dhttp%3A%2F%2Fwww.geocities.com%2Fthebestjwb
%2Findex-free-games.html+%5D+free+games+%5B%2F
URL%5D+Ambien+-+%5BURL%3Dhttp%3A%2F%2F
beadedluwu.su.pl%2F+%5D+Ambien+%5B%2FURL%5D+altace
+-+%5BURL%3Dhttp%3A%2F%2Facellphonehy4.tripod.com
%2Findex-altace.html+%5D+altace+%5B%2FURL%5D
+&comments_reply_threadId=0&comments_title=Chevrolet&
comments_offset=0&comments_previewComment=preview&
comments_grandParentId=
–9075cb7a-F–
HTTP/1.1 200 OK
X-Powered-By: PHP/4.3.10-16
Set-Cookie: PHPSESSID=b2497fd593f56c5af4f3613ba78a7619; path=/tiki
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html; charset=utf-8

–9075cb7a-H–
Stopwatch: 1156270844524739 1475657 (17717* 38503 0)
Producer: ModSecurity v1.9.2 (Apache 2.x)
Server: Apache/2.0.54 (Debian GNU/Linux) PHP/4.3.10-16 mod_ssl/2.0.54 OpenSSL/0.9.7e

–9075cb7a-Z–

A general rule against the comment spam would probably not be that hard. Just blocking “http://” would probably to the trick. However, I’m not quite willing to do this, since people might actually post real and interesting links to the wiki. I noticed that the above comment and the 30 other already posted messages all contained the uppercase word URL, so i decided to block on that. Below are the rules, which as you can see are quite an improvement over these rules, because they now only match on actual comments posts ;-)

SecFilterSelective REQUEST_URI “\/tiki\/tiki-index\.php” “chain,msg:’LOCAL comment spam’”
SecFilterSelective POST_PAYLOAD “URL” chain
SecFilterSelective POST_PAYLOAD “comments_postComment=post” log,deny,status:403

An Apache restart and just wait… but not for long:

[Tue Aug 22 21:35:44 2006] [error] [client 195.225.177.131] mod_security: Access denied with code 403. Pattern match “comments_postComment=post” at POST_PAYLOAD [msg "LOCAL comment spam"] [hostname "wiki.vuurmuur.org"] [uri "/tiki/tiki-index.php"] [unique_id "VTGBGJFhwZUAADMnAWAAAAAA"]

This morning there were 59 attempts blocked already which i would have to remove manually without these rules. So taking the time to setup the rules really pays off.

ModSecurity: more security by obscurity

Thursday, August 17th, 2006

Yesterday, Philippe Baumgart showed me that my obscurity setup is not yet perfect. In fact, he could very easily enter an URL that didn’t exist and caused the webserver behind my proxy to respond with a 404. In this 404 the name and the version of the webserver were exposed.

After some testing i found that adding the following to my config worked very well.

# enable output scanning in Mod Security.
SecFilterScanOutput On

# hide outgoing 404 by webserver behind proxy
SecFilterSelective OUTPUT_STATUS 404 deny,status:404

This catches outgoing 404 errors, and replaces them by the 404 from the proxy. For some reason, this still didn’t exaclty look like the 404 from the proxy itself, because it contained a message that an additional 404 was encountered. I solved this by changing the ErrorDocument in de Apache config:

ErrorDocument 404 “<html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL was not found on this server.</p></body></html>”

After this, there was no longer any difference between 404′s produced by the proxy and by the webserver behind it.

Next, Phil showed me that i also leaked my version number of PHP. By using WordPress hiding the fact that I use PHP is impossible and pointless, but hiding the exact version still looks like a good idea. The version was leaked in the header from a server response: X-Powered-By: PHP/4.4.1build1. Solving this requires the mod_header module again:

# unset X-Powered-By to prevent leaking the PHP version
Header unset X-Powered-By

This hides this header. Thanks to Phil for doing some pen-testing :-)

ModSecurity: redirection

Wednesday, August 9th, 2006

Another nice feature of ModSecurity is rule based redirection. Lets say i want to block visitors of my website from opening the login page of wordpress, /blog/wp-login.php. I could of course just deny access to it, so the visitor gets a 403 error. This works fine, however sometimes you might want to use a more userfriendly message, for example: ‘Due to maintainance logins are currently disabled’.

To do this i first created a very simple html file called nologin.html, and placed it in the webroot of the server. Then i added the following rules to Mod_Security:

# block wp-login.php
SecFilterSelective REMOTE_ADDR “!192\.168\.1\.2″ chain
SecFilterSelective REQUEST_URI “/wp-login.php” log,deny,redirect:http://www.inliniac.net/nologin.html

These rules check first if the ipaddress is not 192.168.1.2, then look for /wp-login.php in the URI. If it is found, the request is logged and blocked. The server then sends a redirect 302 response to the client which will open the nologin.html page. Since the original request is blocked, the webserver behind the reverse proxy never sees the request.

ModSecurity: directory hiding a.k.a. security by obscurity

Sunday, August 6th, 2006

Ok, that’s a bit misleading, because i’m not just hiding, but also blocking and logging. What i wanted is this: I’m running awstats on my reverse proxy, but i don’t want anyone to know. So i just made the entire ‘cgi-bin’ part forbidden for everyone, so that covers the script. The fact that my webserver has a cgi-bin directory is nothing special and won’t tell you i’m using awstats. However, awstats also uses icons, and these are by default in /awstats-icon/

Now, i could have made that restricted as well, but that still would give you the information that it exists! ModSecurity to the rescue. I want only access to awstats from my workstation, so i added these rules:

SecFilterSelective REMOTE_ADDR “!192\.168\.1\.2″ chain
SecFilterSelective REQUEST_URI “/awstats-icon/” log,deny,status:404

These say: if the ipaddress of the visitor is not 192.168.1.2, and his request contains /awstats-icon/, we log it, block it, and send back a 404 error. This makes the visitor think the directory doesn’t exist on the server.

I’m not sure how easy this can be extended to giving an entire subnet access though, maybe i’ll investigate this later.

ModSecurity: my first rules

Tuesday, July 11th, 2006

I have been using ModSecurity for quite some time now to protect a webserver, but i never felt the need to write my own rules. Recently though, my site got quite a lot of spam in the comments of my TikiWiki based site. Since i was not willing to disable the anonymous comment posting i decided to see if i could use Mod_Security to block the spam.

The spam all looked alike with the following characteristics. It all contained a list uri’s with a pipe | before them. So decided to try the most easy way, by blocking all posts with this characteristic.

SecFilterSelective REQUEST_URI “\.php” chain

SecFilterSelective POST_PAYLOAD ” \| http\:”

And it works fine:

[Sat Jul 01 12:37:32 2006] [error] [client 211.47.162.225] mod_security: Access denied with code 404. Pattern match ” \\\\| http\\\\:” at POST_PAYLOAD …

Surely the rule can be much refined, but as long as it works as it does, and i see no bad side effects, i’m happy ;-)

Snort_inline: idea for an improved bait-and-switch

Tuesday, July 11th, 2006

William Metcalf recently wrote a bait-and-switch plugin for Snort_inline. The idea is that when a rule matches on certain traffic this plugin loads an iptables rule into the system that redirects the offending host to another server. This can present the user an error message such as “Access Denied” for example, but this server can also have al kinds of sniffing tools, or even be a honeypot.

As the plugin currently creates an iptables rule it only works with linux. Also, it has some difficulty with existing iptables rulesets that might be maintained by other programs, such as my own Vuurmuur. My idea is to investigate whether or not it is possible to simply do the redirection in Snort_inline itself. By rewriting the ipaddress in the IP header, it might work as well. Naturally, this would need to be done for every packet, but with a connection to either the flow engine or the stream engine, this should be able to work… just a thought…

Books: Preventing Webattacks with Apache

Monday, July 10th, 2006

I just finished Preventing Webattacks with Apache by Ryan C. Barnett. Even though the title says it is about Apache it is really mostly about Mod_Security, and this is why i really love the book.

Especially cool is the part of the book where the author challenges the user to setup his ‘Buggy Bank’ example application to play with the vulnarebilities and with the possible counter measures.

This book got me even more exited about Mod_Security, which I use already to protect one webserver. I plan to check out setting up a reverse filtering web proxy soon.

Snort_inline: Adapting the TCP stream reassembler

Monday, July 10th, 2006

Currently I am rewriting a modification of the TCP reassembler in Snort_inline. Snort’s TCP reassembler is called Stream4 and it works fairly well in IDS mode, however it has some serious issues in inline mode. The biggest and most important issue is that Snort_inline cannot block an attack if it is detected in the reassembled stream. In Snort_inline 2.4 we made our first attempt to fix this with the stream4inline modification.

Stream4 was never designed to be used inline. It was designed to help the detection capabilities of Snort in IDS mode. This had a large consequence for the design. In Stream4, incoming packets are stored in a per-stream list of packets, before the packet is handled normally. After a number of packets have been piled up this way, the stream is flushed. This flush builds a pseudo packet containing the payloads of all the ack’d packets in the list. This pseudo packet is than ran through the detection engine, to see if it contains an attack. This works fine for IDS mode, since this way the attacks can be detected in the reassembled stream.

When running in inline this concept has a big flaw. In inline mode we can use the action drop. This action makes sure that the underlying subsystem (netfilter or ipfilter) discards the packet, making sure it will not reach the destination. The problem with Stream4 is that at the time the pseudo packet is inspected, its content is already accepted and ack’d by the end-host. This situation is of course very unsatisfying.

To deal with this problem in Snort_inline 2.4 we created the stream4inline option. This option is a modification to Stream4 that simply reassembles the stream for every packet received. Then instead of the normal packet, the reassembled stream is scanned every time. There are two performance problems with this approach. The first is that we call the functions to build the pseudo packet for every packet we receive. Since this function walks the packet list every time, this is expensive.

The second problem is harder to solve. Because we scan a sliding window, we end up scanning the same data multiple times. I have not really thought of an (easy) solution for this. The rewrite of the stream4inline option is mostly focused on two improvements. First the performance of the reassembly itself will be improved by keeping a cached version of the reassembled stream. Second, the implementation will be much better and robust. I will discuss it on a more technical level later.