Ruby in the middle (RITM) is an HTTP/HTTPS interception proxy with on-the-fly certificate generation and signing, which leaves the user with the full power of the Ruby language to intercept and even modify requests and responses as she pleases.
gem install ritm
- Write your interception handlers
require 'ritm' # A single answer for all your google searches Ritm.on_request do |req| if req.request_uri.host.start_with? 'www.google.' new_query_string = req.request_uri.query.gsub(/(?<=^q=|&q=)(((?!&|$).)*)(?=&|$)/, 'RubyInTheMiddle') req.request_uri.query = new_query_string end end my_picture = File.read('i_am_famous.jpg') # Replaces every picture on the web with my pretty face Ritm.on_response do |_req, res| if res.header['content-type'] && res.header['content-type'].start_with?('image/') res.header['content-type'] = 'image/jpeg' res.body = my_picture end end
- Start the proxy server
proxy = Ritm::Proxy::Launcher.new proxy.start puts 'Hit enter to finish' gets proxy.shutdown
- Configure your browser
Or whatever HTTP client you want to intercept traffic from, to connect to the proxy in
- Browse the web!
For the examples above, search anything in google and also visit your favorite newspaper website.
Trusting self-signed certificates generated by RITM
With the previous example your client might have encountered issues when trying to access HTTPS resources. In some cases you can add an exception to your browser (or instruct your http client not to verify certificates) but in some other cases you won't be able to add exceptions. The reason for this is that in order to decrypt and to be able to modify SSL traffic, RITM will have to be the one doing the SSL negotiatiation with the client (using its own set of certificates) and then it will establish a separate SSL session towards the server. I.e.:
Client <--- SSL session ---> RITM <--- SSL session ---> Server
For every different server's hostname your client tries to communicate with, RITM will generate a certificate on the fly and sign it with a pre-configured Certificate Authority (CA). So, in order to be able to establish a secure connection you will need to configure your client (e.g. browser) to trust RITM's CA.
For security reasons, every time you start RITM's proxy with the default settings it will generate a new internal Certificate Authority. To use your own CA instead (so it can be loaded and trusted by your browser) perform the following steps:
- Generate a Certificate Authority PEM and Private Key files
You can use OpenSSL or RITM to generate these two files. With OpenSSL:
Or with RITM:
openssl req -new -nodes -x509 -days 365 -extensions v3_ca -keyout insecure_ca.key -out insecure_ca.crt
require 'ritm/certs/ca' ca = Ritm::CA.create common_name: 'InsecureCA' File.write('insecure_ca.crt', ca.pem) File.write('insecure_ca.key', ca.private_key.to_s)
- Repeat step 2 from the previous example, this time indicating what CA should be used to sign certificates
proxy = Ritm::Proxy::Launcher.new(ca_crt_path: 'path/to/insecure_ca.crt', ca_key_path: 'path/to/insecure_ca.key') proxy.start puts 'Hit enter to finish' gets proxy.shutdown
- Trust the CA certificate into your browser or client
I'll leave it to you to figure out how this is done in your browser or client.
- Surf the web!
- When you are done Remove the CA from your trusted authorities!
Or take really good care of the CA private key since anyone in possession of that key will be capable of decrypting all your traffic! Also notice that when using the proxy every server will be automatically trusted even if the end server certificate is not valid.