PT-2012-29: Administrator Privilege Gaining in Simple Machines Forum
Simple Machines Forum
Version: 2.0.3; 1.1.17 and earlier
Severity level: High
Impact: Administrator Privilege Gaining
Access Vector: Remote
Base Score: 10
CVE: not assigned
Simple Machines Forum — SMF in short — is a free, professional grade software package that allows you to set up your own online community within minutes.
Positive Research Center experts have detected "Administrator Privilege Gaining" vulnerability in Simple Machines Forum.
The vulnerability exists in password recovery feature and allows attackers to get administrator password via certain requests.
Vulnerability in file: Sources/Reminder.php:
if (empty($_POST['code']) || substr($realCode, 0, 10) != substr(md5($_POST['code']), 0, 10))
In case password recovery is requested, the user receives a code with 10 characters from 0-9 and a-f sets via email. This code allows users to change their passwords, and users are able to set a new password via a special form.
You can see that the code shown above incorrectly compares the password recovery code stored in the database with the code typed by user. The point is that PHP transforms every string into a number, and then compares the numbers in case "==" operator is used to compare a number with a string or to compare two strings.
Therefore, the string like 0e12345678 (e is the exponent) is equal to 0, and 1e12345678 is equal to 1. An attacker is able to send password recovery requests one by one, until the code stored in the database becomes like 0e or 1e followed by any numbers. Our research shows that generally about 5,000 password recovery requests and 10,000 code checks are needed that takes no more than an hour.
Starting version 2.0 Beta 4, Simple Machines Forum includes a code that makes this attack difficult to implement: the request frequency is limited. But, this measure is not really effective, as it takes just a couple of hours to send enough requests to bruteforce the code format. Also, this code includes an error:
if (empty($number_tries) || $time_stamp < (time() - 10))
// If it wasn't *that* long ago, don't give them another five goes.
$number_tries = !empty($number_tries) && $time_stamp < (time() - 20) ? 2 : 0;
$time_stamp = time();
If an attacker requests password recovery in the interval between 10 and 20 seconds starting the moment number_tries variable exceeds the maximum value (5), then number_tries is set to 0 instead of the expected value (2), that allows an attacker to send additional requests.
How to fix
Update your software up to the latest version.
23.08.2012 - Vendor is notified
23.08.2012 - Vendor gets vulnerability details
01.02.2013 - Vendor releases fixed version and details
15.02.2013 - Public disclosure
The vulnerability has discovered by Arseny Reutov, Positive Research Center (Positive Technologies Company)
Reports on the vulnerabilities previously discovered by Positive Research: