Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SMB NTLMv2-SSP Hash not captured #158

Closed
Hackndo opened this issue May 5, 2021 · 3 comments
Closed

SMB NTLMv2-SSP Hash not captured #158

Hackndo opened this issue May 5, 2021 · 3 comments

Comments

@Hackndo
Copy link

Hackndo commented May 5, 2021

Hello,
I was trying to capture an SMB hash for testing purpose. Responder 2.3 works fine but not current version.
After some debugging, it appears that this line seems to be the issue. If I replace b'\x02' with b'\x03' it works.

So

if data[16:18] == b'\x01\x00' and GrabMessageID(data)[0:1] == b'\x02' and data[4:5] == b'\xfe':

would become

if data[16:18] == b'\x01\x00' and GrabMessageID(data)[0:1] == b'\x03' and data[4:5] == b'\xfe':

at this line:

if data[16:18] == b'\x01\x00' and GrabMessageID(data)[0:1] == b'\x02' and data[4:5] == b'\xfe':

When I checked the SMB packet, messageID seems to be 3 so it makes sense.

image

I'm not sure this can be changed without any consequence, but I hope this issue can help in some way.

If more details are needed, I can give them.

@Hackndo
Copy link
Author

Hackndo commented May 6, 2021

Ok, so it looks like this message ID can be either 2 or 3 for the NTLM response.

image

So in this example, there is a nego from SMB to SMBv2 in (1), but it's directly using SMBv2 in (2)

image

So in (1) the SMBv2 Negotiate Protocol Request has messageID equal to 1
In (2) the SMBv2 Negotiate Protocol Request has messageID equal to 0

So it seems that if there was a negotiation from SMBv1 to SMBv2, messageID for AUTHENTICATE message will be 3, and it there wasn't any negotiation beforehand, it will be 2.

Maybe a dirty fix could be something like this: Save Session Setup 2 MessageId, and then compare next packet MessageId to this one. If it has been incremented then it should be Session Setup 3 answer.

## Session Setup 1 answer SMBv2.
if data[16:18] == b"\x00\x00" and data[4:5] == b"\xfe":
	head = SMB2Header(MessageId=GrabMessageID(data).decode('latin-1'), PID="\xff\xfe\x00\x00", CreditCharge=GrabCreditCharged(data).decode('latin-1'), Credits=GrabCreditRequested(data).decode('latin-1'))
	t = SMB2NegoAns(Dialect="\x10\x02")
	t.calculate()
	packet1 = str(head)+str(t)
	buffer1 = StructPython2or3('>i', str(packet1))+str(packet1)
	self.request.send(NetworkSendBufferPython2or3(buffer1))
	data = self.request.recv(1024)
## Session Setup 2 answer SMBv2.
if data[16:18] == b"\x01\x00" and data[4:5] == b"\xfe":
	# Grap the message ID so it can be compared afterwards
	setup2MessageId = GrabMessageID(data)[0:1]
	head = SMB2Header(Cmd="\x01\x00", MessageId=GrabMessageID(data).decode('latin-1'), PID="\xff\xfe\x00\x00", CreditCharge=GrabCreditCharged(data).decode('latin-1'), Credits=GrabCreditRequested(data).decode('latin-1'), SessionID=GrabSessionID(data).decode('latin-1'),NTStatus="\x16\x00\x00\xc0")
	t = SMB2Session1Data(NTLMSSPNtServerChallenge=NetworkRecvBufferPython2or3(Challenge))
	t.calculate()
	packet1 = str(head)+str(t)
	buffer1 = StructPython2or3('>i', str(packet1))+str(packet1)
	self.request.send(NetworkSendBufferPython2or3(buffer1))
	data = self.request.recv(1024)
## Session Setup 3 answer SMBv2.
## Compare the MessageID of previous message to this one. If it's the next one, then it should be Setup 3 answer
if data[16:18] == b'\x01\x00' and ord(GrabMessageID(data)[0:1]) == ord(setup2MessageId)+1 and data[4:5] == b'\xfe':
	ParseSMBHash(data, self.client_address[0], Challenge)
	head = SMB2Header(Cmd="\x01\x00", MessageId=GrabMessageID(data).decode('latin-1'), PID="\xff\xfe\x00\x00", CreditCharge=GrabCreditCharged(data).decode('latin-1'), Credits=GrabCreditRequested(data).decode('latin-1'), NTStatus="\x22\x00\x00\xc0", SessionID=GrabSessionID(data).decode('latin-1'))
	t = SMB2Session2Data()
	packet1 = str(head)+str(t)
	buffer1 = StructPython2or3('>i', str(packet1))+str(packet1)
	self.request.send(NetworkSendBufferPython2or3(buffer1))
	data = self.request.recv(1024)

@lgandx
Copy link
Owner

lgandx commented May 6, 2021

Nice catch, and great description!
I just pushed a fix which should resolve this issue.
Let me know if you experience any issues.
Cheers

@jmbesnard
Copy link

This was reported in July 2020 and never got fixed :)
#128

I just tried with the clients for which hashes were not shown (smbclient, net rpc, wmiexec and smbexec) and this works just fine now.

Thanks !

@Hackndo Hackndo closed this as completed May 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants