def filter(packetNo, data, source, target): bytes = stringToBytes(data) if packetNo == 0 and 'Client2Server' in str(source): p = Parser(bytes[5:]) p.get(1) clientHello = ClientHello() clientHello.parse(p) print bcolors.OKGREEN + "Client supports TLS version: %s" % \ str(clientHello.client_version) print "Client supports ciphersuites: %s" % \ str([CIPHER_MAP.get(i,i) for i in clientHello.cipher_suites]) \ + bcolors.ENDC elif packetNo == 0 and 'Client2Server' not in str(source): p = Parser(bytes[5:]) p.get(1) serverHello = ServerHello() serverHello.parse(p) print bcolors.OKGREEN + "Server selected TLS version: %s" % \ str(serverHello.server_version) print "Server selected ciphersuite: %s" % \ str(CIPHER_MAP.get(serverHello.cipher_suite, serverHello.cipher_suite)) + bcolors.ENDC target.write(data) return data
def test_parse_with_SSLv2_client_hello(self): parser = Parser( bytearray( # length and type is handled by hello protocol parser #b'\x80\x2e' + # length - 46 bytes #b'\x01' + # message type - client hello b'\x00\x02' + # version - SSLv2 b'\x00\x15' + # cipher spec length - 21 bytes b'\x00\x00' + # session ID length - 0 bytes b'\x00\x10' + # challange length - 16 bytes b'\x07\x00\xc0' + # cipher - SSL2_DES_192_EDE3_CBC_WITH_MD5 b'\x05\x00\x80' + # cipher - SSL2_IDEA_128_CBC_WITH_MD5 b'\x03\x00\x80' + # cipher - SSL2_RC2_CBC_128_CBC_WITH_MD5 b'\x01\x00\x80' + # cipher - SSL2_RC4_128_WITH_MD5 b'\x06\x00\x40' + # cipher - SSL2_DES_64_CBC_WITH_MD5 b'\x04\x00\x80' + # cipher - SSL2_RC2_CBC_128_CBC_WITH_MD5 b'\x02\x00\x80' + # cipher - SSL2_RC4_128_EXPORT40_WITH_MD5 b'\x01' * 16 # challenge )) client_hello = ClientHello(ssl2=True) client_hello = client_hello.parse(parser) # XXX the value on the wire is LSB, but should be interpreted MSB for # SSL2 self.assertEqual((0, 2), client_hello.client_version) self.assertEqual(bytearray(0), client_hello.session_id) self.assertEqual( [458944, 327808, 196736, 65664, 393280, 262272, 131200], client_hello.cipher_suites) self.assertEqual(bytearray(b'\x00' * 16 + b'\x01' * 16), client_hello.random) self.assertEqual([0], client_hello.compression_methods)
def test_parse(self): p = Parser( bytearray( # we don't include the type of message as it is handled by the # hello protocol parser #b'x01' + # type of message - client_hello b'\x00' * 2 + b'\x26' + # length - 38 bytes b'\x01\x01' + # protocol version - arbitrary (invalid) b'\x00' * 32 + # client random b'\x00' + # session ID length b'\x00' * 2 + # cipher suites length b'\x00' # compression methods length )) client_hello = ClientHello() client_hello = client_hello.parse(p) self.assertEqual((1, 1), client_hello.client_version) self.assertEqual(bytearray(32), client_hello.random) self.assertEqual(bytearray(0), client_hello.session_id) self.assertEqual([], client_hello.cipher_suites) self.assertEqual([], client_hello.compression_methods) self.assertEqual(bytearray(0), client_hello.server_name) # XXX not sent self.assertEqual([0], client_hello.certificate_types) self.assertEqual(False, client_hello.supports_npn) self.assertEqual(False, client_hello.tack) self.assertEqual(None, client_hello.srp_username) self.assertEqual(None, client_hello.extensions)
def test_parse_with_SRP_extension(self): p = Parser( bytearray( # we don't include the type of message as it is handled by the # hello protocol parser #b'x01' + # type of message - client_hello b'\x00' * 2 + b'\x35' + # length - 53 bytes b'\x01\x01' + # protocol version - arbitrary (invalid) b'\x00' * 32 + # client random b'\x00' + # session ID length b'\x00' * 2 + # cipher suites length b'\x00' + # compression methods length b'\x00\x0d' + # extensions length - 13 bytes b'\x00\x0c' + # extension type - SRP (12) b'\x00\x09' + # extension length - 9 bytes b'\x08' + # length of name - 8 bytes b'username' # UTF-8 encoding of "username" :) )) client_hello = ClientHello() client_hello = client_hello.parse(p) self.assertEqual((1, 1), client_hello.client_version) self.assertEqual(bytearray(32), client_hello.random) self.assertEqual(bytearray(0), client_hello.session_id) self.assertEqual([], client_hello.cipher_suites) self.assertEqual([], client_hello.compression_methods) self.assertEqual(bytearray(b'username'), client_hello.srp_username) srp = SRPExtension().create(bytearray(b'username')) self.assertEqual([srp], client_hello.extensions)
def test_parse_with_TACK_extension(self): p = Parser( bytearray( # we don't include the type of message as it is handled by the # hello protocol parser #b'x01' + # type of message - client_hello b'\x00' * 2 + b'\x2c' + # length - 44 bytes b'\x01\x01' + # protocol version - arbitrary (invalid) b'\x00' * 32 + # client random b'\x00' + # session ID length b'\x00' * 2 + # cipher suites length b'\x00' + # compression methods length b'\x00\x04' + # extensions length - 4 bytes b'\xf3\x00' + # extension type - TACK (62208) b'\x00\x00' # extension length - 0 bytes )) client_hello = ClientHello() client_hello = client_hello.parse(p) self.assertEqual((1, 1), client_hello.client_version) self.assertEqual(bytearray(32), client_hello.random) self.assertEqual(bytearray(0), client_hello.session_id) self.assertEqual([], client_hello.cipher_suites) self.assertEqual([], client_hello.compression_methods) self.assertEqual(True, client_hello.tack) tack = TLSExtension().create(62208, bytearray(0)) self.assertEqual([tack], client_hello.extensions)
def test_parse_with_SNI_extension(self): p = Parser( bytearray( # we don't include the type of message as it is handled by the # hello protocol parser #b'x01' + # type of message - client_hello b'\x00' * 2 + b'\x3c' + # length - 60 bytes b'\x01\x01' + # protocol version - arbitrary (invalid) b'\x00' * 32 + # client random b'\x00' + # session ID length b'\x00' * 2 + # cipher suites length b'\x00' + # compression methods length b'\x00\x14' + # extensions length - 20 bytes b'\x00\x00' + # extension type - SNI (0) b'\x00\x10' + # extension length - 16 bytes b'\x00\x0e' + # length of array - 14 bytes b'\x00' + # type of entry - host_name (0) b'\x00\x0b' + # length of name - 11 bytes # UTF-8 encoding of example.com b'\x65\x78\x61\x6d\x70\x6c\x65\x2e\x63\x6f\x6d')) client_hello = ClientHello() client_hello = client_hello.parse(p) self.assertEqual((1, 1), client_hello.client_version) self.assertEqual(bytearray(32), client_hello.random) self.assertEqual(bytearray(0), client_hello.session_id) self.assertEqual([], client_hello.cipher_suites) self.assertEqual([], client_hello.compression_methods) self.assertEqual(bytearray(b'example.com'), client_hello.server_name) sni = SNIExtension().create(bytearray(b'example.com')) self.assertEqual([sni], client_hello.extensions)
def test_parse_with_cert_type_extension(self): p = Parser( bytearray( # we don't include the type of message as it is handled by the # hello protocol parser #b'x01' + # type of message - client_hello b'\x00' * 2 + b'\x2f' + # length - 47 bytes b'\x01\x01' + # protocol version - arbitrary (invalid) b'\x00' * 32 + # client random b'\x00' + # session ID length b'\x00' * 2 + # cipher suites length b'\x00' + # compression methods length b'\x00\x07' + # extensions length - 7 bytes b'\x00\x09' + # extension type - certTypes (9) b'\x00\x03' + # extension length - 3 bytes b'\x02' + # length of array - 2 bytes b'\x00' + # type - x509 (0) b'\x01' # type - opengpg (1) )) client_hello = ClientHello() client_hello = client_hello.parse(p) self.assertEqual((1, 1), client_hello.client_version) self.assertEqual(bytearray(32), client_hello.random) self.assertEqual(bytearray(0), client_hello.session_id) self.assertEqual([], client_hello.cipher_suites) self.assertEqual([], client_hello.compression_methods) self.assertEqual([0, 1], client_hello.certificate_types) certTypes = ClientCertTypeExtension().create([0, 1]) self.assertEqual([certTypes], client_hello.extensions)
def test_parse(self): p = Parser(bytearray( # we don't include the type of message as it is handled by the # hello protocol parser #b'x01' + # type of message - client_hello b'\x00'*2 + b'\x26' + # length - 38 bytes b'\x01\x01' + # protocol version - arbitrary (invalid) b'\x00'*32 + # client random b'\x00' + # session ID length b'\x00'*2 + # cipher suites length b'\x00' # compression methods length )) client_hello = ClientHello() client_hello = client_hello.parse(p) self.assertEqual((1,1), client_hello.client_version) self.assertEqual(bytearray(32), client_hello.random) self.assertEqual(bytearray(0), client_hello.session_id) self.assertEqual([], client_hello.cipher_suites) self.assertEqual([], client_hello.compression_methods) self.assertEqual(bytearray(0), client_hello.server_name) # XXX not sent self.assertEqual([0], client_hello.certificate_types) self.assertEqual(False, client_hello.supports_npn) self.assertEqual(False, client_hello.tack) self.assertEqual(None, client_hello.srp_username) self.assertEqual(None, client_hello.extensions)
def test_parse_with_TACK_extension(self): p = Parser(bytearray( # we don't include the type of message as it is handled by the # hello protocol parser #b'x01' + # type of message - client_hello b'\x00'*2 + b'\x2c' + # length - 44 bytes b'\x01\x01' + # protocol version - arbitrary (invalid) b'\x00'*32 + # client random b'\x00' + # session ID length b'\x00'*2 + # cipher suites length b'\x00' + # compression methods length b'\x00\x04' + # extensions length - 4 bytes b'\xf3\x00' + # extension type - TACK (62208) b'\x00\x00' # extension length - 0 bytes )) client_hello = ClientHello() client_hello = client_hello.parse(p) self.assertEqual((1,1), client_hello.client_version) self.assertEqual(bytearray(32), client_hello.random) self.assertEqual(bytearray(0), client_hello.session_id) self.assertEqual([], client_hello.cipher_suites) self.assertEqual([], client_hello.compression_methods) self.assertEqual(True, client_hello.tack) tack = TLSExtension().create(62208, bytearray(0)) self.assertEqual([tack], client_hello.extensions)
def test_parse_with_SRP_extension(self): p = Parser(bytearray( # we don't include the type of message as it is handled by the # hello protocol parser #b'x01' + # type of message - client_hello b'\x00'*2 + b'\x35' + # length - 53 bytes b'\x01\x01' + # protocol version - arbitrary (invalid) b'\x00'*32 + # client random b'\x00' + # session ID length b'\x00'*2 + # cipher suites length b'\x00' + # compression methods length b'\x00\x0d' + # extensions length - 13 bytes b'\x00\x0c' + # extension type - SRP (12) b'\x00\x09' + # extension length - 9 bytes b'\x08' + # length of name - 8 bytes b'username' # UTF-8 encoding of "username" :) )) client_hello = ClientHello() client_hello = client_hello.parse(p) self.assertEqual((1,1), client_hello.client_version) self.assertEqual(bytearray(32), client_hello.random) self.assertEqual(bytearray(0), client_hello.session_id) self.assertEqual([], client_hello.cipher_suites) self.assertEqual([], client_hello.compression_methods) self.assertEqual(bytearray(b'username'), client_hello.srp_username) srp = SRPExtension().create(bytearray(b'username')) self.assertEqual([srp], client_hello.extensions)
def test_parse_with_cert_type_extension(self): p = Parser(bytearray( # we don't include the type of message as it is handled by the # hello protocol parser #b'x01' + # type of message - client_hello b'\x00'*2 + b'\x2f' + # length - 47 bytes b'\x01\x01' + # protocol version - arbitrary (invalid) b'\x00'*32 + # client random b'\x00' + # session ID length b'\x00'*2 + # cipher suites length b'\x00' + # compression methods length b'\x00\x07' + # extensions length - 7 bytes b'\x00\x09' + # extension type - cert_types (9) b'\x00\x03' + # extension length - 3 bytes b'\x02' + # length of array - 2 bytes b'\x00' + # type - x509 (0) b'\x01' # type - opengpg (1) )) client_hello = ClientHello() client_hello = client_hello.parse(p) self.assertEqual((1,1), client_hello.client_version) self.assertEqual(bytearray(32), client_hello.random) self.assertEqual(bytearray(0), client_hello.session_id) self.assertEqual([], client_hello.cipher_suites) self.assertEqual([], client_hello.compression_methods) self.assertEqual([0,1], client_hello.certificate_types) cert_types = ClientCertTypeExtension().create([0,1]) self.assertEqual([cert_types], client_hello.extensions)
def test_parse_with_SNI_extension(self): p = Parser(bytearray( # we don't include the type of message as it is handled by the # hello protocol parser #b'x01' + # type of message - client_hello b'\x00'*2 + b'\x3c' + # length - 60 bytes b'\x01\x01' + # protocol version - arbitrary (invalid) b'\x00'*32 + # client random b'\x00' + # session ID length b'\x00'*2 + # cipher suites length b'\x00' + # compression methods length b'\x00\x14' + # extensions length - 20 bytes b'\x00\x00' + # extension type - SNI (0) b'\x00\x10' + # extension length - 16 bytes b'\x00\x0e' + # length of array - 14 bytes b'\x00' + # type of entry - host_name (0) b'\x00\x0b' + # length of name - 11 bytes # UTF-8 encoding of example.com b'\x65\x78\x61\x6d\x70\x6c\x65\x2e\x63\x6f\x6d' )) client_hello = ClientHello() client_hello = client_hello.parse(p) self.assertEqual((1,1), client_hello.client_version) self.assertEqual(bytearray(32), client_hello.random) self.assertEqual(bytearray(0), client_hello.session_id) self.assertEqual([], client_hello.cipher_suites) self.assertEqual([], client_hello.compression_methods) self.assertEqual(bytearray(b'example.com'), client_hello.server_name) sni = SNIExtension().create(bytearray(b'example.com')) self.assertEqual([sni], client_hello.extensions)
def test_parse_with_SSLv2_client_hello(self): parser = Parser(bytearray( # length and type is handled by hello protocol parser #b'\x80\x2e' + # length - 46 bytes #b'\x01' + # message type - client hello b'\x00\x02' + # version - SSLv2 b'\x00\x15' + # cipher spec length - 21 bytes b'\x00\x00' + # session ID length - 0 bytes b'\x00\x10' + # challange length - 16 bytes b'\x07\x00\xc0' + # cipher - SSL2_DES_192_EDE3_CBC_WITH_MD5 b'\x05\x00\x80' + # cipher - SSL2_IDEA_128_CBC_WITH_MD5 b'\x03\x00\x80' + # cipher - SSL2_RC2_CBC_128_CBC_WITH_MD5 b'\x01\x00\x80' + # cipher - SSL2_RC4_128_WITH_MD5 b'\x06\x00\x40' + # cipher - SSL2_DES_64_CBC_WITH_MD5 b'\x04\x00\x80' + # cipher - SSL2_RC2_CBC_128_CBC_WITH_MD5 b'\x02\x00\x80' + # cipher - SSL2_RC4_128_EXPORT40_WITH_MD5 b'\x01' * 16 # challenge )) client_hello = ClientHello(ssl2=True) client_hello = client_hello.parse(parser) # XXX the value on the wire is LSB, but should be interpreted MSB for # SSL2 self.assertEqual((0, 2), client_hello.client_version) self.assertEqual(bytearray(0), client_hello.session_id) self.assertEqual([458944, 327808, 196736, 65664, 393280, 262272, 131200], client_hello.cipher_suites) self.assertEqual(bytearray(b'\x00'*16 + b'\x01'*16), client_hello.random) self.assertEqual([0], client_hello.compression_methods)
def test_parse_with_empty_extensions(self): p = Parser(bytearray( # we don't include the type of message as it is handled by the # hello protocol parser #b'x01' + # type of message - client_hello b'\x00'*2 + b'\x28' + # length - 38 bytes b'\x01\x01' + # protocol version - arbitrary (invalid) b'\x00'*32 + # client random b'\x00' + # session ID length b'\x00'*2 + # cipher suites length b'\x00' + # compression methods length b'\x00\x00' # extensions length )) client_hello = ClientHello() client_hello = client_hello.parse(p) self.assertEqual((1,1), client_hello.client_version) self.assertEqual(bytearray(32), client_hello.random) self.assertEqual(bytearray(0), client_hello.session_id) self.assertEqual([], client_hello.cipher_suites) self.assertEqual([], client_hello.compression_methods) self.assertEqual([], client_hello.extensions)
def test_parse_with_empty_extensions(self): p = Parser( bytearray( # we don't include the type of message as it is handled by the # hello protocol parser #b'x01' + # type of message - client_hello b'\x00' * 2 + b'\x28' + # length - 38 bytes b'\x01\x01' + # protocol version - arbitrary (invalid) b'\x00' * 32 + # client random b'\x00' + # session ID length b'\x00' * 2 + # cipher suites length b'\x00' + # compression methods length b'\x00\x00' # extensions length )) client_hello = ClientHello() client_hello = client_hello.parse(p) self.assertEqual((1, 1), client_hello.client_version) self.assertEqual(bytearray(32), client_hello.random) self.assertEqual(bytearray(0), client_hello.session_id) self.assertEqual([], client_hello.cipher_suites) self.assertEqual([], client_hello.compression_methods) self.assertEqual([], client_hello.extensions)