FloydATC has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to recover a lost master password for VMware Virtual Center Single Sign-On service. The encoded hash has been recovered from the database and looks like this:

{SSHA256}KGOnPYya2qwhF9w4xK157EZZ/RqIxParohltZWU7h2T/VGjNRA==

Note that this is not the actual string, this is for a known password which can be found in several places on the net: "VMware1234!".

(I have already tried the unsupported pass-the-hash method for password recovery as described in several places and it didn't work. I don't know why.)

Since this string doesn't actually look like a SSHA256 hash, I'm wondering of anyone has a clue how to decode this string into an actual SSHA256 hash that I might run through a hash lookup service?

Applying MIME::Base64 was my first thought, this produces a binary string which is unfortunately a little too long to be the SSHA256 hash. Encryption really isn't my strong suit so I'm at a loss here... Any ideas would be greatly appreciated.

Alternatively, if I knew how to decode/encode this string to a real SHA256 hash I might even try to put together a script to bruteforce it, because I have lots of time and CPU resources to throw at this problem and I'm pretty sure I know part of the password I'm looking for. In short, how do I produce the hash string shown above from the password "VMware1234!"?

I hope you'll trust me when I say that this is completely white-hat; our VMware vCenter was installed two years ago by a consultant who forgot to write down the SSO Master password at the time and this is preventing us from updating that installation to a current version without a full reinstall.

Cracking it would be much cheaper. And so much more fun.

-- FloydATC

Time flies when you don't know what you're doing

Replies are listed 'Best First'.
Re: How to encode/decode an SSHA256 hash?
by oiskuu (Hermit) on Nov 19, 2014 at 22:55 UTC

    Crunch on $salt.$password:

    #! /usr/bin/perl use Digest::SHA 'sha256'; use MIME::Base64; use Data::Dumper; $Data::Dumper::Useqq = 1; my ($hash, $salt) = unpack("a32 a*", decode_base64("KGOnPYya2qwhF9w4xK +157EZZ/RqIxParohltZWU7h2T/VGjNRA==")); print Dumper {SALT => $salt, DIGEST => $hash}; my $guess = "VMware1234!"; print Dumper {SALT => $salt, DIGEST => sha256($salt . $guess), TEST => + $guess};

      This is EXACTLY what I was looking for, thank you so much!!

      Because I'm 99% sure I know the last few characters, my bruteforcer now looks like this:

      #!/usr/bin/perl use Digest::SHA 'sha256'; use MIME::Base64; use Data::Dumper; $Data::Dumper::Useqq = 1; #my $target = "KGOnPYya2qwhF9w4xK157EZZ/RqIxParohltZWU7h2T/VGjNRA=="; +# VMware1234! my $target = "(my actual hash goes here)"; # Unknown my ($hash, $salt) = unpack("a32 a*", decode_base64($target)); my $chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTU +VWXYZ.,-_|!#%=+?'*"; my $base = length($chars); my $guess = ""; my $known = "(the known part of the password goes here)"; my $count = -1; while (1) { my $digest = sha256($salt . $guess . $known); if ($digest eq $hash) { print "Password: '$guess$known'\n"; exit; } $count++; my $temp = $count; $guess = ""; while ($temp) { $guess = substr($chars, ($temp % $base), 1) . $guess; $temp = int($temp / $base); } print "Searching for $target: ($count) '$guess$known'\n" unless $cou +nt % 1000000; }
      -- FloydATC

      Time flies when you don't know what you're doing

Re: How to encode/decode an SSHA256 hash?
by NetWallah (Canon) on Nov 19, 2014 at 04:35 UTC
    This is too obvious/easy to be the correct - but - have you tried to replace the hash in the database with the hash of a KNOWN password ?

            "You're only given one little spark of madness. You mustn't lose it."         - Robin Williams

      Yes, this is known as a "pass-the-hash" attack and described in a few places as an unsupported way to recover from a lost SSO Master password. As I mentioned, I have tried this and it didn't work. I'm not sure why.

      Part of the reason may be that I don't fully understand the actual relationship between the SSO Master password and the "admin@System-Domain" password. From what I understand, you initiallly set the admin password and it is used as a Master password as well. For all I know, the admin account may later have been disabled or broken somehow. If I could recover the password somehow, I'm hoping I'd be able to use it as Master password to perform the upgrade and reset the admin account.

      This mechanism was unique to vCenter 5.1, it was fixed in version 5.5

      -- FloydATC

      Time flies when you don't know what you're doing

Re: How to encode/decode an SSHA256 hash?
by Mr. Muskrat (Canon) on Nov 19, 2014 at 20:12 UTC

    I agree that it does not appear to be a valid SSHA256 hash but it would help if we knew the salt. Here's what I came up with after some searching.

    #!/bin/env perl use strict; use warnings; use MIME::Base64; use Digest::SHA qw( sha256 ); # Only the first one can be validated... my @passwords = ( { encoded => 'M8Nbe/nfLJeVbV3XdvaLD44uxK77eAhJWEx1tIDLBCFteV +9zYWx0Xw==', password => 'P@ssw0rd!', salt => 'my_salt_', }, { encoded => 'B6HO7UNHVi5fglh1RpJXX4z1maGJ9lcicTVcy94ztsmzAe +kseg==', password => 'Passw0rd!', }, { encoded => 'KGOnPYya2qwhF9w4xK157EZZ/RqIxParohltZWU7h2T/VG +jNRA==', password => 'VMware1234!', } ); for my $pass ( @passwords ) { print "encoded: $pass->{encoded}\n"; my $decoded = MIME::Base64::decode_base64( $pass->{encoded} ); print "decoded: $decoded\n"; # Find digest and salt my @salt = unpack( 'C*', $decoded ); my @pass; push @pass, shift @salt for ( 1 .. 32 ); # shift the password off +leaving just the salt behind my $pw = pack( 'C32', @pass ); my $salt = pack( 'C*', @salt ); print "password digest: $pw\n"; print "salt: $salt\n"; print " salt matches what is stored\n" if ( defined $pass->{sa +lt} && $salt eq $pass->{salt} ); # Create a new password digest my $digest = sha256( $pass->{password} . $salt ); print "digest: $digest\n"; my $reencoded = MIME::Base64::encode_base64( $digest . $salt ); chomp $reencoded; print "reencoded (SSHA256): $reencoded\n"; print " reencoded matches the original encoded value!\n" if ( +$reencoded eq $pass->{encoded} ); print "\n\n"; }

      This looks very much like what I was trying, except I couldn't get a match on the salt because I fumbled the length AND looked at the wrong end of the string...

      Fortunately, oiskuu seems to have nailed it, thank you both :-)

      -- FloydATC

      Time flies when you don't know what you're doing