954,587 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

PHP-SHA1 Crack Notice.

I thought I would let you's php gurus know that I am starting to come close to cracking the Sha1 algorithm. And surprisingly it is an easy one to crack. So I would recommend switching to something like the whirlpool algorithm.

cwarn23
Occupation: Genius
Team Colleague
3,033 posts since Sep 2007
Reputation Points: 413
Solved Threads: 259
 
I thought I would let you's php gurus know that I am starting to come close to cracking the Sha1 algorithm. And surprisingly it is an easy one to crack. So I would recommend switching to something like the whirlpool algorithm.


Man you are commited to crack that algorithm! Do you want to get into world record? ;)

And whirlpool, what is it?

evstevemd
Senior Poster
3,713 posts since Jun 2007
Reputation Points: 462
Solved Threads: 392
 

Man you are commited to crack that algorithm! Do you want to get into world record? ;)

And whirlpool, what is it?


The whirlpool algorithm can be used with the following code:

<?php
echo hash('whirlpool', 'The quick brown fox jumped over the lazy dog.');
?>
//outputs
802dc377bf6dc4f905b90cf2f1ddb39d4958526c3772bce41c03488701630eeede8 51f5ddc195714ea9e35311a513e31c3b616ffce5756bd963e0fdc092b2f87

As you can see it has a longer hash and although I haven't checked the algorithm's core I would assume that it is by far more secure as 8 characters of hex = one number to decode into words.

cwarn23
Occupation: Genius
Team Colleague
3,033 posts since Sep 2007
Reputation Points: 413
Solved Threads: 259
 

The whirlpool algorithm can be used with the following code:

<?php
echo hash('whirlpool', 'The quick brown fox jumped over the lazy dog.');
?>
//outputs
802dc377bf6dc4f905b90cf2f1ddb39d4958526c3772bce41c03488701630eeede8 51f5ddc195714ea9e35311a513e31c3b616ffce5756bd963e0fdc092b2f87

As you can see it has a longer hash and although I haven't checked the algorithm's core I would assume that it is by far more secure as 8 characters of hex = one number to decode into words.


So you just use

hash('whirlpools', 'some text to encode');
evstevemd
Senior Poster
3,713 posts since Jun 2007
Reputation Points: 462
Solved Threads: 392
 

So you just use

hash('whirlpools', 'some text to encode');


Except drop the s.

hash('whirlpool', 'some text to encode');
cwarn23
Occupation: Genius
Team Colleague
3,033 posts since Sep 2007
Reputation Points: 413
Solved Threads: 259
 

cool

evstevemd
Senior Poster
3,713 posts since Jun 2007
Reputation Points: 462
Solved Threads: 392
 
I thought I would let you's php gurus know that I am starting to come close to cracking the Sha1 algorithm. And surprisingly it is an easy one to crack. So I would recommend switching to something like the whirlpool algorithm.

Are you serious? Are you willing to share with us how you're cracking it? It would be quite amazing if you did.

digital-ether
Nearly a Posting Virtuoso
Moderator
1,293 posts since Sep 2005
Reputation Points: 461
Solved Threads: 101
 
Are you serious? Are you willing to share with us how you're cracking it? It would be quite amazing if you did.


Yes, tomorrow I will have an update where I should have a data array cracked which will lead to the original data. Btw I'm using c++ and I will post some code in 24 hours. If I don't just remind me in 24 hours and I will post.

cwarn23
Occupation: Genius
Team Colleague
3,033 posts since Sep 2007
Reputation Points: 413
Solved Threads: 259
 

Do you think it is wise to post that in the public domain so that every nut and his brother can run a muck on the internet?

JRM
Practically a Master Poster
621 posts since Nov 2006
Reputation Points: 130
Solved Threads: 75
 
Do you think it is wise to post that in the public domain so that every nut and his brother can run a muck on the internet?


What do you mean by "run a muck"? I thought it would be wise.

cwarn23
Occupation: Genius
Team Colleague
3,033 posts since Sep 2007
Reputation Points: 413
Solved Threads: 259
 
