How Can I detect self signed certificate from charles, wireshark etc in golang - go

I am currently working on GO app and I wanted to know how can I detect someone using reverse proxy apps such as Charles, Wireshark and Fiddler.
I tried to read about SSL-Pinning but I couldn't find anything useful.

Charles and Fiddler are no reverse proxies but forward proxies. TLS interception in such proxies can be detected based on the certificate returned - it will not be the original server certificate but one created by the server. And certificate validation will fail unless the proxy is specifically trusted by importing the proxies CA certificate. SSL pinning helps too since it expects the server to use a specific certificate or a specific CA - which the SSL intercepting proxy cannot provide.
Wireshark is no kind of proxy but passive packet capturing, i.e. it makes no changes to the traffic. Because it is passive it cannot be detected from inside the client application and SSL pinning would not help either. Wireshark can not decrypt TLS traffic though by its own - it would need to have the connection specific secrets from either inside the client application or inside the server application.

Related

How can I make my Windows C++/OpenSSL application proxy-aware?

I'm working on a desktop C++ application which uses OpenSSL sockets (a raw TLS socket, not HTTPS) to communicate with our server.
One of our clients are required to route their traffic through a proxy. The client is using ZScaler in Tunnel with Local Proxy mode.
In theory, it's possible to reconfigure ZScaler to force our traffic through a proxy chosen by ZScaler. However, I want to investigate solutions where our application uses the Windows OS-level proxy settings rather than relying on ZScaler configuration.
I've read this post:
openssl s_client using a proxy
But I'm uncertain whether those answers apply to my situation, because that user didn't mention whether they're using Windows or Linux, and they appear to be talking about an HTTP/HTTPS proxy. Also, that question appears to be asking about the s_client function, rather than simply creating a TLS socket to my server through a "Tunnel with Local Proxy" on Windows.
So, my questions are:
Can OpenSSL be used to open an SSL socket to a server through Tunnel with Local Proxy?
Can we make an OS call to determine the IP/socket for the Tunnel with Local Proxy configuration?
If this is possible, then I have another question: suppose we have a single proxy at 10.100.10.0:5000.
If one user in our client's office opens a socket to our server via their proxy, will a 2nd user be unable to connect from their office because they're bottlenecked at single proxy socket?
Put another way: what is the standard way of implementing proxy-awareness for a Windows application using OpenSSL?
Note: This question was originally posted to Network Engineering stack exchange, but it was closed because it refers to an issue above OSI layer 4.
Note: I'm looking for a solution that does not require administrator permissions on the user PC. I would prefer for our application to discover and use OS-level proxy settings without making any administrative changes to the machine, i.e. by calling netsh.
Can OpenSSL be used to open an SSL socket to a server through Tunnel with Local Proxy?
OpenSSL doesn't do it for you but OpenSSL does not prevent it either. The tunnel has to be established before you do the TLS handshake to the endpoint. Depending on what kind of proxy this is you might need to use a HTTP CONNECT method for this or might need to use the SOCKS protocol or whatever your proxy requires. In case of ZScaler this is likely the HTTP CONNECT method but you need to make sure that the connection to the target IP and port is actually allowed by the security policy.
Once you've established the tunnel to the endpoint using the proxy you can just build the SSL socket on top of the TCP socket for the tunnel. Just do the usual SSL setup (i.e. SSL_new etc) and then associate the SSL object with the existing socket using SSL_set_fd. Then proceed as usual with the handshake, i.e. SSL_connect or similar.
Can we make an OS call to determine the IP/socket for the Tunnel with Local Proxy configuration?
I don't know but Winsock use system proxy settings might answer this part.
If one user in our client's office opens a socket to our server via their proxy, will a 2nd user be unable to connect from their office because they're bottlenecked at single proxy socket?
This should not be a problem. It is perfectly normal to have multiple connections through the proxy.

Does squidman proxy server support https?

I'm trying to set up a proxy server on my local mac.
http - seems to work.
But Safari is not connecting via https.
Did I miss something?
No it doesn't. You need to specify a separate https port and a ssl certificate, as documented in the squid config:
The socket address where Squid will listen for client requests made
over TLS or SSL connections. Commonly referred to as HTTPS.
This is most useful for situations where you are running squid in
accelerator mode and you want to do the TLS work at the accelerator
level.
You may specify multiple socket addresses on multiple lines, each
with their own certificate and/or options.
The tls-cert= option is mandatory on HTTPS ports.
See http_port for a list of modes and options.
http://www.squid-cache.org/Doc/config/https_port/
By design, it is quite hard to intercept https traffic:
When a browser creates a direct secure connection with an origin
server, there are no HTTP CONNECT requests. The first HTTP request
sent on such a connection is already encrypted. In most cases, Squid
is out of the loop: Squid knows nothing about that connection and
cannot block or proxy that traffic.
You also need to load the proxy settings for the browser as a PAC file, otherwise the browsers won't connect or throw a certificate warning:
Chrome The Chrome browser is able to connect to proxies over SSL
connections if configured to use one in a PAC file or command line
switch. GUI configuration appears not to be possible (yet).
More details at
http://dev.chromium.org/developers/design-documents/secure-web-proxy
Firefox The Firefox 33.0 browser is able to connect to proxies over
TLS connections if configured to use one in a PAC file. GUI
configuration appears not to be possible (yet), though there is a
config hack for embedding PAC logic.
There is still an important bug open:
Using a client certificate authentication to a proxy:
https://bugzilla.mozilla.org/show_bug.cgi?id=209312
https://wiki.squid-cache.org/Features/HTTPS

Is it possible for a server to see whether a HTTPS connection is monitored by Fiddler?

