Lucene search

K
securityvulnsSecurityvulnsSECURITYVULNS:DOC:12953
HistoryJun 03, 2006 - 12:00 a.m.

SMF 1.0.7 and lower plus 1.1rc2 and lower - IP spoofing vulnerability/IP ban evasion vulnerability

2006-06-0300:00:00
vulners.com
16

======================================================================

Advisory : SMF 1.0.7 and lower plus 1.1rc2 and lower - IP spoofing
vulnerability/IP ban evasion vulnerability
Release Date : June 02, 2006
Application : SMF
Version : SMF 1.0.7 and previous versions, SMF1.1rc2 and lower
Platform : PHP
Vendor URL : http://www.simplemachines.org/
Author : Jessica Hope ([email protected])

======================================================================

Overview

The IP detection section of SMF's code allows for someone to spoof the
X-Forwarded-For header.
SMF trusts this value over the IP address reported in general.

This allows an attacker to login and post using IP's that are not theirs,
making it impossible for the Administrator of the SMF forum to ban the user.

======================================================================

Discussion

There's code in QueryString.php that starts:

    elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
    {
            // If there are commas, get the last one.. probably.
            if (strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ',') !== false)
            {
                    $ips = array_reverse(explode(', ', $_SERVER['HTTP_X_FORWARDED_FOR']));

                    // Go through each IP...
                    foreach ($ips as $i => $ip)
                    {
                            // Make sure it's in a valid range...
                            if (preg_match('~^((0|10|172\.16|192\.168|255|127\.0)\.|unknown)~',

$ip) != 0)
continue;

                            // Otherwise, we've got an IP!
                            $_SERVER['REMOTE_ADDR'] = trim($ip);
                            break;
                    }
            }
            // Otherwise just use the only one.
            elseif (preg_match('~^((0|10|172\.16|192\.168|255|127\.0)\.|unknown)~',

$_SERVER['HTTP_X_FORWARDED_FOR']) == 0)
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
}

This code is used to obtain the users IP address. However, if
X-Forwarded-For HTTP header has been provided,
it will take the last IP address from the X-Forwared-For header and
blindly trust it to be the real IP address.
The problem is that the X-Forwarded-For HTTP header is easily forgable
via a number of methods.

For example, if the X-Forwarded-For header was set:

X-Forwarded-For: 1.2.3.4

the SMF application trusts 1.2.3.4 to be their IP address, and will
reflect this fact when the user does anything that SMF logs,
such as posting to the forum.This makes it possible for a user to set
the X-Forwareded-For IP to that of another user in
an attempt to masquerade as them. It also would require the SMF
administrator to track down the users real IP via httpd server logs,
assuming this is possible, which in some cases it is not.
This would also assume the SMF administrator knows the IP presented to
them isn't real.

On top of this, there's code in Security.php that starts:

            // Check if we have a valid IP address.
            if (preg_match('/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/',

$user_info['ip'], $ip_parts) == 1)
{
$ban_query[] = "(ban_type = 'ip_ban'
AND ($ip_parts[1] BETWEEN ip_low1 AND ip_high1)
AND ($ip_parts[2] BETWEEN ip_low2 AND ip_high2)
AND ($ip_parts[3] BETWEEN ip_low3 AND ip_high3)
AND ($ip_parts[4] BETWEEN ip_low4 AND ip_high4))";

                    // IP was valid, maybe there's also a hostname...
                    if (empty($modSettings['disableHostnameLookup']))
                    {
                            $hostname = @gethostbyaddr($user_info['ip']);
                            if (strlen($hostname) > 0)
                                    $ban_query[] = "(ban_type = 'hostname_ban' AND ('$hostname'

LIKE
hostname))";
}
}
This code indicates that a user could bypass bans on their IP by
setting the X-Forwarded-For header,
seeing as SMF blindly trusts the X-Forwarded-For IP to be real.

======================================================================

Solution

The offical response from SMF was:

'Trusting any server variable that carries the real IP address would
make no sense.
A hacker would be able to manipulate all headers being received by PHP.
SMF tries to give the best estimate of the user's real IP address,
but on the internet the IP address authenticity can never be relied
upon fully. '

  • Hendrik Jan Visser - Lead Developer Simple Machines

Plus, when pressed about it being a vulnerability, they had this to say:

'I thought we had replied that none of these represent a security issue?
Could you please state again how these could be exploited?' - Grudge (
Matthew Wolf - Developer Simple Machines ).

This issue was first reported on the 14th Apr 2006, the first reply
was on the 23rd Apr 2006.
The follow ups were on the 10th May 2006 and 24th May 2006, with the
final reply of not being an issue sent on the 24th May 2006.

Thus there is no offical solution.

The solution that I will advise is to remove the code quoted from
QueryString.php
so that SMF doesn't trust the X-Forwarded-For variable.
This will also make it possible to properly ban someone by IP address.

======================================================================

Credit

This issue is to be credited to Jessica Hope ( [email protected] )