Open Nefurtity opened 6 years ago
While this sounds possible, I think a VPN would be a better solution. I would imagine a firewall could just as easily filter based on the server certificate, or the subject in that certificate. Stripping out the SNI header doesn't seem to buy any meaningful privacy, and encourages increased IP address consumption. Another consideration is increases the complexity of SNIproxy but requiring the TLS protocol module to modify the buffer state. Presently there is no direct dependency between these two modules.
Your welcome to SNIproxy as a base for this application. I would start by introducing a remove_extension(struct Buffer *client_hello, uint16 tls_extention_id)
function the TLS module.
Removing the SNI header would probably also yield a different certificate. I also know of servers that will outright reject clients without SNI. I do agree that a VPN is probably a better solution. I don't share the concern about IP address consumption, since there are plenty of IPv6 addresses out there.
I have tried to remove the server name extension field, and increases the padding extension to keep the total TLS record length as the same. But finally, I got Handshake Failure (40)
605 2.966434 192.168.10.100 192.168.10.53 TLSv1.2 583 Client Hello
Frame 605: 583 bytes on wire (4664 bits), 583 bytes captured (4664 bits)
Ethernet II, Src: Apple_c5:7f:4f (c4:b3:01:c5:7f:4f), Dst: AsustekC_57:6d:d1 (00:26:18:57:6d:d1)
Internet Protocol Version 4, Src: 192.168.10.100, Dst: 192.168.10.53
Transmission Control Protocol, Src Port: 63433, Dst Port: 443, Seq: 1, Ack: 1, Len: 517
Secure Sockets Layer
TLSv1.2 Record Layer: Handshake Protocol: Client Hello
Content Type: Handshake (22)
Version: TLS 1.0 (0x0301)
Length: 512
Handshake Protocol: Client Hello
Handshake Type: Client Hello (1)
Length: 508
Version: TLS 1.2 (0x0303)
Random: 17a18c56d3818904c1e374c50f289a68119cf815fb681181...
Session ID Length: 0
Cipher Suites Length: 134
Cipher Suites (67 suites)
Compression Methods Length: 1
Compression Methods (1 method)
Extensions Length: 333
Extension: server_name (len=18)
Extension: ec_point_formats (len=4)
Extension: supported_groups (len=58)
Extension: signature_algorithms (len=38)
Extension: next_protocol_negotiation (len=0)
Extension: application_layer_protocol_negotiation (len=14)
Extension: padding (len=173)
625 3.205915 192.168.10.53 163.177.151.110 TLSv1.2 571 Client Hello
Frame 625: 571 bytes on wire (4568 bits), 571 bytes captured (4568 bits)
Ethernet II, Src: AsustekC_57:6d:d1 (00:26:18:57:6d:d1), Dst: NecPlatf_3e:fc:6c (a4:12:42:3e:fc:6c)
Internet Protocol Version 4, Src: 192.168.10.53, Dst: 163.177.151.110
Transmission Control Protocol, Src Port: 41218, Dst Port: 443, Seq: 1, Ack: 1, Len: 517
Secure Sockets Layer
TLSv1.2 Record Layer: Handshake Protocol: Client Hello
Content Type: Handshake (22)
Version: TLS 1.0 (0x0301)
Length: 512
Handshake Protocol: Client Hello
Handshake Type: Client Hello (1)
Length: 508
Version: TLS 1.2 (0x0303)
Random: 17a18c56d3818904c1e374c50f289a68119cf815fb681181...
Session ID Length: 0
Cipher Suites Length: 134
Cipher Suites (67 suites)
Compression Methods Length: 1
Compression Methods (1 method)
Extensions Length: 333
Extension: ec_point_formats (len=4)
Extension: supported_groups (len=58)
Extension: signature_algorithms (len=38)
Extension: next_protocol_negotiation (len=0)
Extension: application_layer_protocol_negotiation (len=14)
Extension: padding (len=195)
627 3.237869 163.177.151.110 192.168.10.53 TLSv1.2 155 Server Hello
Frame 627: 155 bytes on wire (1240 bits), 155 bytes captured (1240 bits)
Ethernet II, Src: NecPlatf_3e:fc:6c (a4:12:42:3e:fc:6c), Dst: AsustekC_57:6d:d1 (00:26:18:57:6d:d1)
Internet Protocol Version 4, Src: 163.177.151.110, Dst: 192.168.10.53
Transmission Control Protocol, Src Port: 443, Dst Port: 41218, Seq: 1, Ack: 518, Len: 101
Secure Sockets Layer
TLSv1.2 Record Layer: Handshake Protocol: Server Hello
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 96
Handshake Protocol: Server Hello
Handshake Type: Server Hello (2)
Length: 92
Version: TLS 1.2 (0x0303)
Random: 5a3aa1dcfdfa6dccae60b660fa7240db52644586fd5117df...
Session ID Length: 32
Session ID: 7a4f0c12bf370047b994e598439974bdb8a7e271312e084f...
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
Compression Method: null (0)
Extensions Length: 20
Extension: renegotiation_info (len=1)
Extension: application_layer_protocol_negotiation (len=11)
629 3.237922 192.168.10.53 192.168.10.100 TLSv1.2 167 Server Hello
Frame 629: 167 bytes on wire (1336 bits), 167 bytes captured (1336 bits)
Ethernet II, Src: AsustekC_57:6d:d1 (00:26:18:57:6d:d1), Dst: Apple_c5:7f:4f (c4:b3:01:c5:7f:4f)
Internet Protocol Version 4, Src: 192.168.10.53, Dst: 192.168.10.100
Transmission Control Protocol, Src Port: 443, Dst Port: 63433, Seq: 1, Ack: 518, Len: 101
Secure Sockets Layer
TLSv1.2 Record Layer: Handshake Protocol: Server Hello
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 96
Handshake Protocol: Server Hello
Handshake Type: Server Hello (2)
Length: 92
Version: TLS 1.2 (0x0303)
Random: 5a3aa1dcfdfa6dccae60b660fa7240db52644586fd5117df...
Session ID Length: 32
Session ID: 7a4f0c12bf370047b994e598439974bdb8a7e271312e084f...
Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
Compression Method: null (0)
Extensions Length: 20
Extension: renegotiation_info (len=1)
Extension: application_layer_protocol_negotiation (len=11)
630 3.238239 163.177.151.110 192.168.10.53 TLSv1.2 3638 Certificate
Frame 630: 3638 bytes on wire (29104 bits), 3638 bytes captured (29104 bits)
Ethernet II, Src: NecPlatf_3e:fc:6c (a4:12:42:3e:fc:6c), Dst: AsustekC_57:6d:d1 (00:26:18:57:6d:d1)
Internet Protocol Version 4, Src: 163.177.151.110, Dst: 192.168.10.53
Transmission Control Protocol, Src Port: 443, Dst Port: 41218, Seq: 102, Ack: 518, Len: 3584
Secure Sockets Layer
TLSv1.2 Record Layer: Handshake Protocol: Certificate
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 3579
Handshake Protocol: Certificate
Handshake Type: Certificate (11)
Length: 3575
Certificates Length: 3572
Certificates (3572 bytes)
632 3.238289 192.168.10.53 192.168.10.100 TCP 1514 443 → 63433 [ACK] Seq=102 Ack=518 Win=30080 Len=1448 TSval=28626668 TSecr=491852132 [TCP segment of a reassembled PDU]
Frame 632: 1514 bytes on wire (12112 bits), 1514 bytes captured (12112 bits)
Ethernet II, Src: AsustekC_57:6d:d1 (00:26:18:57:6d:d1), Dst: Apple_c5:7f:4f (c4:b3:01:c5:7f:4f)
Internet Protocol Version 4, Src: 192.168.10.53, Dst: 192.168.10.100
Transmission Control Protocol, Src Port: 443, Dst Port: 63433, Seq: 102, Ack: 518, Len: 1448
634 3.239616 163.177.151.110 192.168.10.53 TLSv1.2 392 Server Key Exchange
Frame 634: 392 bytes on wire (3136 bits), 392 bytes captured (3136 bits)
Ethernet II, Src: NecPlatf_3e:fc:6c (a4:12:42:3e:fc:6c), Dst: AsustekC_57:6d:d1 (00:26:18:57:6d:d1)
Internet Protocol Version 4, Src: 163.177.151.110, Dst: 192.168.10.53
Transmission Control Protocol, Src Port: 443, Dst Port: 41218, Seq: 3686, Ack: 518, Len: 338
Secure Sockets Layer
TLSv1.2 Record Layer: Handshake Protocol: Server Key Exchange
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 333
Handshake Protocol: Server Key Exchange
Handshake Type: Server Key Exchange (12)
Length: 329
EC Diffie-Hellman Server Params
636 3.239632 163.177.151.110 192.168.10.53 TLSv1.2 63 Server Hello Done
Frame 636: 63 bytes on wire (504 bits), 63 bytes captured (504 bits)
Ethernet II, Src: NecPlatf_3e:fc:6c (a4:12:42:3e:fc:6c), Dst: AsustekC_57:6d:d1 (00:26:18:57:6d:d1)
Internet Protocol Version 4, Src: 163.177.151.110, Dst: 192.168.10.53
Transmission Control Protocol, Src Port: 443, Dst Port: 41218, Seq: 4024, Ack: 518, Len: 9
Secure Sockets Layer
TLSv1.2 Record Layer: Handshake Protocol: Server Hello Done
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 4
Handshake Protocol: Server Hello Done
Handshake Type: Server Hello Done (14)
Length: 0
638 3.249889 192.168.10.53 192.168.10.100 TLSv1.2 1101 Certificate, Server Key Exchange, Server Hello Done
Frame 638: 1101 bytes on wire (8808 bits), 1101 bytes captured (8808 bits)
Ethernet II, Src: AsustekC_57:6d:d1 (00:26:18:57:6d:d1), Dst: Apple_c5:7f:4f (c4:b3:01:c5:7f:4f)
Internet Protocol Version 4, Src: 192.168.10.53, Dst: 192.168.10.100
Transmission Control Protocol, Src Port: 443, Dst Port: 63433, Seq: 2998, Ack: 518, Len: 1035
[3 Reassembled TCP Segments (3584 bytes): #632(1448), #633(1448), #638(688)]
Secure Sockets Layer
TLSv1.2 Record Layer: Handshake Protocol: Certificate
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 3579
Handshake Protocol: Certificate
Handshake Type: Certificate (11)
Length: 3575
Certificates Length: 3572
Certificates (3572 bytes)
Secure Sockets Layer
TLSv1.2 Record Layer: Handshake Protocol: Server Key Exchange
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 333
Handshake Protocol: Server Key Exchange
Handshake Type: Server Key Exchange (12)
Length: 329
EC Diffie-Hellman Server Params
TLSv1.2 Record Layer: Handshake Protocol: Server Hello Done
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 4
Handshake Protocol: Server Hello Done
Handshake Type: Server Hello Done (14)
Length: 0
639 3.249924 163.177.151.110 192.168.10.53 TLSv1.2 63 [TCP Spurious Retransmission] , Server Hello Done
Frame 639: 63 bytes on wire (504 bits), 63 bytes captured (504 bits)
Ethernet II, Src: NecPlatf_3e:fc:6c (a4:12:42:3e:fc:6c), Dst: AsustekC_57:6d:d1 (00:26:18:57:6d:d1)
Internet Protocol Version 4, Src: 163.177.151.110, Dst: 192.168.10.53
Transmission Control Protocol, Src Port: 443, Dst Port: 41218, Seq: 4024, Ack: 518, Len: 9
Secure Sockets Layer
TLSv1.2 Record Layer: Handshake Protocol: Server Hello Done
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 4
Handshake Protocol: Server Hello Done
Handshake Type: Server Hello Done (14)
Length: 0
645 3.330981 192.168.10.100 192.168.10.53 TLSv1.2 192 Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message
Frame 645: 192 bytes on wire (1536 bits), 192 bytes captured (1536 bits)
Ethernet II, Src: Apple_c5:7f:4f (c4:b3:01:c5:7f:4f), Dst: AsustekC_57:6d:d1 (00:26:18:57:6d:d1)
Internet Protocol Version 4, Src: 192.168.10.100, Dst: 192.168.10.53
Transmission Control Protocol, Src Port: 63433, Dst Port: 443, Seq: 518, Ack: 4033, Len: 126
Secure Sockets Layer
TLSv1.2 Record Layer: Handshake Protocol: Client Key Exchange
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 70
Handshake Protocol: Client Key Exchange
Handshake Type: Client Key Exchange (16)
Length: 66
EC Diffie-Hellman Client Params
TLSv1.2 Record Layer: Change Cipher Spec Protocol: Change Cipher Spec
Content Type: Change Cipher Spec (20)
Version: TLS 1.2 (0x0303)
Length: 1
Change Cipher Spec Message
TLSv1.2 Record Layer: Handshake Protocol: Encrypted Handshake Message
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 40
Handshake Protocol: Encrypted Handshake Message
647 3.331042 192.168.10.53 163.177.151.110 TLSv1.2 180 Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message
Frame 647: 180 bytes on wire (1440 bits), 180 bytes captured (1440 bits)
Ethernet II, Src: AsustekC_57:6d:d1 (00:26:18:57:6d:d1), Dst: NecPlatf_3e:fc:6c (a4:12:42:3e:fc:6c)
Internet Protocol Version 4, Src: 192.168.10.53, Dst: 163.177.151.110
Transmission Control Protocol, Src Port: 41218, Dst Port: 443, Seq: 518, Ack: 4033, Len: 126
Secure Sockets Layer
TLSv1.2 Record Layer: Handshake Protocol: Client Key Exchange
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 70
Handshake Protocol: Client Key Exchange
Handshake Type: Client Key Exchange (16)
Length: 66
EC Diffie-Hellman Client Params
TLSv1.2 Record Layer: Change Cipher Spec Protocol: Change Cipher Spec
Content Type: Change Cipher Spec (20)
Version: TLS 1.2 (0x0303)
Length: 1
Change Cipher Spec Message
TLSv1.2 Record Layer: Handshake Protocol: Encrypted Handshake Message
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 40
Handshake Protocol: Encrypted Handshake Message
649 3.363816 163.177.151.110 192.168.10.53 TLSv1.2 61 Alert (Level: Fatal, Description: Handshake Failure)
Frame 649: 61 bytes on wire (488 bits), 61 bytes captured (488 bits)
Ethernet II, Src: NecPlatf_3e:fc:6c (a4:12:42:3e:fc:6c), Dst: AsustekC_57:6d:d1 (00:26:18:57:6d:d1)
Internet Protocol Version 4, Src: 163.177.151.110, Dst: 192.168.10.53
Transmission Control Protocol, Src Port: 443, Dst Port: 41218, Seq: 4033, Ack: 644, Len: 7
Secure Sockets Layer
TLSv1.2 Record Layer: Alert (Level: Fatal, Description: Handshake Failure)
Content Type: Alert (21)
Version: TLS 1.2 (0x0303)
Length: 2
Alert Message
Level: Fatal (2)
Description: Handshake Failure (40)
651 3.363861 192.168.10.53 192.168.10.100 TLSv1.2 73 Alert (Level: Fatal, Description: Handshake Failure)
Frame 651: 73 bytes on wire (584 bits), 73 bytes captured (584 bits)
Ethernet II, Src: AsustekC_57:6d:d1 (00:26:18:57:6d:d1), Dst: Apple_c5:7f:4f (c4:b3:01:c5:7f:4f)
Internet Protocol Version 4, Src: 192.168.10.53, Dst: 192.168.10.100
Transmission Control Protocol, Src Port: 443, Dst Port: 63433, Seq: 4033, Ack: 644, Len: 7
Secure Sockets Layer
TLSv1.2 Record Layer: Alert (Level: Fatal, Description: Handshake Failure)
Content Type: Alert (21)
Version: TLS 1.2 (0x0303)
Length: 2
Alert Message
Level: Fatal (2)
Description: Handshake Failure (40)
@dlundquist Do you have any idea?
After many times retry, remove the server name extension will lead a Handshake Failure (40), or Decrypt Error(51) by different servers. I found that change the hostname to another one which has the same length works.
Client Hello Client Hello
... ...
Length: 84 Length: 84
Server Name Indication: www.blocked.com -> sniproxy -> Server Name Indication: www.another.com
Supported_groups (len=8) Supported_groups (len=8)
... ...
@Nefurtity I didn't analyze your TLS handshakes in detail, but my first through is to check that you updated the TLS record length, handshake length and extension length when you remove the SNI extension. Since you can modify the content of the SNI header without breaking the TLS negotiation, I would suspect that the content of the TLS handshake isn't protected by a message digest later in the handshake. I seem to recall some application proxy that modified the cipher suites to ensure complacence requirements, which would also support this.
I would start by writing a tests for the TLS handshake mutation function similar to the ones in tests/tls.c with a very simple handshake and ensuring the resulting handshake matches one you've modified by hand exactly.
const unsigned char good_data_2[] = {
// TLS record
0x16, // Content Type: Handshake
0x03, 0x01, // Version: TLS 1.0
0x00, 0x48, // Length
// Handshake
0x01, // Handshake Type: Client Hello
0x00, 0x00, 0x42, // Length
0x03, 0x03, // Version: TLS 1.2
// Random
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, // Session ID Length
0x00, 0x04, // Cipher Suites Length
0x00, 0x01, // NULL-MD5
0x00, 0xff, // RENEGOTIATION INFO SCSV
0x01, // Compression Methods
0x00, // NULL
0x00, 0x17, // Extensions Length
// Extension
0x00, 0x00, // Extension Type: Server Name
0x00, 0x0e, // Length
0x00, 0x0c, // Server Name Indication Length
0x00, // Server Name Type: host_name
0x00, 0x09, // Length
// "localhost"
0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74,
// Extension
0x00, 0x0f, // Extension Type: Heart Beat
0x00, 0x01, // Length
0x01 // Mode: Peer allows to send requests
};
Should be modified into:
const unsigned char good_data_2_mangled[] = {
// TLS record
0x16, // Content Type: Handshake
0x03, 0x01, // Version: TLS 1.0
0x00, 0x36, // Length
// Handshake
0x01, // Handshake Type: Client Hello
0x00, 0x00, 0x30, // Length
0x03, 0x03, // Version: TLS 1.2
// Random
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, // Session ID Length
0x00, 0x04, // Cipher Suites Length
0x00, 0x01, // NULL-MD5
0x00, 0xff, // RENEGOTIATION INFO SCSV
0x01, // Compression Methods
0x00, // NULL
0x00, 0x05, // Extensions Length
// Extension
0x00, 0x0f, // Extension Type: Heart Beat
0x00, 0x01, // Length
0x01 // Mode: Peer allows to send requests
};
As for testing handshakes I would look at feeding your requests to OpenSSL s_server with the debug flag for initial testing.
I tried change the first byte of server name (example.com -> axample.com) and finally got a decrypt error from server. Is it possible to doing this? I guess the client and server would check their handshake packets after finished handshake.
The firewall will look for SNI field to block some websites, because SNI is plain texts in Client Hello, the server name can be detected easily, and the SSL connection would be blocked.
Need to specify a list of domains in config file, when the Client Hello message coming, look for SNI field, if SNI is bellowing one of the specified domains, drop the SNI e.g. hostname at the backend, the Client Hello message without SNI go through the firewall, finally SSL connection established.
However this trick only takes effect for some websites which supports non-SNI SSL, but I believe it is very useful to access a lot of websites behind an SNI sensitivity firewall.