Disable HTTPS in the Go code and other questions

Hello…

QUESTION 1

Are any of the main authors aware of a way to disable HTTPS in the Golang code for development?

I want to use wireshark to sniff the local packets so I can look more closely at the BEP and uPnP packets and protocol. I turned on the various debugging features, but they don’t offer the ability to save packets in libpcap format – they just print out to stdout or stderr or whatever.

I’m fine modifying the code, but it’s a bit of a slog since this is my first delve into a Go project.

Ideally, I’d want to be able to just disable HTTPs so I can load up a couple of instances of the Go code in VMware w/ internal networks, so I can look more closely at the packets.

Unfortunately since everything is HTTPS with DH key exchange, even if I use the X509 certs, I can’t easily decrypt the packets . . . Even with a custom mitm proxy, it’s a pain in the neck. I could spit out the session key but this would take forever to get working properly.

The point is to look more closely at both the UDP and TCP packets, data structures, and so forth without any TLS encapsulation. I’d love to just have a ‘plaintext’ pcap dump of all the network traffic to examine more closely.

Any ideas on an easy way to accomplish this?

QUESTION 2

Is there any formal documentation and /or definitions on how to ‘talk’ to a local Syncthing instance, like for purposes of writing a new client GUI? I notice there is a pretty impressive GTK client, but I’d like to know if there was some documentation (besides the BEPv1 document) that the GTK client author referred to in order to execute commands on the server.

Similar issue here in terms of ‘reverse engineering’ the correct protocol for ‘talking’ with the server. Much easier to do if you can see what’s going out and coming back over the wire. I suppose the debug mode is okay, but I’d like something a bit more powerful… Or even better, documentation and/or examples on which commands and packet structures do what, the order of operations, and so forth.

QUESTION 3

Did my post on $10 million NSA and RSA collaboration to put backdoors into crypto go to the great hard drive in the sky-- or does my internet just suck? I think it’s pretty relevant.

I can understand the implications may be controversial. But it was a mainline / vanilla Reuters story, and (regrettably) it’s not like the facts themselves are in dispute.

Given that the transport security of this software (Syncthing) is based upon the assumption that TLS is secure, and the fact that TLS is based upon (in large part) ‘de facto’ NIST standards – in particular, the RSA-based primitives, AES and it’s modes, and certain ECs over finite fields etc…

My question is why would a post (from Reuters nonetheless) about collaboration between the NSA and RSA to insert backdoors into crypto not be important , at least as something to consider in terms of design and architecture ?

I’d think this would be especially pertinent to which TLS modes and ciphers Syncthing should support – and which TLS modes could be considered ‘deprecated’ by Syncthing – and perhaps either rejected or a warning issued to the user?

Another key point here in the same line of thinking is whether TLS modes w/ PFS utilizing RSA should be preferred over ECs w/ PFS , or vice versa , especially in light of the original revelations of hidden connections between RSA and NSA.

The former algorithm – RSA – is only as secure as the premise that the factoring of large composite integers is a suitably difficult / intractable problem. However, there exists no mathematical proof that there is no ‘shortcut’.

In other words, there is no way to prove that to break RSA you must brute-force with Number Field Sieve.

No polynomial-time method for factoring large integers on a classical computer has yet been found, but it has not been proven that none exists.

Meaning that there is no proof that RSA is ‘as hard’ as factoring the modulus. This is even if we disregard quantum attacks as improbable / impossible.

Granted: there are mathematical relationships between breaking RSA and breaking ECs. Recent papers suggest that if you can ‘break’ one you can ‘break’ the other. So that much I can understand.

But what we DO know about EC is that their security is based on the premise of solving a discrete logarithm over a finite field (arguably preferable to factorization), ECs are utilized in the NSA Suite B standards (used for protecting Secret / Top Secret data), and ECs are more efficient to calculate.

Additionally, if we are to consider utilization of independent (non-NIST) ECs like curve25519 with TLS, we begin to have some degree of confidence that the we are not working with a deliberately or inadvertently weakened system.

There are still issues – both schemes (RSA and ECs) are vulnerable to quantum attacks with Shor’s algorithm, although ECs can be made resistant to such attacks with Supersingular Isogeny DHE… Such technology does not (to my knowledge) exist for RSA.

To avoid quantum computing concerns, an elliptic curve based alternative to Elliptic Curve Diffie Hellman which is not susceptible to Shor’s attack is the Supersingular Isogeny Diffie–Hellman Key Exchange of De Feo, Jao and Plut. They use elliptic curve isogenies to create a drop in replacement for the quantum attackable Diffie–Hellman and Elliptic curve Diffie–Hellman key exchanges. This key exchange utilizes the same elliptic curve computational primitives of existing elliptic curve cryptography and requires computational and transmission overhead similar to many currently used public key systems.[36]

