Cisco-encrypt.c

Aus alt.comp.hsr
Wechseln zu: Navigation, Suche

Das hier ist das Programm um das VPN-Passwort für vpnc zu verschlüsseln (http://altcomphsr.vshsr.ch/index.php?title=Vpnc):

/* 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);
}

Quelle: https://www.winhistory-forum.net/showthread.php?tid=3975 (Danke Gandro).