Websocket version 8 Sec-WebSocket-Accept mismatch - websocket

I wrote a websocket server in c++ that works fine with websocket protocol 00 (the one with key1, key2 in handshake header).
Now with the new update I am trying to do the same for the new way handshaking work. Here is my server response to the handshake request:
"HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: " + serverKey + "\r\n\r\n";
in which serverkey is computed correctly. As an example:
handshake request:
GET /test HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: 192.168.123.102:8585
Sec-WebSocket-Origin: http://192.168.123.5
Sec-WebSocket-Key: YB0mPvJ5t8ggCeGUWY39uQ==
Sec-WebSocket-Version: 8
handshake response header :
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: xt9iyCNryQTseELUkHPWjzxA2ts=
I also check my algo with the example here https://datatracker.ietf.org/doc/html/draft-ietf-hybi-thewebsocketprotocol-08 and it produced the exact same response.
However I still get the following error:
"Error during WebSocket handshake: Sec-WebSocket-Accept mismatch"
I am using chrome 15 as my browser.
Do you have any Idea what goes wrong?
(also in chrome inspector Network, it does not show the response which is the case when it does not accept the handshake (even with older versions))

I actually found out what was the primary problem.
the key that I used for base64 encoding was
YB0mPvJ5t8ggCeGUWY39uQ==
258EAFA5-E914-47DA-95CA-C5AB0DC85B11
instead of
YB0mPvJ5t8ggCeGUWY39uQ==258EAFA5-E914-47DA-95CA-C5AB0DC85B11
an extra \n was the whole problem.
HOWEVER, Now that I receive the Connected message (ws client is successfully connected to ws sever) I cannot send or receive anything. The problem is server side.
DO you know what are the server side changes since older websocket protocol? I only change my handshake respond and it doesnt seem enough.

There is a different framing protocol for when the client sends data. Previously it was quite simple. Now it is much more complicated. Please refer to the websockets rfc6455 spec.
https://www.rfc-editor.org/rfc/rfc6455#section-5.2

Related

I am using jmeter for socketcluster connection. Facing issues

