Click here to Skip to main content
15,867,568 members
Articles / Programming Languages / Objective C

NTLM Hash Generator

Rate me:
Please Sign up or sign in to vote.
4.64/5 (11 votes)
13 Feb 2012CPOL2 min read 62.4K   1.9K   23   10
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)


Written By
Software Developer (Senior)
Turkey Turkey
I began programming in Visual Basic 6.0. Coded applications in various branchs. Then, learned C programming language in university and deeply loved it. Now, I develop Win32 and MFC applications in native and pure C++.

Comments and Discussions

 
QuestionBug Pin
Member 396510311-Jan-21 3:20
Member 396510311-Jan-21 3:20 
GeneralMy vote of 5 Pin
johnnyreid7-Oct-20 14:40
johnnyreid7-Oct-20 14:40 
This is awesome work - thanks for putting in the effort!
GeneralMy vote of 5 Pin
johnnyreid7-Oct-20 14:39
johnnyreid7-Oct-20 14:39 
QuestionHow to fix the code to support password length more than 27 character Pin
replyam10-Aug-17 1:47
replyam10-Aug-17 1:47 
Questionwindows.h Pin
WigiPedia30-Aug-16 6:49
WigiPedia30-Aug-16 6:49 
AnswerRe: windows.h Pin
Rick York30-Aug-16 7:48
mveRick York30-Aug-16 7:48 
AnswerRe: windows.h Pin
Mustafa Chelik20-Apr-17 0:16
Mustafa Chelik20-Apr-17 0:16 
QuestionCopy and Paste and also Wrong Pin
Jose A Pascoa19-Aug-15 22:01
Jose A Pascoa19-Aug-15 22:01 
GeneralC# version Pin
Mattias Larsson27-Jun-12 3:18
Mattias Larsson27-Jun-12 3:18 
GeneralRe: C# version Pin
Mustafa Chelik27-Jun-12 13:21
Mustafa Chelik27-Jun-12 13:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.