I'd like to know if it's possible for web services to detect HTTPS connections with "faked" root certificates created by Fiddler4 (Web debugging proxy) to prevent reverse engineering.
Is there any method to check whether the encryption is done with the original certificate or with one made by Fiddler?
A server has no way to know what certificate the client received unless the client sends the server that information.
From client JavaScript, you cannot detect such interception today; JavaScript does not expose the capabilities to introspect the certificate. It is possible to use Java or Flash inside a webpage to inspect the certificate received upon connecting to a server, but a sufficiently devious interceptor could just avoid MITM'ing the Java/Flash connection.
In contrast, a native code client application can detect what certificate was presented by the server and reject any certificate that doesn't match the expected certificate; this is called certificate pinning and it's a technique used by some applications. Note that this will block more than Fiddler; it'll also block connections through corporate inspection proxies (e.g. BlueCoat, ISA TMG, etc) and through some popular consumer antivirus programs' proxies (e.g. BitDefender). More importantly, users can circumvent your certificate pinning checks if they like; your code is running on their device, and they have the ability to modify your code in memory to strip out your certificate pinning checks. On some mobile devices, this code modification requires "jail-breaking" the device, but this isn't an insurmountable barrier.

How do I write a simple HTTPS proxy server in Ruby?

I've seen several examples of writing an HTTP proxy in Ruby, e.g. this gist by Torsten Becker, but how would I extend it to handle HTTPS, aka for a "man in the middle" SSL proxy?
I'm looking for a simple source code framework which I can extend for my own logging and testing needs.
update
I already use Charles, a nifty HTTPS proxy app similar to Fiddler and it is essentially what I want except that it's packaged up in an app. I want to write my own because I have specific needs for filtering and presentation.
update II
Having poked around, I understand the terminology a little better. I'm NOT after a full "Man in the Middle" SSL proxy. Instead, it will run locally on my machine and so I can honor whatever SSL cert it offers. However, I need to see the decrypted contents of packets of my requests and the decrypted contents of the responses.
Just for background information, a normal HTTP proxy handles HTTPS requests via the CONNECT method: it reads the host name and port, establishes a TCP connection to this target server on this port, returns 200 OK and then merely tunnels that TCP connection to the initial client (the fact that SSL/TLS is exchanged on top of that TCP connection is barely relevant).
This is what the do_CONNECT method if WEBrick::HTTPProxyServer.
If you want a MITM proxy, i.e. if you want to be able to look inside the SSL/TLS traffic, you can certainly use WEBrick::HTTPProxyServer, but you'll need to change do_CONNECT completely:
Firstly, your proxy server will need to embed a mini CA, capable of generating certificates on the fly (failing that, you might be able to use self-signed certificates, if you're willing to bypass warning messages in the browser). You would then import that CA certificate into the browser.
When you get the CONNECT request, you'll need to generate a certificate valid for that host name (preferable with a Suject Alt. Name for that host name, or in the Subject DN's Common Name), and upgrade the socket into an SSL/TLS server socket (using that certificate). If the browser accepts to trust that certificate, what you get from thereon on this SSL/TLS socket is the plain text traffic.
You would then have to handle the requests (get the request line, headers and entity) and take it to use it via a normal HTTPS client library. You might be able to send that traffic to a second instance of WEBrick::HTTPProxyServer, but it would have to be tweaked to make outgoing HTTPS requests instead of plain HTTP requests.
Webrick can proxy ssl:
require 'webrick'
require 'webrick/httpproxy'
WEBrick::HTTPProxyServer.new(:Port => 8080).start
from my experience HTTPS is nowhere near "simple". Do you need a proxy that would catch traffic from your own machine? There are several applications, like Fiddler. Or google for alternatives. Comes with everything you need to debug the web traffic.
That blog is no way to write a proxy. It's very easy: you just accept a connection, read one line which tells you what to connect to, attempt the upstream connection, if it fails send the appropriate response and close the socket, otherwise just start copying bytes in both directions, simultaneously, until EOS has occurred in both directions. The only difference HTTPS makes is that you have to speak SSL instead of plaintext.

XMPP Proxy TLS Encryption

I'm trying to develop a XMPP "Proxy" which will be in the middle of a standard Jabber communication.
The schema will be something like this:
Pidgin ---> Proxy <--- eJabberD
|
v
Console
The purpose of this proxy is to log all the stanzas which go over the wire. IMHO, this is very convenient when you're developing XMPP based solutions.
I'm doing this with EventMachine and Ruby, and the main problem is to know how to decypher the traffic after the TLS/SASL handshake.
Before the starttls, all works perfectly, the server and client can talk between them, but when the tls handshake begins, although it works, it is impossible to dump the clear content as all of the traffic is encrypted.
I'm not an expert in TLS/SASL thing, so I don't know which is the best approach to do this. I think one way to achieve this, should be to grab the certificate in the handshake and use it to decypher the content as it goes throught the proxy.
Thanks!
If you could do what you say (grab the certificate on the wire and use it to decrypt), then TLS would be pretty worthless. This is one of the primary attacks TLS exists to prevent.
If the server will allow it, just don't send starttls. This is not required by spec. If starttls is required by your server, then you can configure it to use a null cipher, which will leave the traffic unencrypted. Not all servers will support that of course.
You can man-in-the-middle the starttls. Respond with your own tunnel to the client, and send a separate starttls negotiation to the server. This should generate certificate warnings on the client, but since you control the client you can tell it to accept the certificate anyway.
If you control the server, you can use the private key from it to decrypt the traffic. I'm not aware with any off-the-shelf code to do that easily, but it's writable.

Resources