C Saved Program: ferrous-terrain

facebook share

Here's the online compiler accompanied with IDE at your service. This is a saved code by one of our users. Try it out or save your own from the IDE page and don't forget to leave a feedback. You can find that at the bottom of the page.


#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>

int len;
clock_t tic;
unsigned long total;
static const char alphabet[] =
	"abcdefghijklmnopqrstuvwxyz" "ABCDEGHIJKLMNOPQRSTUVWXYZ" "01234567890"
	"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";
static const int alphabet_size = sizeof(alphabet) - 1;

static const char lower[] = "abcdefghijklmnopqrstuvwxyz";
static const char upper[] = "ABCDEGHIJKLMNOPQRSTUVWXYZ";
static const char number[] = "0123456789";
static const char symbol[] = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";

#define INIT_A 0x67452301
#define INIT_B 0xefcdab89
#define INIT_C 0x98badcfe
#define INIT_D 0x10325476

#define SQRT_2 0x5a827999
#define SQRT_3 0x6ed9eba1

unsigned int nt_buffer[16];

unsigned int output[4];

char hex_format[33];
char orig_hash[33];

char itoa16[17] = "0123456789ABCDEF";

	// *************************************************************** 
void NTLM(char *key)
{

	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Prepare the string for hash calculation
	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	int i = 0;

	int length = strlen(key);

	memset(nt_buffer, 0, 16 * 4);

	// The length of key need to be <= 27
	for (; i < length / 2; i++)

		nt_buffer[i] = key[2 * i] | (key[2 * i + 1] << 16);


	// padding
	if (length % 2 == 1)

		nt_buffer[i] = key[length - 1] | 0x800000;

	else

		nt_buffer[i] = 0x80;

	// put the length
	nt_buffer[14] = length << 4;

	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// NTLM hash calculation
	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	unsigned int a = INIT_A;

	unsigned int b = INIT_B;

	unsigned int c = INIT_C;

	unsigned int d = INIT_D;


	/* Round 1 */
	a += (d ^ (b & (c ^ d))) + nt_buffer[0];
	a = (a << 3) | (a >> 29);

	d += (c ^ (a & (b ^ c))) + nt_buffer[1];
	d = (d << 7) | (d >> 25);

	c += (b ^ (d & (a ^ b))) + nt_buffer[2];
	c = (c << 11) | (c >> 21);

	b += (a ^ (c & (d ^ a))) + nt_buffer[3];
	b = (b << 19) | (b >> 13);


	a += (d ^ (b & (c ^ d))) + nt_buffer[4];
	a = (a << 3) | (a >> 29);

	d += (c ^ (a & (b ^ c))) + nt_buffer[5];
	d = (d << 7) | (d >> 25);

	c += (b ^ (d & (a ^ b))) + nt_buffer[6];
	c = (c << 11) | (c >> 21);

	b += (a ^ (c & (d ^ a))) + nt_buffer[7];
	b = (b << 19) | (b >> 13);


	a += (d ^ (b & (c ^ d))) + nt_buffer[8];
	a = (a << 3) | (a >> 29);

	d += (c ^ (a & (b ^ c))) + nt_buffer[9];
	d = (d << 7) | (d >> 25);

	c += (b ^ (d & (a ^ b))) + nt_buffer[10];
	c = (c << 11) | (c >> 21);

	b += (a ^ (c & (d ^ a))) + nt_buffer[11];
	b = (b << 19) | (b >> 13);


	a += (d ^ (b & (c ^ d))) + nt_buffer[12];
	a = (a << 3) | (a >> 29);

	d += (c ^ (a & (b ^ c))) + nt_buffer[13];
	d = (d << 7) | (d >> 25);

	c += (b ^ (d & (a ^ b))) + nt_buffer[14];
	c = (c << 11) | (c >> 21);

	b += (a ^ (c & (d ^ a))) + nt_buffer[15];
	b = (b << 19) | (b >> 13);


	/* Round 2 */
	a += ((b & (c | d)) | (c & d)) + nt_buffer[0] + SQRT_2;
	a = (a << 3) | (a >> 29);

	d += ((a & (b | c)) | (b & c)) + nt_buffer[4] + SQRT_2;
	d = (d << 5) | (d >> 27);

	c += ((d & (a | b)) | (a & b)) + nt_buffer[8] + SQRT_2;
	c = (c << 9) | (c >> 23);

	b += ((c & (d | a)) | (d & a)) + nt_buffer[12] + SQRT_2;
	b = (b << 13) | (b >> 19);


	a += ((b & (c | d)) | (c & d)) + nt_buffer[1] + SQRT_2;
	a = (a << 3) | (a >> 29);

	d += ((a & (b | c)) | (b & c)) + nt_buffer[5] + SQRT_2;
	d = (d << 5) | (d >> 27);

	c += ((d & (a | b)) | (a & b)) + nt_buffer[9] + SQRT_2;
	c = (c << 9) | (c >> 23);

	b += ((c & (d | a)) | (d & a)) + nt_buffer[13] + SQRT_2;
	b = (b << 13) | (b >> 19);


	a += ((b & (c | d)) | (c & d)) + nt_buffer[2] + SQRT_2;
	a = (a << 3) | (a >> 29);

	d += ((a & (b | c)) | (b & c)) + nt_buffer[6] + SQRT_2;
	d = (d << 5) | (d >> 27);

	c += ((d & (a | b)) | (a & b)) + nt_buffer[10] + SQRT_2;
	c = (c << 9) | (c >> 23);

	b += ((c & (d | a)) | (d & a)) + nt_buffer[14] + SQRT_2;
	b = (b << 13) | (b >> 19);


	a += ((b & (c | d)) | (c & d)) + nt_buffer[3] + SQRT_2;
	a = (a << 3) | (a >> 29);

	d += ((a & (b | c)) | (b & c)) + nt_buffer[7] + SQRT_2;
	d = (d << 5) | (d >> 27);

	c += ((d & (a | b)) | (a & b)) + nt_buffer[11] + SQRT_2;
	c = (c << 9) | (c >> 23);

	b += ((c & (d | a)) | (d & a)) + nt_buffer[15] + SQRT_2;
	b = (b << 13) | (b >> 19);


	/* Round 3 */
	a += (d ^ c ^ b) + nt_buffer[0] + SQRT_3;
	a = (a << 3) | (a >> 29);

	d += (c ^ b ^ a) + nt_buffer[8] + SQRT_3;
	d = (d << 9) | (d >> 23);

	c += (b ^ a ^ d) + nt_buffer[4] + SQRT_3;
	c = (c << 11) | (c >> 21);

	b += (a ^ d ^ c) + nt_buffer[12] + SQRT_3;
	b = (b << 15) | (b >> 17);


	a += (d ^ c ^ b) + nt_buffer[2] + SQRT_3;
	a = (a << 3) | (a >> 29);

	d += (c ^ b ^ a) + nt_buffer[10] + SQRT_3;
	d = (d << 9) | (d >> 23);

	c += (b ^ a ^ d) + nt_buffer[6] + SQRT_3;
	c = (c << 11) | (c >> 21);

	b += (a ^ d ^ c) + nt_buffer[14] + SQRT_3;
	b = (b << 15) | (b >> 17);


	a += (d ^ c ^ b) + nt_buffer[1] + SQRT_3;
	a = (a << 3) | (a >> 29);

	d += (c ^ b ^ a) + nt_buffer[9] + SQRT_3;
	d = (d << 9) | (d >> 23);

	c += (b ^ a ^ d) + nt_buffer[5] + SQRT_3;
	c = (c << 11) | (c >> 21);

	b += (a ^ d ^ c) + nt_buffer[13] + SQRT_3;
	b = (b << 15) | (b >> 17);


	a += (d ^ c ^ b) + nt_buffer[3] + SQRT_3;
	a = (a << 3) | (a >> 29);

	d += (c ^ b ^ a) + nt_buffer[11] + SQRT_3;
	d = (d << 9) | (d >> 23);

	c += (b ^ a ^ d) + nt_buffer[7] + SQRT_3;
	c = (c << 11) | (c >> 21);

	b += (a ^ d ^ c) + nt_buffer[15] + SQRT_3;
	b = (b << 15) | (b >> 17);


	output[0] = a + INIT_A;

	output[1] = b + INIT_B;

	output[2] = c + INIT_C;

	output[3] = d + INIT_D;

	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Convert the hash to hex (for being readable)
	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	for (i = 0; i < 4; i++)

	{

		int j = 0;

		unsigned int n = output[i];

		// iterate the bytes of the integer 
		for (; j < 4; j++)

		{

			unsigned int convert = n % 256;

			hex_format[i * 8 + j * 2 + 1] = itoa16[convert % 16];

			convert = convert / 16;

			hex_format[i * 8 + j * 2 + 0] = itoa16[convert % 16];

			n = n / 256;

		}
	}
	// null terminate the string
	hex_format[33] = 0;

}

