2 * These are NTLM authentication routines for the main module of CNTLM
4 * CNTLM is free software; you can redistribute it and/or modify it under the
5 * terms of the GNU General Public License as published by the Free Software
6 * Foundation; either version 2 of the License, or (at your option) any later
9 * CNTLM is distributed in the hope that it will be useful, but WITHOUT ANY
10 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
16 * St, Fifth Floor, Boston, MA 02110-1301, USA.
18 * Copyright (c) 2007 David Kubicek
35 static void ntlm_set_key(unsigned char *src
, gl_des_ctx
*context
) {
39 key
[1] = ((src
[0] << 7) & 0xff) | (src
[1] >> 1);
40 key
[2] = ((src
[1] << 6) & 0xff) | (src
[2] >> 2);
41 key
[3] = ((src
[2] << 5) & 0xff) | (src
[3] >> 3);
42 key
[4] = ((src
[3] << 4) & 0xff) | (src
[4] >> 4);
43 key
[5] = ((src
[4] << 3) & 0xff) | (src
[5] >> 5);
44 key
[6] = ((src
[5] << 2) & 0xff) | (src
[6] >> 6);
45 key
[7] = (src
[6] << 1) & 0xff;
47 gl_des_setkey(context
, key
);
50 static int ntlm_calc_resp(char **dst
, char *keys
, char *challenge
) {
55 ntlm_set_key(MEM(keys
, unsigned char, 0), &context
);
56 gl_des_ecb_encrypt(&context
, challenge
, *dst
);
58 ntlm_set_key(MEM(keys
, unsigned char, 7), &context
);
59 gl_des_ecb_encrypt(&context
, challenge
, *dst
+8);
61 ntlm_set_key(MEM(keys
, unsigned char, 14), &context
);
62 gl_des_ecb_encrypt(&context
, challenge
, *dst
+16);
67 static void ntlm2_calc_resp(char **nthash
, int *ntlen
, char **lmhash
, int *lmlen
,
68 char *passnt2
, char *challenge
, int tbofs
, int tblen
) {
69 char *tmp
, *blob
, *nonce
, *buf
;
74 VAL(nonce
, uint64_t, 0) = ((uint64_t)random() << 32) | random();
75 tw
= ((uint64_t)time(NULL
) + 11644473600LLU) * 10000000LLU;
78 tmp
= printmem(nonce
, 8, 7);
80 printf("NTLMv2:\n\t Nonce: %s\n\tTimestamp: %"PRId64
"\n", tmp
, tw
);
82 printf("NTLMv2:\n\t Nonce: %s\n\tTimestamp: %ld\n", tmp
, tw
);
87 blob
= new(4+4+8+8+4+tblen
+4 + 1);
88 VAL(blob
, uint32_t, 0) = U32LE(0x00000101);
89 VAL(blob
, uint32_t, 4) = U32LE(0);
90 VAL(blob
, uint64_t, 8) = U64LE(tw
);
91 VAL(blob
, uint64_t, 16) = U64LE(VAL(nonce
, uint64_t, 0));
92 VAL(blob
, uint32_t, 24) = U32LE(0);
93 memcpy(blob
+28, MEM(challenge
, char, tbofs
), tblen
);
94 VAL(blob
, uint32_t, 28+tblen
) = U32LE(0);
98 tmp
= printmem(blob
, blen
, 7);
99 printf("\t Blob: %s (%d)\n", tmp
, blen
);
104 *nthash
= new(*ntlen
+ 1);
105 buf
= new(8+blen
+ 1);
106 memcpy(buf
, MEM(challenge
, char, 24), 8);
107 memcpy(buf
+8, blob
, blen
);
108 hmac_md5(passnt2
, 16, buf
, 8+blen
, *nthash
);
109 memcpy(*nthash
+16, blob
, blen
);
113 *lmhash
= new(*lmlen
+ 1);
115 memcpy(buf
, MEM(challenge
, char, 24), 8);
116 memcpy(buf
+8, nonce
, 8);
117 hmac_md5(passnt2
, 16, buf
, 16, *lmhash
);
118 memcpy(*lmhash
+16, nonce
, 8);
126 static void ntlm2sr_calc_rest(char **nthash
, int *ntlen
, char **lmhash
, int *lmlen
, char *passnt
, char *challenge
) {
127 char *sess
, *nonce
, *buf
;
130 VAL(nonce
, uint64_t, 0) = ((uint64_t)random() << 32) | random();
133 *lmhash
= new(*lmlen
+ 1);
134 memcpy(*lmhash
, nonce
, 8);
135 memset(*lmhash
+8, 0, 16);
139 memcpy(buf
, MEM(challenge
, char, 24), 8);
140 memcpy(buf
+8, nonce
, 8);
141 md5_buffer(buf
, 16, sess
);
145 ntlm_calc_resp(nthash
, passnt
, sess
);
152 char *ntlm_hash_lm_password(char *password
) {
153 char magic
[8] = {0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
159 uppercase(strncpy(pass
, password
, MIN(14, strlen(password
))));
161 ntlm_set_key(MEM(pass
, unsigned char, 0), &context
);
162 gl_des_ecb_encrypt(&context
, magic
, keys
);
164 ntlm_set_key(MEM(pass
, unsigned char, 7), &context
);
165 gl_des_ecb_encrypt(&context
, magic
, keys
+8);
167 memset(keys
+16, 0, 5);
174 char *ntlm_hash_nt_password(char *password
) {
179 len
= unicode(&u16
, password
);
180 md4_buffer(u16
, len
, keys
);
182 memset(keys
+16, 0, 5);
189 char *ntlm2_hash_password(char *username
, char *domain
, char *password
) {
190 char *tmp
, *buf
, *passnt
, *passnt2
;
193 passnt
= ntlm_hash_nt_password(password
);
195 buf
= new(strlen(username
)+strlen(domain
) + 1);
196 strcat(buf
, username
);
199 len
= unicode(&tmp
, buf
);
201 passnt2
= new(16 + 1);
202 hmac_md5(passnt
, 16, tmp
, len
, passnt2
);
211 int ntlm_request(char **dst
, struct auth_s
*creds
) {
214 uint32_t flags
= 0xb206;
217 dlen
= strlen(creds
->domain
);
218 hlen
= strlen(creds
->workstation
);
221 if (creds
->hashntlm2
)
223 else if (creds
->hashnt
== 2)
225 else if (creds
->hashnt
&& creds
->hashlm
)
227 else if (creds
->hashnt
)
229 else if (creds
->hashlm
)
233 printf("You're requesting with empty auth_s?!\n");
239 flags
= creds
->flags
;
242 printf("NTLM Request:\n");
243 printf("\t Domain: %s\n", creds
->domain
);
244 printf("\t Hostname: %s\n", creds
->workstation
);
245 printf("\t Flags: 0x%X\n", (int)flags
);
248 buf
= new(NTLM_BUFSIZE
);
249 memcpy(buf
, "NTLMSSP\0", 8);
250 VAL(buf
, uint32_t, 8) = U32LE(1);
251 VAL(buf
, uint32_t, 12) = U32LE(flags
);
252 VAL(buf
, uint16_t, 16) = U16LE(dlen
);
253 VAL(buf
, uint16_t, 18) = U16LE(dlen
);
254 VAL(buf
, uint32_t, 20) = U32LE(32 + hlen
);
255 VAL(buf
, uint16_t, 24) = U16LE(hlen
);
256 VAL(buf
, uint16_t, 26) = U16LE(hlen
);
257 VAL(buf
, uint32_t, 28) = U32LE(32);
259 tmp
= uppercase(strdup(creds
->workstation
));
260 memcpy(buf
+32, tmp
, hlen
);
263 tmp
= uppercase(strdup(creds
->domain
));
264 memcpy(buf
+32+hlen
, tmp
, dlen
);
271 static char *printuc(char *src
, int len
) {
275 tmp
= new((len
+1)/2 + 1);
276 for (i
= 0; i
< len
/2; ++i
) {
284 void dump(char *src, int len) {
289 for (i = 0; i < len; ++i) {
290 snprintf(tmp+i*3, 4, "%0hhX ", src[i]);
291 printf("%c ", src[i]);
293 printf("\n%s\n", tmp);
298 int ntlm_response(char **dst
, char *challenge
, int challen
, struct auth_s
*creds
) {
299 char *buf
, *udomain
, *uuser
, *uhost
, *tmp
;
300 int dlen
, ulen
, hlen
;
301 uint16_t tpos
, tlen
, ttype
= -1, tbofs
= 0, tblen
= 0;
302 char *lmhash
= NULL
, *nthash
= NULL
;
303 int lmlen
= 0, ntlen
= 0;
306 printf("NTLM Challenge:\n");
307 tmp
= printmem(MEM(challenge
, char, 24), 8, 7);
308 printf("\tChallenge: %s (len: %d)\n", tmp
, challen
);
310 printf("\t Flags: 0x%X\n", U32LE(VAL(challenge
, uint32_t, 20)));
314 tbofs
= tpos
= U16LE(VAL(challenge
, uint16_t, 44));
315 while (tpos
+4 <= challen
&& (ttype
= U16LE(VAL(challenge
, uint16_t, tpos
)))) {
316 tlen
= U16LE(VAL(challenge
, uint16_t, tpos
+2));
317 if (tpos
+4+tlen
> challen
)
323 printf("\t Server: ");
326 printf("\tNT domain: ");
332 printf("\t Domain: ");
338 printf("\t %3d: ", ttype
);
341 tmp
= printuc(MEM(challenge
, char, tpos
+4), tlen
);
350 if (tblen
&& ttype
== 0)
354 printf("\t TBofs: %d\n\t TBlen: %d\n\t ttype: %d\n", tbofs
, tblen
, ttype
);
358 if (creds
->hashntlm2
&& !tblen
) {
362 if (creds
->hashntlm2
) {
363 ntlm2_calc_resp(&nthash
, &ntlen
, &lmhash
, &lmlen
, creds
->passntlm2
, challenge
, tbofs
, tblen
);
366 if (creds
->hashnt
== 2) {
367 ntlm2sr_calc_rest(&nthash
, &ntlen
, &lmhash
, &lmlen
, creds
->passnt
, challenge
);
370 if (creds
->hashnt
== 1) {
371 ntlen
= ntlm_calc_resp(&nthash
, creds
->passnt
, MEM(challenge
, char, 24));
375 lmlen
= ntlm_calc_resp(&lmhash
, creds
->passlm
, MEM(challenge
, char, 24));
378 if (creds
->hashnt
|| creds
->hashntlm2
) {
379 tmp
= uppercase(strdup(creds
->domain
));
380 dlen
= unicode(&udomain
, tmp
);
382 ulen
= unicode(&uuser
, creds
->user
);
383 tmp
= uppercase(strdup(creds
->workstation
));
384 hlen
= unicode(&uhost
, tmp
);
387 udomain
= uppercase(strdup(creds
->domain
));
388 uuser
= uppercase(strdup(creds
->user
));
389 uhost
= uppercase(strdup(creds
->workstation
));
391 dlen
= strlen(creds
->domain
);
392 ulen
= strlen(creds
->user
);
393 hlen
= strlen(creds
->workstation
);
397 printf("NTLM Response:\n");
398 printf("\t Hostname: '%s'\n", creds
->workstation
);
399 printf("\t Domain: '%s'\n", creds
->domain
);
400 printf("\t Username: '%s'\n", creds
->user
);
402 tmp
= printmem(nthash
, ntlen
, 7);
403 printf("\t Response: '%s' (%d)\n", tmp
, ntlen
);
407 tmp
= printmem(lmhash
, lmlen
, 7);
408 printf("\t Response: '%s' (%d)\n", tmp
, lmlen
);
413 buf
= new(NTLM_BUFSIZE
);
414 memcpy(buf
, "NTLMSSP\0", 8);
415 VAL(buf
, uint32_t, 8) = U32LE(3);
418 VAL(buf
, uint16_t, 12) = U16LE(lmlen
);
419 VAL(buf
, uint16_t, 14) = U16LE(lmlen
);
420 VAL(buf
, uint32_t, 16) = U32LE(64+dlen
+ulen
+hlen
);
423 VAL(buf
, uint16_t, 20) = U16LE(ntlen
);
424 VAL(buf
, uint16_t, 22) = U16LE(ntlen
);
425 VAL(buf
, uint32_t, 24) = U32LE(64+dlen
+ulen
+hlen
+lmlen
);
428 VAL(buf
, uint16_t, 28) = U16LE(dlen
);
429 VAL(buf
, uint16_t, 30) = U16LE(dlen
);
430 VAL(buf
, uint32_t, 32) = U32LE(64);
433 VAL(buf
, uint16_t, 36) = U16LE(ulen
);
434 VAL(buf
, uint16_t, 38) = U16LE(ulen
);
435 VAL(buf
, uint32_t, 40) = U32LE(64+dlen
);
438 VAL(buf
, uint16_t, 44) = U16LE(hlen
);
439 VAL(buf
, uint16_t, 46) = U16LE(hlen
);
440 VAL(buf
, uint32_t, 48) = U32LE(64+dlen
+ulen
);
443 VAL(buf
, uint16_t, 52) = U16LE(0);
444 VAL(buf
, uint16_t, 54) = U16LE(0);
445 VAL(buf
, uint16_t, 56) = U16LE(64+dlen
+ulen
+hlen
+lmlen
+ntlen
);
448 VAL(buf
, uint32_t, 60) = VAL(challenge
, uint32_t, 20);
450 memcpy(MEM(buf
, char, 64), udomain
, dlen
);
451 memcpy(MEM(buf
, char, 64+dlen
), uuser
, ulen
);
452 memcpy(MEM(buf
, char, 64+dlen
+ulen
), uhost
, hlen
);
453 memcpy(MEM(buf
, char, 64+dlen
+ulen
+hlen
), lmhash
, lmlen
);
454 memcpy(MEM(buf
, char, 64+dlen
+ulen
+hlen
+24), nthash
, ntlen
);
466 return 64+dlen
+ulen
+hlen
+lmlen
+ntlen
;