DontRespondTo fails to blacklist target IPs (solution included).
Hi @lgandx . Absolutely amazing tool. Want to help with improving it.
Context: OS - Raspberry Pi with Kali Linux (using responder from the original Kali repo). Version - Responder 3.1.3.0 Network interface - eth0, has IPv4 and IPv6 addresses.
There are two issues with the DontRespondTo config option which fails to do what it needs to do.
1. IPv4 IPs in DontRespondTo are not blacklisted
The problem is with IPv4 and IPv6 interfaces. During poisoning i noticed that the target IPv4 comes in like '::ffff:10.0.0.1' and for magic reasons i could not figure out WHY the replace in MDNS.py (https://github.com/lgandx/Responder/blob/master/poisoners/MDNS.py#L63 and maybe elsewhere) does not properly stirp the "::ffff" part which later fails in blacklist validation. I did extensive debugging and traced that "if (not Request_Name) or (RespondToThisHost(self.client_address[0].replace("::ffff:",""), Request_Name) is not True):" does not replace the "ffff" as i was outputing the incoming ClientIp in RespondToThisHost() and saw that it comes in with the "ffff"s.
So what I did was I modified the RespondToThisIP() function in utils.py to explicitly replace the prefix again:
def RespondToThisIP(ClientIp):
ClientIp = ClientIp.replace("::ffff:","")
if ClientIp.startswith('127.0.0.'):
return False
elif settings.Config.AutoIgnore and ClientIp in settings.Config.AutoIgnoreList:
print(color('[*]', 3, 1), 'Received request from auto-ignored client %s, not answering.' % ClientIp)
return False
elif settings.Config.RespondTo and ClientIp not in settings.Config.RespondTo:
return False
elif ClientIp in settings.Config.RespondTo or settings.Config.RespondTo == []:
if ClientIp not in settings.Config.DontRespondTo:
return True
return False
This way I was getting consistent and working '::ffff:10.0.0.1' prefix removal before the check (if ClientIp not in settings.Config.DontRespondTo:) which resulted in the expected behavior.
2. IPv6 blacklist support
Currently if we try to blacklist IPv6 via DontRespondTo we get an error:
Traceback (most recent call last):
File "/usr/share/responder/./Responder.py", line 62, in <module>
settings.Config.ExpandIPRanges()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
File "/usr/share/responder/settings.py", line 67, in ExpandIPRanges
self.DontRespondTo = expand_ranges(self.DontRespondTo)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
File "/usr/share/responder/settings.py", line 53, in expand_ranges
x[i] = x[i+1] = int(byte)
~~~^^^^^^
ValueError: invalid literal for int() with base 10: 'FE80::1111:AAAA:2222:333'
This is because the tool does not have IPv6 ip address parsing via expand_ranges() function.
With some AI help I updated the code to include modified expand_ranges() (settings.py) which allows specifyin IPv6 addresses in the DontRespondTo config option.
def expand_ranges(lst):
ret = []
for l in lst:
if ':' in l: #For IPv6 addresses
# Check if it's actually an IPv6 address (not just an IPv4 with port)
if l.count(':') >= 2: # IPv6 has at least 2 colons
while l.count(':') < 7:
pos = l.find('::')
if pos == -1:
break # No :: found, can't expand further
l = l[:pos] + ':' + l[pos:]
tab = l.split(':')
x = {}
i = 0
for byte in tab:
if byte == '':
byte = '0'
if '-' not in byte:
x[i] = x[i+1] = int(byte, 16) # Use base 16 for hex
else:
b = byte.split('-')
x[i] = int(b[0], 16) # Use base 16 for hex
x[i+1] = int(b[1], 16) # Use base 16 for hex
i += 2
for a in range(x[0], x[1]+1):
for b in range(x[2], x[3]+1):
for c in range(x[4], x[5]+1):
for d in range(x[6], x[7]+1):
for e in range(x[8], x[9]+1):
for f in range(x[10], x[11]+1):
for g in range(x[12], x[13]+1):
for h in range(x[14], x[15]+1):
xaddr = ('%x:%x:%x:%x:%x:%x:%x:%x' % (a, b, c, d, e, f, g, h))
xaddr = re.sub('(^|:)0{1,4}', ':', xaddr, count = 7)
xaddr = re.sub(':{3,7}', '::', xaddr, count = 7)
ret.append(xaddr)
else:
# It's an IPv4 address with port, treat as single IP
ret.append(l)
else:
# IPv4 address processing (existing code)
tab = l.split('.')
x = {}
i = 0
for byte in tab:
if '-' not in byte:
x[i] = x[i+1] = int(byte) # Base 10 for IPv4
else:
b = byte.split('-')
x[i] = int(b[0])
x[i+1] = int(b[1])
i += 2
for a in range(x[0], x[1]+1):
for b in range(x[2], x[3]+1):
for c in range(x[4], x[5]+1):
for d in range(x[6], x[7]+1):
ret.append('%d.%d.%d.%d' % (a, b, c, d))
return ret
I would be happy if this gets merged into the next release since it happens too often that i need to blacklist noisy IPs but fail due to the caveats of the tool.
Hi,
Thanks for the detailed issue, if this was not fixed in the latest version 3.1.6.0 please submit a PR and i will review it.
Thanks!