If you ever need to disguise a password in a VuGen script, you will no doubt have used the lr_decrypt() function. If you have stopped to think for a second or two, you will have realised “encrypting” the password in your script doesn’t make it more secure in any meaningful way. Anyone with access to the script can decode the password with a single line of code:
// As a security measure, LoadRunner password encryption is about as effective as rot13.
lr_output_message("The secret password is: %s", lr_decrypt("50de7ec44d2ff7033c2fcb9e5cf7307799d7"))
So, if this feature doesn’t really make anything more secure, why was it included in LoadRunner? This is a classic example of a “pre-sales feature” – during the sales process, you just know that a potential customer is going to have an attack of “due dilligence” and say that everyone knows that passwords should not be stored in plaintext and they couldn’t possibly buy the product because it is so insecure. As a pre-sales engineer, you can say “it’s okay, all the passwords in the script are encrypted”, and the barrier to sale suddently disappears.
Read on if you want to learn more about encoding passwords in LoadRunner…
Encoding Passwords
There are several ways that a password string can be encrypted/encoded:
- During recording, if the VuGen recording engine sees that you have made an HTTP POST request with a name/value pair called “password”, it will replace the password value with a call to lr_decrypt() when the script is generated.
- When editing your script in VuGen, you can right-click any string constant function argument and
- By using the Password Encoder, located under Start > Programs > HP > LoadRunner > Tools > Password Encoder
- There is also a command line version of the Password Encoder, that can be found under <install dir>LoadRunner\bin\PasswordEncoderConsole.exe. Note that the command line program can also be called from a LoadRunner script using popen() or invoked from a batch file if you need to encode a large number of passwords.
Decoding Passwords
An encoded password can be translated to plaintext in two ways:
- By calling lr_decrypt() and using the plaintext string that is returned by the function.
- Recently added to VuGen (with the release of LoadRunner 11.50), is the ability to right-click on a call to lr_decrypt() in your script and select “Restore Encrypted String” from the context menu.
Source Code Examples
If you want to have a play with with the LoadRunner encrypt/decrypt function directly (without using lr_decrypt()), you can do this by calling the vugen_crypt_encrypt() and vugen_crypt_decrypt() functions in VuGenCallback.dll.
// C example
Action()
{
char* plaintext = "my secret password";
char encryptedBuf[100];
char decryptedBuf[100];
lr_load_dll("C:\\Program Files\\HP\\LoadRunner\\bin\\VuGenCallback.dll");
lr_output_message("plaintext: %s", plaintext);
vugen_crypt_encrypt(plaintext, -1, encryptedBuf);
lr_output_message("encrypted: %s", encryptedBuf);
vugen_crypt_decrypt(encryptedBuf, decryptedBuf);
lr_output_message("decrypted 1: %s", decryptedBuf);
lr_output_message("decrypted 2: %s", lr_decrypt(encryptedBuf));
return 0;
}
// C# example. Use the .NET vuser type to run this code.
namespace Script
{
using System.Runtime.InteropServices; // DllImport
using System.Text; // StringBuilder
public partial class VuserClass
{
// Note: this program uses VuGenCallback.dll, which is also used by
// DecryptAddin (which gives the context menu encrypt/decrypt options in VuGen).
// The PasswordEncoderConsole.exe and PasswordEncoder.exe programs use
// PwdEncoder.dll instead.
// Note: do not add a reference to this DLL in the Runtime Settings, as it will
// give a compilation error (due to a missing manifest).
[DllImport(@"C:\Program Files\HP\LoadRunner\bin\VuGenCallback.dll")]
private extern static int vugen_crypt_encrypt(string currentString, int miLen, [MarshalAs(UnmanagedType.LPStr), In, Out] StringBuilder encodedString);
[DllImport(@"C:\Program Files\HP\LoadRunner\bin\VuGenCallback.dll")]
private extern static int vugen_crypt_decrypt(string encodedString, [MarshalAs(UnmanagedType.LPStr), In, Out] StringBuilder decodedString);
public int Action()
{
string plaintext = "my secret password";
var encrypted = new StringBuilder();
var decrypted = new StringBuilder();
lr.output_message("plaintext: " + plaintext);
VuserClass.vugen_crypt_encrypt(plaintext, -1, encrypted);
lr.output_message("encrypted: " + encrypted);
VuserClass.vugen_crypt_decrypt(encrypted.ToString(), decrypted);
lr.output_message("decrypted 1: " + decrypted.ToString());
lr.output_message("decrypted 2: " + lr.decrypt(encrypted.ToString()));
return 0;
}
}
}
Please leave a comment if you manage to crack the encoding scheme used for encryption/decryption.
4 Comments
Comments are closed.
Hints about the encoding method:
Where can i find VuGenCallback.dll.? I am not seing any such dll in my installation directory
lr_load_dll(“C:\\Program Files\\HP\\LoadRunner\\bin\\VuGenCallback.dll”);
Would probably be the hint here, What version of LoadRunner are you using?
It seems that the algorithm used at some point has changed. For LR 12.50, for instance, the ‘encryption’ (as noted by Stuart, this function does not meaningfully increase security) no longer includes a time component. The ‘encrypted’ string has the following format:
1) The first four bytes is the key
2) the remaining n – 4 bytes is the ‘encrypted’ string
It is fairly easy to recover the plaintext string. I have a ‘clean-room’ reimplementation of the lr_decrypt function written in Java, feel free to contact me if you need it and I will happily share (active performance testing engineers/consultants only, please!)