UNPKG

tedious

Version:

A TDS driver, for connecting to MS SQLServer databases.

179 lines (161 loc) 6.13 kB
// Generated by CoffeeScript 1.7.1 var BigInteger, NTLMResponsePayload, WritableTrackingBuffer, crypto, hex; BigInteger = require('big-number').n; crypto = require('crypto'); hex = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f']; WritableTrackingBuffer = require('./tracking-buffer/writable-tracking-buffer'); NTLMResponsePayload = (function() { function NTLMResponsePayload(loginData) { this.data = this.createResponse(loginData); } NTLMResponsePayload.prototype.toString = function(indent) { indent || (indent = ''); return indent + 'NTLM Auth'; }; NTLMResponsePayload.prototype.createResponse = function(challenge) { var baseIdx, bufferLength, client_nonce, data, dnIdx, domain, genTime, l2Idx, lmv2Data, lmv2len, ntIdx, ntlmData, ntlmv2len, password, server_data, server_nonce, timestamp, unIdx, username; client_nonce = this.createClientNonce(); lmv2len = 24; ntlmv2len = 16; domain = challenge.domain; username = challenge.userName; password = challenge.password; ntlmData = challenge.ntlmpacket; server_data = ntlmData.target; server_nonce = ntlmData.nonce; bufferLength = 64 + (domain.length * 2) + (username.length * 2) + lmv2len + ntlmv2len + 8 + 8 + 8 + 4 + server_data.length + 4; data = new WritableTrackingBuffer(bufferLength); data.position = 0; data.writeString('NTLMSSP\u0000', 'utf8'); data.writeUInt32LE(0x03); baseIdx = 64; dnIdx = baseIdx; unIdx = dnIdx + domain.length * 2; l2Idx = unIdx + username.length * 2; ntIdx = l2Idx + lmv2len; data.writeUInt16LE(lmv2len); data.writeUInt16LE(lmv2len); data.writeUInt32LE(l2Idx); data.writeUInt16LE(ntlmv2len); data.writeUInt16LE(ntlmv2len); data.writeUInt32LE(ntIdx); data.writeUInt16LE(domain.length * 2); data.writeUInt16LE(domain.length * 2); data.writeUInt32LE(dnIdx); data.writeUInt16LE(username.length * 2); data.writeUInt16LE(username.length * 2); data.writeUInt32LE(unIdx); data.writeUInt16LE(0); data.writeUInt16LE(0); data.writeUInt32LE(baseIdx); data.writeUInt16LE(0); data.writeUInt16LE(0); data.writeUInt32LE(baseIdx); data.writeUInt16LE(0x8201); data.writeUInt16LE(0x08); data.writeString(domain, 'ucs2'); data.writeString(username, 'ucs2'); lmv2Data = this.lmv2Response(domain, username, password, server_nonce, client_nonce); data.copyFrom(lmv2Data); genTime = (new Date).getTime(); ntlmData = this.ntlmv2Response(domain, username, password, server_nonce, server_data, client_nonce, genTime); data.copyFrom(ntlmData); data.writeUInt32LE(0x0101); data.writeUInt32LE(0x0000); timestamp = this.createTimestamp(genTime); data.copyFrom(timestamp); data.copyFrom(client_nonce); data.writeUInt32LE(0x0000); data.copyFrom(server_data); data.writeUInt32LE(0x0000); return data.data; }; NTLMResponsePayload.prototype.createClientNonce = function() { var client_nonce, nidx; client_nonce = new Buffer(8); nidx = 0; while (nidx < 8) { client_nonce.writeUInt8(Math.ceil(Math.random() * 255), nidx); nidx++; } return client_nonce; }; NTLMResponsePayload.prototype.ntlmv2Response = function(domain, user, password, serverNonce, targetInfo, clientNonce, mytime) { var data, dataLength, hash, timestamp; timestamp = this.createTimestamp(mytime); hash = this.ntv2Hash(domain, user, password); dataLength = 40 + targetInfo.length; data = new Buffer(dataLength); serverNonce.copy(data, 0, 0, 8); data.writeUInt32LE(0x101, 8); data.writeUInt32LE(0x0, 12); timestamp.copy(data, 16, 0, 8); clientNonce.copy(data, 24, 0, 8); data.writeUInt32LE(0x0, 32); targetInfo.copy(data, 36, 0, targetInfo.length); data.writeUInt32LE(0x0, 36 + targetInfo.length); return this.hmacMD5(data, hash); }; NTLMResponsePayload.prototype.createTimestamp = function(time) { var hexArray, idx, pair, tenthsOfAMicrosecond; tenthsOfAMicrosecond = new BigInteger(time).plus(11644473600).multiply(10000000); hexArray = []; pair = []; while (tenthsOfAMicrosecond.val() !== '0') { idx = tenthsOfAMicrosecond.mod(16); pair.unshift(hex[idx]); if (pair.length === 2) { hexArray.push(pair.join('')); pair = []; } } if (pair.length > 0) { hexArray.push(pair[0] + '0'); } return new Buffer(hexArray.join(''), 'hex'); }; NTLMResponsePayload.prototype.lmv2Response = function(domain, user, password, serverNonce, clientNonce) { var data, hash, newhash, response; hash = this.ntv2Hash(domain, user, password); data = new Buffer(serverNonce.length + clientNonce.length); serverNonce.copy(data); clientNonce.copy(data, serverNonce.length, 0, clientNonce.length); newhash = this.hmacMD5(data, hash); response = new Buffer(newhash.length + clientNonce.length); newhash.copy(response); clientNonce.copy(response, newhash.length, 0, clientNonce.length); return response; }; NTLMResponsePayload.prototype.ntv2Hash = function(domain, user, password) { var hash, identity; hash = this.ntHash(password); identity = new Buffer(user.toUpperCase() + domain.toUpperCase(), 'ucs2'); return this.hmacMD5(identity, hash); }; NTLMResponsePayload.prototype.ntHash = function(text) { var hash, md4, unicodeString; hash = new Buffer(21); hash.fill(0); unicodeString = new Buffer(text, 'ucs2'); md4 = crypto.createHash('md4').update(unicodeString).digest(); if (md4.copy) { md4.copy(hash); } else { new Buffer(md4, 'ascii').copy(hash); } return hash; }; NTLMResponsePayload.prototype.hmacMD5 = function(data, key) { var hmac, result; hmac = crypto.createHmac('MD5', key); hmac.update(data); result = hmac.digest(); if (result.copy) { return result; } else { return new Buffer(result, 'ascii').slice(0, 16); } }; return NTLMResponsePayload; })(); module.exports = NTLMResponsePayload;