void GetTableList( std::string wildCharPathName, std::vector<std::string>& pathNames ) { struct stat buf; if ( lstat( wildCharPathName.c_str(), &buf ) == 0 ) { if ( S_ISDIR(buf.st_mode) ) { DIR *dir = opendir( wildCharPathName.c_str() ); if ( dir ) { struct dirent *dirEntry = NULL; while ( ( dirEntry = readdir( dir ) ) != NULL ) { std::string filename = ""; filename += (*dirEntry).d_name; if ( filename != "." && filename != ".." ) { std::string new_filename = wildCharPathName + '/' + filename; GetTableList( new_filename, pathNames ); } } } closedir( dir ); } else if ( S_ISREG(buf.st_mode) ) { pathNames.push_back( wildCharPathName ); } } }
void GetTableList( std::string sWildCharPathName, std::vector<std::string>& vPathName ) { std::string sPath; std::string::size_type n = sWildCharPathName.find_last_of('\\'); if ( n == (sWildCharPathName.size() - 1) ) { sWildCharPathName = sWildCharPathName.substr(0, n); n = sWildCharPathName.find_last_of('\\'); } if (n != std::string::npos) sPath = sWildCharPathName.substr(0, n + 1); _finddata_t fd; long handle = _findfirst(sWildCharPathName.c_str(), &fd); if (handle != -1) { do { std::string sName = fd.name; if (sName.size()>3) { if (sName.substr(sName.size()-3, 3) == ".rt" && !(fd.attrib & _A_SUBDIR)) { std::string sPathName = sPath + sName; vPathName.push_back(sPathName); } } if (sName.size()>4) { if (sName.substr(sName.size()-4, 4) == ".rti" && !(fd.attrib & _A_SUBDIR)) { std::string sPathName = sPath + sName; vPathName.push_back(sPathName); } } if (sName.size()>5) { if (sName.substr(sName.size()-5, 5) == ".rti2" && !(fd.attrib & _A_SUBDIR)) { std::string sPathName = sPath + sName; vPathName.push_back(sPathName); } } if (sName != "." && sName != ".." && (fd.attrib & _A_SUBDIR)) { std::string sPath_sub = sPath + sName + '\\'; std::string sWildCharPathName_sub = sPath_sub + '*'; GetTableList(sWildCharPathName_sub, vPathName); } } while (_findnext(handle, &fd) == 0); _findclose(handle); } //printf("Found %d rainbowtables (files) in %d sub directories...\n", vPathName.size(), subDir_count); }
void GetTableList( std::string sWildCharPathName, std::vector<std::string>& vPathName ) { struct stat buf; if (lstat(sWildCharPathName.c_str(), &buf) == 0) { if (S_ISDIR(buf.st_mode)) { DIR *dir = opendir(sWildCharPathName.c_str()); if(dir) { struct dirent *pDir=NULL; while((pDir = readdir(dir)) != NULL) { std::string filename = ""; filename += (*pDir).d_name; if (filename != "." && filename != "..") { std::string new_filename = sWildCharPathName + '/' + filename; GetTableList(new_filename, vPathName); } } closedir(dir); } } else if (S_ISREG(buf.st_mode)) { if (sWildCharPathName.size() > 3) { if (sWildCharPathName.substr(sWildCharPathName.size()-3, 3) == ".rt") { vPathName.push_back(sWildCharPathName); } } if (sWildCharPathName.size()>4) { if (sWildCharPathName.substr(sWildCharPathName.size()-4, 4) == ".rti") { //string sPathName_sub = sPath_sub + sName_sub; vPathName.push_back(sWildCharPathName); //printf("sPathName_sub: %s\n", sPathName_sub.c_str()); } } if (sWildCharPathName.size() > 5) { if ( sWildCharPathName.substr( sWildCharPathName.size() - 5, 5 ) == ".rti2" ) { vPathName.push_back( sWildCharPathName ); } } } } }
/* Crack a PWDUMP file */ boost::python::dict pwdump(std::string pwdumpFilePath, std::string pathToTables, std::string outputFile, std::string sSessionPathName, std::string sProgressPathName, std::string sPrecalcPathName, std::string output, bool debug, bool keepPrecalcFiles, int enableGPU, unsigned int maxThreads, uint64 maxMem) { std::vector<std::string> vHash; // hash cracker std::vector<std::string> vUserName; // lm cracker std::vector<std::string> vLMHash; // lm cracker std::vector<std::string> vNTLMHash; // lm cracker std::vector<std::string> vPathName; bool resumeSession = false; // Sessions not currently supported CHashSet hashSet; if ( !output.empty() ) { freopen(output.c_str(), "a", stdout); } if ( debug ) { version(debug); } /* Parse file for hashes */ LoadLMHashFromPwdumpFile(pwdumpFilePath, vUserName, vLMHash, vNTLMHash); for (uint32 index = 0; index < vLMHash.size(); index++) { hashSet.AddHash(vLMHash[index].substr(0, 16)); hashSet.AddHash(vLMHash[index].substr(16, 16)); } /* Load rainbow tables */ GetTableList(pathToTables, vPathName); if ( debug ) { std::cout << "[Debug]: Found " << vPathName.size() << " rainbow table file(s)..." << std::endl; } /* Start cracking! */ boost::python::dict results; CCrackEngine* crackEngine = new CCrackEngine(); crackEngine->setSession(sSessionPathName, sProgressPathName, sPrecalcPathName, keepPrecalcFiles); try { crackEngine->Run(vPathName, hashSet, maxThreads, maxMem, resumeSession, debug, enableGPU); results = otherResults(vLMHash, vNTLMHash, vUserName, hashSet, outputFile, debug); } catch (std::exception& error) { if (debug) { std::cout << "[Debug]: Caught a C++ exception, converting to Python exception ..." << std::endl; } delete crackEngine; // Release GIL PyErr_SetString(PyExc_ValueError, error.what()); throw boost::python::error_already_set(); } return results; }
/* Crack a Cain & Abel file */ boost::python::dict cain(std::string cainFilePath, std::string pathToTables, std::string outputFile, std::string sSessionPathName, std::string sProgressPathName, std::string sPrecalcPathName, bool debug, bool keepPrecalcFiles, int enableGPU, unsigned int maxThreads, uint64 maxMem) { std::vector<std::string> vHash; // hash cracker std::vector<std::string> vUserName; // lm cracker std::vector<std::string> vLMHash; // lm cracker std::vector<std::string> vNTLMHash; // lm cracker std::vector<std::string> vPathName; bool resumeSession = false; // Sessions not currently supported CHashSet hashSet; if ( debug ) { version(debug); } /* Parse file for hashes */ LoadLMHashFromCainLSTFile(cainFilePath, vUserName, vLMHash, vNTLMHash); for (uint32 index = 0; index < vLMHash.size(); index++) { hashSet.AddHash(vLMHash[index].substr(0, 16)); hashSet.AddHash(vLMHash[index].substr(16, 16)); } /* Load rainbow tables */ GetTableList(pathToTables, vPathName); if ( debug ) { std::cout << "[Debug]: Found " << vPathName.size() << " rainbow table file(s)..." << std::endl; } /* Start cracking! */ CCrackEngine crackEngine; crackEngine.setSession(sSessionPathName, sProgressPathName, sPrecalcPathName, keepPrecalcFiles); crackEngine.Run(vPathName, hashSet, maxThreads, maxMem, resumeSession, debug, enableGPU); boost::python::dict results = otherResults(vLMHash, vNTLMHash, vUserName, hashSet, outputFile, debug); return results; }
int main(int argc, char* argv[]) { #ifdef _WIN32 if (argc != 4) { Usage(); return 0; } string sWildCharPathName = argv[1]; string sInputType = argv[2]; string sInput = argv[3]; // vPathName vector<string> vPathName; GetTableList(sWildCharPathName, vPathName); #else if (argc < 4) { Usage(); return 0; } string sInputType = argv[argc - 2]; string sInput = argv[argc - 1]; // vPathName vector<string> vPathName; GetTableList(argc, argv, vPathName); #endif if (vPathName.size() == 0) { printf("no rainbow table found\n"); return 0; } // fCrackerType, vHash, vUserName, vLMHash bool fCrackerType; // true: hash cracker, false: lm cracker vector<string> vHash; // hash cracker vector<string> vUserName; // lm cracker vector<string> vLMHash; // lm cracker vector<string> vNTLMHash; // lm cracker if (sInputType == "-h") { fCrackerType = true; string sHash = sInput; if (NormalizeHash(sHash)) vHash.push_back(sHash); else printf("invalid hash: %s\n", sHash.c_str()); } else if (sInputType == "-l") { fCrackerType = true; string sPathName = sInput; vector<string> vLine; if (ReadLinesFromFile(sPathName, vLine)) { int i; for (i = 0; i < vLine.size(); i++) { string sHash = vLine[i]; if (NormalizeHash(sHash)) vHash.push_back(sHash); else printf("invalid hash: %s\n", sHash.c_str()); } } else printf("can't open %s\n", sPathName.c_str()); } else if (sInputType == "-f") { fCrackerType = false; string sPathName = sInput; LoadLMHashFromPwdumpFile(sPathName, vUserName, vLMHash, vNTLMHash); } else { Usage(); return 0; } if (fCrackerType && vHash.size() == 0) return 0; if (!fCrackerType && vLMHash.size() == 0) return 0; // hs CHashSet hs; if (fCrackerType) { int i; for (i = 0; i < vHash.size(); i++) hs.AddHash(vHash[i]); } else { int i; for (i = 0; i < vLMHash.size(); i++) { hs.AddHash(vLMHash[i].substr(0, 16)); hs.AddHash(vLMHash[i].substr(16, 16)); } } // Run CCrackEngine ce; ce.Run(vPathName, hs); // Statistics //printf("statistics\n"); //printf("-------------------------------------------------------\n"); //printf("plaintext found: %d of %d (%.2f%%)\n", hs.GetStatHashFound(), // hs.GetStatHashTotal(), // 100.0f * hs.GetStatHashFound() / hs.GetStatHashTotal()); //printf("total disk access time: %.2f s\n", ce.GetStatTotalDiskAccessTime()); //printf("total cryptanalysis time: %.2f s\n", ce.GetStatTotalCryptanalysisTime()); //printf("total chain walk step: %d\n", ce.GetStatTotalChainWalkStep()); //printf("total false alarm: %d\n", ce.GetStatTotalFalseAlarm()); //printf("total chain walk step due to false alarm: %d\n", ce.GetStatTotalChainWalkStepDueToFalseAlarm()); //printf("\n"); // Result //printf("result\n"); //printf("-------------------------------------------------------\n"); if (fCrackerType) { int i; for (i = 0; i < vHash.size(); i++) { string sPlain, sBinary; if (!hs.GetPlain(vHash[i], sPlain, sBinary)) { sPlain = "<notfound>"; sBinary = "<notfound>"; } //printf("%s %s hex:%s\n", vHash[i].c_str(), sPlain.c_str(), sBinary.c_str()); } } else { int i; for (i = 0; i < vLMHash.size(); i++) { string sPlain1, sBinary1; bool fPart1Found = hs.GetPlain(vLMHash[i].substr(0, 16), sPlain1, sBinary1); if (!fPart1Found) { sPlain1 = "<notfound>"; sBinary1 = "<notfound>"; } string sPlain2, sBinary2; bool fPart2Found = hs.GetPlain(vLMHash[i].substr(16, 16), sPlain2, sBinary2); if (!fPart2Found) { sPlain2 = "<notfound>"; sBinary2 = "<notfound>"; } string sPlain = sPlain1 + sPlain2; string sBinary = sBinary1 + sBinary2; // Correct case if (fPart1Found && fPart2Found) { unsigned char NTLMHash[16]; int nHashLen; ParseHash(vNTLMHash[i], NTLMHash, nHashLen); if (nHashLen != 16) printf("debug: nHashLen mismatch\n"); string sNTLMPassword; if (LMPasswordCorrectCase(sPlain, NTLMHash, sNTLMPassword)) { sPlain = sNTLMPassword; sBinary = HexToStr((const unsigned char*)sNTLMPassword.c_str(), sNTLMPassword.size()); } else printf("case correction for password %s fail!\n", sPlain.c_str()); } // Display //printf("%-14s %s hex:%s\n", vUserName[i].c_str(), // sPlain.c_str(), // sBinary.c_str()); } } return 0; }
int main(int argc, char* argv[]) { bool debug = false; uint32 dropLastNchains = 0; uint32 dropHighSPcount = 0; int sptl = 0; if (argc < 2) { usage(); return 0; } std::vector<std::string> pathNames; // Parse command line args int i; for( i = 1; i < argc; i++ ) { if ( strncmp( argv[i], "-v", 2 ) == 0 ) debug = true; else if ( strncmp( argv[i], "-drop_last_n_chains=", 20 ) == 0 ) { uint32 j; for ( j = 20; argv[i][j] >= '0' && argv[i][j] <= '9'; j++ ) { dropLastNchains *= 10; dropLastNchains += ((int) argv[i][j] ) - 0x30; } if ( argv[i][j] != '\0' ) { printf("Error: Invalid drop_last_n_chains number.\n\n"); usage(); exit( 1 ); } } else if ( strncmp( argv[i], "-drop_high_sp_n_chains=", 23 ) == 0 ) { uint32 j; for ( j = 23; argv[i][j] >= '0' && argv[i][j] <= '9'; j++ ) { dropHighSPcount *= 10; dropHighSPcount += ((int) argv[i][j] ) - 0x30; } if ( argv[i][j] != '\0' ) { printf("Error: Invalid drop_high_sp_n_chains number.\n\n"); usage(); exit( 1 ); } } else if ( strncmp( argv[i], "-sptl=", 6 ) == 0 ) { uint32 j; for ( j = 6; argv[i][j] >= '0' && argv[i][j] <= '9'; j++ ) { sptl *= 10; sptl += ((int) argv[i][j] ) - 0x30; } if ( argv[i][j] != '\0' ) { printf("Error: Invalid sptl number.\n\n"); usage(); exit( 1 ); } } else GetTableList( argv[i], pathNames ); } if ( debug ) { for( int i = 0; i < argc; i++ ) printf("%i: %s\n", i, argv[i]); } if ( pathNames.size() == 0 ) { printf("no rainbow table found\n"); return 0; } std::string resultFile, sType; for ( uint32 i = 0; i < pathNames.size(); i++ ) { if( pathNames[i].substr( pathNames[i].length() - 4, pathNames[i].length()) == "rti2") { resultFile = pathNames[i].substr(0, pathNames[i].length() - 2); // Resulting file is .rt, not .rti2 sType = "RTI2"; } else if( pathNames[i].substr( pathNames[i].length() - 3, pathNames[i].length()) == "rti") { resultFile = pathNames[i].substr( 0, pathNames[i].length() - 1 ); // Resulting file is .rt, not .rti sType = "RTI"; } else { printf("File %s is not a RTI or a RTI2 file", pathNames[i].c_str() ); continue; } // XXX this assumes someone is converting either just the last file // *or* doing a whole set which will read the last file first if ( dropLastNchains > 0 && i == 0 ) { std::string::size_type lastX = resultFile.find_last_of('x'); if ( lastX == std::string::npos ) { std::cout << "Could not parse the filename to drop the last chains" << std::endl; exit( -1 ); } std::string::size_type firstSplit = resultFile.find_first_of('_',lastX); #if defined(_WIN32) && !defined(__GNUC__) uint64 chains = _atoi64( resultFile.substr( lastX + 1, firstSplit - lastX - 1).c_str() ); #else uint64 chains = atoll( resultFile.substr( lastX + 1, firstSplit - lastX - 1 ).c_str() ); #endif chains -= dropLastNchains; resultFile.replace( lastX + 1, firstSplit - lastX - 1, uint64tostr( chains ) ); } ConvertRainbowTable( pathNames[i], resultFile, sType, debug, dropLastNchains, dropHighSPcount, sptl ); dropLastNchains = 0; dropHighSPcount = 0; printf("\n"); } return 0; }
/* Open one or more folders */ void OpenDir(GtkWidget *empty) { GtkWidget *chooser; GSList *folders; std::string tmp; chooser = gtk_file_chooser_dialog_new("Open", GTK_WINDOW(gui.windows.table), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(chooser), true); if (gtk_dialog_run(GTK_DIALOG(chooser)) == GTK_RESPONSE_ACCEPT) { folders = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(chooser)); GSList *list = folders; db.n_folders = 1; while (list->next != NULL) { list = list->next; db.n_folders++; } if (tabledir != NULL) free(tabledir); tabledir = (TableDir*)calloc(sizeof(TableDir), db.n_folders+1); list = folders; strcpy(tabledir[0].dir, (char*)list->data); tmp = tabledir[0].dir; int i = 1, k; while (list->next != NULL) { list = list->next; strcat(tabledir[i].dir, (char*)list->data); tmp += tabledir[i].dir; i++; } std::vector<std::string> old_tables = db.tables; for (i = 0; i < db.n_folders; i++) GetTableList((std::string)tabledir[i].dir, db.tables); /* Insert tables into list */ int max; if ((int)db.tables.size() > MAX_TABLES) max = MAX_TABLES; else max = (int)db.tables.size(); for (k = 0; k < max; k++) { if (TableAlreadyInList(db.tables[k].c_str(), old_tables)) { db.tables.erase(db.tables.begin()+k); continue; } /* Get algorithm & charset */ std::string algo, n; n = db.tables[k]; for (i = 0; i < (int)n.length(); i++) n[i] = tolower(n[i]); size_t found = n.find("md5"); if (found != std::string::npos) algo = "MD5"; found = n.find("ntlm"); if (found != std::string::npos) algo = "NTLM"; found = n.find("lm"); if (found != std::string::npos) algo = "LM"; found = n.find("sha1"); if (found != std::string::npos) algo = "SHA1"; found = n.find("mysqlsha1"); if (found != std::string::npos) algo = "MySQLSHA1"; #ifndef _WIN32 found = db.tables[k].find_last_of("/"); #else found = db.tables[k].find_last_of("\\"); #endif if (found == std::string::npos) found = 0; char path[256]; strcpy(path, db.tables[k].substr(0, found).c_str()); gtk_list_store_append(gui.table.store, &gui.table.iter[db.n_tables]); gtk_list_store_set(gui.table.store, &gui.table.iter[db.n_tables], 0, algo.c_str(), 1, db.tables[k].substr(found+1).c_str(), 2, path, -1); db.n_tables++; } if (max > (int)db.tables.size()) MessageStackPush("col-red", "Maximum amount of rainbow table files is %d\n", MAX_TABLES); } gtk_widget_destroy(chooser); }
/* Cracks a single hash and returns a Python dictionary */ boost::python::dict crack(boost::python::list& hashes, std::string pathToTables, std::string outputFile, std::string sSessionPathName, std::string sProgressPathName, std::string sPrecalcPathName, std::string output, bool mysqlsha1format, bool debug, bool keepPrecalcFiles, int enableGPU, unsigned int maxThreads, uint64 maxMem) { #ifndef _WIN32 signal(SIGSEGV, handler); // Register segfault handler #endif CHashSet hashSet; bool resumeSession = false; // Sessions not currently supported std::vector<std::string> verifiedHashes; std::vector<std::string> vPathName; if ( !output.empty() ) { freopen(output.c_str(), "a", stdout); } if ( debug ) { std::cout << "[Debug]: List contains " << boost::python::len(hashes) << " hash(es)" << std::endl; } for (unsigned int index = 0; index < boost::python::len(hashes); ++index) { std::string sHash = boost::python::extract<std::string>(hashes[index]); if (NormalizeHash(sHash)) { verifiedHashes.push_back(sHash); } else { std::ostringstream stringBuilder; stringBuilder << "Invalid hash: <" << sHash.c_str() << ">"; std::string message = stringBuilder.str(); PyErr_SetString(PyExc_ValueError, message.c_str()); throw boost::python::error_already_set(); } } std::vector<std::string> sha1AsMysqlSha1; for (unsigned int index = 0; index < verifiedHashes.size(); ++index) { if (mysqlsha1format) { HASHROUTINE hashRoutine; CHashRoutine hr; std::string hashName = "sha1"; int hashLen = 20; hr.GetHashRoutine( hashName, hashRoutine, hashLen ); unsigned char* plain = new unsigned char[hashLen*2]; memcpy( plain, HexToBinary(verifiedHashes[index].c_str(), hashLen*2 ).c_str(), hashLen ); unsigned char hash_output[MAX_HASH_LEN]; hashRoutine( plain, hashLen, hash_output); sha1AsMysqlSha1.push_back(HexToStr(hash_output, hashLen)); hashSet.AddHash( sha1AsMysqlSha1[index] ); } else { hashSet.AddHash(verifiedHashes[index]); } } /* Load rainbow tables */ GetTableList(pathToTables, vPathName); if (debug) { std::cout << "[Debug]: Found " << vPathName.size() << " rainbow table file(s)" << std::endl; } /* Start cracking! */ CCrackEngine crackEngine; crackEngine.setSession(sSessionPathName, sProgressPathName, sPrecalcPathName, keepPrecalcFiles); crackEngine.Run(vPathName, hashSet, maxThreads, maxMem, resumeSession, debug, enableGPU); boost::python::dict results; results = fCrackerResults(verifiedHashes, sha1AsMysqlSha1, hashSet); return results; }