ya-express-ntlm
Version:
95 lines • 3.44 kB
JavaScript
import { DES } from 'des.js';
import { create as createMd4 } from 'js-md4';
import { insertZerosEvery7Bits } from './utils';
export const NTLMFlag = {
NegotiateUnicode: 1,
NegotiateOEM: 2,
RequestTarget: 4,
Unknown9: 8,
NegotiateSign: 16,
NegotiateSeal: 32,
NegotiateDatagram: 64,
NegotiateLanManagerKey: 128,
Unknown8: 256,
NegotiateNTLM: 512,
NegotiateNTOnly: 1024,
Anonymous: 2048,
NegotiateOemDomainSupplied: 4096,
NegotiateOemWorkstationSupplied: 8192,
Unknown6: 16384,
NegotiateAlwaysSign: 32768,
TargetTypeDomain: 65536,
TargetTypeServer: 131072,
TargetTypeShare: 262144,
NegotiateExtendedSecurity: 524288,
NegotiateIdentify: 1048576,
Unknown5: 2097152,
RequestNonNTSessionKey: 4194304,
NegotiateTargetInfo: 8388608,
Unknown4: 16777216,
NegotiateVersion: 33554432,
Unknown3: 67108864,
Unknown2: 134217728,
Unknown1: 268435456,
Negotiate128: 536870912,
NegotiateKeyExchange: 1073741824,
Negotiate56: 2147483648,
};
export const NTLMTypeFlags = {
TYPE1_FLAGS: NTLMFlag.NegotiateUnicode
+ NTLMFlag.NegotiateOEM
+ NTLMFlag.RequestTarget
+ NTLMFlag.NegotiateNTLM
+ NTLMFlag.NegotiateOemDomainSupplied
+ NTLMFlag.NegotiateOemWorkstationSupplied
+ NTLMFlag.NegotiateAlwaysSign
+ NTLMFlag.NegotiateExtendedSecurity
+ NTLMFlag.NegotiateVersion
+ NTLMFlag.Negotiate128
+ NTLMFlag.Negotiate56,
TYPE2_FLAGS: NTLMFlag.NegotiateUnicode
+ NTLMFlag.RequestTarget
+ NTLMFlag.NegotiateNTLM
+ NTLMFlag.NegotiateAlwaysSign
+ NTLMFlag.NegotiateExtendedSecurity
+ NTLMFlag.NegotiateTargetInfo
+ NTLMFlag.NegotiateVersion
+ NTLMFlag.Negotiate128
+ NTLMFlag.Negotiate56,
};
export function extractNtlmMessageFromAuthenticateHeader(authenticateHeader) {
// The header may look like this: `Negotiate, NTLM, Basic realm="hidden-realm.example.net"`
// so extract the 'NTLM' part first
return (authenticateHeader
?.split(',')
.find((part) => part.match(/ *NTLM/))
?.trim() ?? undefined);
}
export const createDesEncrypt = (key) => DES.create({ type: 'encrypt', key });
export const createLMHashedPasswordV1 = (password) => {
// fix the password length to 14 bytes
password = password.toUpperCase();
const passwordBytes = Buffer.from(password, 'ascii');
const passwordBytesPadded = Buffer.alloc(14);
passwordBytesPadded.fill('\0');
let sourceEnd = 14;
if (passwordBytes.length < 14)
sourceEnd = passwordBytes.length;
passwordBytes.copy(passwordBytesPadded, 0, 0, sourceEnd);
// split into 2 parts of 7 bytes:
const firstPart = passwordBytesPadded.subarray(0, 7);
const secondPart = passwordBytesPadded.subarray(7);
function encrypt(buf) {
const key = insertZerosEvery7Bits(buf);
const des = createDesEncrypt(key);
return Buffer.from(des.update('KGS!@#$%')); // page 57 in [MS-NLMP]);
}
const firstPartEncrypted = encrypt(firstPart);
const secondPartEncrypted = encrypt(secondPart);
return Buffer.concat([firstPartEncrypted, secondPartEncrypted]);
};
export const createNTHashedPasswordV1 = (password) => {
const buf = Buffer.from(password, 'utf16le');
return Buffer.from(createMd4().update(buf).digest());
};
//# sourceMappingURL=core.js.map