Securing -server and -remote remote debugging sessions

Previously, I’ve discussed the basics of -server and -remote, and how to do reverse debugging connections.  This covers most of the interesting functionality for this remote debugging mechanism, with one big exception: securing your remote debugger connection when you are operating over an untrusted network (such as the Internet).

Used as-is, none of the remote debugging techniques I have discussed so far provide any real security, other than the inherent difficulty of hijacking a TCP connection.  Data is sent in plaintext and there is no authentication of potentially sensitive commands that could direct a debugger to do dangerous operations and even potentially take control of the target’s computer if a privileged process is being remotely debugged.

If you are using the NTSD over KD remoting technique, this is usually less of a concern, since you are usually operating over a serial or 1394 cable physically connecting the two computers.  For plain -server and -remote debugging, or remote.exe debugging, however, this problem is more serious as these methods are typically used over networks.

For remote.exe, there is not all that much that you can do to secure connections.  The -server and -remote mechanism has a happier tale to tell, however.  This remoting mechanism does in fact have built-in support for secure connections using both SSL over the TCP transport or SSL over the named pipe transport.  I’ll primarily cover SSL over TCP, but the general concepts apply to the SSL over named pipe (“SPIPE”) transport as well.  There is additional support for simple password authentication, for all transports, which I’ll discuss as well.  However, this only adds a very basic form of protection and usually buys you only minimally more security than an unpassworded connection.

To use password authenticated connections, simply append the “password=password” parameter to the connection string for both the client and the server.  For instance, “tcp:port=1234,server=127.0.0.1” becomes “tcp:port=1234,server=127.0.0.1,password=secret”.  That’s all there is to this mechanism; after using it, both ends must specify the same password or the connection will fail.  I should emphasize that this again does not really provide strong protection, and the SSL alternatives should usually be used instead.

The SSL options are slightly more complicated.  These require a certificate that supports server authentication and is known to both ends of the remote connection.  The certificate that you use needs to have the “server authentication” role enabled for it.  Additionally, note that the same certificate is needed by both parties; that is, both parties must have the private key for the certificate.  This makes using the SSL option unfortunately more cumbersome than it could be.  To get this to work, you will typicallly have to request a server authentication certificate from your domain CA, and then install it (with the private key) on both computers.  Then, you can use it with SSL or SPIPE remote debugging.

The general format of an SSL transport connection string is very similar to the TCP transport, with some additional options added.  For the client, it is in the format of “ssl:port=port,proto=ssl-protocol,server=server-ip,[certuser|machuser]=cert-name-or-thumbprint“.  For a server, use “ssl:port=port,proto=ssl-protocol,[certuser|machuser]=cert-name-or-thumbprint“.  Remember that the certificate must match for both parties.

The “proto” parameter specifies which dialect of SSL to use, and can be one of tls1, pct1, ssl2, or ssl3.  The protocol must be the same for both the client and the server.

The “certuser” parameter specifies either the name (e.g. “Subjectname”) or thumbprint (e.g. “12345689abcdef…”) of a certifcate in the user certificate store.  Alternative, you can use “machuser” instead of “certuser” to specify that the certificate is contained within the machine store (using “machuser” typically requires that the debugger be run with administrator or localsystem privileges).  To determine the subject name or thumbprint of a certificate, run mmc.exe, add the “Certificates” snapin for either your user or the computer user (if you are an administrator and want to use “machuser”), locate the certificate you want to use (typically under “Personal\Certificates”), open the certificate property sheet, and view the “Details” tab.  The common name (“CN = “) under “Subject” is the subject name you will use, and the hex string under “Thumbprint” is the thumbprint you will use (you only need one).  If you are using the thumbprint, then remove all spaces between the hex digits when providing the parameter to “certuser” or “machuser”.

Putting all of these together, once you get the certificate in place on both computers, activating an SSL remote debugging session is basically the same as with a TCP remote debugging session.  To start an SSL debugging server, you might do this:

debugger -server ssl:port=1234,proto=tls1,
machcert=1111111111111111111111111111111111111111

Likewise, to start the client, you would use something like this:

debugger -remote ssl:port=1234,server=127.0.0.1,proto=tls1,
machcert=1111111111111111111111111111111111111111

Afterwards, the debugging connection should operate as any other -server/-remote session would.  All of the usual other considerations for -server/-remote apply to SSL as well; for instance, you can use reverse debugging and you can use “.server” instead of “-server”.

Because of the difficulty in setting up the certificate for SSL debugging, I usually recommend using something else to secure the remote debugging session other than the built-in SSL support, such as a VPN.

Next time: Debugger process servers and smart clients.

2 Responses to “Securing -server and -remote remote debugging sessions”

  1. Any reason this wouldn’t work with ssh tunneling? You can get just as much security for much less complexity if you know how to operate ssh.

    Also, I think it’s an understatement to call password security “minimally more secure” than no security at all. Having a good password to an otherwise plaintext connection means that the attacker has to be a man in the middle. Bad passwords are always bad security, but a good password can be an effective way to decrease the attack surface substantially – the attacker now has to be in a position to intercept packets or perform another MITM-style attack.

    It’s definitely a lot better than nothing.

  2. […] Like -server and -remote, process server / smart client debugging uses connection strings for both the client and the server. The syntax for client and server connection strings are for the most part compatible, so you should look back on my existing posts about basic remote connectivity, reverse connections, and securing debugger connections. For the most part, things work exactly the same as -server and -remote; all of the connectivity options supported by -server and -remote work for process servers and smart clients, and all of the features (such as reverse connections and secured connections) are available using the same mechanisms as well. […]