/* * ShivaDecrypt: Shiva encrypted user password decryptor * * The Shiva encrypted user passwords are saved to the configuration along * with the key used to encrypt them (!). They are then encoded using base64 * with a shuffled translation table. * * This program decodes the pseudo-base64 string, extracts the key and * then uses it to decrypt the password. * * by Jfs / t0s * * ChangeLog: * * 11/7/2003 1.0 Initial release * 29/7/2003 1.1 Added functionality to decrypt passwords in configuration files (a la ciscocrack.c) */ #include #include char *base64="EoTy9dOCVWi1p7tfHJ2NjYKk8Usqrb5.ZAnP0zQu3RMh4XvcS*eLagGDwl6BFIxm"; void usage(char *progname) { fprintf(stderr, "ShivaDecrypt v1.1 - by Jfs / t0s\n"); fprintf(stderr, "usage:\t%s -p password\n", progname); fprintf(stderr, "\t%s \n", progname); exit(-1); } int decode(char c) { int i; for(i = 0; i < 64; i++) if(c == base64[i]) return i; return -1; } void decrypt(char *in, int in_len, char *out, int out_len, short k) { int i; int a[] = {153, 64, 23, 34, 218, 201, 10, 222, 8, 169, 164, 77, 157, 7, 106, 2, 71, 94, 84, 222, 236, 174, 251, 41, 246, 125, 141, 140, 102, 174, 186 }; int b[] = {210, 130, 222, 182, 41, 29, 223, 213, 197, 221, 172, 191, 149, 151, 234, 146, 245 }; for(i = 0; i < out_len; i++) out[i] = in[i % in_len] ^ a[(i + k) % 31] ^ b[i % 17]; } int decode_base64(char *in, int len, char *out) { int i = 0; int a, b, c, d; unsigned char n; for(; len > 1; len = strlen(in)) { a = decode(in[0]); if(a == -1) return -1; b = decode(in[1]); if(b == -1) return -1; n = (a << 2 | b >> 4); out[i] = n; i++; if(len == 2) break; c = decode(in[2]); if(c == -1) return -1; n = (b << 4 | c >> 2); out[i] = n; i++; if(len == 3) break; d = decode(in[3]); if(d == -1) return -1; n = (c << 6 | d); out[i] = n; i++; in += 4; } return i; } char *data_decrypt(unsigned char *in, int in_len, int out_len) { unsigned short key; unsigned char *tmp, *out; if(in_len < 2) { return NULL; } tmp = (char *) malloc(in_len - 2); out = (char *) malloc(out_len); memcpy(tmp, in + 2, in_len - 2); key = (in[0] << 8) + in[1]; decrypt(tmp, in_len - 2, out, out_len, key); return out; } char *decrypt_string(char *str) { int len; char *decoded; if(str && *str) { decoded = (char *)malloc(strlen(str)); memset(decoded, 0, strlen(str)); len = decode_base64(str, strlen(str), decoded); if(len >= 0) { return data_decrypt(decoded, len, 27); } else { return NULL; } } else { return (char *)strdup(""); } } int file_decrypt(char *in_filename, char *out_filename) { FILE *in, *out; char buf[1024]; char *start, *pwd, *slash, *decrypted_password; int line = 0; if((in = fopen(in_filename, "r")) == NULL) { fprintf(stderr, "Error opening input file \"%s\": %s\n", in_filename, strerror(errno)); return(-1); } if((out = fopen(out_filename, "w")) == NULL) { fprintf(stderr, "Error opening output file \"%s\": %s\n", out_filename, strerror(errno)); return(-1); } while(fgets(buf, 1024, in)) { line++; start = (char *) strstr(buf, "/pwd="); if(start) { pwd = start + 5; slash = (char *)strchr(pwd, '/'); if(slash) { *slash = 0; decrypted_password = decrypt_string(pwd); *slash = '/'; if(decrypted_password) { *start = 0; fprintf(out, "%s/ppwd=%s%s", buf, decrypted_password, slash); free(decrypted_password); continue; } else { printf("WARNING: Error decrypting password in line %d\n", line); } } } fprintf(out, "%s", buf); } fclose(in); fclose(out); } int main(int argc, char **argv) { char *encrypted, *decrypted; if(argc < 3) usage(argv[0]); if(!strcmp(argv[1], "-p")) { encrypted = (char *)strdup(argv[2]); decrypted = decrypt_string(encrypted); free(encrypted); if(decrypted) { printf("Decrypted password is: %s\n", decrypted); free(decrypted); } else { fprintf(stderr, "Invalid encrypted password\n"); } } else { file_decrypt(argv[1], argv[2]); } }