What do you mean by "run a muck"? I thought it would be wise.


Maybe you should think again.
Maybe it's ok to do as a personal intellectual exercise, but what's the point of compromising sha1 for everybody?
I don't get it.

JRM
Practically a Master Poster
621 posts since Nov 2006
Reputation Points: 130
Solved Threads: 75
 
Salem
Posting Sage
Team Colleague
11,531 posts since Dec 2005
Reputation Points: 5,862
Solved Threads: 953
 
Maybe you should think again. Maybe it's ok to do as a personal intellectual exercise, but what's the point of compromising sha1 for everybody? I don't get it.


For better security practices to be taken into place. IMO any hash function can be cracked and I am going to prove that by going to selected algorithms and cracking them. If you truly want a secure hash then you would need to use something like the following:

function truehash($hashzzz) {
return hash('sha1',hash('whirlpool',$hashzzz));
}

A function like that will never be cracked unless both algorithms are cracked with a third algorithm written. So pritty much the reason why I am revealing the weaknesses in SHA1 is to prove that no hash is truly secure. I heard some officials in America have already cracked sha1 but is closed source. As for my source at digital-ethers request is below. I have managed to store both the previous temp variable value and the core data of the word variable/subarray into a single variable. This variable changes on each loop round. The next step is to separate rotateleft(a,5) from word[m] which are stored in val. After that it is possible to gain access to the word array which will lead to the next set of equations.

//#include<stdio.h>   
#include<string.h>   
#include<malloc.h>   
#include<math.h>   
#include<stdlib.h>   
#include<iostream>

#include <sstream>

#define rotateleft(x,n) ((x<<n) | (x>>(32-n)))   
#define rotateright(x,n) ((x>>n) | (x<<(32-n)))   

#define rotateleftrev(x,n) ((x<<n) | (x>>((32-n)+n)))   
    
void SHA1(unsigned char * str1)   
{   
	int i;
    unsigned long int h0,h1,h2,h3,h4,a,b,c,d,e,f,k,temp;   
    h0 = 0x67452301;   
    h1 = 0xEFCDAB89;   
    h2 = 0x98BADCFE;   
    h3 = 0x10325476;   
    h4 = 0xC3D2E1F0;   
    
    unsigned char * str;   
    str = (unsigned char *)malloc(strlen((const char *)str1)+100);   
    strcpy((char *)str,(const char *)str1);   
    
    int current_length = strlen((const char *)str);   
    int original_length = current_length;   
    str[current_length] = 0x80;   
    str[current_length + 1] = '\0';   
    
    char ic = str[current_length];   
    current_length++;   
    
    int ib = current_length % 64;   
    if(ib<56)   
        ib = 56-ib;   
    else   
        ib = 120 - ib;   
    
    for(i=0;i < ib;i++)   
    {   
        str[current_length]=0x00;   
        current_length++;   
    }   
    str[current_length + 1]='\0';   
    
    for(i=0;i<6;i++)   
    {   
        str[current_length]=0x0;   
        current_length++;   
    }   
    str[current_length] = (original_length * 8) / 0x100 ;   
    current_length++;   
    str[current_length] = (original_length * 8) % 0x100;   
    current_length++;   
    str[current_length+i]='\0';   
    
    int number_of_chunks = current_length/64;   
    unsigned long int word[80];   
    for(i=0;i<number_of_chunks;i++)   
    {   
        for(int j=0;j<16;j++)   
        {   
            word[j] = str[i*64 + j*4 + 0] * 0x1000000 + str[i*64 + j*4 + 1] * 0x10000 + str[i*64 + j*4 + 2] * 0x100 + str[i*64 + j*4 + 3];   
        }   
        for(int j=16;j<80;j++)   
        {   
            word[j] = rotateleft((word[j-3] ^ word[j-8] ^ word[j-14] ^ word[j-16]),1);   
        }   
    
        a = h0;   
        b = h1;   
        c = h2;   
        d = h3;   
        e = h4;   
    
        for(int m=0;m<80;m++)   
        {   
            if(m<=19)   
            {   
                f = (b & c) | ((~b) & d);   
                k = 0x5A827999;   
            }   
            else if(m<=39)   
            {   
                f = b ^ c ^ d;   
                k = 0x6ED9EBA1;   
            }   
            else if(m<=59)   
            {   
                f = (b & c) | (b & d) | (c & d);   
                k = 0x8F1BBCDC;   
            }   
            else   
            {   
                f = b ^ c ^ d;   
                k = 0xCA62C1D6;    
            }   
			//std::cout << word[m] << std::endl;
            temp = (rotateleft(a,5) + f + e + k + word[m]) & 0xFFFFFFFF;   
            if (m==79) {
			std::cout << "+++ " << a << std::endl;
			std::cout << "++ " << rotateleft(a,5) << std::endl;
			}
			e = d;   
            d = c;
            c = rotateleft(b,30);   //std::cout << "++ " << b << std::endl;
            b = a;
			a = temp;   
    
        }   
		//std::cout << "--++ " << c << std::endl;
		//std::cout << b << std::endl;
		//std::cout << c << std::endl;
		//std::cout << h3 << "+" << d << "=" << (h3+d) << std::endl;
		//printf("%x",(h3+d));
		std::cout << std::endl;
		//std::cout << e << std::endl;
        h0 = h0 + a;   
        h1 = h1 + b;   
        h2 = h2 + c;   
        h3 = h3 + d;   
        h4 = h4 + e;   
    
    }   
    
	printf("Hash: %x %x %x %x %x",h0, h1, h2, h3, h4);
	std::cout << std::endl << "Hash: " << h0 << " " << h1 << " " << h2 << " " << h3 << " " << h4 << std::endl;
	
}   
//----------------------------------------------
// edit below
//----------------------------------------------
unsigned long int bin2dec(std::string bin)
{
  unsigned long int result=0;
  for(unsigned int i=0;i<bin.length();i++)
  {
    //if((bin[i]!='0')&&(bin[i]!='1'))
    //  return -1;
    result=result*2+(bin[i]-'0');
    //if(result<=0) return -1;
  }
  return result;
}

