#define _GNU_SOURCE
#include
#include
#include
#include
#include
#include
struct opts
{
char *fname;
char *challenge;
char *response;
char *charset;
char *name;
int id;
int verbose;
int minlen;
int maxlen;
} options = {0, 0, 0, 0, 0, 0, 0, 0, 8};
static void usage(const char* app)
{
printf("pppoe chap password cracker(MD5 only,no MS-CHAPV2 support!) build %s %s\n\n", __TIME__, __DATE__);
printf("usage: %s -c -r -i -u [options]\n", app);
printf("\toptions:\n");
printf("\t\t-f prefix string file name\n");
printf("\t\t-M password max length, default 8\n");
printf("\t\t-m password min length, default 0\n");
printf("\t\t-C password char set, default \"0123456789\"\n");
printf("\t\t-v verbose\n");
exit(1);
}
static void process_opts(int argc, char *argv[])
{
int ch;
while ((ch = getopt(argc, argv, "c:r:i:u:M:m:C:vf:")) != -1)
switch (ch)
{
case 'c':
options.challenge = strdup(optarg);
break;
case 'r':
options.response = strdup(optarg);
break;
case 'i':
options.id = strtol(optarg, 0, 16);
break;
case 'u':
options.name = strdup(optarg);
break;
case 'M':
options.maxlen = atoi(optarg);
break;
case 'm':
options.minlen = atoi(optarg);
break;
case 'C':
options.charset = strdup(optarg);
break;
case 'v':
options.verbose = 1;
break;
case 'f':
options.fname = strdup(optarg);
break;
default:
usage(argv[0]);
}
if((options.challenge==0) || (options.response == 0) || (options.name == 0))
usage(argv[0]);
if(!options.charset)
options.charset = strdup("0123456789");
}
#include "new_dic.h"
static char conv_ch(char ch)
{
if (ch <= '9' && ch >= '0')
ch -= '0';
else if (ch >= 'a' && ch <='f')
ch -= 'a' - 10;
else if (ch >= 'A' && ch <='F')
ch -= 'A' - 10;
return ch;
}
static int tobitstream(const char *input, unsigned char *val)
{
int i;
for(i=0; i
val[i]=(conv_ch(input[2*i])<<4)|conv_ch(input[2*i+1]);
return strlen(input)/2;
}
typedef int (*crack_func)(int id, char *name, unsigned char *secret, int secret_len, unsigned char *challenge, unsigned char *response);
static inline int readline(char s[], int lim, FILE *fp)
{
int c = EOF;
int i;
for(i=0; i
s[i] = c;
s[i] = '\0';
return ((c==EOF)? EOF : i);
}
#include
long gettickcount()
{
struct timespec current;
clock_gettime(CLOCK_MONOTONIC, ¤t);
return (current.tv_sec*1000+current.tv_nsec/1000000);
}
static int crack(struct opts *opt, crack_func func)
{
int retval = EXIT_FAILURE;
FILE *pfile = NULL;;
if(opt->fname)
if((pfile = fopen(opt->fname, "r")) == NULL)
{
if(opt->verbose)
printf("open file error: %s\n", strerror(errno));
}
unsigned char challenge[1024];
unsigned char response[1024];
challenge[0] = (char)tobitstream(opt->challenge, challenge+1);
response[0] = tobitstream(opt->response, response+1);
dic_t dic;
if(EXIT_SUCCESS != init_dic(&dic, opt->minlen, opt->maxlen, opt->charset))
{
retval = EXIT_FAILURE;
goto L_E00;
}
char secret[512];
char hiword[256] = {0,};
char loword[256];
int read;
if(pfile)
read = readline(hiword, 256, pfile);
else
read = EOF;
u_int64_t val = 0;
u_int64_t *count = &val;
pid_t pid = getpid();
long t1, t0 = gettickcount();
do
{
while(EXIT_SUCCESS == getseq(&dic, loword, count))
{
strcpy(secret, hiword);
strcat(secret, loword);
if((*(func))(opt->id, opt->name, (unsigned char*)secret, strlen(secret), challenge, response))
{
printf("\"%s\" * \"%s\" *\n", opt->name, secret);
retval = EXIT_SUCCESS;
goto L_E00;
}
if(*count > 5000000)
{
t1 = t0;
t0 = gettickcount();
printf("%d : speed = %jd\n", pid, ((*count) * 1000)/((t0 - t1) ? (t0 - t1) : 1));
fflush(stdout);
*count = 0;
}
}
if(pfile)
read = readline(hiword, 256, pfile);
else
read = EOF;
}while(read != EOF);
L_E00:
free_dic(&dic);
if(pfile)
fclose(pfile);
return retval;
}
extern int chap_md5_verify_response(int id, char *name, unsigned char *secret, int secret_len, unsigned char *challenge, unsigned char *response);
int main(int argc, char *argv[])
{
process_opts(argc, argv);
if(options.verbose)
{
printf("challenage: %s\n", options.challenge);
printf("response: %s\n", options.response);
printf("id: %02x\n", options.id);
printf("name: %s\n", options.name);
printf("max: %d\n", options.maxlen);
printf("min: %d\n", options.minlen);
printf("charset: %s\n", options.charset);
printf("prefix file: %s\n", options.fname ? options.fname : "N/A");
}
int retval = EXIT_FAILURE;
crack_func func = chap_md5_verify_response;
retval = crack(&options, func);
free(options.charset);
free(options.challenge);
free(options.response);
free(options.name);
if(options.fname)
free(options.fname);
return retval;
}