In any case, I think it’s probably a wise idea for any security software using TLS to have a debate on crypto design decisions in light of the RSA revelations. Every year seems to bring another serious SSL/TLS attack, whether heartbleed, lucky13, various padding oracles, BEAST, MitM attacks, MAC authentication/encryption misordering, and other incredibly massive ‘fails’ … Certainly we should discuss such issues, or at least be aware of the pitfalls …

Particularly important I think is the question of whether to enforce particular modes in TLS (modes which ensure perfect forward secrecy), and whether to prefer RSA over EC (or vice versa)…

This is especially important since a healthy plurality of all browsers do not support TLS modes with PFS… Most browsers do not support TLS 1.1 / TLS 1.2 , and are (somewhat astonishingly) using vulnerable RC4 implementations for which attacks are not merely academic – they are are a reality and routinely occur in the wild.

Heck , 80% of the top 150,000 web sites using SSL/TLS are still vulnerable to BEAST!

Survey of the SSL Implementation of the Most Popular Web Sites https://www.trustworthyinternet.org/ssl-pulse/

A significant number of internet browsers / server sites are essentially about as secure as a WEP-based access point, and can be broken within a few hours, due to statistical biases in the first 8k of the RC4 keystream.

Not to mention the fact that we can always attack the CA system – if a single root CA is malicious or compromised, it’s trivial to decrypt pretty much all RSA-based internet traffic, no matter what symmetric algo it’s using for transport secuirty.

Fortunately, the CA attack does not apply to Syncthing due to the wise design decision to ‘opt-out’ of the CA system altogether – in favor of a web-of-trust / shared-secret security model. But some of these other problems may apply, particularly with older OSs and browsers.

Avoiding RSA may be far preferable in light of the media revelations that RSA and the NSA deliberately weakened NIST standards with regards to CSPRNGs – whether this occurred with the knowledge and consent or RSA is a bit of a moot point.

Another angle to consider (which favors enforcement of RSA-based modes) is that ECs are more vulnerable to bad CSPRNGs since ECs are more ‘entropy hungry’ – in the case of poor entropy sources (ie. older versions of Windows), then RSA is perhaps the stronger candidate.

My hope was to encourage some thinking about (A) avoiding side channel attacks in general, and (B) whether it makes sense to force certain SSL/TLS modes as ‘obsolete’ and/or others are ‘preferred’.

QUESTION 4

During development of the original reference client, how did you guys handle debugging across the wire? Do you first get it working with HTTP, then enable TLS? Or was there another tactic that was used to ensure that a client and server were having an appropriate exchange of messages, populating local vars with the correct data, ensuring there were no mix-ups between big-endian / little-endian (host vs network byte order) and so on?

The best way I can think of is to have two virtual machines on the same subnet, with HTTPs disabled, and sniff the traffic while setting breakpoints in the respective IDEs on both sides of the session.

Is there a better way, or is this how you guys developed this originally?

QUESTION 5

What IDE are you guys using for Go? And on what OS? Is LiteIDE on Debian a suitable environment?

2 Likes

Somewhat tricky. There’s a lot of code wired to expect *tls.Conn as the underlying connection, with the expectation of being able to look at the certificate to find the device ID etc. Most of the relevant code is in https://github.com/syncthing/syncthing/blob/master/cmd/syncthing/connections.go though, you could probably chop it down to not talk TLS and just simulate hardcoded device IDs or whatever.

I think an easier and more fruitful approach to inspecting and debugging stuff on the wire is to wire up a TLS-to-TLS proxy, with correct certificates and that can output the cleartext to wherever you want. Configure your syncthing instances to talk to the proxy and expect it’s device ID instead of what is really on the other side. Such a proxy is probably less than 40 lines of Go or thereabout, if there isn’t already something suitable that does the same.

There’s also STTRACE=protocol syncthing which dumps most or all of the protocol talk in cleartext (hex+ascii) to stdout.

(That’s just plain TLS btw, not HTTPS.)

Yep!

It’s long, and hypothetical. :slight_smile: We have the luxury/limitation of depending on the Go TLS implementation. This has advantages and disadvantages. A disadvantage is that some cool stuff like the latest curves and ciphers are not implemented yet. An advantage is that we carry all the code with us in the binary. It doesn’t matter the least what version of OpenSSL you have or what browser you run. (At least for the sync connection. For the GUI, your browser is of course involved.)

