Friday, June 14, 2013

Password Algorithms: Bomgar Remote Desktop Software

Introduction

This will just be a short write up on something I looked at earlier today out of curiosity.
Bomgar is a Remote Desktop application used mainly by corporations.
I’m not entirely sure why it’s preferred over other Remote Desktop solutions; seecomparisons here.
One could speculate it’s due to support of multiple operating systems.
In addition to support for Windows and Linux, there’s also iOS, Android, Blackberry, Windows Mobile and Mac OS.
For large corporations and government agencies, Bomgar’s certainly a good choice.
Anyway, I’m not trying to endorse it, just discuss the password algorithm used to protect a technicians credentials.
Just in case there’s any misunderstanding, no corporations were harmed as a result of this research :P

Storage

I’ve installed the trial version on Windows 7 and saved my username and password provided by Bomgar through e-mail.
Depending on where you’ve installed your configuration, this next part may differ for you.
My configuration was stored under:
C:\Users\dietrich\AppData\Local\Bomgar\Representative\<portal domain>\bomgar.ini
I’ve removed the portal domain as it’s not important here.
Inside bomgar.ini there are 2 properties lUsername and lPassword which have 2 strings assigned to them.
The following are just dummy entries to illustrate.
lUsername="@-@-01VGhlcmUgaXMgbm90aGluZyBoZXJl"
lPassword="@-@-01cGFzc3dvcmQgaGVyZQ=="
Note that each entry is padded with random bytes and will be longer than dummy entries above.
The string prefix “@-@-01″ is just an identifier and isn’t important.
You can remove this and pass the string through base64 decoder which leaves you with ciphertext.
At this point, I had to dig into the representative console and anaylse what’s done with the binary once it’s decoded.

Recovery

The encryption/decryption process uses RC4 and a static key which is a little peculiar.
/* just a mishmash of strings */

uint8_t static_key[] = 
{ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
  0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
  0x01, 0x02, 0x03, 0x30, 0x31, 0x32, 0x33, 0x34,
  0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63,
  0x64, 0x65, 0x66, 0x04, 0x77, 0x30, 0x32, 0x6d,
  0x58, 0x30, 0x40, 0x2d, 0x78, 0x31, 0x01, 0x14,
  0x91, 0x0a, 0xd1, 0xb1, 0x52, 0x66, 0x32, 0x39,
  0x31, 0x32, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x2a,
  0x67, 0x65, 0x74, 0x6d, 0x65, 0x6d, 0x28, 0x69,
  0x6e, 0x74, 0x2c, 0x69, 0x6e, 0x74, 0x2c, 0x69,
  0x6e, 0x74, 0x29 };
The decryption/encryption is the same, using RC4
void bomgar_crypt(uint8_t ciphertext[], size_t len) {
  RC4_KEY key;
  uint8_t plaintext[32];
  
  memset(plaintext, 0, sizeof(plaintext));

  RC4_set_key(&key, sizeof(static_key), static_key);
  RC4(&key, len > 32 ? 32 : len, ciphertext, plaintext);

  for (int i = 0;i < 32;i++) {
    printf("%02x ", plaintext[i]);
  }
}
How to determine the exact length of username/password I leave up to you.
Just a note to the authors, I could recommend using CryptProtectData() on Windows and the Gnome-Keyring for Linux as they both provide more security than the existing algorithm.
The recovery demonstrated here isn’t very significant since the attacker needs Administrator privileges.
Enjoy Labor day! ;)

0 comments:

Post a Comment