Total Commander Password Recovery

Bartosz Wójcik - Jul 18 '20 - - Dev Community

🖧 Recovering FTP passwords

Total Commander is a classic file manager for Windows, Windows CE, Windows Phone & now also Android.

It comes with a built-in FTP client and it keeps the FTP logins and encrypted passwords in wcx_ftp.ini configuration file.

🔍 Password encryption algorithm

I have used reverse engineering techniques and restored the password decoding algorithm years ago from the compiled executable file.

It was made available by me to another popular FlashFXP software (for free license key) to import FTP connection profiles from Total Commander (back then it was called Windows Commander).

<?php

////////////////////////////////////////////////////////////////////////////////
//
// Total Commander FTP Password Recovery Algorithm
//
// Bartosz Wójcik
// https://www.pelock.com
//
////////////////////////////////////////////////////////////////////////////////

class TotalCommanderPasswordDecoder
{
  private int $random_seed = 0;

  public static function hexstr2bytearray($str)
  {
    if (!is_string($str)) return false;

    $result = [];

    $len = strlen($str);

    if ($len == 0 || ($len & 1) != 0)
    {
      return false;
    }

    for ($i = 0; $i < $len; $i += 2)
    {
      $result[] = ( hexdec($str[$i]) << 4 ) | hexdec($str[$i + 1]);
    }

    return $result;
  }

  // initialize random generator with specified seed
  public function srand($seed)
  {
    $this->random_seed = $seed;
  }

  // generate pseudo-random number from the specified seed
  public function rand_max($nMax)
  {
    // cut numbers to 32 bit values (important)
    $this->random_seed = (( ($this->random_seed * 0x8088405) & 0xFFFFFFFF) + 1) & 0xFFFFFFFF;

    return ($this->random_seed * $nMax) >> 32;
  }

  // rotate bits left
  public static function rol8($var, $counter)
  {
    return (($var << $counter) | ($var >> (8 - $counter))) & 0xFF;
  }

  // decrypt Total Commander FTP password
  public function decryptPassword($password)
  {
    // convert hex string to array of integers
    $password_hex = static::hexstr2bytearray($password);

    // if the conversion failed - exit
    if (!$password_hex) return false;

    // number of converted bytes
    $password_length = count($password_hex);

    // length includes checksum at the end
    if ($password_length <= 4)
    {
      return false;
    }

    // minus checksum
    $password_length -= 4;

    $this->srand(849521);

    for ($i = 0; $i < $password_length; $i++)
    {
      $password_hex[ $i ] = static::rol8($password_hex[ $i ], $this->rand_max(8));
    }

    $this->srand(12345);

    for ($i = 0; $i < 256; $i++)
    {
      $x = $this->rand_max($password_length);
      $y = $this->rand_max($password_length);

      $c = $password_hex[ $x ];

      $password_hex[ $x ] = $password_hex[ $y ];
      $password_hex[ $y ] = $c;
    }

    $this->srand(42340);

    for($i = 0; $i < $password_length; $i++)
    {
      $password_hex[ $i ] ^= $this->rand_max(256);
    }

    $this->srand(54321);

    for ($i = 0; $i < $password_length; $i++)
    {
      $password_hex[ $i ] = ($password_hex[ $i ] - $this->rand_max(256)) & 0xFF;
    }

    // build final password
    $decoded_password = "";

    for($i = 0; $i < $password_length; $i++)
    {
      $decoded_password .= chr($password_hex[ $i ]);
    }

    return $decoded_password;
  }
}
Enter fullscreen mode Exit fullscreen mode

🔑 Password recovery tool

You can use the algorithm above to recover the passwords yourself, or you can use my ready to use online decoder:

💾 Total Commander Password Recovery Tool

📚 Reverse engineering resources

If you are interested in reverse engineering, you would like to know how to do things like recovering some algorithm from the compiled binary into high-level language format, I invite you to read my articles:

📰 Reverse Engineering Articles

. . . . . . . .
Terabox Video Player