IO::Socket::SSL::Intercept -- SSL interception |
IO::Socket::SSL::Intercept -- SSL interception (man in the middle)
use IO::Socket::SSL::Intercept; # create interceptor with proxy certificates my $mitm = IO::Socket::SSL::Intercept->new( proxy_cert_file => 'proxy_cert.pem', proxy_key_file => 'proxy_key.pem', ... ); my $listen = IO::Socket::INET->new( LocalAddr => .., Listen => .. ); while (1) { # TCP accept new client my $client = $listen->accept or next; # SSL connect to server my $server = IO::Socket::SSL->new( PeerAddr => .., SSL_verify_mode => ..., ... ) or die "ssl connect failed: $!,$SSL_ERROR"; # clone server certificate my ($cert,$key) = $mitm->clone_cert( $server->peer_certificate ); # and upgrade client side to SSL with cloned certificate IO::Socket::SSL->start_SSL($client, SSL_server => 1, SSL_cert => $cert, SSL_key => $key ) or die "upgrade failed: $SSL_ERROR"; # now transfer data between $client and $server and analyze # the unencrypted data ... }
This module provides functionality to clone certificates and sign them with a proxy certificate, thus making it easy to intercept SSL connections (man in the middle). It also manages a cache of the generated certificates.
Intercepting SSL connections is useful for analyzing encrypted traffic for security reasons or for testing. It does not break the end-to-end security of SSL, e.g. a properly written client will notice the interception unless you explicitly configure the client to trust your interceptor. Intercepting SSL works the following way:
Using openssl such a proxy CA certificate and private key can be created with:
openssl genrsa -out proxy_key.pem 1024 openssl req -new -x509 -extensions v3_ca -key proxy_key.pem -out proxy_cert.pem # export as PKCS12 for import into browser openssl pkcs12 -export -in proxy_cert.pem -inkey proxy_key.pem -out proxy_cert.p12Configure client to connect to use intercepting proxy or somehow redirect connections from client to the proxy (e.g. packet filter redirects, ARP or DNS spoofing etc). Accept the TCP connection from the client, e.g. don't do any SSL handshakes with the client yet. Establish the SSL connection to the server and verify the servers certificate as usually. Then create a new certificate based on the original servers certificate, but signed by your proxy CA. This is the step where IO::Socket::SSL::Intercept helps. Upgrade the TCP connection to the client to SSL using the cloned certificate from the server. If the client trusts your proxy CA it will accept the upgrade to SSL. Transfer data between client and server. While the connections to client and server are both encrypted with SSL you will read/write the unencrypted data in your proxy application.
IO::Socket::SSL::Intercept helps creating the cloned certificate with the following methods:
new(%args)
>>%args
should be
new
.
If the argument is a hash it will store for each generated certificate a hash
reference with cert
and atime
in the hash, where atime
is the time of
last access (to expire unused entries) and cert
is the certificate. Please
note, that the certificate is in the Net::SSLeay manpages internal X509 format and can
thus not be simply dumped and restored.
The key for the hash is an ident
either given to clone_cert
or generated
from the original certificate.
If the argument is a subroutine it will be called as $cache->(ident)
to get an existing (cert,key) and with $cache->(ident,cert,key)
to cache
the newly created certificate.
host:port
), if not it
will be created from the properties of the original certificate.
It returns the cloned certificate and its key (which is the same for alle
created certificates).
STORABLE_freeze
function is defined to
call serialize
.
unserialize($string)
>>STORABLE_thaw
function is defined to
call unserialize
.
Steffen Ullrich
IO::Socket::SSL::Intercept -- SSL interception |