Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Objective-C

NTLM Hash Generator

4.64/5 (11 votes)
13 Feb 2012CPOL2 min read 64.3K   1.9K  
Calculates NTLM hash of given string in pure C/C++

Introduction

The project is NTLM hash generator in pure C/C++ (without using windows APIs or libraries). It's useful for developers whom want to work with windows authentication related projects, rainbow table etc.

The code is clean and easy to use. You are completely free to use my code.

Using the Project

Using Code:

Briefly, you should call NTLM() function like this:

C++
NTLM("password");
printf("%s", hex_format); //hex_format contains the NTLM hash

Using Compiled Executable:

ntlm.exe STRING

snapshot.JPG

Code Explanation

The project contains just two functions: NTLM and main

First function:

C++
void NTLM(char *key)  

The NTLM() function has one char array parameter. It's the string that NTLM hash of that should be calculated. If you want to use NTLM() function in your code, just copy/paste it (don't forget to copy my global definitions too).

Before starting of hash calculation, there is a piece of code:

C++
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 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;

The code maps the string to sixteen unsigned ints. That's the way hash calculation starts to process. unsigned ints are input of hash calculation.

Calculation of NTLM has 3 phrases that I marked them in comments like this:

C++
/* 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);

If you are interested of NTLM hash calculation's phrases deeply, you should read about how MD4 hash works. Because NTLM is MD4 of the little endian UTF-16 Unicode.

After "Round 3", hash is ready. The last part of NTLM() function, converts calculated hash to hex. Because hex is more readable to human.

C++
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 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;

When NTLM() function returns, the hex format of hash is in hex_format data member. You can show it using printf() or MessageBox(), or write it to a file.

Second function:

C++
int main(int argc, char *argv[]) 

The main() function just passes the application's parameter to the NTLM() function:

C++
if(argc == 2)
{
    NTLM(argv[1]);
    printf("\r\nNTLM of %s is: %s\r\n", argv[1], hex_format);
}
else
    printf("usage: ntlm.exe STRING_FOR_NTLM_HASH_CALCULATION");
return 0;

It's for demo. You can delete it.

Guarantee

You can check my project's accuracy using online hash calculators like this one: OnlineHashCrack.com (I don't want to advertise this site. I found it via Google).

Don't be afraid of my code's accuracy. It's flawless; although I tested it thousand times.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)