By using websocket open connection sampler I am making socketcluster connection. I am getting response code as 101 and response message as switching protocols and response headers as:
Response headers:
Connection: Upgrade
Sec-WebSocket-Accept: 8i/hUMajQLY5hYfg0hq9z1U1HxI=
Sec-WebSocket-Version: 13
Upgrade: websocket
WebSocket-Server: uWebSockets
I am not able to find whether it is making connection in server. In server side I am not able to see active users. Throwing some error like below:
1524146177889 - Origin: Worker (PID 14262) [Warning]
SocketProtocolError: Socket hung up
at SCSocket._onSCClose (/home/centos/jioplay/node_modules/socketcluster/node_modules/socketcluster-server/scsocket.js:240:17)
at WebSocket.internalOnClose (/home/centos/jioplay/node_modules/socketcluster/node_modules/socketcluster-server/scsocket.js:75:10)
at process.nextTick (/home/centos/jioplay/node_modules/uws/uws.js:445:27)
at _combinedTickCallback (internal/process/next_tick.js:131:7)
at process._tickCallback (internal/process/next_tick.js:180:9
Please find attached files regarding script and results tree enter image description here.

Websockets with proxy

I'm unable to get my application utilizing web sockets to work.
I have a site www.example.com which uses an anti-DDoS service so it resolves to IP X.X.X.X. The real address of the server is Y.Y.Y.Y. The anti-DDoS service does not proxy web sockets traffic so I wanted to stream it directly to the real address (it's difficult to find it for attack in reality so this will work) so what I did is instead of pointing it to ws://www.example.com:100/, I pointed it to ws://Y.Y.Y.Y:100/.
Now if I access my application by the real IP (http://Y.Y.Y.Y), it connects to ws://Y.Y.Y.Y:100/ just fine but if I use http://www.example.com link (which resolves to X.X.X.X), ws://Y.Y.Y.Y:100/ won't connect saying "WebSocket connection to 'ws://Y.Y.Y.Y:100/' failed: Error in connection establishment: net::ERR_CONNECTION_REFUSED".
I guess this has something to do with security but I don't know what exactly. Please help.
Maybe the websocket server sees the domain in Origin HTTP header different than the domain in the Host HTTP header and it is refusing the connection because of that. The Origin header is usually used to figure out if the connection is coming from an allowed website, since websockets are not under the Same Origin Policy.
The request that works will look like this:
GET / HTTP/1.1
Host: YYYY
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Version: 13
Origin: http://YYYY
The request that is refused will look like this:
GET / HTTP/1.1
Host: YYYY
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Version: 13
Origin: http://www.example.com
It is hard to tell with this little information. Don't you get any error in the server logs?

Fiddler is not showing HTTPS traffic

I enabled "Decrypt HTTPS traffic" and "Ignore server certificate errors" in Fiddler but the traffic of one website is not being showed.
This is the error that Fiddler is returning:
[Fiddler] The connection to '...' failed. System.Security.SecurityException Failed to negotiate HTTPS
connection with server.fiddler.network.https> HTTPS handshake to
... failed. System.IO.IOException Received an unexpected EOF
or 0 bytes from the transport stream.
I remember that I could ignore this error in Fiddler script, but I really don't remember.
Does anyone know what's going on?
Thanks! =)
What is the site's URL?
It is probably caused by either of these two issues: http://blogs.msdn.com/b/ieinternals/archive/2009/12/08/aes-is-not-a-valid-cipher-for-sslv3.aspx or http://blogs.msdn.com/b/fiddler/archive/2012/03/29/https-request-hangs-.net-application-connection-on-tls-server-name-indicator-warning.aspx
The old workaround is to configure Fiddler to only use SSL3 when talking to the host in question. The newer workaround is to either use Fiddler4 with the latest .NET4.5.2 framework, or if you're using Fiddler 2.5.1, see the "SNI Hack" section of http://www.telerik.com/blogs/what-s-new-in-fiddler-4-5-1
In your OnBeforeRequest event handler, add the following code to fix the issue for certain sites:
if (oSession.HTTPMethodIs("CONNECT") && oSession.HostnameIs("BuggySite.com"))
{
oSession["https-DropSNIAlerts"] = "yup";
FiddlerApplication.Log.LogString("Legacy compat applied for request to BuggySite.com");
}
A bit late for the poster unfortunately but I just needed to add tls1.2:
Tools
Options
HTTPS
Protocols
Add tls1.2 to the end of the list and click ok
I was seeing the following exception:
System.Security.SecurityException Failed to negotiate HTTPS connection
with server.fiddler.network.https. HTTPS handshake to
api.etadirect.com (for #9) failed. System.IO.IOException Unable to
read data from the transport connection: An existing connection was
forcibly closed by the remote host. An existing connection was
forcibly closed by the remote host
I was able to fix it by enabling the TLS1.2 protocol which is not enabled by default for outgoing connections
Tools -> Options -> HTTPS -> click on protocols list

TLS handshake inside SSLv3 record layer

My Server is configured to accept both SSLv3 and TLS1.0 protocols. But a few clients are sending below handshake parameters and after the server hello, the client drops the connection and sends 'handshare failure(40) alert, not sure if it's the client fault or server.
Here's the initial client hello packet:
Secure Socket Layer
SSLv3 Record Layer: Client Hello
Content Type: Handshake (22)
Version: SSL 3.0 (0x0300) <-----------------
Length: 103
Handshake Protocol: Client Hello
Handshake Type: Client Hello (1)
Length: 78
Version: TLS 1.0 (0x0301) <-------------
Random
Session ID Length: 0
Cipher Suites Length: 18
Cipher Suites (9 suites)
The Record layer is SSL 3.0 but the inside handshake protocol is TLS 1.0. My question is, is this the right way of doing it i.e. using different versions for each layer? if it is what method is it? I can't find it anywhere, I looked through the RFC but can't find any reference. Also, how can I produce such requests?
EDIT: I'm not interested in troubleshooting and fixing the issue, I just want to know how can I send such packets? Any command? And what should I name this method?
i.e. I can use curl or openssl to either use ssl3 or tls1 but that would send same version in both record layer and handshake layer:
curl -v -ssl3 https://www.mywebserver.com
Above curl command would look on wireshark:
EDIT2: Is this even legal? I have been googling around and can't find any example. Is it violating any rfc standards?
Thanks
Yes, this is legal (at least it was clarified in recent TLS specifications).
You can look this up in rfc5246 (TLS 1.2) or in rfc6101 (SSL 3.0) or other rfc's concerning the SSL/TLS. The problem is with the initial version of the record protocol and with the handshake protocol:
rfc5246:
Earlier versions of the TLS specification were not fully clear on
what the record layer version number (TLSPlaintext.version) should
contain when sending ClientHello (i.e., before it is known which
version of the protocol will be employed). Thus, TLS servers
compliant with this specification MUST accept any value {03,XX} as
the record layer version number for ClientHello.
TLS clients that wish to negotiate with older servers MAY send any
value {03,XX} as the record layer version number. Typical values
would be {03,00}, the lowest version number supported by the client,
and the value of ClientHello.client_version.
Regarding the handshake protocol, the client will negotiate the highest version that it has implemented:
client_version: The version of the TLS protocol by which the client wishes to
communicate during this session. This SHOULD be the latest
(highest valued) version supported by the client
I just want to know how can I send such packets? Any command?
openssl s_client -connect www.myserver.com:443 -no_ssl2
should produce something similar to the trace you provided.

how to connect http server implemented by the c# socket class

I have finished http protocol via the socket class according to rfc2616 protocol, but how to connect https protocol and send data to server using the socket class?
When i connected https server https://www.example.com, I always get 404 error. The following is the socket command that to send to server https://www.example.com/
GET / HTTP/1.1 Host: www.example.com
the default always use http protocol
I found connected to https server need to use a connect command instead of the Get command and a client certificate. for example:
CONNECT login.example.com:443 HTTP/1.0
Major Version: 3
Minor Version: 1
......
I will try to use the connect command. Thanks for your replies.
==================================================
OK,i have solved my problem ,use the SLStream class.
NetworkStream networkStream=new NetWorkStream(socket)
var stream=New SslStream(networkStream)
.......
Now, will can read stream and write stream, until finished.

Resources