lgandx/Responder

Bug with single byte comparisons in python3

nobbd opened this issue · 2 comments

nobbd commented

Hello,
I noticed what I assume to be a bug in the Python3 compatibility of Responder when single bytes from a client/server response are compared to single byte static values.

The Bug

One example whould be this check:
image

From my testing it looks like this compare is always "False" in Python3.
That is because if only a single byte is selected from a byte-array, this value is returned as an "int". If this "int" is then compared to the single byte (or also single characters), this returns "False" even when the original byte in the byte array matches.
In Python2 byte-arrays were simply strings and selecting a single entry from a string returned a string that could be compared successfully.

The following screenshot shows the difference between the behaviour in Python2 and Python3:
image

Possible fixes

To circumvent the problem of an "int" being returned on the selection, one can specify a range with the length of 1. That would return a byte string that can then be compared:

Python 3.9.12 (main, Mar 24 2022, 13:02:21) 
[GCC 11.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> b"\x72\x01\x02\x03"
b'r\x01\x02\x03'
>>> b"\x72\x01\x02\x03"[0:2]
b'r\x01'
>>> b"\x72\x01\x02\x03"[0:1]
b'r'
>>> b"\x72\x01\x02\x03"[0]
114

Alternatively an additional compare to the integer value could be performed. I saw this beeing done in servers/MSSQL.py for example. There we have if data[0] == b"\x10" or data[0] == 16: # NegoSSP.

Other occurences

A quick grep showed the following lines of code that might be affected by the same problem:

./tools/MultiRelay/RelayMultiCore.py:639:            if data[64:66] == b"\x05\x00" and data[67] == b"\x02":##Last DCE/RPC Frag
./tools/MultiRelay/RelayMultiCore.py:649:            if data[64:66] == b"\x05\x00" and data[67] == b"\x03":##First and Last DCE/RPCFrag
./tools/RunFinger.py:109:       if data[70] == "\x03":
./tools/RunFinger.py:204:    if data[39] == "\x0f":
./tools/RunFinger.py:367:       if data[28] == "\x00":
./tools/RunFinger.py:376:       if data[28] == "\x01":
./tools/RunFinger.py:388:       if data[28] == "\x02":
./tools/SMBFinger/Finger.py:155:    if data[39] == "\x0f":
./servers/SMB.py:203:                           if data[0] == "\x81":  #session request 139
./servers/SMB.py:338:                   if data[0] == b"\x81":  #session request 139
./servers/MSSQL.py:171:                 elif data[0] == b'\x04': # CLNT_UCAST_INST
./servers/MSSQL.py:173:                 elif data[0] == b'\x0F': # CLNT_UCAST_DAC

Please let me know if you think that this is a real bug and not some quirk on my system. If we find a prefered solution, I would gladly prepare a Pull request.

lgandx commented

Hi,
Sorry for the delay on this, that's a great catch!
This should be fixed as some hashes might get missed.
If you want to provide a pull request thats great, if not I will fix this when I get a minute.
Thanks!

nobbd commented

Hey there,
thank you for the reply. I created #243 for the fix.
But maybe you want to have a look if found all instances of the bug nonetheless.