Apr 24, 2013

SSL over IO Usage for Converting HTTPS Connect Requests on MITM Analysis

Mobile applications use SSL Connect requests to connect remote server for HTTPS Communications. Mobile Applications should be analyzed dynamically during Penetration Tests and MITM attacks are very useful in this stage. HTTPS communications should be converted via MITM Proxies such as Burp Proxy and Fiddler2. These tools useful to convert HTTPS Connect requests and intercept them. Manual request mangling and fuzzing depend on this HTTPS Connect conversion. These tools are closed source and they don't explain this feature.   

MBFuzzer is a subproject of Yakindan Egitim, I'm mentor of this MBFuzzer and Mehmet Kilic is the developer of it. MBFuzzer is an MITM Mobile Application Fuzzing tool, HTTPS Connect conversion is one of the main requirements. We presented a way to convert HTTPS Connect requests via IO (Input/Output).  It has a little CA Error bug but it works for conversion, it will be fixed later.

When MBFuzzer Proxy detects a HTTPS Connect Request (CONNECT domain:port HTTP/1.1), it connects target (domain:port) and send "HTTP/1.1 200 Connection Established" message to client socket. After this message, Client tries to initiate a HTTPS session and MBFuzzer accepts this connection as a server via sending connection to ssl_io function (ssl_connection=ssl_io(connection)).

This Code is Responsible to Convert HTTPS Requests

#creating ssl io object
def ssl_io(io)
   sslContext = OpenSSL::SSL::SSLContext.new
   sslContext.cert = OpenSSL::X509::Certificate.new(File.open('./certs/server.crt'))
   sslContext.key = OpenSSL::PKey::RSA.new(File.open('./certs/server.key'))
   sslContext.ca_file = './certs/cacert.pem'
   sslContext.verify_mode = OpenSSL::SSL::VERIFY_NONE
sslio = OpenSSL::SSL::SSLSocket.new(io, sslContext)
sslio.sync_close = true
rescue Exception => sslException
puts "SSL Exception : #{sslException}"
return sslio

Standard implementations of ruby SSL servers use OpenSSL::SSL::SSLServer class, unfortunately this class is not useful in this situation. It's designed to serve SSL via TCP Socket and it doesn't work without it. We used OpenSSL::SSL::SSLSocket class that designed to initiate SSL client requests. We disabled "sync" that try to make an SSL handshake and started to accept this IO as an SSL socket. After this modifications; MBFuzzer accepts HTTPS Connect requests, handles SSL IO as a server, manipulate content, sends it to remote server and redirect response to client via SSL session.

We have a few bugs of course, a tls error caused by CA issues and IO.sysread problems. You can inspect our project, use this HTTPS Proxy Library in your project or send us fixes. It's license is GPL, you can use or contribute it. We are working on bugs, on-the-fly certification generation and request mangling features. I'll keep this blog updated about MBFuzzer and Yakindan Egitim projects.