Advertisement
paulogp

Decoder for password encoding of Cisco VPN client

Jul 13th, 2011
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.47 KB | None | 0 0
  1. /* 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.
  2.  
  3. 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.
  4.  
  5. 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*/
  6.  
  7.  
  8. /* Requires libgcrypt version 1.1.90 or newer
  9. Compile with: gcc -Wall -o cisco-decrypt cisco-decrypt.c $(libgcrypt-config --libs --cflags)
  10. Usage: ./cisco-decrypt DEADBEEF...012345678 424242...7261 */
  11.  
  12.  
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <gcrypt.h>
  16. #include <errno.h>
  17.  
  18. int hex2bin_c(unsigned int c) {
  19.     if ((c >= '0') && (c <= '9'))
  20.         return c - '0';
  21.     if ((c >= 'A') && (c <= 'F'))
  22.         return c - 'A' + 10;
  23.     if ((c >= 'a') && (c <= 'f'))
  24.         return c - 'a' + 10;
  25.     return -1;
  26. }
  27.  
  28.  
  29. int hex2bin(const char *str, char **bin, int *len) {
  30.     char *p;
  31.     int i, l;
  32.  
  33.     if (!bin)
  34.         return EINVAL;
  35.  
  36.     for (i = 0; str[i] != '\0'; i++)
  37.         if (hex2bin_c(str[i]) == -1)
  38.             return EINVAL;
  39.  
  40.     l = i;
  41.     if ((l & 1) != 0)
  42.         return EINVAL;
  43.     l /= 2;
  44.  
  45.     p = malloc(l);
  46.     if (p == NULL)
  47.         return ENOMEM;
  48.  
  49.     for (i = 0; i < l; i++)
  50.         p[i] = hex2bin_c(str[i*2]) << 4 | hex2bin_c(str[i*2+1]);
  51.  
  52.     *bin = p;
  53.     if (len)
  54.         *len = l;
  55.  
  56.     return 0;
  57. }
  58.  
  59.  
  60. int c_decrypt(char *ct, int len, char **resp, char *reslenp) {
  61.     const char *h1  = ct;
  62.     const char *h4  = ct + 20;
  63.     const char *enc = ct + 40;
  64.  
  65.     char ht[20], h2[20], h3[20], key[24];
  66.     const char *iv = h1;
  67.     char *res;
  68.     gcry_cipher_hd_t ctx;
  69.     int reslen;
  70.  
  71.     if (len < 48)
  72.         return 0;
  73.     len -= 40;
  74.  
  75.     memcpy(ht, h1, 20);
  76.  
  77.     ht[19]++;
  78.     gcry_md_hash_buffer(GCRY_MD_SHA1, h2, ht, 20);
  79.  
  80.     ht[19] += 2;
  81.     gcry_md_hash_buffer(GCRY_MD_SHA1, h3, ht, 20);
  82.  
  83.     memcpy(key, h2, 20);
  84.     memcpy(key+20, h3, 4);
  85.     /* who cares about parity anyway? */
  86.  
  87.     gcry_md_hash_buffer(GCRY_MD_SHA1, ht, enc, len);
  88.  
  89.     if (memcmp(h4, ht, 20) != 0)
  90.         return -1;
  91.  
  92.     res = malloc(len);
  93.     if (res == NULL)
  94.         return -1;
  95.  
  96.     gcry_cipher_open(&ctx, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, 0);
  97.     gcry_cipher_setkey(ctx, key, 24);
  98.     gcry_cipher_setiv(ctx, iv, 8);
  99.     gcry_cipher_decrypt(ctx, (unsigned char *)res, len, (unsigned char *)enc, len);
  100.     gcry_cipher_close(ctx);
  101.  
  102.     reslen = len - res[len-1];
  103.     res[reslen] = '\0';
  104.  
  105.     if (resp)
  106.         *resp = res;
  107.     if (reslenp)
  108.         *reslenp = reslen;
  109.     return 0;
  110. }
  111.  
  112.  
  113. int main(int argc, char *argv[]) {
  114.     int i, len, ret = 0;
  115.     char *bin, *pw;
  116.  
  117.     gcry_check_version(NULL);
  118.  
  119.     for (i = 1; i < argc; i++) {
  120.         ret = hex2bin(argv[i], &bin, &len);
  121.         if (ret != 0) {
  122.             perror("decoding input");
  123.             continue;
  124.         }
  125.  
  126.         ret = c_decrypt(bin, len, &pw, NULL);
  127.         free(bin);
  128.         if (ret != 0) {
  129.             perror("decrypting input");
  130.             continue;
  131.         }
  132.  
  133.         printf("%s\n", pw);
  134.         free(pw);
  135.     }
  136.  
  137.     exit(ret != 0);
  138. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement