From 35cc77c63c82a5ef4d37cced54c9c58423c4ec63 Mon Sep 17 00:00:00 2001 From: pranavrajtyagi Date: Mon, 4 May 2015 23:41:34 -0400 Subject: [PATCH 01/11] updated dnscommon for NS and PTR --- dnscommon.r2py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/dnscommon.r2py b/dnscommon.r2py index 9658d2b..3132b58 100755 --- a/dnscommon.r2py +++ b/dnscommon.r2py @@ -494,12 +494,12 @@ def _read_single_answer(answer_index, dns_query_data): """ # Parse answer address. read_index, answer_name = _parse_address(answer_index, dns_query_data) - + # Read the type. answer_type = _type_lookup_table[ _charpair_to_int16(dns_query_data[read_index:read_index + 2])] - read_index += 2 + read_index += 2 # Read the class. answer_class = _class_lookup_table[ _charpair_to_int16(dns_query_data[read_index:read_index + 2])] @@ -519,9 +519,13 @@ def _read_single_answer(answer_index, dns_query_data): # There are a lot of different types of queries. We can parse all of these ones # in the same way, though. - simple_answers = ['A', 'NS', 'CNAME', 'MD', 'MB', 'MF', 'MG', 'MR', 'MX', 'PTR'] + simple_answers = ['A', 'CNAME', 'MD', 'MB', 'MF', 'MG', 'MR', 'MX'] if answer_type in simple_answers: read_index, resource_data['address'] = _parse_answer_address(read_index, dns_query_data) + elif answer_type == 'NS': + read_index, resource_data['nameserver'] = _parse_address(read_index,dns_query_data) + elif answer_type == 'PTR': + read_index, resource_data['domain'] = _parse_address(read_index, dns_query_data) elif answer_type == 'SOA': read_index, mname = _parse_address(read_index, dns_query_data) resource_data['mname'] = mname @@ -560,7 +564,7 @@ def _read_single_answer(answer_index, dns_query_data): 'time_to_live' : time_to_live, 'answer_data' : resource_data } - + return read_index, answer_dict @@ -600,7 +604,7 @@ def _parse_answer_address(address_index, dns_query_data): address_index += 1 address += str(ord(dns_query_data[address_index])) address_index += 1 - + return address_index, address From ba000272964d87de2d26515d25ecd9e01ef72b51 Mon Sep 17 00:00:00 2001 From: pranavrajtyagi Date: Mon, 11 May 2015 22:21:45 -0400 Subject: [PATCH 02/11] fix for 'MX' and support for 'AAAA' records --- dnscommon.r2py | 66 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 4 deletions(-) diff --git a/dnscommon.r2py b/dnscommon.r2py index 3132b58..813760a 100755 --- a/dnscommon.r2py +++ b/dnscommon.r2py @@ -109,6 +109,7 @@ _type_lookup_table = { 14 : 'MINFO', # Mailbox Information 15 : 'MX', # Mail Exchange 16 : 'TXT', # Text Strings + 28 : 'AAAA', # IPv6 address 252 : 'AXFR', # Request for transfer of zone 253 : 'MAILB', # Request for mailbox-related RRs 254 : 'MAILA', # Request for mail agent RRs (Obsolete) @@ -130,6 +131,7 @@ _type_lookup_table = { 'MINFO' : 14, 'MX' : 15, 'TXT' : 16, + 'AAAA' : 28, 'AXFR' : 252, 'MAILB' : 253, 'MAILA' : 254, @@ -504,7 +506,6 @@ def _read_single_answer(answer_index, dns_query_data): answer_class = _class_lookup_table[ _charpair_to_int16(dns_query_data[read_index:read_index + 2])] read_index += 2 - # Some math magic with the TTL. time_to_live = _charpair_to_int16(dns_query_data[read_index:read_index + 2]) * 2 ** 16 read_index += 2 @@ -519,13 +520,18 @@ def _read_single_answer(answer_index, dns_query_data): # There are a lot of different types of queries. We can parse all of these ones # in the same way, though. - simple_answers = ['A', 'CNAME', 'MD', 'MB', 'MF', 'MG', 'MR', 'MX'] + simple_answers = ['A', 'CNAME', 'MD', 'MB', 'MF', 'MG', 'MR'] if answer_type in simple_answers: read_index, resource_data['address'] = _parse_answer_address(read_index, dns_query_data) elif answer_type == 'NS': read_index, resource_data['nameserver'] = _parse_address(read_index,dns_query_data) elif answer_type == 'PTR': read_index, resource_data['domain'] = _parse_address(read_index, dns_query_data) + elif answer_type == 'MX': + read_index+=2 + read_index, resource_data['records'] = _parse_address(read_index, dns_query_data) + elif answer_type == 'AAAA': + read_index, resource_data['address'] = _parse_aaaa_address(read_index, dns_query_data) elif answer_type == 'SOA': read_index, mname = _parse_address(read_index, dns_query_data) resource_data['mname'] = mname @@ -556,7 +562,6 @@ def _read_single_answer(answer_index, dns_query_data): resource_data['retry'] = retry resource_data['expire'] = expire resource_data['minimum'] = minimum - answer_dict = { 'name' : answer_name, 'type' : answer_type, @@ -564,11 +569,64 @@ def _read_single_answer(answer_index, dns_query_data): 'time_to_live' : time_to_live, 'answer_data' : resource_data } - + return read_index, answer_dict +def _parse_aaaa_address(address_index, dns_query_data): + """ + + This method parses a IPv6 directly out of an answer + section. This method is needed because answer IPs are not delimited, + since their labels are not of variable length. + + + address_index + The integer index at which the address starts. + dns_query_data + The string containing raw query data + + + If the address is improperly formatted, this will produce an integer + parsing failure. + + + None + + + A tuple containing the new read index and IPv6 Address. + """ + #converts packet data to hex + add = '' + address = '' + new_list = [] + for i in range(0,16): + add+=str(hex(ord(dns_query_data[address_index]))) + add+=":" + address_index += 1 + add = add[:-1] + + #converts hex data to readable IPv6 + add_list = add.split(":") + for i in add_list: + i = i[2:] + if len(i) == 2: + new_list.append(i) + elif len(i)==1: + i = '0'+i + new_list.append(i) + + for i in range(0,16,2): + try: + address+= new_list[i]+new_list[i+1] + address+=':' + except IndexError: + pass + address=address[:-1] + #address = address.replace('0000','') + #address = address.replace('::',':') + return address_index, address def _parse_answer_address(address_index, dns_query_data): """ From 7f73846d2f5877b8fa0cf0131c1010259b846123 Mon Sep 17 00:00:00 2001 From: pranavrajtyagi Date: Mon, 11 May 2015 22:25:30 -0400 Subject: [PATCH 03/11] updating support for 'TXT' queries --- dnscommon.r2py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dnscommon.r2py b/dnscommon.r2py index 813760a..3ec2691 100755 --- a/dnscommon.r2py +++ b/dnscommon.r2py @@ -532,6 +532,13 @@ def _read_single_answer(answer_index, dns_query_data): read_index, resource_data['records'] = _parse_address(read_index, dns_query_data) elif answer_type == 'AAAA': read_index, resource_data['address'] = _parse_aaaa_address(read_index, dns_query_data) + elif answer_type == 'TXT': + txt_length = len(dns_query_data)-read_index + resource_text = [] + for i in range(0,txt_length): + resource_text.append(dns_query_data[read_index]) + read_index+=1 + resource_data['text'] = ''.join(resource_text) elif answer_type == 'SOA': read_index, mname = _parse_address(read_index, dns_query_data) resource_data['mname'] = mname From 71d1fd123bb618d05daeee7360e75899479d7227 Mon Sep 17 00:00:00 2001 From: pranavrajtyagi Date: Fri, 15 May 2015 16:32:32 -0400 Subject: [PATCH 04/11] dnsquery update --- dnsquery.r2py | 391 ++++++++++++++++++++++++++++++++++++++++++++++++++ librepy.r2py | 17 +++ 2 files changed, 408 insertions(+) create mode 100644 dnsquery.r2py diff --git a/dnsquery.r2py b/dnsquery.r2py new file mode 100644 index 0000000..660f94f --- /dev/null +++ b/dnsquery.r2py @@ -0,0 +1,391 @@ +""" + + dnsquery.r2py + + + February 20, 2010 + + + Pranav Raj Tyagi + pt992@nyu.edu + + + None + + + Implements a function to query a name server for the INTERNET-class A recordof a FQDN + and replies in a 'tuple' + + + Implement a function to query a name server for the INTERNET-class A record of a FQDN, + and return the reply in a `tuple`, as Python's `socket.gethostbyname_ex` does. + + 'gethostbyname_ex(name)' - to get IPv4 address for given domain naime + 'reverseLookup(address)' - to get the domain name for the given IPv4 address + 'namingServer(name)' - to get the NS for the given domain name + 'recordsMX(name)' - to get the MX records for the given domain name + 'txtRecords(name)' - to get the TXT records for the given domain name + 'getAAAA(name)' - to get the IPV6 address for the given domain name + + ------------ +""" + +#imports dnscommon.r2py file from repyv2 library using dylink.r2py +dnscommon = dy_import_module("dnscommon.r2py") +libsocket = dy_import_module("librepysocket.r2py") + +listen_ip = '8.8.8.8' +listen_port = 53 +client_ip = getmyip() +client_port = libsocket.get_messports(client_ip)[0] +#destip = gethostbyname('myresolver.zenodotus.poly.edu') + + +default_flags = { + 'communication_id': 'a7', + 'query_response': False, + 'operation_code': 0, + 'authority_advisory': False, + 'truncation': False, + 'recursion_desired': True, + 'recursion_accepted': False, + 'z': False, + 'authentic_data': False, + 'checking_disabled': False, + 'error_code': 0, + 'answer_count': 0, + 'authority_record_count': 0, + 'additional_record_count': 0, + 'answers': [] + } +#sends and receive the packet to and from DNS +def dns_connection(client_ip,client_port,destip, destport ,questions): + """ + + Parses the question and sends it to DNS. + + + questions + An array of dictionaries, one dictionary per question. Format is: + {'name', 'type', 'class'} + + + None + + + A formatted dictionary in the form: + { + 'raw_data': (network raw) + 'remote_ip': string (formatted unicode, IP Address) + 'remote_port': integer + 'communication_id' string (network raw) + 'query_response' boolean + 'operation_code' integer + 'authority_advisory' boolean + 'truncation' boolean + 'recursion_desired' boolean + 'recursion_accepted' boolean + 'z' boolean + 'authentic_data' boolean + 'checking_disabled' boolean + 'error_code' integer (4 bit) + 'question_count' integer (16 bit) + 'answer_count' integer (16 bit) + 'authority_record_count' integer (16 bit) + 'additional_record_count' integer (16 bit) ) + 'questions': array of dictionaries containing: + 'name' string (formatted unicode, IP Address) + 'type' string (formatted unicode, eg A, AAAA, MX) + 'class' string (formatted unicode, eg IN, HE, CH) + 'answers': array of dictionaries containing: + 'name' string (formatted unicode, IP Address) + 'type' string (formatted unicode, eg A, AAAA, MX) + 'class' string (formatted unicode, eg IN, HE, CH) + 'time_to_live' integer (seconds, 32 bit) + 'answer_data' dictionary (format based on type) + + } + + The 'answer_data' dictionary field can have various formats. Here are the + three which are currently supported: + SOA: + 'mname' + 'rname' + 'serial' <32 bit int> + 'refresh' <32 bit int> + 'retry' <32 bit int> + 'expire' <32 bit int> + 'minimum' <32 bit int> + NS: + 'address' + A: + 'address' + """ + + packet_dict = {} + response_string = "" + succeeded = False + #generate packet from question that are asked by the user + converted_packet = dnscommon.generate_packet(questions, flags=default_flags) + #listens for UDP messages + udpserversocket = listenformessage(client_ip, client_port) + #sends data to DNS + sent = sendmessage(destip, destport, converted_packet, client_ip, client_port) + #receives packet from DNS and then converts into dictionary and returns dictionary + while succeeded != True: + try: + remote_ip, remote_port, response_string = udpserversocket.getmessage() + packet_dict = dnscommon.convert_packet_to_dictionary(response_string) + if packet_dict != None: + succeeded = True + udpserversocket.close() + return packet_dict + except SocketWouldBlockError: + #https://seattle.poly.edu/wiki/FutureRepyExceptions/SocketWouldBlockError + succeeded = False + +def gethostbyname_ex(dns_query_data): + """ + + Interrogate dns_query_data + + + dns_query_data contains query name or IP address user wants + + + KeyError if dns_query_data is not correct. If caught, it will pass and not show any result. + + + + A dictionary that contains the list of IPv4 addresses for the same interface on the same host. Its in form of + answer_dict{ + 'name' : dns_query_data + 'answer_data' : list_of_addresses + } + + """ + + #query data needs to create a simple dictionary + questions = [{'name': dns_query_data , 'type' : 'A', 'class': 'IN'}] + #calls dns_connection to get answers from DNS. + packet_dict = dns_connection(client_ip,client_port,listen_ip,listen_port, questions) + #fetches answers from packet_dictionary received + answers = packet_dict['answers'] + resource_data = [] + add_list = [] + try: + for item in answers: + resource_data.append(item['answer_data']) + for answer in resource_data: + add_list.append(answer['address']) + except KeyError: + pass + if not add_list: + answer_dict = None + else: + answer_dict = (dns_query_data,add_list) + return answer_dict + +def reverseLookup(dns_query_data): + """ + + Interrogate dns_query_data for reverse query i.e. gets a domain name for queried IPv4 + address + + + dns_query_data contains query name + + + KeyError if dns_query_data is not correct. If caught, it will pass and not show any result. + + + A dictionary that contains the domain name. Its in form of + answer_dict{ + 'name' : dns_query_data + 'answer_data' : name_list + } + + """ + querySplit = dns_query_data.split('.') + querySplit.reverse() + query = '' + for offset in querySplit: + query += offset+'.' + query +='in-addr.arpa' + + questions = [{'name': query , 'type' : 'PTR', 'class': 'IN'}] + packet_dict = dns_connection(client_ip,client_port,destip,listen_port, questions) + answers = packet_dict['answers'] + resource_data = [] + name_list = [] + try: + for item in answers: + resource_data.append(item['answer_data']) + domain = resource_data[0] + except KeyError: + pass + if domain == None: + answer_dict = None + else: + answer_dict = (dns_query_data,domain) + return answer_dict + +def namingServer(dns_query_data): + """ + + Interrogate dns_query_data for Naming servers records + + + dns_query_data contains query name + + + KeyError if dns_query_data is not correct. If caught, it will pass and not show any result. + + + A dictionary that contains the naming servers. Its in form of + answer_dict{ + 'name' : dns_query_data + 'answer_data' : name_list + } + + """ + + questions = [{'name': dns_query_data , 'type' : 'NS', 'class': 'IN'}] + packet_dict = dns_connection(client_ip,client_port,destip,listen_port, questions) + answers = packet_dict['answers'] + resource_data = [] + name_list = [] + try: + for item in answers: + resource_data.append(item['answer_data']) + for answer in resource_data: + name_list.append(answer['nameserver']) + except KeyError: + pass + if not name_list: + answer_dict = None + else: + answer_dict = (dns_query_data, name_list) + return answer_dict + +def recordsMX(dns_query_data): + """ + + Interrogate dns_query_data for MX records + + + dns_query_data contains query name + + + KeyError if dns_query_data is not correct. If caught, it will pass and not show any result. + + + A dictionary that contains the MX records. Its in form of + answer_dict{ + 'name' : dns_query_data + 'answer_data' : record_list + } + + """ + + questions = [{'name': dns_query_data , 'type' : 'MX', 'class': 'IN'}] + packet_dict = dns_connection(client_ip,client_port,destip,listen_port, questions) + answers = packet_dict['answers'] + resource_data = [] + record_list = [] + try: + for item in answers: + resource_data.append(item['answer_data']) + for answer in resource_data: + record_list.append(answer['records']) + except KeyError: + pass + if not record_list: + answer_dict = None + else: + answer_dict = (dns_query_data, record_list) + return answer_dict + +def txtRecords(dns_query_data): + """ + + Interrogate dns_query_data for TXT record + + + dns_query_data contains query name + + + KeyError if dns_query_data is not correct. If caught, it will pass and not show any result. + + + + A dictionary that contains the text data. Its in form of + answer_dict{ + 'name' : dns_query_data + 'answer_data' : text_data + } + + """ + + #query data needs to create a simple dictionary + questions = [{'name': dns_query_data , 'type' : 'TXT', 'class': 'IN'}] + #calls dns_connection to get answers from DNS. + packet_dict = dns_connection(client_ip,client_port,listen_ip,listen_port, questions) + #fetches answers from packet_dictionary received + answers = packet_dict['answers'] + resource_data = [] + text_data = [] + try: + for item in answers: + resource_data.append(item['answer_data']) + for answer in resource_data: + text_data.append(answer['text']) + except KeyError: + pass + if not text_data: + answer_dict = None + else: + answer_dict = (dns_query_data, text_data) + return answer_dict + +def getAAAA(dns_query_data): + """ + + Interrogate dns_query_data + + + dns_query_data contains query name or IPv6 address user wants + + + KeyError if dns_query_data is not correct. If caught, it will pass and not show any result. + + + + A dictionary that contains the list of IPv6 addresses for the same interface on the same host. Its in form of + answer_dict{ + 'name' : dns_query_data + 'answer_data' : IPv6 address + } + + """ + + #query data needs to create a simple dictionary + questions = [{'name': dns_query_data , 'type' : 'AAAA', 'class': 'IN'}] + #calls dns_connection to get answers from DNS. + packet_dict = dns_connection(client_ip,client_port,listen_ip,listen_port, questions) + #fetches answers from packet_dictionary received + answers = packet_dict['answers'] + resource_data = [] + add_list = [] + try: + for item in answers: + resource_data.append(item['answer_data']) + for answer in resource_data: + add_list.append(answer['address']) + except KeyError: + pass + if not add_list: + answer_dict = None + else: + answer_dict = (dns_query_data,add_list) + return answer_dict \ No newline at end of file diff --git a/librepy.r2py b/librepy.r2py index b38746b..9485434 100644 --- a/librepy.r2py +++ b/librepy.r2py @@ -48,6 +48,10 @@ LIBREPY_EXPORTS.append("libthread") libsocket = dy_import_module("librepysocket.r2py") LIBREPY_EXPORTS.append("libsocket") +#Import the sub-library, dnsquery +libdnsquery = dy_import_module("dnsquery.r2py") +LIBREPY_EXPORTS.append("libdnsquery") + # Override the imported version of librunloop to use a unified run-loop libthread._context["librunloop"] = librunloop libsocket._context["librunloop"] = librunloop @@ -118,6 +122,19 @@ LIBREPY_EXPORTS.append("recvmess") LIBREPY_EXPORTS.append("openconn") LIBREPY_EXPORTS.append("waitforconn") +#Exports from dnsquery +gethostbyname_ex = libdnsquery.gethostbyname_ex +reverseLookup = libdnsquery.reverseLookup +namingServer = libdnsquery.namingServer +recordsMX = libdnsquery.recordsMX +txtRecords = libdnsquery.txtRecords +getAAAA = libdnsquery.getAAAA +LIBREPY_EXPORTS.append("gethostbyname_ex") +LIBREPY_EXPORTS.append("reverseLookup") +LIBREPY_EXPORTS.append("namingServer") +LIBREPY_EXPORTS.append("recordsMX") +LIBREPY_EXPORTS.append("txtRecords") +LIBREPY_EXPORTS.append("getAAAA") ##### Run-time From 34aac48b8eff77a0f6984725bedcd4e9b6bf5888 Mon Sep 17 00:00:00 2001 From: Pranav Raj Tyagi Date: Fri, 15 May 2015 17:02:36 -0400 Subject: [PATCH 05/11] Update dnsquery.r2py --- dnsquery.r2py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dnsquery.r2py b/dnsquery.r2py index 660f94f..48e25dd 100644 --- a/dnsquery.r2py +++ b/dnsquery.r2py @@ -38,7 +38,7 @@ listen_ip = '8.8.8.8' listen_port = 53 client_ip = getmyip() client_port = libsocket.get_messports(client_ip)[0] -#destip = gethostbyname('myresolver.zenodotus.poly.edu') +destip = gethostbyname('myresolver.zenodotus.poly.edu') default_flags = { @@ -388,4 +388,4 @@ def getAAAA(dns_query_data): answer_dict = None else: answer_dict = (dns_query_data,add_list) - return answer_dict \ No newline at end of file + return answer_dict From c2421fdf05e7427112524189fb8016085043e4f0 Mon Sep 17 00:00:00 2001 From: pranavrajtyagi Date: Thu, 21 May 2015 01:54:32 -0400 Subject: [PATCH 06/11] updated dnscommon --- dnscommon.r2py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/dnscommon.r2py b/dnscommon.r2py index 3ec2691..d8997d4 100755 --- a/dnscommon.r2py +++ b/dnscommon.r2py @@ -528,7 +528,7 @@ def _read_single_answer(answer_index, dns_query_data): elif answer_type == 'PTR': read_index, resource_data['domain'] = _parse_address(read_index, dns_query_data) elif answer_type == 'MX': - read_index+=2 + read_index += 2 read_index, resource_data['records'] = _parse_address(read_index, dns_query_data) elif answer_type == 'AAAA': read_index, resource_data['address'] = _parse_aaaa_address(read_index, dns_query_data) @@ -537,7 +537,7 @@ def _read_single_answer(answer_index, dns_query_data): resource_text = [] for i in range(0,txt_length): resource_text.append(dns_query_data[read_index]) - read_index+=1 + read_index += 1 resource_data['text'] = ''.join(resource_text) elif answer_type == 'SOA': read_index, mname = _parse_address(read_index, dns_query_data) @@ -618,20 +618,18 @@ def _parse_aaaa_address(address_index, dns_query_data): for i in add_list: i = i[2:] if len(i) == 2: - new_list.append(i) + new_list.append(i) elif len(i)==1: - i = '0'+i - new_list.append(i) + i = '0'+i + new_list.append(i) for i in range(0,16,2): try: - address+= new_list[i]+new_list[i+1] - address+=':' + address+= new_list[i]+new_list[i+1] + address+=':' except IndexError: - pass + pass address=address[:-1] - #address = address.replace('0000','') - #address = address.replace('::',':') return address_index, address From 49e888fcde897d14916083becd4e4b770faad158 Mon Sep 17 00:00:00 2001 From: pranavrajtyagi Date: Wed, 27 May 2015 01:49:21 -0400 Subject: [PATCH 07/11] updated dnsquery and dnscommon --- dnscommon.r2py | 35 +++++++++++++---------------------- dnsquery.r2py | 7 ++----- 2 files changed, 15 insertions(+), 27 deletions(-) diff --git a/dnscommon.r2py b/dnscommon.r2py index d8997d4..3fb1849 100755 --- a/dnscommon.r2py +++ b/dnscommon.r2py @@ -528,17 +528,19 @@ def _read_single_answer(answer_index, dns_query_data): elif answer_type == 'PTR': read_index, resource_data['domain'] = _parse_address(read_index, dns_query_data) elif answer_type == 'MX': - read_index += 2 - read_index, resource_data['records'] = _parse_address(read_index, dns_query_data) + read_index += 1 + resource_data['preference'] = str(ord(dns_query_data[read_index])) + read_index += 1 + read_index, resource_data['record'] = _parse_address(read_index, dns_query_data) elif answer_type == 'AAAA': read_index, resource_data['address'] = _parse_aaaa_address(read_index, dns_query_data) elif answer_type == 'TXT': txt_length = len(dns_query_data)-read_index - resource_text = [] + resource_text = '' for i in range(0,txt_length): - resource_text.append(dns_query_data[read_index]) + resource_text += dns_query_data[read_index] read_index += 1 - resource_data['text'] = ''.join(resource_text) + resource_data['text'] = resource_text elif answer_type == 'SOA': read_index, mname = _parse_address(read_index, dns_query_data) resource_data['mname'] = mname @@ -604,32 +606,21 @@ def _parse_aaaa_address(address_index, dns_query_data): A tuple containing the new read index and IPv6 Address. """ #converts packet data to hex - add = '' + add = [] address = '' - new_list = [] for i in range(0,16): - add+=str(hex(ord(dns_query_data[address_index]))) - add+=":" + add.append(str(hex(ord(dns_query_data[address_index])))) address_index += 1 - add = add[:-1] #converts hex data to readable IPv6 - add_list = add.split(":") - for i in add_list: + for i in add: i = i[2:] if len(i) == 2: - new_list.append(i) + address += i elif len(i)==1: i = '0'+i - new_list.append(i) - - for i in range(0,16,2): - try: - address+= new_list[i]+new_list[i+1] - address+=':' - except IndexError: - pass - address=address[:-1] + address += i + address = ':'.join([address[x:x+4] for x in range(0, len(address)-1, 4)]) return address_index, address diff --git a/dnsquery.r2py b/dnsquery.r2py index 48e25dd..44fde5a 100644 --- a/dnsquery.r2py +++ b/dnsquery.r2py @@ -292,18 +292,15 @@ def recordsMX(dns_query_data): packet_dict = dns_connection(client_ip,client_port,destip,listen_port, questions) answers = packet_dict['answers'] resource_data = [] - record_list = [] try: for item in answers: resource_data.append(item['answer_data']) - for answer in resource_data: - record_list.append(answer['records']) except KeyError: pass - if not record_list: + if not resource_data: answer_dict = None else: - answer_dict = (dns_query_data, record_list) + answer_dict = (dns_query_data, resource_data) return answer_dict def txtRecords(dns_query_data): From 9ea31f27c739086444035db376c43687bfa9b262 Mon Sep 17 00:00:00 2001 From: pranavrajtyagi Date: Tue, 2 Jun 2015 02:03:26 -0400 Subject: [PATCH 08/11] updated dnscommon --- dnscommon.r2py | 6 ++---- dnsquery.r2py | 56 +++++++++++++++++++------------------------------- 2 files changed, 23 insertions(+), 39 deletions(-) diff --git a/dnscommon.r2py b/dnscommon.r2py index 3fb1849..ca85807 100755 --- a/dnscommon.r2py +++ b/dnscommon.r2py @@ -537,9 +537,8 @@ def _read_single_answer(answer_index, dns_query_data): elif answer_type == 'TXT': txt_length = len(dns_query_data)-read_index resource_text = '' - for i in range(0,txt_length): - resource_text += dns_query_data[read_index] - read_index += 1 + resource_text += dns_query_data[read_index:read_index+txt_length] + read_index += txt_length resource_data['text'] = resource_text elif answer_type == 'SOA': read_index, mname = _parse_address(read_index, dns_query_data) @@ -611,7 +610,6 @@ def _parse_aaaa_address(address_index, dns_query_data): for i in range(0,16): add.append(str(hex(ord(dns_query_data[address_index])))) address_index += 1 - #converts hex data to readable IPv6 for i in add: i = i[2:] diff --git a/dnsquery.r2py b/dnsquery.r2py index 44fde5a..dbcaf7a 100644 --- a/dnsquery.r2py +++ b/dnsquery.r2py @@ -40,7 +40,6 @@ client_ip = getmyip() client_port = libsocket.get_messports(client_ip)[0] destip = gethostbyname('myresolver.zenodotus.poly.edu') - default_flags = { 'communication_id': 'a7', 'query_response': False, @@ -172,18 +171,15 @@ def gethostbyname_ex(dns_query_data): #fetches answers from packet_dictionary received answers = packet_dict['answers'] resource_data = [] - add_list = [] try: for item in answers: - resource_data.append(item['answer_data']) - for answer in resource_data: - add_list.append(answer['address']) + resource_data.append(item['answer_data']['address']) except KeyError: pass - if not add_list: - answer_dict = None - else: - answer_dict = (dns_query_data,add_list) + if not resource_data: + for item in answers: + resource_data.append(item['answer_data']) + answer_dict = (dns_query_data,resource_data) return answer_dict def reverseLookup(dns_query_data): @@ -217,7 +213,6 @@ def reverseLookup(dns_query_data): packet_dict = dns_connection(client_ip,client_port,destip,listen_port, questions) answers = packet_dict['answers'] resource_data = [] - name_list = [] try: for item in answers: resource_data.append(item['answer_data']) @@ -254,18 +249,15 @@ def namingServer(dns_query_data): packet_dict = dns_connection(client_ip,client_port,destip,listen_port, questions) answers = packet_dict['answers'] resource_data = [] - name_list = [] try: for item in answers: - resource_data.append(item['answer_data']) - for answer in resource_data: - name_list.append(answer['nameserver']) + resource_data.append(item['answer_data']['nameserver']) except KeyError: pass - if not name_list: - answer_dict = None - else: - answer_dict = (dns_query_data, name_list) + if not resource_data: + for item in answers: + resource_data.append(item['answer_data']) + answer_dict = (dns_query_data, resource_data) return answer_dict def recordsMX(dns_query_data): @@ -289,7 +281,7 @@ def recordsMX(dns_query_data): """ questions = [{'name': dns_query_data , 'type' : 'MX', 'class': 'IN'}] - packet_dict = dns_connection(client_ip,client_port,destip,listen_port, questions) + packet_dict = dns_connection(client_ip,client_port,listen_ip,listen_port, questions) answers = packet_dict['answers'] resource_data = [] try: @@ -331,18 +323,15 @@ def txtRecords(dns_query_data): #fetches answers from packet_dictionary received answers = packet_dict['answers'] resource_data = [] - text_data = [] try: for item in answers: - resource_data.append(item['answer_data']) - for answer in resource_data: - text_data.append(answer['text']) + resource_data.append(item['answer_data']['text']) except KeyError: pass - if not text_data: - answer_dict = None - else: - answer_dict = (dns_query_data, text_data) + if not resource_data: + for item in answers: + resource_data.append(item['answer_data']) + answer_dict = (dns_query_data, text_data) return answer_dict def getAAAA(dns_query_data): @@ -373,16 +362,13 @@ def getAAAA(dns_query_data): #fetches answers from packet_dictionary received answers = packet_dict['answers'] resource_data = [] - add_list = [] try: for item in answers: - resource_data.append(item['answer_data']) - for answer in resource_data: - add_list.append(answer['address']) + resource_data.append(item['answer_data']['address']) except KeyError: pass - if not add_list: - answer_dict = None - else: - answer_dict = (dns_query_data,add_list) + if not resource_data: + for item in answers: + resource_data.append(item['answer_data']) + answer_dict = (dns_query_data, resource_data) return answer_dict From 4a965e09e9478681baee426f9ce0bec7dd71c639 Mon Sep 17 00:00:00 2001 From: pranavrajtyagi Date: Tue, 2 Jun 2015 02:12:06 -0400 Subject: [PATCH 09/11] updated --- dnsquery.r2py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsquery.r2py b/dnsquery.r2py index dbcaf7a..7647c6c 100644 --- a/dnsquery.r2py +++ b/dnsquery.r2py @@ -331,7 +331,7 @@ def txtRecords(dns_query_data): if not resource_data: for item in answers: resource_data.append(item['answer_data']) - answer_dict = (dns_query_data, text_data) + answer_dict = (dns_query_data, resource_data) return answer_dict def getAAAA(dns_query_data): From 14f78f04fddc4032a2f63a4883dfdcbe0abdc8a7 Mon Sep 17 00:00:00 2001 From: pranavrajtyagi Date: Thu, 25 Jun 2015 15:45:36 -0400 Subject: [PATCH 10/11] updated dnsquery with exception in gethostbyname function --- dnsquery.r2py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/dnsquery.r2py b/dnsquery.r2py index 7647c6c..182d094 100644 --- a/dnsquery.r2py +++ b/dnsquery.r2py @@ -29,6 +29,9 @@ ------------ """ +class NonExistentDomainError(Exception): + # Used to indicate that one of our methods was passed bad arguments. + pass #imports dnscommon.r2py file from repyv2 library using dylink.r2py dnscommon = dy_import_module("dnscommon.r2py") @@ -38,7 +41,7 @@ listen_ip = '8.8.8.8' listen_port = 53 client_ip = getmyip() client_port = libsocket.get_messports(client_ip)[0] -destip = gethostbyname('myresolver.zenodotus.poly.edu') +#destip = gethostbyname('myresolver.zenodotus.poly.edu') default_flags = { 'communication_id': 'a7', @@ -171,14 +174,15 @@ def gethostbyname_ex(dns_query_data): #fetches answers from packet_dictionary received answers = packet_dict['answers'] resource_data = [] - try: - for item in answers: - resource_data.append(item['answer_data']['address']) - except KeyError: - pass - if not resource_data: - for item in answers: - resource_data.append(item['answer_data']) + if answers[0]['type'] == 'SOA': + error_string = "Domain not found" + raise NonExistentDomainError(error_string) + else: + try: + for item in answers: + resource_data.append(item['answer_data']['address']) + except KeyError: + pass answer_dict = (dns_query_data,resource_data) return answer_dict From d4c2ef71fe420a1916a7a2aaf08e6881257ced06 Mon Sep 17 00:00:00 2001 From: pranavrajtyagi Date: Thu, 25 Jun 2015 15:50:23 -0400 Subject: [PATCH 11/11] updated --- dnsquery.r2py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dnsquery.r2py b/dnsquery.r2py index 182d094..1dd028c 100644 --- a/dnsquery.r2py +++ b/dnsquery.r2py @@ -41,7 +41,7 @@ listen_ip = '8.8.8.8' listen_port = 53 client_ip = getmyip() client_port = libsocket.get_messports(client_ip)[0] -#destip = gethostbyname('myresolver.zenodotus.poly.edu') +destip = gethostbyname('myresolver.zenodotus.poly.edu') default_flags = { 'communication_id': 'a7',