Our cipher suite selection etc is here: https://github.com/syncthing/syncthing/blob/master/cmd/syncthing/main.go#L464

Suggestions for concrete improvements are always welcome.

Two syncthing instances talking to each other, tests, and trace printouts in strategic places (i.e. the STTRACE=protocol stuff etc).

1 Like

I use LiteIDE for my stuff.

Sublime Text 3 (in eternal beta, just like Syncthing…) + gosublime, Mac OS X, probably.

Okay, yeah I got that working, the STRACE thing, I thought it was decent , but it’s hard to say since I’m unfamiliar with Go… I wanted a way to look at the network logs from a ‘session’ level, coordinating network packets to activity and commands by the user.

This is more difficult since I don’t know Go, I can’t really tell what is running when, where and when there are threads (is this project multithreaded, hah), and whether we are operating procedurely / event driven, whether the traffic is processed blocking / non-blocking etc.

Realistically I’ll probably need to do some Go tutorials because the language is a bit alien… Go is not like comparing C++ to Java, where if you know one you know the other. . .

I suppose I can wrap the STRACE output to pcap or something. I just want to write something so I can look at the ‘big picture’ of what happening on the wire. I’m a bit of a protocol nut, so I like seeing packets to understand what’s actually going on.

As a side note, I’m always surprised to see the plethora of chatty traffic that comes out of my machine and is dumped onto the network interface, whether broadcast or otherwise. One of the reasons I ditched Ubuntu with Unity for Debian was every time I searched for a file locally, Ubuntu send out a call to a server with my search term. It also kept updating some geo location thing as well.

I think an easier and more fruitful approach to inspecting and debugging stuff on the wire is to wire up a TLS-to-TLS proxy, with correct certificates and that can output the cleartext to wherever you want. Configure your syncthing instances to talk to the proxy and expect it’s device ID instead of what is really on the other side. Such a proxy is probably less than 40 lines of Go or thereabout, if there isn’t already something suitable that does the same.

That’s a great idea. I tried something similar by adding the X509 certs to Wireshark, but that didn’t work at all. Apparently, any sort of DH is not supported.

I like the TLS-to-TLS idea. Very clever. There are proxies that do this for HTTPS, though I agree it’s probably way easier to write it yourself in Go, in particular if there is spoofing of device IDs involved, since that’s a bit of a customization.

Most of the OTS solutions out there (TLS mitm proxies, mainly intended for debugging / sniffing local TLS sessions)… These solutions are invariably geared towards HTTP web traffic, or TLS IMAP traffic etc, but not towards custom protocols. I’ve used them for logging HTTPS session for web scraping, but never for a custom TLS protocol.

Let me think about this TLS-to-TLS thing a bit , and I’ll get back to you once I understand the principle. Gotta whiteboard this out, heh.

Two syncthing instances talking to each other, tests, and trace printouts in strategic places (i.e. the STTRACE=protocol stuff etc).

Okay, that makes sense. That’s kind of the route I was going down, so I’ll just keep going til I hit something, break something, or get it working.

I use LiteIDE for my stuff.

