11.12.2010 yahe administration code legacy security windows
Letztens hatte ich euch erklärt, dass es möglich ist, die Passwörter zu entschlüsseln, die das Tool TightVNC in der Registry ablegt. Heute möchte ich euch gerne anhand eines Quelltextes zeigen, wie das gemacht werden kann. Den Ansporn dazu hat mir Hannes Schurig mit seinem neuen Artikel zu TightVNC gegeben. Darin beschreibt er, wie man TightVNC für die Fernwartung mehrerer Rechner nutzen kann, inklusive automatisierter Konfiguration und allem drum und dran.
Leider ist mir bei der ganzen Sache aufgefallen, dass das Problem der Passwortwiederherstellung viel zu stiefmütterlich behandelt wurde. Ja, es wurde gesagt, dass die Wiederherstellung möglich sei. Allerdings wurde auch darauf verwiesen, dass dies nur mit viel Können und Forscherdrang möglich sei. Um diese Aussage zu widerlegen, habe ich nun kurzerhand das Tool "tvncpass" geschrieben, mit dem man die Passwörter verschlüsseln und auch wieder entschlüsseln kann.
#include <stdio.h>
#include <string.h>
#include "VncPassCrypt.h"
const char* HEX_CHARS = "0123456789ABCDEF";
#define APP_NAME "tvncpass"
#define DECODE_PARAM "--decode"
#define ENCODE_PARAM "--encode"
void hexToDecimal(char* hexText, UINT8* decimalText, int decimalLength) {
int index;
if (decimalLength > 0) {
// reset output
memset(decimalText, 0, decimalLength);
if ((strlen(hexText) <= decimalLength * 2) && ((strlen(hexText) % 2) == 0)) {
// only proceed if string length is small enough
for (index = 0; index < strlen(hexText); index += 2) {
decimalText[index/2] = ((strchr(HEX_CHARS, hexText[index]) - HEX_CHARS) * strlen(HEX_CHARS)) + (strchr(HEX_CHARS, hexText[index+1]) - HEX_CHARS);
}
}
}
}
void printHelp() {
printf("Usage: %s (%s|%s) PASSWORD\n", APP_NAME, DECODE_PARAM, ENCODE_PARAM);
printf("\n");
printf("The password has to be provided in hexadecimal form.\n");
printf("In addition to that the password must not be longer\n");
printf("than 8 bytes and the hexadecimal representation must\n");
printf("be in all uppercase.\n");
}
void printHex(UINT8* decimalText, int decimalLength) {
for (int index = 0; index < decimalLength; index++) {
if (decimalText[index] < strlen(HEX_CHARS)) {
printf("0%X", decimalText[index]);
} else {
printf("%X", decimalText[index]);
}
}
printf("\n");
}
int main(int argc, char** argv) {
// define variables
int index;
UINT8 input[8];
bool isEncode;
UINT8 output[8];
char* password;
if (argc == 3) {
isEncode = (strcmp(argv[1], ENCODE_PARAM) == 0);
if (!isEncode) {
if (strcmp(argv[1], DECODE_PARAM) != 0) {
// exit if first param does not match
printHelp();
return 1;
}
}
// this is our password
password = argv[2];
if ((strlen(password) <= 16) && ((strlen(password) % 2) == 0)) {
// read password as decimal
hexToDecimal(password, input, sizeof(input)/sizeof(UINT8));
// encrypt or decrypt
if (isEncode) {
VncPassCrypt::getEncryptedPass(output, input);
} else {
VncPassCrypt::getPlainPass(output, input);
}
// print result as hex
printHex(output, sizeof(output)/sizeof(UINT8));
} else {
// the password must not be longer than 8 bytes
printHelp();
return 1;
}
} else {
// exit if wrong number of params
printHelp();
return 1;
}
return 0;
}
Da der Quelltext ziemlich quick-and-dirty geschrieben wurde, gibt es dieses Mal keine kompilierte Version des ganzen. Wenn ihr das Tool also selbst kompiliert haben solltet, könnt ihr es wie folgt aufrufen:
tvncpass (--decode|--encode) PASSWORD
Wenn ihr den "--decode" Modus nutzt, könnt ihr das Passwort entschlüsseln, wenn ihr den "--encode" Modus nutzt, könnt ihr es verschlüsseln. Das Passwort selbst muss dabei in Hexadezimalform und in Großbuchstaben übergeben werden und es darf nicht länger als 16 Zeichen lang sein. Um also z.B. das Passwort "test" zu verschlüsseln, muss es als "74657374" an das Programm übergeben werden:
tvncpass --encode 74657374
Um daraus nun wieder das ursprüngliche Passwort zu erhalten, müsst ihr das Ergebnis der ersten Operation an das Programm übergeben:
tvncpass --decode 2F981DC548E09EC2