std::string *parts8(std::string originalhash) {
	int arr_pos=0;
	std::string chrset="";
	std::string *parts;
	parts = new std::string[5];
	for (int i=0; i<40; i++) {
		double tmp=(i+1)/8;
		arr_pos=floor(tmp)-1;
		tmp=((i+1.0)/8.0)-1.0;

		std::string str;
		str=originalhash.at(i);
		chrset=chrset.append(str.c_str());
		if (arr_pos==tmp) {
			parts[arr_pos]=chrset;
			chrset="";
			}
		}
	
	return parts;
}
char xtod(char c) {
 if (c>='0' && c<='9') return c-'0';
 if (c>='A' && c<='F') return c-'A'+10;
 if (c>='a' && c<='f') return c-'a'+10;
 return c=0;        // not Hex digit
}
/*long hex2int(const std::string& hexStr) {
  
  char *offset;

  if (hexStr.length( ) > 2) {
    if (hexStr[0] == '0' && hexStr[1] == 'x') {
      return strtol(hexStr.c_str( ), &offset, 0);
    }else{
		std::string str="0x";
		str.append(hexStr);
		return strtol(str.c_str( ), &offset, 0);
    }
  }
  
  }*/
typedef __int64 int64;
 
int64 hexToInt64(const std::string hexStr){
	std::stringstream strm;
	strm << std::hex << hexStr;
	int64 value = 0;
	if(!(strm >> value)) throw std::exception("Conversion to int64 failed!\n");
	return value;
}
unsigned long int hex2int(const std::string hexString) {
unsigned long int v;
v=hexToInt64(hexString);
return v;
}

