Thursday, March 26, 2009

Problems with UDP streams and STUN

I recently came across a problem with longer lasting UDP sessions that use STUN for NAT traversal. More specifically when using a Microsoft LiveMeeting session to share real time video.

The client PC initiates a connection to the Microsoft servers and starts sending UDP data to which the Microsoft servers respond. The response packets contain other users' video or if you are in the conference by yourself your own video. NAT traffic through the firewall looks something like this in a packet capture:

  • Before reaching the firewall
  • Client Source IP, UDP Source Port, STUN Destination Port (e.g., Source Port 43000, Destination Port 3478)
  • After passing through the firewall
  • NAT Source IP, UDP translated Source Port, STUN Destination Port (e.g., Source Port 56565, Destination Port 3478)

In this example the firewall translates the source IP and source port in a PAT or many-to-one NAT situation.
After about 7 minutes the firewall all of a sudden changes the translated Source Port, for example 56565 becomes 61616. The original source port on the client however has not changed. Therefore the destination server on the far end no longer sees the correct UDP source port and after several seconds ends the connection due to lack of UDP data. This behaviour has been confirmed in FortiOS 3.0 MR7. In further testing I found that FortiOS 4.0 does not exhibit this behaviour.

The temporary workaround is to use static NAT where possible. Static NAT uses a one-to-one relationship between the original and translated source port and IP addresses. Therefore no translation is done on any ports, only the source IP, and the connection stays alive.

** Update from Fortinet **

Fortinet has identified two bugs which have been fixed in FortiOS 4.0. The bugs are "Port changed in SIP header" and "SDP contact not modified correctly". There are currently no plans to resolve this in 3.0 MR7.

Tuesday, March 24, 2009

Internet Malware - Anatomy of a Forensic Investigation

I wanted to take a second and write down some notes on a recent malicious code attack and how Fortinet was able to help stamp out the culprit.

I first noticed some irregular activity when doing some routine reviews of our Cacti monitoring system. In a previous post I described how to monitor firewall statistics such as CPU, session counters and interface traffic with Cacti. One of our low volume web servers all of a sudden spiked to several thousand active sessions which is highly unusual.

Upon further investigation using our FortiAnalyzer I determined that the server was trying to access a particular website at a rapid pace.

Initially it looked like the server was participating in a denial of service attack. I dug a little deeper and manually connected to port 8080 on the destination server and was greeted with the following message: NOTICE AUTH :*** Looking up your hostname... NOTICE AUTH :*** Found your hostname 451 GET :You have not registered 451 Host: :You have not registered 451 User-Agent: :You have not registered 451 Accept: :You have not registered 451 Accept-Language: :You have not registered 451 Accept-Encoding: :You have not registered 451 Accept-Charset: :You have not registered 451 Keep-Alive: :You have not registered 451 Connection: :You have not registered (devastate, they are so clever :) seemed a weird place for my system to connect to, further confirming my suspicions about bad things going on. Since I did not yet know why this machine was behaving strangely I installed various Linux rootkit detection systems to see if the machine had actually been penetrated. However all the systems came up blank.

As a next step I reviewed my FortiAnalyzer IDP attack logs but nothing there either even though I had cranked up the IDP settings to full force by enabling all signatures and setting them to log and block bad traffic.

Next I turned up Content Archiving to see what my system was accessing and more importantly what was being accessed on my server. By this point I was leaning in the direction that somewhere on the webserver I had a vulnerable script with a buffer overflow or similar exploit.
After sitting back and watching for a while I saw my server accessing an odd text file on a server in China. I attempted to download the text file to a machine specifically configured for forensics and found a nasty little script which opens various backdoors on an infected machine. My PC's anti-virus actually picked it up and quarantined it which means it made its way through the firewall's anti-virus scanners without the Fortinet picking it up.

An additional tool I installed on the server was OSSEC. OSSEC is an open source host intrusion detection system. Installing it was very straightforward and later the same evening I got the first alert via email. The server was attempting to download and save the file from the server in China again but failed due to the limited permissions of the web server process.
I then went back to the logs to see if I could find out what was triggering the download attempts. And sure enough just before my server went active there was a POST operation to a PHP script on the box. I immediately modified my firewall policies to deny all traffic to and from the machine to prevent any further exploit of the script.

I googled the php script that was being accessed and wouldn't you know it the developers had issued a security alert for a code injection vulnerability that I had missed. Obviously the safest thing to do was to entirely remove the application since it was only used for a proof-of-concept and then discontinued. I then re-enabled access for the server at the firewall level.

