#include #include #include #include #define MAX_REC_LEN 1024 /** * permute.c * * Copyright (c) 2011, Geir Skjotskift, geir@underworld.no * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Permutes a list of passwords according to a pattern. * * build instructions: * * $ gcc -o permute -O3 -Wall -pedantic permute.c * ./permute pwd.txt pwd.out pattern.txt * * permmute pattern file contain a permute string on each line on the format * [char to permute (lowercase][chars to permute to] * * e3 * i!1 * * will permute all e's to 3 as well as e and * permute all i's to ! and 1 as well as i */ void permute_password_list(char*, char*); void scan(char*, int, char **, FILE*); void permute(char*, int, char *, FILE*); void handle_arguments(int, char **); void read_pattern_file(char *); char **perm_pattern; int main(int argc, char ** argv ) { handle_arguments( argc, argv ); read_pattern_file(argv[3]); permute_password_list(argv[1], argv[2]); return 0; } void handle_arguments(int argc, char **argv) { if (argc != 4) { printf("%s INFILE OUTFILE [PATTERNFILE]\n", argv[0]); exit(1); } } void read_pattern_file(char *PATTERNFILE) { int c; FILE *h_patternfile; char line[MAX_REC_LEN]; perm_pattern = malloc(sizeof(*perm_pattern) * MAX_REC_LEN); h_patternfile = fopen(PATTERNFILE, "r"); c = 0; while (fgets(line, MAX_REC_LEN, h_patternfile) != NULL && c < MAX_REC_LEN){ perm_pattern[c] = malloc(sizeof(char) * MAX_REC_LEN); if ( line[strlen(line)-1] == '\n') { line[strlen(line)-1] = '\0'; } strncpy( perm_pattern[c], line, MAX_REC_LEN); c++; } perm_pattern[c] = NULL; } void permute_password_list(char *INFILE, char *OUTFILE) { FILE *h_inputfile; FILE *h_outputfile; char line[MAX_REC_LEN]; int counter = 0; h_inputfile = fopen(INFILE, "r"); h_outputfile = fopen(OUTFILE, "w"); /* run through every password in the file and scan for characters to permute */ while (fgets(line, MAX_REC_LEN, h_inputfile) != NULL) { if ((char) *line == '#') continue; /* allow for comments in pwd list */ if (strlen(line) >= 10) continue; /* fail safe */ if (counter % 100 == 0) /* Write progress to screen */ printf("%i\n", counter); counter++; /* Progress counter */ /* Write every un-permuted password to the file */ fprintf(h_outputfile, "%s", line); line[strlen(line) - 1] = '\0'; /* Remove CRLF */ /* scan for characters to permute */ scan(line, 0, perm_pattern, h_outputfile ); } fclose(h_outputfile); fclose(h_inputfile); } void scan(char *line, int i, char **pattern, FILE *h_outputfile) { if (line[i] == '\0') return; for ( ; *pattern != NULL; pattern++) { /* check every pattern key against a lowercase representation of the current character */ if ((char) **pattern == tolower(line[i])) { /* try all permutes of this character */ permute(line, i, *pattern, h_outputfile); } } /* scan for the next occurence of a pattern key */ scan(line, i+1, perm_pattern, h_outputfile); } void permute(char *line, int i, char *permutes, FILE *h_outputfile) { /* -- begin house keeping */ char t = line[i]; char *tmp_p = permutes; ++permutes; /* step past the permutation key */ /* -- end house keeping */ /* run through every possible permute variation */ for ( ; *permutes != '\0'; permutes++ ) { line[i] = (char) *permutes; fprintf(h_outputfile, "%s\n", line); /* scan for more pattern keys in the remaining string */ scan(line, i+1, perm_pattern, h_outputfile); } /* house keeping */ line[i] = t; permutes = tmp_p; return; }