main

Home
Blog
IRC


Netgarage RSS Feed
Linux Powered
Hacker Emblem
Apache 2.0 Power
Valid XHTML








Code
Written by cr   
Thursday, 17 May 2007
 
/*
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;
}
 
 
Last Updated ( Thursday, 17 May 2007 )