std::string dehash_SHA1 (std::string originalhash) {
	if (originalhash.length()!=40) {
		return "^Error: Invalid hash";
	} else {
		std::string *arr;
		arr=parts8(originalhash);
		
		unsigned long int *parts;
		parts = new unsigned long int[5];
	parts[0]=hex2int(arr[0]);
	parts[1]=hex2int(arr[1]);
	parts[2]=hex2int(arr[2]);
	parts[3]=hex2int(arr[3]);
	//std::cout << "Num=" << parts[3] << std::endl;
	parts[4]=hex2int(arr[4]);

	/*std::cout << parts[0] << std::endl;
	std::cout << parts[1] << std::endl;
	std::cout << parts[2] << std::endl;
	std::cout << parts[3] << std::endl;
	std::cout << parts[4] << std::endl;*/
	unsigned long int h0,h1,h2,h3,h4, a,b,c,d,e,k,f, ulong,temp,val;
	unsigned int zplus;
	zplus=500;
	unsigned long int worddata[80][500];
    unsigned long int worddata2[80][16];
	h0 = 0x67452301;
    h1 = 0xEFCDAB89;
    h2 = 0x98BADCFE;
    h3 = 0x10325476;
    h4 = 0xC3D2E1F0;
	ulong = 4294967295;
	ulong = 18446744073709551615;
	//std::cout << std::endl << parts[3] << "-" << h3 << "=" << (parts[3]-h3) << std::endl;
	
	// --- loop beginning --- //
	a=parts[0]-h0; parts[0]=a;
	b=parts[1]-h1; parts[1]=b;
	c=parts[2]-h2; parts[2]=c;
	d=parts[3]-h3; parts[3]=d;
	e=parts[4]-h4; parts[4]=e;
	
	for (int m=79; m>=0; m--) {
		if(m<=19)   
            {   
                f = (b & c) | ((~b) & d);   
                k = 0x5A827999;   
            }   
            else if(m<=39)   
            {   
                f = b ^ c ^ d;   
                k = 0x6ED9EBA1;   
            }   
            else if(m<=59)   
            {   
                f = (b & c) | (b & d) | (c & d);   
                k = 0x8F1BBCDC;   
            }   
            else   
            {   
                f = b ^ c ^ d;   
                k = 0xCA62C1D6;    
            } 
		//c = rotateright();
		//std::cout << "++" << b << std::endl;
		//std::cout << "++" << b << std::endl;
		//std::cout << "++" << c << std::endl;
		//temp is smaller than var a;
			/*temp = (rotateleft(a,5) + f + e + k + word[m]) & 0xFFFFFFFF;   
            e = d;   
            d = c;
            c = rotateleft(b,30);  //// std::cout << "++ " << b << std::endl;
            b = a;   
            a = temp;*/
			
			temp = a;
			val=0;
			while (true) {
				if ((( f + e + k + val) & 0xFFFFFFFF)==temp) {
				break;
				} else {
				val++;
				if ((( f + e + k + val + 1000000) & 0xFFFFFFFF)<temp) {
					val+=1000000;
					}
				}
			}
			unsigned int zz=1;
			for (unsigned int z=0;z<zplus;z++) {
				if (rotateleft(zz,5)<val) {
					if (rotateleft(zz,5)>0) {
						worddata[m][z]=rotateleft(zz,5);
						std::cout << worddata[m][z] << std::endl;
					}
				}
				zz++;
			}
			std::cout << std::endl;
			/*
			val = rotateleft(a,5) + word[m] The current value of val
			worddata[x] contains the possible numbers of word[m].
			worddata2 needs to be populated by going through the array worddata
			and changing the last for binary digits to 1010, 1101, 1011 etc.

			Get number smaller than the val variable and it's binary value ends in 00000
			That is ends in 5 zeros for it's binary value.
			*/
            a = b;
			if (m==78) {
			std::cout << a << std::endl;
			}
            b = rotateright(c,30);
			c = d;
			d = e;
		}
	//std::cout << d << std::endl;
	//std::cout << std::endl << parts[0] << std::endl;
	//std::cout << parts[1] << std::endl;
	//std::cout << parts[2] << std::endl;
	//std::cout << parts[3] << "--" << 0x10325476 << std::endl;
	//std::cout << parts[4] << std::endl;

	return "";
	}
}

