Nmap Development mailing list archives

Re: NSE script: HTTP websocket discovery (was: NSE script: HTTP web service discovery)


From: Daniel Miller <bonsaiviking () gmail com>
Date: Thu, 5 Feb 2015 22:13:52 -0600

On Mon, Oct 6, 2014 at 6:15 AM, George Chatzisofroniou <sophron () latthi com>
wrote:

Hey Jacek,

On Sun, Oct 05, 2014 at 11:01:34PM +0200, Jacek Wielemborek wrote:
05.10.2014 21:57, Jacek Wielemborek:
Hello,

I just created a simple NSE script that detects HTTP Web Services.
Please find the first version attached and take a look at this URL for
any updates:

https://gist.github.com/d33tah/b902eb4e10c1e2b8e095

Why don't you let the user specify the directory to check for websockets by
providing an option that defaults to "/"?

I believe it makes more sense to make our http library support the opening
handshake for websockets and then leverage this feature from your script.
More
scripts may need to handle websockets in the future.


Jacek, George,

I looked into this a bit more today. I think this would be a great script
to add, with a couple enhancements. I also think there's room to expand it
quite a bit. Here are my notes:

1. cr0hn on Github already added some code to grab the Server header:
https://gist.github.com/cr0hn/76babebe40c199344220

2. He also expanded the "valid" condition to match the 101 Switching
Protocols response, which is a step in the right direction. RFC 6455 says
that the correct way to determine that the server really supports
websockets is to check the Sec-WebSocket-Accept header value, which is the
base64-encodedSHA-1 hash of the concatenation of the Sec-WebSocket-Key
request header with the string "258EAFA5-E914-47DA-95CA-C5AB0DC85B11". If
we use a static Key (as your script does currently) then we can
pre-calculate the Accept value, too. Otherwise we need to bring in base64
and openssl libs.

3. The RFC says that when a server receives an unsupported version in the
Sec-WebSocket-Version request header, it MUST respond with its supported
versions in one or more Sec-WebSocket-Version response headers. This means
we can enumerate supported versions by sending "Sec-WebSocket-Version: 100"
for example.

4. We should probably have a websocket.lua library, since there are a lot
of different applications of websockets. It would be nice to be able to
leverage http.lua, but its current design doesn't really lend itself to
this sort of use: each exported function creates and closes a socket, so we
can't just use it as a "handshake builder" without modification. I already
looked at one option which seems promising: use the options table to pass
in an already-connected socket to use instead of creating and closing one.
Then we could use http.generic_request to do the handshake, assuming we can
alter the current "treat all 1XX responses as 100 Continue" logic and let
it just stop after the 101 Switching Protocols response.

5. There are currently 2 extensions (RFC 6455 section 9) in draft (though
no official names registered with IANA): multiplexing and compression. We
could probably use extension negotiation to determine support for these,
too. The oreilly.com reference below lists another that may be supported in
the wild.

6. There are 22 registered subprotocols that could also be enumerated with
the Sec-WebSocket-Protocol header. Other scripts could then do further
probing, perhaps.

7. Maybe we could leverage the httpspider library to search a web site for
ws:// or wss:// urls in order to do better discovery. This should probably
not be the default, but should be turned on with a script-arg.

Have fun coding!
Dan

References:
* http://chimera.labs.oreilly.com/books/1230000000545/ch17.html
* https://www.iana.org/assignments/websocket/websocket.xhtml
* https://tools.ietf.org/html/rfc6455
_______________________________________________
Sent through the dev mailing list
https://nmap.org/mailman/listinfo/dev
Archived at http://seclists.org/nmap-dev/

Current thread: