home *** CD-ROM | disk | FTP | other *** search
- /* PGPCrack v0.6b
- * by Mark Miller <markm@voicenet.com>
- * A program that can crack PGP conventionally encrypted files.
- * Copyright (c) Mark Miller 1996
- * Feel free to distribute and modify this program. Just please keep this
- * comment block on the code and make note of the modification.
- */
-
- #include <stdio.h>
- #include <string.h>
- #include "md5.h"
- #include "idea.h"
-
- void chop(char *buf);
- void hash(char *buf, char md5hash[16]);
- int ctb_check(char c);
- int ideacrack(char buf1[10], char buf2[8], char key[16]);
-
- main(int argc, char *argv[])
- {
- FILE *phrases;
- FILE *ideafile;
- FILE *log;
- char md5hash[16];
- char data[256];
- char buf1[10];
- char buf2[8];
- char ctb;
- int ctb_return;
- if(argc < 3) {
- fprintf(stderr, "Usage: %s [phraselist] [pgpfile] <logfile>\n", argv[0]);
- exit(1);
- }
- /* Open passphrase list */
- if((phrases=fopen(argv[1], "r"))==NULL) {
- fprintf(stderr, "%s: Cannot open %s\n", argv[0], argv[1]);
- fclose(phrases);
- exit(2);
- }
- if((ideafile=fopen(argv[2], "r"))==NULL) {
- fprintf(stderr, "%s: Cannot open %s\n", argv[0], argv[2]);
- fclose(ideafile);
- exit(3);
- }
- fread(&ctb, 1, 1, ideafile);
- ctb_return = ctb_check(ctb);
- switch(ctb_return)
- {
- case(1) : { fprintf(stderr, "%s: %s is a secret key\n", argv[0], argv[2]);
- exit(4); }
- case(-2) : { fprintf(stderr, "%s: %s is not a PGP file\n", argv[0], argv[2]);
- exit(5); }
- case(2) : { fprintf(stderr, "%s: %s is not conventionally encrypted\n", argv[0], argv[2]);
- exit(6); }
- case(-1) : { fprintf(stderr, "%s: %s appears to be ascii-armored\n", argv[0], argv[2]);
- exit(5); }
- default : { break; }
- }
- /* Open a file to which to write the cracked passphrase. If none is specified,
- * use stderr.
- */
- if(argv[3]) {
- if((log=fopen(argv[3], "w"))==NULL) {
- fprintf(stderr, "%s: Cannot open logfile %s. Using stderr.\n", argv[0], argv[3]);
- log=stderr;
- }
- } else {
- log=stderr;
- }
- fseek(ideafile, 5, SEEK_SET);
- fread(buf1, 1, 10, ideafile);
- fread(buf2, 1, 8, ideafile);
- fclose(ideafile);
- while((fgets(data, 256, phrases))!=NULL) {
- chop(data);
- hash(data, md5hash);
- if(ideacrack(buf1, buf2, md5hash)==0) {
- fprintf(log, "PGPCrack passphrase: %s\n", data);
- /* break; */
- }
- }
- fclose(phrases);
- exit(0);
- }
-
- /* This function is roughly equivalent to the chop() function in Perl. This
- * chops off the last byte of the character array and if the second to last
- * byte contains a '\r' character (0x0d), then that byte is also deleted.
- * Passphrase lists can now be in DOS text format also.
- */
-
- void chop(char *buf)
- {
- int i;
- i = strlen(buf);
- buf[i-1] = 0;
- if(buf[i-2] == 13)
- buf[i-2] = 0;
- }
-
- void hash(char *buf, char md5hash[16])
- {
- MD5_CTX md5;
- MD5Init(&md5);
- MD5Update(&md5, buf, strlen(buf));
- MD5Final(md5hash, &md5);
- }
-
- /* Check to make sure that byte is a valid CTB. */
- int ctb_check(char c)
- {
- int i;
- i = (int)c;
- if(i & 0x80) {
- if((i & 0x24)==36)
- return 0;
- else if((i & 0x14)==20)
- return 1;
- else
- return 2;
- }
- if(i == 0x2d)
- return -1;
- return -2;
- }
-
- int ideacrack(char buf1[10], char buf2[8], char key[16])
- {
- struct IdeaCfbContext ctx;
- char plainbuf1[10];
- char plainbuf2[8];
- ideaCfbInit(&ctx, key);
- ideaCfbDecrypt(&ctx, buf1, plainbuf1, 10);
- if((plainbuf1[6] == plainbuf1[8]) && (plainbuf1[7] == plainbuf1[9])) {
- ideaCfbSync(&ctx);
- ideaCfbDecrypt(&ctx, buf2, plainbuf2, 8);
- if(ctb_check(plainbuf2[0]) < 0)
- return 1;
- return 0;
- }
- return 1;
- }
-