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.
Installation
gem install ritm
Basic usage
- 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 inlocalhost:8080
- 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.