254 lines
9.2 KiB
HTML
254 lines
9.2 KiB
HTML
|
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
<HTML><HEAD><TITLE>Man page of IO::Socket::SSL::Intercept</TITLE>
|
|
</HEAD><BODY>
|
|
<H1>IO::Socket::SSL::Intercept</H1>
|
|
Section: User Contributed Perl Documentation (3pm)<BR>Updated: 2020-02-14<BR><A HREF="#index">Index</A>
|
|
<A HREF="/cgi-bin/man/man2html">Return to Main Contents</A><HR>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<A NAME="lbAB"> </A>
|
|
<H2>NAME</H2>
|
|
|
|
IO::Socket::SSL::Intercept -- SSL interception (man in the middle)
|
|
<A NAME="lbAC"> </A>
|
|
<H2>SYNOPSIS</H2>
|
|
|
|
|
|
|
|
|
|
|
|
<PRE>
|
|
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
|
|
...
|
|
}
|
|
|
|
</PRE>
|
|
|
|
|
|
<A NAME="lbAD"> </A>
|
|
<H2>DESCRIPTION</H2>
|
|
|
|
|
|
|
|
This module provides functionality to clone certificates and sign them with a
|
|
proxy certificate, thus making it easy to intercept <FONT SIZE="-1">SSL</FONT> connections (man in the
|
|
middle). It also manages a cache of the generated certificates.
|
|
<A NAME="lbAE"> </A>
|
|
<H2>How Intercepting SSL Works</H2>
|
|
|
|
|
|
|
|
Intercepting <FONT SIZE="-1">SSL</FONT> connections is useful for analyzing encrypted traffic for
|
|
security reasons or for testing. It does not break the end-to-end security of
|
|
<FONT SIZE="-1">SSL,</FONT> e.g. a properly written client will notice the interception unless you
|
|
explicitly configure the client to trust your interceptor.
|
|
Intercepting <FONT SIZE="-1">SSL</FONT> works the following way:
|
|
<DL COMPACT>
|
|
<DT id="1">•<DD>
|
|
Create a new <FONT SIZE="-1">CA</FONT> certificate, which will be used to sign the cloned certificates.
|
|
This proxy <FONT SIZE="-1">CA</FONT> certificate should be trusted by the client, or (a properly
|
|
written client) will throw error messages or deny the connections because it
|
|
detected a man in the middle attack.
|
|
Due to the way the interception works there no support for client side
|
|
certificates is possible.
|
|
|
|
|
|
<P>
|
|
|
|
|
|
Using openssl such a proxy <FONT SIZE="-1">CA</FONT> certificate and private key can be created with:
|
|
|
|
|
|
<P>
|
|
|
|
|
|
|
|
|
|
<PRE>
|
|
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.p12
|
|
|
|
</PRE>
|
|
|
|
|
|
<DT id="2">•<DD>
|
|
Configure client to connect to use intercepting proxy or somehow redirect
|
|
connections from client to the proxy (e.g. packet filter redirects, <FONT SIZE="-1">ARP</FONT> or <FONT SIZE="-1">DNS</FONT>
|
|
spoofing etc).
|
|
<DT id="3">•<DD>
|
|
Accept the <FONT SIZE="-1">TCP</FONT> connection from the client, e.g. don't do any <FONT SIZE="-1">SSL</FONT> handshakes with
|
|
the client yet.
|
|
<DT id="4">•<DD>
|
|
Establish the <FONT SIZE="-1">SSL</FONT> 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 <FONT SIZE="-1">CA.</FONT>
|
|
This is the step where IO::Socket::SSL::Intercept helps.
|
|
<DT id="5">•<DD>
|
|
Upgrade the <FONT SIZE="-1">TCP</FONT> connection to the client to <FONT SIZE="-1">SSL</FONT> using the cloned certificate
|
|
from the server. If the client trusts your proxy <FONT SIZE="-1">CA</FONT> it will accept the upgrade
|
|
to <FONT SIZE="-1">SSL.</FONT>
|
|
<DT id="6">•<DD>
|
|
Transfer data between client and server. While the connections to client and
|
|
server are both encrypted with <FONT SIZE="-1">SSL</FONT> you will read/write the unencrypted data in
|
|
your proxy application.
|
|
</DL>
|
|
<A NAME="lbAF"> </A>
|
|
<H2>METHODS</H2>
|
|
|
|
|
|
|
|
IO::Socket::SSL::Intercept helps creating the cloned certificate with the
|
|
following methods:
|
|
<DL COMPACT>
|
|
<DT id="7"><B></B>$mitm<B> = IO::Socket::SSL::Intercept->new(%args)</B><DD>
|
|
|
|
|
|
This creates a new interceptor object. <TT>%args</TT> should be
|
|
<DL COMPACT><DT id="8"><DD>
|
|
<DL COMPACT>
|
|
<DT id="9">proxy_cert X509 | proxy_cert_file filename<DD>
|
|
|
|
|
|
This is the proxy certificate.
|
|
It can be either given by an X509 object from Net::SSLeays internal
|
|
representation, or using a file in <FONT SIZE="-1">PEM</FONT> format.
|
|
<DT id="10">proxy_key <FONT SIZE="-1">EVP_PKEY</FONT> | proxy_key_file filename<DD>
|
|
|
|
|
|
This is the key for the proxy certificate.
|
|
It can be either given by an <FONT SIZE="-1">EVP_PKEY</FONT> object from Net::SSLeays internal
|
|
representation, or using a file in <FONT SIZE="-1">PEM</FONT> format.
|
|
The key should not have a passphrase.
|
|
<DT id="11">pubkey <FONT SIZE="-1">EVP_PKEY</FONT> | pubkey_file filename<DD>
|
|
|
|
|
|
This optional argument specifies the public key used for the cloned certificate.
|
|
It can be either given by an <FONT SIZE="-1">EVP_PKEY</FONT> object from Net::SSLeays internal
|
|
representation, or using a file in <FONT SIZE="-1">PEM</FONT> format.
|
|
If not given it will create a new public key on each call of <TT>"new"</TT>.
|
|
<DT id="12">serial INTEGER|CODE<DD>
|
|
|
|
|
|
This optional argument gives the starting point for the serial numbers of the
|
|
newly created certificates. If not set the serial number will be created based
|
|
on the digest of the original certificate. If the value is code it will be
|
|
called with <TT>"serial(original_cert,CERT_asHash(original_cert))"</TT> and should
|
|
return the new serial number.
|
|
<DT id="13">cache <FONT SIZE="-1">HASH</FONT> | <FONT SIZE="-1">SUBROUTINE</FONT><DD>
|
|
|
|
|
|
This optional argument gives a way to cache created certificates, so that they
|
|
don't get recreated on future accesses to the same host.
|
|
If the argument ist not given an internal <FONT SIZE="-1">HASH</FONT> ist used.
|
|
|
|
|
|
<P>
|
|
|
|
|
|
If the argument is a hash it will store for each generated certificate a hash
|
|
reference with <TT>"cert"</TT> and <TT>"atime"</TT> in the hash, where <TT>"atime"</TT> is the time of
|
|
last access (to expire unused entries) and <TT>"cert"</TT> is the certificate. Please
|
|
note, that the certificate is in Net::SSLeays internal X509 format and can
|
|
thus not be simply dumped and restored.
|
|
The key for the hash is an <TT>"ident"</TT> either given to <TT>"clone_cert"</TT> or generated
|
|
from the original certificate.
|
|
|
|
|
|
<P>
|
|
|
|
|
|
If the argument is a subroutine it will be called as <TT>"$cache->(ident,sub)"</TT>.
|
|
This call should return either an existing (cached) <TT>"(cert,key)"</TT> or
|
|
call <TT>"sub"</TT> without arguments to create a new <TT>"(cert,key)"</TT>, store it
|
|
and return it.
|
|
If called with <TT>"$cache->('type')"</TT> the function should just return 1 to
|
|
signal that it supports the current type of cache. If it reutrns nothing
|
|
instead the older cache interface is assumed for compatibility reasons.
|
|
</DL>
|
|
</DL>
|
|
|
|
<DL COMPACT><DT id="14"><DD>
|
|
</DL>
|
|
|
|
<DT id="15"><B>($clone_cert,$key) = </B>$mitm<B>->clone_cert($original_cert,[ </B>$ident<B> ])</B><DD>
|
|
|
|
|
|
This clones the given certificate.
|
|
An ident as the key into the cache can be given (like <TT>"host:port"</TT>), 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).
|
|
<DT id="16"><B></B>$string<B> = </B>$mitm<B>->serialize</B><DD>
|
|
|
|
|
|
This creates a serialized version of the object (e.g. a string) which can then
|
|
be used to persistantly store created certificates over restarts of the
|
|
application. The cache will only be serialized if it is a <FONT SIZE="-1">HASH.</FONT>
|
|
To work together with Storable the <TT>"STORABLE_freeze"</TT> function is defined to
|
|
call <TT>"serialize"</TT>.
|
|
<DT id="17"><B></B>$mitm<B> = IO::Socket::SSL::Intercept->unserialize($string)</B><DD>
|
|
|
|
|
|
This restores an Intercept object from a serialized string.
|
|
To work together with Storable the <TT>"STORABLE_thaw"</TT> function is defined to
|
|
call <TT>"unserialize"</TT>.
|
|
</DL>
|
|
<A NAME="lbAG"> </A>
|
|
<H2>AUTHOR</H2>
|
|
|
|
|
|
|
|
Steffen Ullrich
|
|
<P>
|
|
|
|
<HR>
|
|
<A NAME="index"> </A><H2>Index</H2>
|
|
<DL>
|
|
<DT id="18"><A HREF="#lbAB">NAME</A><DD>
|
|
<DT id="19"><A HREF="#lbAC">SYNOPSIS</A><DD>
|
|
<DT id="20"><A HREF="#lbAD">DESCRIPTION</A><DD>
|
|
<DT id="21"><A HREF="#lbAE">How Intercepting SSL Works</A><DD>
|
|
<DT id="22"><A HREF="#lbAF">METHODS</A><DD>
|
|
<DT id="23"><A HREF="#lbAG">AUTHOR</A><DD>
|
|
</DL>
|
|
<HR>
|
|
This document was created by
|
|
<A HREF="/cgi-bin/man/man2html">man2html</A>,
|
|
using the manual pages.<BR>
|
|
Time: 00:05:46 GMT, March 31, 2021
|
|
</BODY>
|
|
</HTML>
|