/*
- RainbowCrack - a general propose implementation of Philippe Oechslin's faster time-memory trade-off technique.
-
- Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
-
- Modified by Martin Westergaard Jørgensen <martinwj2005@gmail.com> to support indexed and hybrid tables
-
- Modified by neinbrucke to support multi threading and a bunch of other stuff :)
-
- 2009-01-04 - <james.dickson@comhem.se> - Slightly modified (or "fulhack" as we say in sweden)
- to support cain .lst files.
-*/
-
-#ifdef _WIN32
+ * rcracki_mt is a multithreaded implementation and fork of the original
+ * RainbowCrack
+ *
+ * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
+ * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>
+ * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
+ * Copyright 2009 James Dickson
+ * Copyright 2009, 2010 James Nobis <frt@quelrod.net>
+ * Copyright 2010 uroskn
+ *
+ * Modified by Martin Westergaard Jørgensen <martinwj2005@gmail.com> to support * indexed and hybrid tables
+ *
+ * Modified by neinbrucke to support multi threading and a bunch of other stuff :)
+ *
+ * 2009-01-04 - <james.dickson@comhem.se> - Slightly modified (or "fulhack" as
+ * we say in sweden) to support cain .lst files.
+ *
+ * This file is part of rcracki_mt.
+ *
+ * rcracki_mt is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * rcracki_mt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with rcracki_mt. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#if defined(_WIN32) && !defined(__GNUC__)
#pragma warning(disable : 4786 4267 4018)
#endif
#include "lm2ntlm.h"
#include <algorithm>
-
-
#ifdef _WIN32
#include <io.h>
#else
#include <dirent.h>
#endif
-#include <openssl/md4.h>
-#ifdef _WIN32
+#if defined(_WIN32) && !defined(__GNUC__)
#pragma comment(lib, "libeay32.lib")
#endif
//vPathName.clear();
string sPath;
- int n = sWildCharPathName.find_last_of('\\');
+ string::size_type n = sWildCharPathName.find_last_of('\\');
- if (n == (sWildCharPathName.size() - 1))
+ if ( n == (sWildCharPathName.size() - 1) )
{
sWildCharPathName = sWildCharPathName.substr(0, n);
n = sWildCharPathName.find_last_of('\\');
}
- if (n != -1)
+ if (n != string::npos)
sPath = sWildCharPathName.substr(0, n + 1);
_finddata_t fd;
//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 );
+ }
+ }
}
}
}
return false;
// Make lower
- int i;
+ UINT4 i;
for (i = 0; i < sNormalizedHash.size(); i++)
{
if (sNormalizedHash[i] >= 'A' && sNormalizedHash[i] <= 'F')
- sNormalizedHash[i] = sNormalizedHash[i] - 'A' + 'a';
+ sNormalizedHash[i] = (char) sNormalizedHash[i] - 'A' + 'a';
}
// Character check
vector<string> vLine;
if (ReadLinesFromFile(sPathName, vLine))
{
- int i;
+ UINT4 i;
for (i = 0; i < vLine.size(); i++)
{
vector<string> vPart;
printf("can't open %s\n", sPathName.c_str());
}
-// 2009-01-04 - james - Added this so we can load hashes from cain .LST files.
+// 2009-01-04 - james.dickson - Added this so we can load hashes from cain .LST files.
void LoadLMHashFromCainLSTFile(string sPathName, vector<string>& vUserName, vector<string>& vLMHash, vector<string>& vNTLMHash)
{
vector<string> vLine;
if (ReadLinesFromFile(sPathName, vLine))
{
- int i;
+ UINT4 i;
for (i = 0; i < vLine.size(); i++)
{
vector<string> vPart;
{
if (nLMPasswordNext == nLMPasswordLen)
{
- unsigned char md[16];
- MD4(pLMPassword, nLMPasswordLen * 2, md);
- if (memcmp(md, pNTLMHash, 16) == 0)
+ unsigned char md[MD4_DIGEST_LENGTH];
+ MD4_NEW(pLMPassword, nLMPasswordLen * 2, md);
+
+ if (memcmp(md, pNTLMHash, MD4_DIGEST_LENGTH) == 0)
{
sNTLMPassword = "";
int i;
if ( pLMPassword[nLMPasswordNext * 2] >= 'A'
&& pLMPassword[nLMPasswordNext * 2] <= 'Z')
{
- pLMPassword[nLMPasswordNext * 2] = pLMPassword[nLMPasswordNext * 2] - 'A' + 'a';
+ pLMPassword[nLMPasswordNext * 2] = (unsigned char) pLMPassword[nLMPasswordNext * 2] - 'A' + 'a';
if (NTLMPasswordSeek(pLMPassword, nLMPasswordLen, nLMPasswordNext + 1, pNTLMHash, sNTLMPassword))
return true;
- pLMPassword[nLMPasswordNext * 2] = pLMPassword[nLMPasswordNext * 2] - 'a' + 'A';
+ pLMPassword[nLMPasswordNext * 2] = (unsigned char) pLMPassword[nLMPasswordNext * 2] - 'a' + 'A';
}
return false;
}
unsigned char* pLMPassword = new unsigned char[sLMPassword.size() * 2];
- int i;
+ UINT4 i;
for (i = 0; i < sLMPassword.size(); i++)
{
pLMPassword[i * 2 ] = sLMPassword[i];
printf(" -o [output_file] write (temporary) results to this file\n");
printf(" -s [session_name] write session data with this name\n");
printf(" -k keep precalculation on disk\n");
+ printf(" -m [megabytes] limit memory usage\n");
printf(" -v show debug information\n");
printf("\n");
#ifdef _WIN32
printf(" rcracki_mt -l hash.txt [path_to_specific_table]/*\n");
#endif
printf(" rcracki_mt -f hash.txt -t 4 -o results.txt *.rti\n");
-
}
int main(int argc, char* argv[])
vector<string> vPathName;
vector<string> vDefaultRainbowTablePath;
- string sWildCharPathName = "";
- string sInputType = "";
- string sInput = "";
- string outputFile = "";
- string sApplicationPath = "";
- string sIniPathName = "rcracki_mt.ini";
- bool writeOutput = false;
- string sSessionPathName = "rcracki.session";
- string sProgressPathName = "rcracki.progress";
- string sPrecalcPathName = "rcracki.precalc";
- bool resumeSession = false;
- bool useDefaultRainbowTablePath = false;
- bool debug = false;
- bool keepPrecalcFiles = false;
- string sAlgorithm = "";
- int maxThreads = 1;
+ string sWildCharPathName = "";
+ string sInputType = "";
+ string sInput = "";
+ string outputFile = "";
+ string sApplicationPath = "";
+ string sIniPathName = "rcracki_mt.ini";
+ bool writeOutput = false;
+ string sSessionPathName = "rcracki.session";
+ string sProgressPathName = "rcracki.progress";
+ string sPrecalcPathName = "rcracki.precalc";
+ bool resumeSession = false;
+ bool useDefaultRainbowTablePath = false;
+ bool debug = false;
+ bool keepPrecalcFiles = false;
+ string sAlgorithm = "";
+ int maxThreads = 1;
+ uint64 maxMem = 0;
CHashSet hs;
// Read defaults from ini file;
}
if (readFromIni)
{
- int i;
+ UINT4 i;
for (i = 0; i < vLine.size(); i++)
{
if (vLine[i].substr(0,1) != "#")
if (sOption == "Threads") {
maxThreads = atoi(sValue.c_str());
}
+ else if (sOption == "MaxMemoryUsage" ) {
+ maxMem = atoi(sValue.c_str()) * 1024 *1024;
+ }
else if (sOption == "DefaultResultsFile") {
outputFile = sValue;
}
if (i < argc)
maxThreads = atoi(argv[i]);
}
+ else if ( cla == "-m" ) {
+ i++;
+ if ( i < argc )
+ maxMem = atoi(argv[i]) * 1024 * 1024;
+ }
else if (cla == "-o") {
writeOutput = true;
i++;
vector<string> sSessionData;
if (ReadLinesFromFile(sSessionPathName.c_str(), sSessionData))
{
- int i;
+ UINT4 i;
for (i = 0; i < sSessionData.size(); i++)
{
vector<string> vPart;
// don't load these if we are resuming a session that already has a list of tables
if (useDefaultRainbowTablePath && !resumeSession)
{
- int i;
+ UINT4 i;
for (i = 0; i < vDefaultRainbowTablePath.size(); i++)
{
vector<string> vPart;
printf("no rainbow table found\n");
return 0;
}
- printf("Found %d rainbowtable files...\n\n", vPathName.size());
+ printf("Found %lu rainbowtable files...\n\n",
+ (unsigned long)vPathName.size());
bool fCrackerType; // true: hash cracker, false: lm cracker
vector<string> vHash; // hash cracker
vector<string> vLine;
if (ReadLinesFromFile(sPathName, vLine))
{
- int i;
+ UINT4 i;
for (i = 0; i < vLine.size(); i++)
{
string sHash = vLine[i];
}
else if (sInputType == "-c")
{
- // 2009-01-04 - james - Added this for cain-files.
+ // 2009-01-04 - james.dickson - Added this for cain-files.
fCrackerType = false;
string sPathName = sInput;
LoadLMHashFromCainLSTFile(sPathName, vUserName, vLMHash, vNTLMHash);
if (fCrackerType)
{
- int i;
+ UINT4 i;
for (i = 0; i < vHash.size(); i++)
hs.AddHash(vHash[i]);
}
else
{
- int i;
+ UINT4 i;
for (i = 0; i < vLMHash.size(); i++)
{
hs.AddHash(vLMHash[i].substr(0, 16));
vector<string> sSessionData;
if (ReadLinesFromFile(sSessionPathName.c_str(), sSessionData))
{
- int i;
+ UINT4 i;
for (i = 0; i < sSessionData.size(); i++)
{
vector<string> vPart;
buffer += "sInputType=" + sInputType + "\n";
buffer += "sInput=" + sInput + "\n";
- int i;
+ UINT4 i;
for (i = 0; i < vPathName.size(); i++)
{
buffer += "sPathName=" + vPathName[i] + "\n";
if (writeOutput)
ce.setOutputFile(outputFile);
ce.setSession(sSessionPathName, sProgressPathName, sPrecalcPathName, keepPrecalcFiles);
- ce.Run(vPathName, hs, maxThreads, resumeSession, debug);
+ ce.Run(vPathName, hs, maxThreads, maxMem, resumeSession, debug);
// Remove session files
if (debug) printf("Debug: Removing session files.\n");
+
if (remove(sSessionPathName.c_str()) == 0)
remove(sProgressPathName.c_str());
else
// Statistics
printf("statistics\n");
printf("-------------------------------------------------------\n");
- printf("plaintext found: %d of %d (%.2f%%)\n", hs.GetStatHashFound(),
+ 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 disk access time: %.2f s\n", ce.GetStatTotalDiskAccessTime());
+ printf("total cryptanalysis time: %.2f s\n", ce.GetStatTotalCryptanalysisTime());
+ printf("total pre-calculation time: %.2f s\n", ce.GetStatTotalPrecalculationTime());
+ 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("total chain walk step skipped due to checkpoints: %d\n", ce.GetStatTotalFalseAlarmSkipped()); // Checkpoints not used - yet
printf("\n");
printf("-------------------------------------------------------\n");
if (fCrackerType)
{
- int i;
+ UINT4 i;
for (i = 0; i < vHash.size(); i++)
{
string sPlain, sBinary;
}
else
{
- int i;
+ UINT4 i;
for (i = 0; i < vLMHash.size(); i++)
{
string sPlain1, sBinary1;