void check(char *str)
{
	NTLM(str);
	if ((strcmp(orig_hash, hex_format) == 0))
	{
		printf("Password is: %s", str);
		clock_t toc = clock();
		double elapse = (double)(toc - tic) / CLOCKS_PER_SEC;
		printf("\nElapsed: %f seconds\n", elapse);
		printf("%f Passwords Per Secs.", total / elapse);
		exit(0);
	}
}

int power(long base, int pow)
{
	int temp = base;
	if (pow == 0)
		return 1;
	else if (pow == 1)
		return base;
	else
		for (int i = 2; i <= pow; i++)
		{
			base = base * temp;
		}
	return base;
}

void brute_impl(char *str, int index, int max_depth)
{
	int i;
	for (i = 0; i < alphabet_size; ++i)
	{
		str[index] = alphabet[i];
		if (index == max_depth - 1)
		{
			// printf("%s\n", str); 
			total++;
			check(str);
		}
		else
		{
			brute_impl(str, index + 1, max_depth);
		}
	}
}

void brute_sequential(int min_len, int max_len)
{
	char *buf = malloc(max_len + 1);
	int i;
	for (i = min_len; i <= max_len; ++i)
	{
		memset(buf, 0, max_len + 1);
		brute_impl(buf, 0, i);
	}
	free(buf);
}

int main(void)
{
	printf("Enter NTLM hash for cracking: ");
	scanf("%s", &orig_hash);
	len = strlen(orig_hash);
	if (len == 32)
	{
		printf("Enter length of password: \n");
		printf("Min length(1):");
		int min, max;
		scanf("%d", &min);
		printf("Max length(10):");
		scanf("%d", &max);
		if (min > max)
		{
			int temp;
			temp = min;
			min = max;
			max = temp;
		}
		if (min == 0)
			min = 1;
		tic = clock();
		total = 0;
		brute_sequential(min, max);
		clock_t toc = clock();
		double elapse = (double)(toc - tic) / CLOCKS_PER_SEC;
		printf("Password not found!!!");
		printf("\nElapsed: %f seconds\n", elapse);
		printf("%f Passwords Per Secs.", total / elapse);
		return 0;
	}
	else
		main();
}
Execute

Output

Press the execute button or CTRL + enter to run code.

Inputs