import { AbstractParser } from './AbstractParser'; import { LMResponseData, NTLMMessageType, NTLMResponseData, NTLMType3, NTLMType3v2, NTLMType3v3 } from './parser-interfaces'; import { getFlags, getNtlmEncoding, getNtLmResponseData, getOSVersionStructure, getSecBuf, getSecBufData } from './parser-utils'; import { ntlmFlags } from './flags'; export class NTLMType3Parser extends AbstractParser { constructor (buffer: ArrayBuffer) { super(buffer); } parse (): NTLMType3 { const lmResponse = getSecBuf(this.buffer, 12); const ntlmResponse = getSecBuf(this.buffer, 20); const targetName = getSecBuf(this.buffer, 28); const userName = getSecBuf(this.buffer, 36); const workstationName = getSecBuf(this.buffer, 44); const flag = new Uint32Array(this.buffer.slice(60, 64))[0]; const encoding = getNtlmEncoding(flag); const lmResponseData = getNtLmResponseData(this.buffer, lmResponse); const ntlmResponseData = getNtLmResponseData(this.buffer, ntlmResponse); const domain = getSecBufData(this.buffer, targetName, encoding); const username = getSecBufData(this.buffer, userName, encoding); const workstation = getSecBufData(this.buffer, workstationName, encoding); const result: NTLMType3 = { messageType: NTLMMessageType.AUTHENTICATE_MESSAGE, version: 1, domain, username, workstation, flags: undefined, sessionKey: undefined, lmResponse, ntlmResponse, targetName, userName, workstationName, lmResponseData, ntlmResponseData, }; const firstOffset = Math.min( ...[lmResponse, ntlmResponse, targetName, userName, workstationName].map( (s) => s.offset, ), ); if (firstOffset !== 52) { // NTLM version 2 const r2 = result as NTLMType3v2; r2.version = 2; r2.sessionKey = getSecBuf(this.buffer, 52); r2.flags = getFlags(ntlmFlags, flag); if (firstOffset !== 64) { // NTLM version 3 const r3 = result as NTLMType3v3; r3.version = 3; r3.osVersionStructure = getOSVersionStructure(this.buffer, 64); } } return result; } }