void LoadLMHashFromPwdumpFile(string sPathName, vector<string>& vUserName, vector<string>& vLMHash, vector<string>& vNTLMHash) { vector<string> vLine; if (ReadLinesFromFile(sPathName, vLine)) { int i; for (i = 0; i < vLine.size(); i++) { vector<string> vPart; if (SeperateString(vLine[i], "::::", vPart)) { string sUserName = vPart[0]; string sLMHash = vPart[2]; string sNTLMHash = vPart[3]; if (sLMHash.size() == 32 && sNTLMHash.size() == 32) { if (NormalizeHash(sLMHash) && NormalizeHash(sNTLMHash)) { vUserName.push_back(sUserName); vLMHash.push_back(sLMHash); vNTLMHash.push_back(sNTLMHash); } else printf("invalid lm/ntlm hash %s:%s\n", sLMHash.c_str(), sNTLMHash.c_str()); } } } } else printf("can't open %s\n", sPathName.c_str()); }
// 2009-01-04 - james.dickson - Added this so we can load hashes from cain .LST files. void LoadLMHashFromCainLSTFile( std::string sPathName, std::vector<std::string>& vUserName, std::vector<std::string>& vLMHash, std::vector<std::string>& vNTLMHash ) { std::vector<std::string> vLine; if (ReadLinesFromFile(sPathName, vLine)) { uint32 index; for (index = 0; index < vLine.size(); index++) { std::vector<std::string> vPart; if (SeperateString(vLine[index], "\t\t\t\t\t\t", vPart)) { std::string sUserName = vPart[0]; std::string sLMHash = vPart[4]; std::string sNTLMHash = vPart[5]; if (sLMHash.size() == 32 && sNTLMHash.size() == 32) { if (NormalizeHash(sLMHash) && NormalizeHash(sNTLMHash)) { vUserName.push_back(sUserName); vLMHash.push_back(sLMHash); vNTLMHash.push_back(sNTLMHash); } else { std::ostringstream stringBuilder; stringBuilder << "Invalid lm/ntlm hash " << sLMHash.c_str(); std::string message = stringBuilder.str(); PyErr_SetString(PyExc_ValueError, message.c_str()); throw boost::python::error_already_set(); } } } } } else { std::ostringstream stringBuilder; stringBuilder << "Can't open " << sPathName.c_str(); std::string message = stringBuilder.str(); PyErr_SetString(PyExc_IOError, message.c_str()); throw boost::python::error_already_set(); } }
int AddHash(const char *buffer) { std::string normalized_hash = buffer; if (NormalizeHash(normalized_hash) && !HashAlreadyInList(normalized_hash.c_str())) db.hashes.push_back((std::string)buffer); else return -2; int len = strlen(buffer); if (len == 32) return HASH_MD5 | HASH_NTLM; else if (len == 40) return HASH_SHA1; else return -1; }
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; }
/* 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; }