DDOS simulation through IP spoofing – (Sucuri Security <= 1.8.35)

| in


Affected pluginSucuri Security
Active installs800,000+
Vulnerable version<= 1.8.35
Audited version1.8.35
Fully patched version
Recommended remediationNever use the plugin without the remote WAF (premium) enabled

Description


The plugin is vulnerable to IP spoofing if the remote WAF is not enabled.
Currently, the (free) plugin is mostly sending alerts and does not take any proactive measures, so an attacker can currently exploit this in the following ways:

  • Simulate a distributed brute-force attack on the wp-login endpoint.
  • Bypass all alerts by spoofing his IP address to one in the allowlist.
  • Sending alerts to Sucuri’s remote API with a spoofed IP address (impact unknown, worst case: Sucuri uses the alerts to trigger bans at the WAF level, best case: Sucuri uses them for logging purposes only).

Proof of concept


The plugin uses the SucuriScan::getRemoteAddr() method almost everywhere it needs access to the current request’s IP address.

public static function getRemoteAddr($with_header = false)
{
    $remote_addr = false;
    $header_used = 'unknown';
    $headers = self::orderedHttpHeaders();
    foreach ($headers as $header) {
        if (array_key_exists($header, $_SERVER)
            && self::isValidIP($_SERVER[$header])
        ) {
            $remote_addr = $_SERVER[$header];
            $header_used = $header;
            break;
        }
    }
    if (!$remote_addr || $remote_addr === '::1') {
        $remote_addr = '127.0.0.1';
    }
    if ($with_header) {
        return $header_used;
    }
    return $remote_addr;
}

By default, the value assigned to the “$headers” variable will be the following array:

$headers = array(
    /* Sucuri custom HTTP headers */
    'HTTP_X_SUCURI_CLIENTIP',
    /* Cloudflare custom HTTP headers */
    'HTTP_CF_CONNECTING_IP', /* Real visitor IP. */
    'HTTP_CF_IPCOUNTRY', /* Country of visitor. */
    'HTTP_CF_RAY', /* https://support.cloudflare.com/entries/23046742-w. */
    'HTTP_CF_VISITOR', /* Determine if HTTP or HTTPS. */
    /* Possible HTTP headers */
    'HTTP_X_REAL_IP',
    'HTTP_CLIENT_IP',
    'HTTP_X_FORWARDED_FOR',
    'HTTP_X_FORWARDED',
    'HTTP_FORWARDED_FOR',
    'HTTP_FORWARDED',
    'SUCURI_RIP',
    'REMOTE_ADDR',
);

If the plugin is used on a site that does not use Sucuri’s hosted WAF, it is wide open to IP spoofing since the plugin blindly reads the IP address out of HTTP headers that an attacker can set to arbitrary values

If Sucuri’s hosted WAF is used, the entire protection against IP spoofing depends entirely on whether Sucuri’s WAF will drop any spoofed “X-Sucuri-Client-IP” headers at the WAF level.

Spoofing is impossible if the WAF drops a spoofed “X-Sucuri-Client-IP” header and replaces it with the connecting REMOTE_ADDR IP. (unless an attacker can directly connect to the target server)

We have not verified this but the documentation here does not give us the greatest confidence that this is handled correctly at the WAF level:

<?php

class Tools extends ToolsCore
{
    /**
    * Get the server variable REMOTE_ADDR, or the first ip of HTTP_X_FORWARDED_FOR (when using proxy)
    *
    * @return string $remote_addr ip of client
    */
    public static function getRemoteAddr()
    {
        // This condition is necessary when using CDN, don't remove it.
        if (isset($_SERVER['HTTP_X_SUCURI_CLIENTIP']) AND $_SERVER['HTTP_X_SUCURI_CLIENTIP'])
        {
            if (strpos($_SERVER['HTTP_X_SUCURI_CLIENTIP'], ','))
            {
                $ips = explode(',', $_SERVER['HTTP_X_SUCURI_CLIENTIP']);
                return $ips[0];
            }
            else
                return $_SERVER['HTTP_X_SUCURI_CLIENTIP'];
        }
        return $_SERVER['REMOTE_ADDR'];
    }
}

The above code from the documentation suggests that the “X-Sucuri-Client-IP” header might contain multiple IP addresses, which would make the plugin vulnerable to IP spoofing even if behind the remote WAF (again, not verified)

Proposed patch


The needed patch is described in great length in this article of us.

Summary: Only ever use REMOTE_ADDR to access to current IP.

Timeline


Vendor contactedSeptember 10, 2022
First Response
Fully patched at
Publicly disclosedApril 24, 2023

Miscellaneous


  • Sucuri has not responded to our POC despite sending it to a dedicated security@ email.
  • It is concerning that the vendor of a WAF does not implement IP detection correctly.

Leave a Reply

Your email address will not be published. Required fields are marked *