Just Like Riding a Pony: Session brute force vulnerability

How the Pony Stealer Botnet’s Weak Server-Side Security Enabled Exploitation

The Pony Stealer botnet, notorious for its ability to harvest credentials and sensitive data, had a flawed server-side authentication mechanism.

This post delves into a vulnerability I discovered in Pony Stealer’s authorization and authentication practices, highlighting implementation oversights, the role of session handling, and how these flaws facilitated a brute-force attack on sessions, ultimately leaving the system susceptible to exploitation and potential compromise.


The authenticate Function

The authenticate function handled user login authentication for the Pony Stealer server-side interface. Below is an analysis of the function’s key components:

function authenticate($login, $password)
{
    $login = trim($login);
    $password = trim($password);
    
    if (!$this->state || !strlen($login) || !strlen($password))
        return false;
        
    $password = mixed_sha1($password);
        
    $query = sprintf("SELECT user_id, privileges FROM pony_user WHERE (username='%s' AND password='%s') LIMIT 1",
        mysql_real_escape_string($login),
        mysql_real_escape_string($password));
                
    $result = mysql_query($query, $this->db_link);

    if (!$result)
    {
        $this->state = false;
    } else
    {
        if (mysql_num_rows($result) == 1)
        {
            $row = mysql_fetch_assoc($result);
            if ($row)
            {
                $this->user_id = $row['user_id'];
                $this->update_auth_cookie($row['user_id'], mixed_sha1(12345 * microtime()));
                $this->privileges = $row['privileges'];
                $this->login = $login;
                return true;
            }
        }
    }
    
    return false;
}


Weak Points in the Authentication Mechanism

  1. Static Salt in mixed_sha1:
    The mixed_sha1 function is responsible for hashing sensitive values:
function mixed_sha1($value)
{
    return sha1('random_salt_value_start'.$value.'random_salt_value_end');
}

  1. While salting is intended to add entropy to hashed values, the static nature of 'random_salt_value_start' and 'random_salt_value_end' means the salt does not change across different hashing operations. This introduces a significant weakness: an attacker can precompute hash values for common inputs, reducing the time needed for brute-forcing.
  1. Predictable Session Value:
    The session value generated in update_auth_cookie uses the formula mixed_sha1(12345 * microtime()). This formula is inherently weak due to the reliance on microtime(), which provides a timestamp with microsecond precision. With only about one million potential values in a given second, the search space for brute-forcing becomes feasible.

Exploiting the Vulnerability

The combination of these weaknesses allowed for a straightforward brute-force attack on session values:

  1. Static Salt and Weak Hashing:
    Since the salt in mixed_sha1 was static, hashing values became predictable. The attacker could simulate the hashing process locally, reducing the complexity of verifying potential session values.
  2. Microtime as the Basis for Session ID:
    The use of 12345 * microtime() provided a finite set of possible session values for a given time period. An attacker could generate all possible session values for the relevant timestamp window and compare them against intercepted or predictable session identifiers.
  3. Brute-Forcing Valid Sessions:
    By iterating through approximately one million possible session values, an attacker could find a valid session within an hour or less, depending on computational resources. Once a valid session was brute-forced, the attacker could gain access to the botnet’s command-and-control panel or user accounts.

Exploit code can be found here – https://github.com/k1p0d/pony_session_bf/blob/master/session_bf_exploit.py

Leave a comment