forked from jclulow/node-smbhash
-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix: Resolved compatability issue hashing with openssl v3 by replacin…
…g native calls with pure JS deps
- Loading branch information
Showing
8 changed files
with
78 additions
and
73 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
node_modules | ||
.*.swp | ||
.vscode | ||
yarn.lock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,7 +14,8 @@ | |
* Copyright (C) 2012 Joshua M. Clulow <[email protected]> | ||
*/ | ||
|
||
var crypto = require('crypto'); | ||
var { DES } = require('des.js'); | ||
var md4 = require('js-md4'); | ||
|
||
function zeroextend(str, len) | ||
{ | ||
|
@@ -46,7 +47,7 @@ function oddpar(buf) | |
*/ | ||
function expandkey(key56) | ||
{ | ||
var key64 = new Buffer(8); | ||
var key64 = Buffer.alloc(8); | ||
|
||
key64[0] = key56[0] & 0xFE; | ||
key64[1] = ((key56[0] << 7) & 0xFF) | (key56[1] >> 1); | ||
|
@@ -65,13 +66,41 @@ function expandkey(key56) | |
*/ | ||
function bintohex(bin) | ||
{ | ||
var buf = (Buffer.isBuffer(buf) ? buf : new Buffer(bin, 'binary')); | ||
var buf = (Buffer.isBuffer(buf) ? buf : Buffer.from(bin, 'binary')); | ||
var str = buf.toString('hex').toUpperCase(); | ||
return zeroextend(str, 32); | ||
} | ||
|
||
function calculateDES(key, message) { | ||
var desKey = new Buffer.alloc(8); | ||
desKey[0] = key[0] & 0xFE; | ||
desKey[1] = ((key[0] << 7) & 0xFF) | (key[1] >> 1); | ||
desKey[2] = ((key[1] << 6) & 0xFF) | (key[2] >> 2); | ||
desKey[3] = ((key[2] << 5) & 0xFF) | (key[3] >> 3); | ||
desKey[4] = ((key[3] << 4) & 0xFF) | (key[4] >> 4); | ||
desKey[5] = ((key[4] << 3) & 0xFF) | (key[5] >> 5); | ||
desKey[6] = ((key[5] << 2) & 0xFF) | (key[6] >> 6); | ||
desKey[7] = (key[6] << 1) & 0xFF; | ||
for (var i = 0; i < 8; i++) { | ||
var parity = 0; | ||
for (var j = 1; j < 8; j++) { | ||
parity += (desKey[i] >> j) % 2; | ||
} | ||
desKey[i] |= (parity % 2) === 0 ? 1 : 0; | ||
} | ||
var des = DES.create({ type: 'encrypt', key: desKey}); | ||
return Buffer.from(des.update(message)); | ||
} | ||
|
||
function calculateMD4(message) { | ||
var md4sum = md4.create(); | ||
md4sum.update(new Buffer.from(message, 'ucs2')); | ||
return Buffer.from(md4sum.buffer()); | ||
} | ||
|
||
module.exports.zeroextend = zeroextend; | ||
module.exports.oddpar = oddpar; | ||
module.exports.expandkey = expandkey; | ||
module.exports.bintohex = bintohex; | ||
module.exports.calculateDES = calculateDES; | ||
module.exports.calculateMD4 = calculateMD4; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,12 +14,10 @@ | |
* Copyright (C) 2012 Joshua M. Clulow <[email protected]> | ||
*/ | ||
|
||
var log = console.log; | ||
var crypto = require('crypto'); | ||
const { url } = require('inspector'); | ||
var $ = require('./common'); | ||
var lmhashbuf = require('./smbhash').lmhashbuf; | ||
var nthashbuf = require('./smbhash').nthashbuf; | ||
|
||
var { lmhashbuf, nthashbuf } = require('./smbhash'); | ||
var { URL } = require('url'); | ||
|
||
function encodeType1(hostname, ntdomain) { | ||
hostname = hostname.toUpperCase(); | ||
|
@@ -28,7 +26,7 @@ function encodeType1(hostname, ntdomain) { | |
var ntdomainlen = Buffer.byteLength(ntdomain, 'ascii'); | ||
|
||
var pos = 0; | ||
var buf = new Buffer(32 + hostnamelen + ntdomainlen); | ||
var buf = Buffer.alloc(32 + hostnamelen + ntdomainlen); | ||
|
||
buf.write('NTLMSSP', pos, 7, 'ascii'); // byte protocol[8]; | ||
pos += 7; | ||
|
@@ -102,15 +100,10 @@ function encodeType3(username, hostname, ntdomain, nonce, password) { | |
hostname = hostname.toUpperCase(); | ||
ntdomain = ntdomain.toUpperCase(); | ||
|
||
var lmh = new Buffer(21); | ||
lmhashbuf(password).copy(lmh); | ||
lmh.fill(0x00, 16); // null pad to 21 bytes | ||
var nth = new Buffer(21); | ||
nthashbuf(password).copy(nth); | ||
nth.fill(0x00, 16); // null pad to 21 bytes | ||
const challenge = new Buffer.from(nonce, 'ascii') | ||
|
||
var lmr = makeResponse(lmh, nonce); | ||
var ntr = makeResponse(nth, nonce); | ||
var lmr = makeResponse(lmhashbuf(password), challenge); | ||
var ntr = makeResponse(nthashbuf(password), challenge); | ||
|
||
var usernamelen = Buffer.byteLength(username, 'ucs2'); | ||
var hostnamelen = Buffer.byteLength(hostname, 'ucs2'); | ||
|
@@ -126,7 +119,7 @@ function encodeType3(username, hostname, ntdomain, nonce, password) { | |
|
||
var pos = 0; | ||
var msg_len = 64 + ntdomainlen + usernamelen + hostnamelen + lmrlen + ntrlen; | ||
var buf = new Buffer(msg_len); | ||
var buf = Buffer.alloc(msg_len); | ||
|
||
buf.write('NTLMSSP', pos, 7, 'ascii'); // byte protocol[8]; | ||
pos += 7; | ||
|
@@ -203,16 +196,18 @@ function encodeType3(username, hostname, ntdomain, nonce, password) { | |
return buf; | ||
} | ||
|
||
function makeResponse(hash, nonce) | ||
function makeResponse(lmhash, challenge) | ||
{ | ||
var out = new Buffer(24); | ||
for (var i = 0; i < 3; i++) { | ||
var keybuf = $.oddpar($.expandkey(hash.slice(i * 7, i * 7 + 7))); | ||
var des = crypto.createCipheriv('DES-ECB', keybuf, ''); | ||
var str = des.update(nonce.toString('binary'), 'binary', 'binary'); | ||
out.write(str, i * 8, i * 8 + 8, 'binary'); | ||
} | ||
return out; | ||
let buf = new Buffer.alloc(24), | ||
pwBuffer = new Buffer.alloc(21).fill(0); | ||
|
||
lmhash.copy(pwBuffer); | ||
|
||
$.calculateDES(pwBuffer.slice(0, 7), challenge).copy(buf); | ||
$.calculateDES(pwBuffer.slice(7, 14), challenge).copy(buf, 8); | ||
$.calculateDES(pwBuffer.slice(14), challenge).copy(buf, 16); | ||
|
||
return buf; | ||
} | ||
|
||
exports.encodeType1 = encodeType1; | ||
|
@@ -226,9 +221,9 @@ exports.challengeHeader = function (hostname, domain) { | |
}; | ||
|
||
exports.responseHeader = function (res, url, domain, username, password) { | ||
var serverNonce = new Buffer((res.headers['www-authenticate'].match(/^NTLM\s+(.+?)(,|\s+|$)/) || [])[1], 'base64'); | ||
var hostname = require('url').parse(url).hostname; | ||
return 'NTLM ' + exports.encodeType3(username, hostname, domain, exports.decodeType2(serverNonce), password).toString('base64') | ||
const serverNonce = Buffer.from((res.headers['www-authenticate'].match(/^NTLM\s+(.+?)(,|\s+|$)/) || [])[1], 'base64'); | ||
const host = new URL(url).host; | ||
return 'NTLM ' + exports.encodeType3(username, host, domain, exports.decodeType2(serverNonce), password).toString('base64'); | ||
}; | ||
|
||
// Import smbhash module. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,53 +14,29 @@ | |
* Copyright (C) 2011-2012 Joshua M. Clulow <[email protected]> | ||
*/ | ||
|
||
var crypto = require('crypto'); | ||
var $ = require('./common'); | ||
|
||
/* | ||
* Generate the LM Hash | ||
*/ | ||
function lmhashbuf(inputstr) | ||
function lmhashbuf(password) | ||
{ | ||
/* ASCII --> uppercase */ | ||
var x = inputstr.substring(0, 14).toUpperCase(); | ||
var xl = Buffer.byteLength(x, 'ascii'); | ||
let pwBuffer = new Buffer.alloc(14), | ||
magicKey = new Buffer.from('KGS!@#$%', 'ascii'); | ||
|
||
/* null pad to 14 bytes */ | ||
var y = new Buffer(14); | ||
y.write(x, 0, xl, 'ascii'); | ||
y.fill(0, xl); | ||
if (password.length > 14) { | ||
password = password.slice(0, ); | ||
} | ||
|
||
/* insert odd parity bits in key */ | ||
var halves = [ | ||
$.oddpar($.expandkey(y.slice(0, 7))), | ||
$.oddpar($.expandkey(y.slice(7, 14))) | ||
]; | ||
pwBuffer.fill(0); | ||
pwBuffer.write(password.toUpperCase(), 0, 'ascii'); | ||
|
||
/* DES encrypt magic number "KGS!@#$%" to two | ||
* 8-byte ciphertexts, (ECB, no padding) | ||
*/ | ||
var buf = new Buffer(16); | ||
var pos = 0; | ||
var cts = halves.forEach(function(z) { | ||
var des = crypto.createCipheriv('DES-ECB', z, ''); | ||
var str = des.update('KGS!@#$%', 'binary', 'binary'); | ||
buf.write(str, pos, pos + 8, 'binary'); | ||
pos += 8; | ||
}); | ||
|
||
/* concat the two ciphertexts to form 16byte value, | ||
* the LM hash */ | ||
return buf; | ||
return Buffer.from([...$.calculateDES(pwBuffer.slice(0, 7), magicKey), ...$.calculateDES(pwBuffer.slice(7), magicKey)]); | ||
} | ||
|
||
function nthashbuf(str) | ||
function nthashbuf(password) | ||
{ | ||
/* take MD4 hash of UCS-2 encoded password */ | ||
var ucs2 = new Buffer(str, 'ucs2'); | ||
var md4 = crypto.createHash('md4'); | ||
md4.update(ucs2); | ||
return new Buffer(md4.digest('binary'), 'binary'); | ||
return $.calculateMD4(password) | ||
} | ||
|
||
function lmhash(is) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,8 +14,7 @@ | |
* Copyright (C) 2011-2012 Joshua M. Clulow <[email protected]> | ||
*/ | ||
|
||
var lmhash = require('..').smbhash.lmhash; | ||
var nthash = require('..').smbhash.nthash; | ||
const { lmhash, nthash } = require('../lib/smbhash'); | ||
|
||
var GOOD = [ | ||
{ password: 'pass123', | ||
|