void main()   
{   
	std::string tmp;
	coda:
	system("CLS");
    SHA1((unsigned char *)"The quick brown fox jumps over the lazy dog");
	
	//above and below are same hash

	tmp=dehash_SHA1("2fd4e1c67a2d28fced849ee1bb76e7391b93eb12");
	std::cout << tmp.c_str() << std::endl;

	std::cout << std::endl;
	std::cout << bin2dec("1101") << std::endl;

	system("PAUSE");
	goto coda;
}
cwarn23
Occupation: Genius
Team Colleague
3,033 posts since Sep 2007
Reputation Points: 413
Solved Threads: 259
 
goto coda;


Infamous phrase gOtO ;)

evstevemd
Senior Poster
3,713 posts since Jun 2007
Reputation Points: 462
Solved Threads: 392
 
Infamous phrase gOtO ;)

I don't see how that stops without ctrl-c. You are trying to match the phrase to it's hash code? How do you know when you got it?
My c++ is a bit rusty, but I guess you started in c and decided c++ was easier to deal with?. I'm not going to pretend that I know anything about code cracking. I don't understand what you are displaying in main() . I think it will look like one of those cracking devices they use in the movies where they attach the thing to an electronic safe and it rotates through a number sequences till the safe pops open?

JRM
Practically a Master Poster
621 posts since Nov 2006
Reputation Points: 130
Solved Threads: 75
 

I dunno either.
It burned a few minutes of CPU time, and printed out 0 to 16000 (in steps of 32) a total of 80 times.

But even uncommenting some extra print statements around line 320 (which would appear to be the result) didn't leave me any the wiser.

Salem
Posting Sage
Team Colleague
11,531 posts since Dec 2005
Reputation Points: 5,862
Solved Threads: 953
 

This is way beyond me, but looks really impressive. Does it work? If so, is SHA1 doomed?

diafol
Rhod Gilbert Fan (ardav)
Moderator
7,792 posts since Oct 2006
Reputation Points: 1,170
Solved Threads: 1,080
 
I dunno either.
It burned a few minutes of CPU time, and printed out 0 to 16000 (in steps of 32) a total of 80 times.

But even uncommenting some extra print statements around line 320 (which would appear to be the result) didn't leave me any the wiser.

What you saw was the raw diagnostics checking the comparisons for the dehash vs hash. At the moment I managed to get a match on the first loop for two variables added and and am working on separating those two variables to allow all loop rounds work and to get the core data. So at the moment I haven't completed it but am coming very close.This is way beyond me, but looks really impressive. Does it work? If so, is SHA1 doomed?
Yes sha1 is doomed and it will be soon before it is cracked.

cwarn23
Occupation: Genius
Team Colleague
3,033 posts since Sep 2007
Reputation Points: 413
Solved Threads: 259
 

What you saw was the raw diagnostics checking the comparisons for the dehash vs hash. At the moment I managed to get a match on the first loop for two variables added and and am working on separating those two variables to allow all loop rounds work and to get the core data. So at the moment I haven't completed it but am coming very close.

yes sha1 is doomed and it will be soon before it is cracked.

Doesn't the algorithm encode based on the ENTIRE input? I would guess that it makes a hex representation of the string probably from th ascii value, then applies the encryption. So, the string randomizes the resultant hash.
Making a two variable match could even be a random result. Do you get matches with ANY OTHER input?

Logically, I don't see how you think you can crack sha1, one variable at time.
What's the science behind your approach?

JRM
Practically a Master Poster
621 posts since Nov 2006
Reputation Points: 130
Solved Threads: 75
 
What's the science behind your approach?


Basically reversing the math and reversing the algorithm to get the reverse result. I know with any good algorithm that should be impossible but with SHA1 I have been having great success. IMO SHA1 is Insecure Hash Algorithm because it has so many security floors.

cwarn23
Occupation: Genius
Team Colleague
3,033 posts since Sep 2007
Reputation Points: 413
Solved Threads: 259
 

This article has been dead for over three months

Post: Markdown Syntax: Formatting Help
You