def test_is_valid_ip_address(self): valid_ips = ['127.0.0.1', '10.0.0.1', '200.100.0.1', 'fe80::1', '::1'] invalid_ips = ['localhost', 'www.google.com', ''] for address in valid_ips: self.assertTrue(ipaddress.is_valid(address)) for address in invalid_ips: self.assertFalse(ipaddress.is_valid(address))
def get_client_ip(self): """ Intelligently get the IP address of the HTTP client, optionally accounting for proxies that may be in use. :return: The clients IP address. :rtype: str """ address = self.client_address[0] header_name = self.config.get_if_exists('server.client_ip_header') # new style header_name = header_name or self.config.get_if_exists('server.client_ip_cookie') # old style if not header_name: return address header_value = self.headers.get(header_name, '') if not header_value: return address header_value = header_value.split(',')[0] header_value = header_value.strip() if header_value.startswith('['): # header_value looks like an IPv6 address header_value = header_value.split(']:', 1)[0] else: # treat header_value as an IPv4 address header_value = header_value.split(':', 1)[0] if ipaddress.is_valid(header_value): address = header_value return address
def main(): parser = argparse.ArgumentParser(description='King Phisher SPF Check Utility', conflict_handler='resolve') utilities.argp_add_args(parser) parser.add_argument('smtp_server_ip', help='the ip address of the sending smtp server') parser.add_argument('target_email', help='the email address that messages are from') arguments = parser.parse_args() utilities.configure_stream_logger(arguments.logger, arguments.loglvl) server_ip = arguments.smtp_server_ip target_email = arguments.target_email if not ipaddress.is_valid(server_ip): color.print_error('the smtp server ip address specified is invalid') return if not '@' in target_email: target_email = utilities.random_string_lower_numeric(8) + '@' + target_email color.print_status('target email appears to be just a domain, changed to: ' + target_email) if not utilities.is_valid_email_address(target_email): color.print_error('the email address specified is invalid') return spf_sender, spf_domain = target_email.split('@') spf_test = spf.SenderPolicyFramework(server_ip, spf_domain, spf_sender) try: result = spf_test.check_host() except spf.SPFParseError as error: color.print_error('check_host failed with error: permerror (parsing failed)') color.print_error('error reason: ' + error.message) return except spf.SPFPermError as error: color.print_error('check_host failed with error: permerror') color.print_error('error reason: ' + error.message) return except spf.SPFTempError as error: color.print_error('check_host failed with error: temperror') color.print_error('error reason: ' + error.message) return if not result: color.print_status('no spf policy was found for the specified domain') return color.print_good("spf policy result: {0}".format(result)) color.print_status('top level spf records found:') match = spf_test.match for record_id, record in enumerate(spf_test.records.values(), 1): color.print_status(" #{0} {1: <10} {2}".format( record_id, ('(matched)' if match.record == record else ''), record.domain )) for directive_id, directive in enumerate(record.directives, 1): color.print_status(" #{0}.{1} {2: <10} {3}".format( record_id, directive_id, ('(matched)' if match.record == record and match.directive == directive else ''), directive ))
def main(): parser = argparse.ArgumentParser(description='King Phisher SPF Check Utility', conflict_handler='resolve') utilities.argp_add_args(parser) parser.add_argument('smtp_server_ip', help='the ip address of the sending smtp server') parser.add_argument('target_email', help='the email address that messages are from') parser.add_argument('--dns-timeout', dest='dns_timeout', default=spf.DEFAULT_DNS_TIMEOUT, type=int, help='the timeout for dns queries') arguments = parser.parse_args() server_ip = arguments.smtp_server_ip target_email = arguments.target_email if not ipaddress.is_valid(server_ip): color.print_error('the smtp server ip address specified is invalid') return if not '@' in target_email: target_email = utilities.random_string_lower_numeric(8) + '@' + target_email color.print_status('target email appears to be just a domain, changed to: ' + target_email) if not utilities.is_valid_email_address(target_email): color.print_error('the email address specified is invalid') return spf_sender, spf_domain = target_email.split('@') spf_test = spf.SenderPolicyFramework(server_ip, spf_domain, sender=spf_sender, timeout=arguments.dns_timeout) try: result = spf_test.check_host() except spf.SPFParseError as error: color.print_error('check_host failed with error: permerror (parsing failed)') color.print_error('error reason: ' + error.message) return except spf.SPFPermError as error: color.print_error('check_host failed with error: permerror') color.print_error('error reason: ' + error.message) return except spf.SPFTempError as error: color.print_error('check_host failed with error: temperror') color.print_error('error reason: ' + error.message) return if not result: color.print_status('no spf policy was found for the specified domain') return color.print_good("spf policy result: {0}".format(result)) color.print_status('top level spf records found:') match = spf_test.match for record_id, record in enumerate(spf_test.records.values(), 1): color.print_status(" #{0} {1: <10} {2}".format( record_id, ('(matched)' if match.record == record else ''), record.domain )) for directive_id, directive in enumerate(record.directives, 1): color.print_status(" #{0}.{1: <2} {2: <10} {3}".format( record_id, directive_id, ('(matched)' if match.record == record and match.directive == directive else ''), directive ))
def test_is_valid_ip_address(self): valid_ips = [ '127.0.0.1', '10.0.0.1', '200.100.0.1', 'fe80::1', '::1' ] invalid_ips = [ 'localhost', 'www.google.com', '' ] for address in valid_ips: self.assertTrue(ipaddress.is_valid(address)) for address in invalid_ips: self.assertFalse(ipaddress.is_valid(address))
def main(): parser = argparse.ArgumentParser(description='King Phisher SPF Check Utility', conflict_handler='resolve') utilities.argp_add_args(parser) parser.add_argument('smtp_server_ip', help='the ip address of the sending smtp server') parser.add_argument('target_email', help='the email address that messages are from') arguments = parser.parse_args() utilities.configure_stream_logger(arguments.loglvl, arguments.logger) server_ip = arguments.smtp_server_ip target_email = arguments.target_email if not ipaddress.is_valid(server_ip): color.print_error('the smtp server ip address specified is invalid') return if not '@' in target_email: target_email = utilities.random_string_lower_numeric(8) + '@' + target_email color.print_status('target email appears to be just a domain, changed to: ' + target_email) if not utilities.is_valid_email_address(target_email): color.print_error('the email address specified is invalid') return spf_sender, spf_domain = target_email.split('@') spf_test = spf.SenderPolicyFramework(server_ip, spf_domain, spf_sender) try: result = spf_test.check_host() except spf.SPFPermError as error: color.print_error('check_host failed with error: permerror') color.print_error('error reason: ' + error.message) return except spf.SPFTempError as error: color.print_error('check_host failed with error: temperror') color.print_error('error reason: ' + error.message) return if not result: color.print_status('no spf policy was found for the specified domain') return color.print_good("spf policy result: {0}".format(result)) color.print_status('top level spf records found:') for rid in range(len(spf_test.spf_records)): record = spf.record_unparse(spf_test.spf_records[rid]) color.print_status(" #{0} {1: <10} {2}".format(rid + 1, ('(matched)' if rid == spf_test.spf_record_id else ''), record))
def guess_smtp_server_address(host, forward_host=None): """ Guess the IP address of the SMTP server that will be connected to given the SMTP host information and an optional SSH forwarding host. If a hostname is in use it will be resolved to an IP address, either IPv4 or IPv6 and in that order. If a hostname resolves to multiple IP addresses, None will be returned. This function is intended to guess the SMTP servers IP address given the client configuration so it can be used for SPF record checks. :param str host: The SMTP server that is being connected to. :param str forward_host: An optional host that is being used to tunnel the connection. :return: The IP address of the SMTP server. :rtype: None, :py:class:`ipaddress.IPv4Address`, :py:class:`ipaddress.IPv6Address` """ host = host.rsplit(':', 1)[0] if ipaddress.is_valid(host): ip = ipaddress.ip_address(host) if not ip.is_loopback: return ip else: info = None for family in (socket.AF_INET, socket.AF_INET6): try: info = socket.getaddrinfo(host, 1, family) except socket.gaierror: continue info = set(list([r[4][0] for r in info])) if len(info) != 1: return break if info: ip = ipaddress.ip_address(info.pop()) if not ip.is_loopback: return ip if forward_host: return guess_smtp_server_address(forward_host) return
def get_client_ip(self): """ Intelligently get the IP address of the HTTP client, optionally accounting for proxies that may be in use. :return: The clients IP address. :rtype: str """ address = self.client_address[0] cookie_name = self.config.get_if_exists('server.client_ip_cookie') if not cookie_name: return address cookie_value = self.headers.get(cookie_name, '') if not cookie_value: return address if cookie_value.startswith('['): # cookie_value looks like an IPv6 address cookie_value = cookie_value.split(']:', 1)[0] else: # treat cookie_value ad an IPv4 address cookie_value = cookie_value.split(':', 1)[0] if ipaddress.is_valid(cookie_value): address = cookie_value return address
def main(): parser = argparse.ArgumentParser( conflict_handler='resolve', description=PARSER_DESCRIPTION, epilog=PARSER_EPILOG, formatter_class=argparse.RawTextHelpFormatter ) utilities.argp_add_args(parser) parser.add_argument('smtp_server_ip', help='the ip address of the sending smtp server') parser.add_argument('target_email', help='the email address that messages are from') parser.add_argument('--dns-timeout', dest='dns_timeout', default=spf.DEFAULT_DNS_TIMEOUT, metavar='TIMEOUT', type=int, help='the timeout for dns queries') arguments = parser.parse_args() server_ip = arguments.smtp_server_ip target_email = arguments.target_email if not ipaddress.is_valid(server_ip): color.print_error('the smtp server ip address specified is invalid') return if not '@' in target_email: target_email = utilities.random_string_lower_numeric(8) + '@' + target_email color.print_status('target email appears to be just a domain, changed to: ' + target_email) if not utilities.is_valid_email_address(target_email): color.print_error('the email address specified is invalid') return spf_sender, spf_domain = target_email.split('@') spf_test = spf.SenderPolicyFramework(server_ip, spf_domain, sender=spf_sender, timeout=arguments.dns_timeout) try: result = spf_test.check_host() except spf.SPFParseError as error: color.print_error('check_host failed with error: permerror (parsing failed)') color.print_error('error reason: ' + error.message) return except spf.SPFPermError as error: color.print_error('check_host failed with error: permerror') color.print_error('error reason: ' + error.message) return except spf.SPFTempError as error: color.print_error('check_host failed with error: temperror') color.print_error('error reason: ' + error.message) return if not result: color.print_status('no spf policy was found for the specified domain') return color.print_good("spf policy result: {0}".format(result)) color.print_status('top level spf records found:') match = spf_test.match for record_id, record in enumerate(spf_test.records.values(), 1): color.print_status(" #{0} {1: <10} {2}".format( record_id, ('(matched)' if match.record == record else ''), record.domain )) for directive_id, directive in enumerate(record.directives, 1): color.print_status(" #{0}.{1: <2} {2: <10} {3}".format( record_id, directive_id, ('(matched)' if match.record == record and match.directive == directive else ''), directive ))