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
- Static Salt in
mixed_sha1:
Themixed_sha1function is responsible for hashing sensitive values:
function mixed_sha1($value)
{
return sha1('random_salt_value_start'.$value.'random_salt_value_end');
}
- 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.
- Predictable Session Value:
The session value generated inupdate_auth_cookieuses the formulamixed_sha1(12345 * microtime()). This formula is inherently weak due to the reliance onmicrotime(), 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:
- Static Salt and Weak Hashing:
Since the salt inmixed_sha1was static, hashing values became predictable. The attacker could simulate the hashing process locally, reducing the complexity of verifying potential session values. - Microtime as the Basis for Session ID:
The use of12345 * 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. - 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