View Issue Details Jump to Notes ] Related Changesets ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0005654ATutoratutor.capublic2016-03-18 17:432016-06-30 17:43
Assigned Tomr_me 
Platform*nixOSDebianOS Version8
Product Version2.2.1 
Target Version2.2.1Fixed in Version2.2.2 
Summary0005654: Failed logic password_reminder.php Remote Password Reset vulnerability
DescriptionThere a failed logic flaw in the ‘password_reminder.php’ script that we can leverage for a remote password reset without requiring any kind of authentication or interaction via email. This is fatal mistake.

} else if (isset($_REQUEST['id']) && isset($_REQUEST['g']) && isset($_REQUEST['h'])) {
//coming from an email link
      //check if expired
        $current = intval(((time()/60)/60)/24);
        $expiry_date = $_REQUEST['g'] + AT_PASSWORD_REMINDER_EXPIRY; //2 days after creation
        if ($current > $expiry_date) {
    /* check if already visited (possibley add a "last login" field to members table)... if password was changed, won't work anyway. do later. */
    //check for valid hash
      $sql = "SELECT password, email FROM %smembers WHERE member_id=%d";
      $row = queryDB($sql, array(TABLE_PREFIX, $_REQUEST['id']), TRUE);
      if (isset($row['email']) && $row['email'] != '') {
          $email = $row['email'];
          $hash = sha1($_REQUEST['id'] + $_REQUEST['g'] + $row['password']);
          $hash_bit = substr($hash, 5, 15);
          if ($_REQUEST['h'] != $hash_bit) {

Although this vulnerability is very hard to see, we start out by setting the ‘id’, ‘g’ and ‘h’ REQUEST. The ‘g’ variable is used to calculate the ‘expiry_date’ variable and needs to ensure that the value is greater than the number of days since epoch (1/1/1970).

Then later in the code, the our controlled ‘h’ REQUEST variable is compared against a computed string. If it fails, the ‘INVALID_LINK’ error is appended to our session array using $msg->addError('INVALID_LINK');. The problem arises on the next line of code. The call to $savant->display('password_reminder_feedback.tmpl.php'); actually includes that PHP file (and subsequently several other PHP files). Eventually, one of the files calls session_start() and rewrite’s our session to not contain our error in it. This essentially erases the error that the previous line appended!

Why is this important? Let’s see in the next few lines of code.

    //changing the password
    if (isset($_POST['form_change'])) {
        /* password check: password is verified front end by javascript. here is to handle the errors from javascript */
        if ($_POST['password_error'] <> ""){
            $pwd_errors = explode(",", $_POST['password_error']);
                foreach ($pwd_errors as $pwd_error){
                if ($pwd_error == "missing_password")
                    $missing_fields[] = _AT('password');

        if (!$msg->containsErrors()) {
            //save data
            $password = $addslashes($_POST['form_password_hidden']);

            $sql = "UPDATE %smembers SET password='%s', last_login=last_login, creation_date=creation_date WHERE member_id=%d";
            $result = queryDB($sql,array(TABLE_PREFIX, $password, $_REQUEST['id']));

The code continues (even if we hit that error) then checks for the presence of the POST variable ‘form_change’. We need to sure that we do not include the POST variable “password_error” (generated from client side JavaScript) otherwise we will append errors to our session array. Then finally, a check is done on our session array if (!$msg->containsErrors()) then the code proceeds to update the members table with the supplied POST variable ‘form_password_hidden’


Please just remove the line here:


Steps To ReproducePOST /ATutor/password_reminder.php HTTP/1.1
Host: [target]
Content-Type: application/x-www-form-urlencoded
Connection: close
Content-Length: 77


1. You do not need a valid session to change the first members password
2. I have integrated this issue into a fully functional working exploit. Please patch this asap. Its critical
TagsNo tags attached.
Affects versionSVN
SVN Revision#5ba3481f300d58535405dd02b640f2c1bc33dc1c
Attached Filespng file icon poc-auth-bypass.png [^] (249,353 bytes) 2016-03-18 17:43

- Relationships

-  Notes
greg (administrator)
2016-03-19 15:24

removed unneeded password reminder feedback
greg (administrator)
2016-06-30 17:43

Close for 2.2.2

- Related Changesets
ATutor: master 5ba3481f
Timestamp: 2016-03-19 15:21:46
Author: greg
Details ] Diff ]
Merge pull request 0000108 from net-ninja/patch-1

5654 Update password_reminder.php, removed unneeded, thx net-ninja
mod - password_reminder.php Diff ] File ]

- Issue History
Date Modified Username Field Change
2016-03-18 17:43 mr_me New Issue
2016-03-18 17:43 mr_me Status new => assigned
2016-03-18 17:43 mr_me Assigned To => greg
2016-03-18 17:43 mr_me File Added: poc-auth-bypass.png
2016-03-19 15:24 greg SVN Revision# => 5ba3481f300d58535405dd02b640f2c1bc33dc1c
2016-03-19 15:24 greg Note Added: 0007356
2016-03-19 15:24 greg Status assigned => resolved
2016-03-19 15:24 greg Fixed in Version => 2.2.2
2016-03-19 15:24 greg Resolution open => fixed
2016-03-19 15:24 greg Assigned To greg => mr_me
2016-04-16 16:15 greg Changeset attached => ATutor master 5ba3481f
2016-06-30 17:43 greg Note Added: 0007446
2016-06-30 17:43 greg Status resolved => closed

Copyright © 2000 - 2018 MantisBT Team
Powered by Mantis Bugtracker