Der eine oder andere hier hat es ja schon mitgekriegt, um mich an die ETHZ einwählen zu können, muss ich auf die VPN-Lösung von Cisco setzen.
Dessen Client kann die Passwörter in den Profilen verschleiert abspeichern - diese "Verschlüsselung" wurde, da sie ohne Benutzereingaben funktioniert, dementsprechend bereits 2005 geknackt. Die quelloffene, kompatible Alternative zum proprietären Cisco-Client - vpnc - kann daher bereits seit längerem solche verschleierten Passwörter auslesen.
heise online - 16.10.05 - Ciscos VPN-Client-Passwörter entschlüsselt
Cisco Password Enc. at EvilScientists
Online-Entschlüsselung:
cisco vpnclient password decoder
Aufruf:
$ ./cisco-encrypt "Geheimes Passwort"
48ECCEADBF730C100FB0488AF9D8B02B47C4669421E16B607A1D4E415F9703CBF272008D459B2EC02BC966C03653866158099E8806D76442EDA1DFFCA267B755
(diesen Code könnt ihr z.B. in obigem Online-Decoder wieder entschlüsseln).
Leider kann der quelloffene Client die Passwörter nur entschleiern, und nicht verschleiern. Natürlich bietet Verschleiern kaum Sicherheit, ist aber immer noch besser als direkt im Klartext abspeichern. Deswegen habe ich kurzerhand den Verschleierungsmechanismus von Cisco (welcher zwar bekannt ist, aber nicht in Codeform darliegt) in C nachprogrammiert, das Ergebnis seht ihr nun hier:
Quelltext:
Spoiler anzeigen
/* Password encoder for Cisco VPN client.
Copyright (C) 2009 Sebastian Wicki
Derivated from cisco-decrypt - Copyright (C) 2005 Maurice Massar
Thanks to HAL-9000@evilscientists.de for decoding and posting the algorithm!
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
Requires libgcrypt version 1.1.90 or newer
Compile with:
gcc -Wall -o cisco-encrypt cisco-encrypt.c $(libgcrypt-config --libs --cflags)
Usage:
./cisco-encrypt PASSWORD1 PASSWORD2 ...
*/
#include <stdio.h>
#include <stdlib.h>
#include <gcrypt.h>
#include <errno.h>
#include <time.h>
void printhex(unsigned char *buffer, int length) {
int i;
for(i=0; i<length; i++) {
printf("%02X", buffer[i]);
}
printf("\n");
}
int c_encrypt(const char *pw, int pwlen, char **resp, int *reslenp) {
char ht[20], h1[20], h2[20], h3[20], h4[20], key[24];
const char *iv = h1;
char *res, *enc, *tmp;
int i, enclen = (pwlen%8) ? ((pwlen/8)+1)*8 : pwlen;
gcry_cipher_hd_t ctx;
time_t rawtime;
time(&rawtime);
tmp = ctime(&rawtime);
/* h1 = SHA1 of ctime - bad source for entropy */
gcry_md_hash_buffer(GCRY_MD_SHA1, h1, tmp, strlen(tmp));
/* ht = temporary hash */
memcpy(ht, h1, 20);
/* h2 = SHA1 of modified h1*/
ht[19]++;
gcry_md_hash_buffer(GCRY_MD_SHA1, h2, ht, 20);
/* h3 = SHA1 of modified h2 */
ht[19] += 2;
gcry_md_hash_buffer(GCRY_MD_SHA1, h3, ht, 20);
/* key = h2 + (4 bytes of h3) */
memcpy(key, h2, 20);
memcpy(key+20, h3, 4);
/* allocate buffer for in-place encryption */
enc = malloc(enclen);
if(enc == NULL) {
return -1;
}
memcpy(enc, pw, pwlen);
/* padding */
for(i=pwlen; i<enclen; i++) {
enc[i] = enclen - pwlen;
}
/* encrypt password with 3DES with iv = 8 bytes of h1, key = see above */
gcry_cipher_open(&ctx, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, 0);
gcry_cipher_setkey(ctx, key, 24);
gcry_cipher_setiv(ctx, iv, 8);
gcry_cipher_encrypt(ctx, (unsigned char *)enc, enclen, NULL, 0);
gcry_cipher_close(ctx);
/* h4 = SHA1 of encrypted password */
gcry_md_hash_buffer(GCRY_MD_SHA1, h4, enc, enclen);
/* hash length */
*reslenp = enclen+40;
res = malloc(*reslenp);
/* hash = h1 | h4 | encrypted password */
memcpy(res, h1, 20);
memcpy(res+20, h4, 20);
memcpy(res+40, enc, enclen);
*resp = res;
free(enc);
return 0;
}
int main(int argc, char *argv[]) {
int i, ret = 0, pwlen, hashlen;
char *hash;
gcry_check_version(NULL);
for (i = 1; i < argc; i++) {
pwlen = strlen(argv[i])+1;
ret = c_encrypt(argv[i], pwlen, &hash, &hashlen);
if(ret != 0) {
perror("encodig failed");
continue;
}
printhex((unsigned char *)hash, hashlen);
free(hash);
}
exit(ret != 0);
}
Alles anzeigen
Quelltext-Download:
cisco-encrypt.c (3,58 KB)
Anweisung zum Kompilieren steht im Quelltext, benötigt wird die libgcrypt (und deren Header, also auch libgcrypt-dev) für SHA1 und 3DES. Das ganze steht unter der GPL, weil ich mich ja am Entschlüsselungs-Programm orientieren musste und das unter der GPL steht.