lgandx / Responder

Responder is a LLMNR, NBT-NS and MDNS poisoner, with built-in HTTP/SMB/MSSQL/FTP/LDAP rogue authentication server supporting NTLMv1/NTLMv2/LMv2, Extended Security NTLMSSP and Basic HTTP authentication.
GNU General Public License v3.0
5.47k stars 776 forks source link

DHCP poisoner crashes for IP addresses ending in F #181

Open ncc-brian opened 2 years ago

ncc-brian commented 2 years ago

The DHCP poisoner Fails to handle some packets with the following error:

# ./Responder.py -I eth0 -Pdv  
...
[+] Listening for events...

[*] [DHCP] Found DHCP server IP: [xx.xx.xx.xx], now waiting for incoming requests...
Traceback (most recent call last):
  File "/root/Responder/./Responder.py", line 383, in <module>
    main()
  File "/root/Responder/./Responder.py", line 374, in main
    DHCP(settings.Config.DHCP_DNS)
  File "/root/Responder/poisoners/DHCP.py", line 351, in DHCP
    ret = ParseDHCPCode(data[0][42:], ClientIP,DHCP_DNS)
  File "/root/Responder/poisoners/DHCP.py", line 271, in ParseDHCPCode
    IPConv = socket.inet_ntoa(IP)
OSError: packed IP wrong length for inet_ntoa

IP address is selected by regex at https://github.com/lgandx/Responder/blob/5cf69228cf5ce4c0433904ee1d05955e8fd6f618/poisoners/DHCP.py#L243 and should look something like this: b'\xac\x165L'

This then lands at https://github.com/lgandx/Responder/blob/5cf69228cf5ce4c0433904ee1d05955e8fd6f618/poisoners/DHCP.py#L268 where it is translated to a human-readable IP (this is where Python3 errors out).

A bit of digging shows that for the packets that fail, the value for IP returned from FindIP is a byte short. When this value is then fed into inet_ntoa it errors.

Example (this is the IP that was erroring):

>>> socket.inet_ntoa(b'\xac\x165F') # if IP is parsed correctly
'172.22.53.70'
>>> socket.inet_ntoa(b'\xac\x165') # as IP is parsed by the existing regex
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: packed IP wrong length for inet_ntoa

For the moment I'm working around it as follows:

def FindIP(data):
    # data = data.decode('latin-1')
    # IP = ''.join(re.findall(r'(?<=\x32\x04)[^EOF]*', data))
    # return ''.join(IP[0:4]).encode('latin-1')
    offset = data.find(b'\x32\x04')
    return data[offset+2:offset+6]

It also appears to work if the regex adds a dot before the star:

def FindIP(data):
    data = data.decode('latin-1')
    # IP = ''.join(re.findall(r'(?<=\x32\x04)[^EOF]*', data))
    IP = ''.join(re.findall(r'(?<=\x32\x04)[^EOF].*', data))
    return ''.join(IP[0:4]).encode('latin-1')

I won't say either fix is a good idea, just that it seems to be working for me. I suggest further investigation by people who know more than I do about this.

Thanks!

ITmustang commented 1 year ago

im having the same issue and the workarounds above do not work. any update on this issue?

fsacer commented 4 months ago

just ran into the same issue

chadministratorwastaken commented 3 months ago

Same issue here. Trying out the second workaround option.

neiltylerbell commented 3 months ago

Adding that I just saw this as well. Attempting ncc-brian's workaround.