ntlm-payload.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = void 0;
  6. var _writableTrackingBuffer = _interopRequireDefault(require("./tracking-buffer/writable-tracking-buffer"));
  7. var crypto = _interopRequireWildcard(require("crypto"));
  8. var _jsbi = _interopRequireDefault(require("jsbi"));
  9. function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
  10. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; if (obj != null) { var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
  11. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  12. class NTLMResponsePayload {
  13. constructor(loginData) {
  14. this.data = this.createResponse(loginData);
  15. }
  16. toString(indent = '') {
  17. return indent + 'NTLM Auth';
  18. }
  19. createResponse(challenge) {
  20. const client_nonce = this.createClientNonce();
  21. const lmv2len = 24;
  22. const ntlmv2len = 16;
  23. const domain = challenge.domain;
  24. const username = challenge.userName;
  25. const password = challenge.password;
  26. const ntlmData = challenge.ntlmpacket;
  27. const server_data = ntlmData.target;
  28. const server_nonce = ntlmData.nonce;
  29. const bufferLength = 64 + domain.length * 2 + username.length * 2 + lmv2len + ntlmv2len + 8 + 8 + 8 + 4 + server_data.length + 4;
  30. const data = new _writableTrackingBuffer.default(bufferLength);
  31. data.position = 0;
  32. data.writeString('NTLMSSP\u0000', 'utf8');
  33. data.writeUInt32LE(0x03);
  34. const baseIdx = 64;
  35. const dnIdx = baseIdx;
  36. const unIdx = dnIdx + domain.length * 2;
  37. const l2Idx = unIdx + username.length * 2;
  38. const ntIdx = l2Idx + lmv2len;
  39. data.writeUInt16LE(lmv2len);
  40. data.writeUInt16LE(lmv2len);
  41. data.writeUInt32LE(l2Idx);
  42. data.writeUInt16LE(ntlmv2len);
  43. data.writeUInt16LE(ntlmv2len);
  44. data.writeUInt32LE(ntIdx);
  45. data.writeUInt16LE(domain.length * 2);
  46. data.writeUInt16LE(domain.length * 2);
  47. data.writeUInt32LE(dnIdx);
  48. data.writeUInt16LE(username.length * 2);
  49. data.writeUInt16LE(username.length * 2);
  50. data.writeUInt32LE(unIdx);
  51. data.writeUInt16LE(0);
  52. data.writeUInt16LE(0);
  53. data.writeUInt32LE(baseIdx);
  54. data.writeUInt16LE(0);
  55. data.writeUInt16LE(0);
  56. data.writeUInt32LE(baseIdx);
  57. data.writeUInt16LE(0x8201);
  58. data.writeUInt16LE(0x08);
  59. data.writeString(domain, 'ucs2');
  60. data.writeString(username, 'ucs2');
  61. const lmv2Data = this.lmv2Response(domain, username, password, server_nonce, client_nonce);
  62. data.copyFrom(lmv2Data);
  63. const genTime = new Date().getTime();
  64. const ntlmDataBuffer = this.ntlmv2Response(domain, username, password, server_nonce, server_data, client_nonce, genTime);
  65. data.copyFrom(ntlmDataBuffer);
  66. data.writeUInt32LE(0x0101);
  67. data.writeUInt32LE(0x0000);
  68. const timestamp = this.createTimestamp(genTime);
  69. data.copyFrom(timestamp);
  70. data.copyFrom(client_nonce);
  71. data.writeUInt32LE(0x0000);
  72. data.copyFrom(server_data);
  73. data.writeUInt32LE(0x0000);
  74. return data.data;
  75. }
  76. createClientNonce() {
  77. const client_nonce = Buffer.alloc(8, 0);
  78. let nidx = 0;
  79. while (nidx < 8) {
  80. client_nonce.writeUInt8(Math.ceil(Math.random() * 255), nidx);
  81. nidx++;
  82. }
  83. return client_nonce;
  84. }
  85. ntlmv2Response(domain, user, password, serverNonce, targetInfo, clientNonce, mytime) {
  86. const timestamp = this.createTimestamp(mytime);
  87. const hash = this.ntv2Hash(domain, user, password);
  88. const dataLength = 40 + targetInfo.length;
  89. const data = Buffer.alloc(dataLength, 0);
  90. serverNonce.copy(data, 0, 0, 8);
  91. data.writeUInt32LE(0x101, 8);
  92. data.writeUInt32LE(0x0, 12);
  93. timestamp.copy(data, 16, 0, 8);
  94. clientNonce.copy(data, 24, 0, 8);
  95. data.writeUInt32LE(0x0, 32);
  96. targetInfo.copy(data, 36, 0, targetInfo.length);
  97. data.writeUInt32LE(0x0, 36 + targetInfo.length);
  98. return this.hmacMD5(data, hash);
  99. }
  100. createTimestamp(time) {
  101. const tenthsOfAMicrosecond = _jsbi.default.multiply(_jsbi.default.add(_jsbi.default.BigInt(time), _jsbi.default.BigInt(11644473600)), _jsbi.default.BigInt(10000000));
  102. const lo = _jsbi.default.toNumber(_jsbi.default.bitwiseAnd(tenthsOfAMicrosecond, _jsbi.default.BigInt(0xffffffff)));
  103. const hi = _jsbi.default.toNumber(_jsbi.default.bitwiseAnd(_jsbi.default.signedRightShift(tenthsOfAMicrosecond, _jsbi.default.BigInt(32)), _jsbi.default.BigInt(0xffffffff)));
  104. const result = Buffer.alloc(8);
  105. result.writeUInt32LE(lo, 0);
  106. result.writeUInt32LE(hi, 4);
  107. return result;
  108. }
  109. lmv2Response(domain, user, password, serverNonce, clientNonce) {
  110. const hash = this.ntv2Hash(domain, user, password);
  111. const data = Buffer.alloc(serverNonce.length + clientNonce.length, 0);
  112. serverNonce.copy(data);
  113. clientNonce.copy(data, serverNonce.length, 0, clientNonce.length);
  114. const newhash = this.hmacMD5(data, hash);
  115. const response = Buffer.alloc(newhash.length + clientNonce.length, 0);
  116. newhash.copy(response);
  117. clientNonce.copy(response, newhash.length, 0, clientNonce.length);
  118. return response;
  119. }
  120. ntv2Hash(domain, user, password) {
  121. const hash = this.ntHash(password);
  122. const identity = Buffer.from(user.toUpperCase() + domain.toUpperCase(), 'ucs2');
  123. return this.hmacMD5(identity, hash);
  124. }
  125. ntHash(text) {
  126. const hash = Buffer.alloc(21, 0);
  127. const unicodeString = Buffer.from(text, 'ucs2');
  128. const md4 = crypto.createHash('md4').update(unicodeString).digest();
  129. if (md4.copy) {
  130. md4.copy(hash);
  131. } else {
  132. Buffer.from(md4).copy(hash);
  133. }
  134. return hash;
  135. }
  136. hmacMD5(data, key) {
  137. const hmac = crypto.createHmac('MD5', key);
  138. hmac.update(data);
  139. const result = hmac.digest();
  140. if (result.copy) {
  141. return result;
  142. } else {
  143. return Buffer.from(result).slice(0, 16);
  144. }
  145. }
  146. }
  147. var _default = NTLMResponsePayload;
  148. exports.default = _default;
  149. module.exports = NTLMResponsePayload;