Okay, cool. That’s what I installed. The main issue is that I’ve never used Go. I’ve done **** near everything else (Python, Java, C++, C, Processing/Wiring, C#, Perl, etc) but never used Go.

The last big project I wrote was embedded code for an Arduino-based micro-drone flight controller in C, so this is much higher level.

What language did you guys come from prior to Go? Is there some tutorial you did that accelerated the learning curve ? Probably my strongest language at the moment is Python followed by Java.

Sublime Text 3 (in eternal beta, just like Syncthing…) + gosublime, Mac OS X, probably.

Okay , cool . Yeah I use Sublime Text for Java and Python on Windows for small to moderate sized projects. I definitely like the plugins and themes for Sublime Text, it’s easy on the eyes.

The other main IDE’s I’ve used lately are Pycharm for Python and IntelliJ for Java, especially if I have to do any debugging. Also used Eclipse , but that’s a bit heavy for my tastes.

Okay, thanks! I think I’ll probably do a Go tutorial in LiteIDE for Python or Java developers, then either write that TLS-TLS proxy, or alternately, write some module or filter to output all the raw packet data in pcap format. At the very least, maybe add a logging function to write the data to a file so I can post-process it.

As you, roughly. The tour is a decent intro, if somewhat tedious sometimes (I don’t have the temperament for it I guess), the docs and standard library are surprisingly readable (click a method in the stdlib docs to go directly to the implementation).

There is/was a Go plugin for Pycharm, but I wasn’t impressed. Pycharm is nice otherwise.

About the on wire stuff, note that all packets are in XDR format and their structures are documented in the code as well as the spec. Where they differ, the code is correct. :wink: That code is autogenerated by the xdr package (the genxdr command is unfortunately one of the uglier hacks I’m guilty of… :()

I actually generated C code from them. Though the order of definition is incorrect, no forward declares are possible AFAIK, and a few extra semicolons here and there.

Oh! Pull request on genxdr? :slight_smile:

Are any of the main authors aware of a way to disable HTTPS in the Golang code for development?

Why not point wireshark at the private key?

This sounds really nifty! I can do a capture with

tcpdump -n -s0 -i lo0 -w foo.pcap port 22001

(Assuming something that talks on localhost port 22001, which the test suite does)

and then inspect it with (after some Googling)

tshark -V -r foo.pcap -d tcp.port==22001,ssl -o ssl.keys_list:127.0.0.1,22001,whatever,/Users/jb/src/github.com/syncthing/syncthing/test/h1/key.pem

Unfortunately that didn’t work; it doesn’t get decrypted. Enabling some debug options yield

ssl_decrypt_pre_master_secret session uses DH (17) key exchange, which is impossible to decrypt

which is neat and proves things are working. Basically, since we are using cipher suites with forward secrecy, having the private key doesn’t help in decrypting the session after the fact. Cool, huh?

To get this to work, I tried to hobble syncthing with oldcrap crypto instead;

--- a/cmd/syncthing/main.go
+++ b/cmd/syncthing/main.go
@@ -470,12 +470,7 @@ func syncthingMain() {
                InsecureSkipVerify:     true,
                MinVersion:             tls.VersionTLS12,
                CipherSuites: []uint16{
-                       tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
-                       tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
-                       tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
-                       tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
-                       tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
-                       tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+                       tls.TLS_RSA_WITH_RC4_128_SHA,
                },
        }

Unfortunately wireshark still doesn’t get it;

ssl_decrypt_pre_master_secret wrong pre_master_secret length (326, expected 48)
ssl_generate_pre_master_secret: can't decrypt pre master secret

I don’t know what the problem is here. Bug in wireshark? :confused:

1 Like

Hm. Do the moduli match? Does changing the CipherSuite need a key regen? Is the SSL library wireshark uses dodgy?

@calmh it works for me (with your diff). Tested capture on Linux talking to a Mac.

Edit: maybe syncthing could support session key logging as a debug option, like Firefox does.

Yeah that’s what I discovered. The only way to attack it is via the TLS-to-TLS proxy as suggested, or other MitM style attacks. Those are the easy ways without too much code changes.

I tried wireshark and tcpdump - - you cant crack DH without some inside info. It’s possible if you spit out internal cipher states.

Better to go for the path of least resistance.

@Jakob

Wow neat idea there in commenting out the details. I actually think that TLS_RSA_WITH_RC4_128_SHA does not use DH at all.

It uses " RSA for secure key exchange, RC4 for bulk data encryption and SHA1 as a hash." … I don’t really know why Wireshark doesn’t work with that, but I’m gonna try it !! Haha

When the cipher suite is TLS_RSA_WITH_RC4_128_SHA, the PRF is seeded with the pre-master secret, client random and server random data to generate a master secret. This master secret is then seeded to the PRF, again together with the random data, to create keying material. In this case, the keying material is for the RC4 stream cipher and HMAC-SHA1.

With the cipher suite TLS_RSA_WITH_RC4_128_SHA, the handshake is authenticated because the pre master secret is encrypted with the public key in the server ceritificate, making sure only the holder of the private key can decrypt it. From the client side, this is some proof the server is valid.

http://blog.bjrn.se/2012/07/fun-with-tls-handshake.html

AND

https://ask.wireshark.org/questions/22813/not-able-to-decrypt-ssl-data-with-private-keys

Looks like it probably works in tshark if not wireshark…

Nice find!

Okay, got it. I was able to decrypt the traffic in Wireshark are forcing the cipher to non-DH as recommendedby Jakob.

Made the same commit as he did – plus I set up two Syncthing instances on Ubuntu 12.04 LTS in VMware 11 workstation , with both instances using the same shared NAT virtual device called vmnet1 or whatever. They would sync files etc but encrypted so I couldn’t see BEP bytes. Now I can, heh.

I just had wireshark listen on vmnet1 in promic mode. Prior to sniffing, I put the private keys for each of the two peers (located in ~/.config/syncthing/key.pem) . I followed the procedure linked below, and said the protocol was some nonsense (SPDY) running on port 22000.

Wireshark was able then to decrypt the packets, although it thinks they are SPDY packets. Probably net step is to see if I can write a quick module to classify and highlight the decrypted packets.

2 Likes