|
/*
ngOrca - Brute Force Cracking programm for Oracle Hashes version 0.3
Copyright (C) cr - cr a t netgarage d o t org
This program 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.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <openssl/des.h>
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <inttypes.h>
#include <ctime>
#include <csignal>
char alnum_charset[37]="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
char al_charset[27]="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char num_charset[11]="0123456789";
char alnumspecial_charset[69]="ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.:,;-_#'+?="
"()/&%$§\"!<>|\\}][{~@";
class Hash
{
public:
Hash() {}
Hash(const std::string& u, const std::string h, int p, int l) :
username(u), password(""), hashstring(h), pad(p), length(l)
{
read_hex(hashstring.c_str(), hash);
}
std::string username, password, hashstring;
unsigned char hash[8];
int pad, length;
std::string print()
{
std::stringstream str;
str<<username<<":"<<hashstring;
if(password!="")
str<<":"<<password;
str<<"\n";
return str.str();
}
void read_hex(const char* x, unsigned char* p)
{
for(;*x;x+=2)
*p++=hex_digit(x[0])*16+hex_digit(x[1]);
}
unsigned char hex_digit(char c)
{
if(c<='9') return c-'0';
else if (c<'a') return c-'A'+10;
else return c-'a'+10;
}
};
class NGOrca
{
private:
unsigned char plaintextstring[128];
unsigned char ciphertextstring[128];
unsigned char salt_iv[8];
unsigned char init_deskey[8];
unsigned char deskey[8];
des_key_schedule schedule1, schedule2;
char* logfile,* hashfile;
std::ofstream log;
std::fstream file;
std::string usage, line, username, userhash;
unsigned long long int pwd, maxpwd, tmp;
float percent;
clock_t starttime, oldtime;
unsigned char current_hash[8];
unsigned char hash[8];
std::vector<Hash> hashlist;
int passwordlength;
int charsetlength;
char* charset;
public:
NGOrca(int argc, char* argv[]) : password(""), pwd(0), maxpwd(36ULL),
tmp(0), percent(0), oldtime(0), logfile(0), hashfile(0), passwordlength(3)
{
usage="ngOrca v0.8 \n\n"
"./ng-orca hashfile.txt [param]\n"
" -l <int> length of the password\n"
" -s <uint64_t> start password number\n"
" -f <file> hashfile (username:hash)\n"
" -o <logfile> file containing the cracked hashes and the status\n"
" -c <charset> 1 for alpha, 2 for num, 3 for alphanum (default)\n";
if(argc<1){
std::cout<<usage;
exit(0);
}
init_deskey[0]=0x01;
init_deskey[1]=0x23;
init_deskey[2]=0x45;
init_deskey[3]=0x67;
init_deskey[4]=0x89;
init_deskey[5]=0xab;
init_deskey[6]=0xcd;
init_deskey[7]=0xef;
charset=alnum_charset;
charsetlength=strlen(alnum_charset);
des_set_key(&init_deskey, schedule1);
int opt=0, loc;
while((opt=getopt(argc, argv, "l:s:f:c:o:"))!=-1){
switch(opt){
case 'l': passwordlength=atoi(optarg); break;
case 's': tmp=strtoull(optarg, 0, 0); break;
case 'f': hashfile=optarg;break;
case 'o': logfile=optarg;break;
case 'c': switch (atoi(optarg)){
case 1: charset=al_charset;
charsetlength=strlen(al_charset);break;
case 2: charset=num_charset;
charsetlength=strlen(num_charset); break;
case 3: charset=alnum_charset;
charsetlength=strlen(alnum_charset);break;
case 4: charset=alnumspecial_charset;
charsetlength=strlen(alnumspecial_charset); break;
default: charset=alnum_charset;
charsetlength=strlen(alnum_charset); break;
}
default: std::cout<<usage;exit(0);
}
}
if(hashfile==0){
std::cout<<"no hashlist given\n";
exit(0);
}
file.open(hashfile, std::ios::in);
if(logfile==0)
logfile="log.txt";
log.open(logfile, std::ios::app);
for(int i=1; i<passwordlength; ++i){
maxpwd*=charsetlength;
}
while(getline(file, line)){
if((loc=line.find("pwd=",0))!=std::string::npos){
std::string temp=line.substr(loc+4, line.size()-loc+4);
if(tmp==0)
tmp=strtoull(temp.c_str(),0 ,0);
continue;
}
if((loc=line.find(":",0))!=std::string::npos){
username=line.substr(0,loc);
std::transform(username.begin(), username.end(), username.begin(), toupper);
userhash=line.substr(++loc, line.size());
if(userhash.size()!=16){
std::cout<<"invalid hashformat\n";
exit(0);
}
int pad=8-((username.size()+passwordlength)%8);
hashlist.push_back(Hash(username, userhash, pad, username.size()+passwordlength+pad));
}
}
pwd=tmp;
std::cout<<"startpwd="<<pwd<<"\n";
std::cout<<"read "<<hashlist.size()<<" hashes.\n";
std::cout<<"maxpwd "<<maxpwd<<" .\n";
log<<"[ng-orca] started cracking file="<<hashfile<<" pwd="<<pwd<<"\n";
log.flush();
}
~NGOrca()
{
log<<"[ng-orca] stopped cracking at pwd="<<pwd<<"\n";
log.flush();
log.close();
safe();
}
bool compare_hash(unsigned char* hash, unsigned char* current_hash)
{
for(int i=0; i<8; ++i)
if(hash[i]!=current_hash[i])
return false;
return true;
}
void generate_hash(std::string& username, const char* password, unsigned char* current_hash, int pad, int length)
{
std::string tmp(username+password);
for(int i=0; i<pad; ++i)
tmp.push_back(0x00);
int l=-1;
length*=2;
for(int i=0; i<length; ++i)
if(i&1)
plaintextstring[i]=tmp[++l];
else
plaintextstring[i]=0x00;
memset(salt_iv,0,8);
des_ncbc_encrypt(plaintextstring, ciphertextstring, length, schedule1, &salt_iv, 1);
for(int i=0, j=8;i<8;++i, --j)
deskey[i]=ciphertextstring[length-j];
des_set_key(&deskey, schedule2);
memset(salt_iv,0,8);
des_ncbc_encrypt(plaintextstring, ciphertextstring, length, schedule2, &salt_iv, 1);
for(int i=0;i<8;++i)
current_hash[i]=ciphertextstring[length-8+i];
}
void safe()
{
std::ofstream out(hashfile);
out<<"pwd="<<pwd<<"\n";
for(int i=0; i<hashlist.size(); ++i)
out<<hashlist[i].print();
file.close();
}
void run();
};
namespace {
NGOrca* ngo;
}
void sig_int(int s)
{
delete ngo;
exit(0);
}
void NGOrca::run()
{
std::vector<Hash>::iterator it;
std::vector<Hash>::iterator endit=hashlist.end();
char password[passwordlength+1];
char plaintext[128];
signal(SIGINT, sig_int);
starttime=clock();
while(pwd<=maxpwd) {
tmp=pwd;
for (int i=0; i<passwordlength; ++i) {
password[i]=charset[tmp%charsetlength];
tmp/=charsetlength;
}
password[passwordlength]='\0';
for(it=hashlist.begin(); it!=endit; ++it){
generate_hash(it->username, password, current_hash, it->pad, it->length);
if(compare_hash(it->hash, current_hash)){
it->password=password;
std::cout<<pwd<<":"<<it->print();
log<<pwd<<":"<<it->print();
log.flush();
hashlist.erase(it);
it=hashlist.begin();
endit=hashlist.end();
--it;
safe();
if(hashlist.size()==0){
std::cout<<"all passwords cracked :)\n";
pwd=maxpwd;
}
}
}
if((pwd%1000000)==0){
percent=(float)pwd/(float)maxpwd;
std::cout<<pwd<<" : "<<percent*100<<"% "<<password;
oldtime=clock();
std::cout<<" time: "<<(float)(oldtime-starttime)/(float)1000<<" ms/1000000h.\n";
starttime=clock();
}
++pwd;
}
}
int main(int argc, char* argv[])
{
ngo=new NGOrca(argc, argv);
std::cout<<".....................................\n";
ngo->run();
delete ngo;
return 0;
}
|