Follow-Up with Fortinet

To enhance security for other systems protected by Fortinet firewalls I went ahead and submitted the different pieces of the above investigation to Fortinet for dissemination:

I was very happy to see that within six hours I had received responses to all my requests. The virus is now being detected by a signature in the Fortinet A/V, the IDP signature will be able to block the code injection as soon as Fortinet releases their new signatures and the URL has now been rated as a malware hosting site. The obvious benefit here is that anyone else around the world using FortiGuard services will be able to profit from this experience.

Friday, March 13, 2009

Software Updates

Fortinet has release the following software updates:

FortiAnalyzer: 4.0 GA, Build 36
FortiAnalyzer: 3.0 MR 7, Patch 4, Build 729

Please note that Fortinet has discontinued support for the FortiAnalyzer 100 and 100A platforms in the 4.0 software releases.

FortiClient: 4.0 GA, Build 47

FortiMail: 3.0 MR4 Patch 4, Build 432

FortiManager: 4.0 GA, Build 76

Please note that only the following FortiManager platforms are supported
  • FortiManager100
  • FortiManager400A
  • FortiManager400B
  • FortiManager3000
  • FortiManager3000B

I have confirmed with our Fortinet rep that the FortiManager 400 will not be supported in version 4.0. You can contact if you are interested in upgrading. (No, I don't work there :)

Monday, March 9, 2009

Fortinet and Cisco MARS Integration - Part II

If you haven't already please read Part I of the Fortinet with Cisco MARS integration. This post talks about configuring additional custom parsers for MARS as well as using the Keyword field in MARS for freeform syslog text matching. In the following example I will describe how to detect administrative login failures for SSH and HTTPS access to a Fortigate unit.

In your MARS Global Controller or standalone Local Controller perform the following steps:

  • Click Admin -> Custom Setup (tab at the top) -> User Defined Log Parser Templates
  • Under Vendor select Fortinet and click Edit, then click Next
  • Add a new Device Event ID by clicking Add and Add again on the next screen
  • Fill out the following fields: Event ID=Event Log, Description=Event Log, Severity=Green
  • In the Event Type Group section select Info/Misc from the right hand side and click on the Add button with the double left arrow. Then click Submit.
  • On the next page in the Choose Event Type From section select the newly created Event Log's radio button and click the double arrow to the left. At the top of the page enter Event Log in the Device Event ID and Description fields. Then click Apply on the bottom right of the page.
  • The Patterns link at the top of the page now becomes available, click there and add the following patterns:

  1. Position= 1, Key pattern: date\=, Parsed Field=Device Time, Value Type=Time, Pattern Name=%Y-%m-%d time=%H:%M:%S, Value Format=%Y-%m-%d time=%H:%M:%S, Value Pattern=\d{4}-\d{1,2}-\d{1,2} time=\d{1,2}:\d{1,2}:\d{1,2}
  2. Position=2, Key pattern=.+user\=\", Parsed Field=Reported user, Value Type=String, Pattern Name=STRING_WORD_QUOTES, Value Pattern=\w+
  3. Position=3, Key pattern=.+ui\=, Parsed Field=Workstation Name, Value Type=String, Pattern Name=STRING_SERVICE_IP (enter this in the Or enter new field), Value Pattern=\S+ (notice that the S must be capitalized)
  • When you are done defining the three patterns click Submit on the Patterns for Device ID: Event Log page, the Done on the next page.
  • Now click on the Rules tab at the top of the page and click Add to add a new rule. Give the rule a descriptive name and description and click Next
  • Define applicable zones or leave blank to apply this rule to all zones. Click Next
  • Set Source IP, Destination IP, Service Name, Event, Device and Reported User to Any
  • Leave the IPS Risk and Threat rating at default and click Next
  • Set Keyword to action=login status=failed and click Next
  • Leave Severity at Any and for Counts enter the amount of failed logins the firewall must report before triggering the rule, for example 5.
  • Click Yes on the next page to finish defining the rule conditions
  • Select the appropriate action to perform when the rule is triggered
  • Set the time range to 10 minutes or another appropriate value. This will trigger the rule if any firewall reports 5 failed login attempts within a 10 minute period for example
  • On the Rule Summary page click Submit
  • Activate the changes

To enhance security you can add additional conditions to the rule, such as adding another statement looking for action=login status=failed in the keyword section. This rule would trigger on attempts to log into the firewall which fail followed by a successful login. This could indicate a successfull brute password attack.