Files
nexus/sreweekly/articles/6/10-lostpass.html
2026-09-12 17:23:01 +08:00

297 lines
20 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<title>sean cassidy : LostPass</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href='https://fonts.googleapis.com/css?family=EB+Garamond' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="https://www.seancassidy.me/theme/css/main.css" type="text/css" />
<link href="https://www.seancassidy.me/atom.xml" type="application/atom+xml" rel="alternate" title="sean cassidy ATOM Feed" />
<!--[if IE]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
</head>
<body>
<header>
<h1><a href="https://www.seancassidy.me" id="site-title">sean cassidy </a> :
<a href="https://www.seancassidy.me/lostpass.html" id="page-title">LostPass</a></h1>
<time datetime="2016-01-16T08:19:00-08:00">Sat 16 January 2016</time><span class="category">in: <a href="https://www.seancassidy.me/category/programming.html">programming</a></span></header>
<article>
<p><strong>Updated 2016-02-04</strong>: LastPass has
<a href="/images/lastpass_notification_nobutton.png">removed the button from
notifications</a>
and now requires <a href="https://lastpass.com/support.php?cmd=showfaq&amp;id=10072">email confirmation for all logins from new IPs</a>.
This substantially mitigates LostPass, but does not eliminate it.</p>
<p>I have discovered a phishing attack against LastPass that allows an attacker to
steal a LastPass user's email, password, and even two-factor auth code, giving
full access to all passwords and documents stored in LastPass. </p>
<p>I call this attack LostPass. The code is available <a href="https://github.com/cxxr/lostpass">via Github</a>.</p>
<p>LostPass works because LastPass displays messages in the browser that attackers
can fake. Users can't tell the difference between a fake LostPass message and
the real thing because there is no difference. It's pixel-for-pixel the same
notification and login screen.</p>
<p>I discussed LostPass at <a href="https://shmoocon.org">ShmooCon 2016</a>. You can <a href="https://raw.githubusercontent.com/cxxr/lostpass/master/lostpass_shmoocon_slides.pdf">read my slides
(PDF)</a>, or you can <a href="https://archive.org/details/Lostpass">watch the video</a>.</p>
<h1 id="pixel-perfect-phishing">Pixel-perfect Phishing</h1>
<p>A few months ago, <a href="https://en.wikipedia.org/wiki/LastPass">LastPass</a> displayed a message on my browser that
my session had expired and I needed to log in again. I hadn't used LastPass in
a few hours, and hadn't done anything that would have caused me to be logged
out. When I went to click the notification, I realized something: it was
displaying this in the browser viewport. An attacker could have drawn this
notification.</p>
<p><a href="https://www.seancassidy.me/static/images/"><img src="/images/lastpass_notification.png" width="100%" alt="LastPass error notification"></a></p>
<p>Any malicious website could have drawn that notification. Because
LastPass trained users to expect notifications in the browser viewport, they
would be none the wiser. The LastPass login screen and two-factor prompt are
drawn in the viewport as well.</p>
<p><a href="https://www.seancassidy.me/static/images/"><img src="/images/lastpass_login.png" width="100%" alt="LastPass login screen"></a>
<a href="https://www.seancassidy.me/static/images/"><img src="/images/lastpass_2fa.png" width="100%" alt="LastPass two-factor screen"></a></p>
<p>Since LastPass has an API that can be accessed remotely, an attack materialized
in my mind.</p>
<h2 id="the-attack">The Attack</h2>
<p>Here are the steps for LostPass, in order.</p>
<h4 id="visit-the-malicious-site">Visit the malicious site</h4>
<p>Get the victim to go to a malicious website that looks benign, or a real
website that is vulnerable to XSS. This is where we'll deploy lostpass.js.
Unlike most phishing attacks, users won't be on their guard because this isn't
supposed to be a secure website. It could be a funny video or image, even.</p>
<h4 id="check-for-lastpass-and-show-the-notification">Check for LastPass and show the notification</h4>
<p>If they have LastPass installed, show the login expired notification and log
the user out of LastPass. LastPass is vulnerable to a logout <a href="https://en.wikipedia.org/wiki/Cross-site_request_forgery">CSRF</a>, so
any website can log any user out of LastPass. This will make it appear to the
user that they are truly logged out.</p>
<p><a href="https://www.seancassidy.me/static/images/"><img src="/images/lostpass_notification.png" width="100%" alt="LostPass notification screen"></a></p>
<h4 id="direct-the-victim-to-the-login-page">Direct the victim to the login page</h4>
<p>Once the victim clicks on the fake banner, direct them to an
attacker-controlled login page that looks identical to the LastPass one. This
is the login page for Chrome.</p>
<p><a href="https://www.seancassidy.me/static/images/"><img src="/images/lostpass_login.png" width="100%" alt="LostPass login screen"></a></p>
<p>Notice the domain, "chrome-extension.pw". This looks similar to the Chrome
protocol for real extensions "chrome-extension". There is an <a href="https://code.google.com/p/chromium/issues/detail?id=453093">open issue in
Chromium</a> to address this.</p>
<h4 id="get-the-credentials">Get the credentials</h4>
<p>The victim will enter their password and send the credentials to the
attacker's server. The attacker's server will check if the credentials are
correct by calling LastPass's API. The API will inform us if two-factor
authentication is required.</p>
<p>If the username and password is incorrect, we'll redirect the user back to the
malicious website, but this time, the LostPass notification bar will say
"Invalid Password".</p>
<p>If the user has two-factor authentication, redirect them to a two-factor
prompt, like so:</p>
<p><a href="https://www.seancassidy.me/static/images/"><img src="/images/lostpass_2fa.png" width="100%" alt="LostPass 2fa screen"></a></p>
<h4 id="download-the-vault">Download the vault</h4>
<p>Once the attacker has the correct username and password (and two-factor
token), download all of the victim's information from the LastPass API. We can
install a backdoor in their account via the emergency contact feature, disable
two-factor authentication, add the attacker's server as a "trusted device".
Anything we want, really.</p>
<h2 id="implications">Implications</h2>
<p>These steps mirror the exact path that LastPass does when a user is logged
out remotely. LostPass mimics steps 2 through 7.</p>
<p>Some things to note about why this is so effective:</p>
<ul>
<li>Many responses to the phishing problem are "Train the users", as if it was
their fault that they were phished. Training is not effective at combating
LostPass because there is little to no difference in what is shown to the
user</li>
<li>LastPass's login workflow is complex and somewhat buggy. Sometimes it shows
in-viewport login pages, and sometimes it shows them as popup windows</li>
<li>It is easy to detect LastPass and it was even easier to find the exact HTML
and CSS that LastPass uses to show notifications and login pages</li>
<li>It even phishes for the two-factor auth code, so 2FA is no help</li>
</ul>
<p>See <a href="https://github.com/cxxr/lostpass">the Github repository</a> for the code itself.</p>
<h1 id="faq">FAQ</h1>
<p>Here I've collected a list of questions that I've been asked about this.</p>
<h2 id="what-browsers-and-operating-systems-does-it-work-on">What browsers and operating systems does it work on?</h2>
<p>The attack works best against the Chrome browser because they use an HTML login
page. Firefox actually pops up a window for its login page, so it looks like
whatever operating system you're on. I have experimental support for
Firefox on OS X and Windows 8 in LostPass but it is not enabled by default. </p>
<h2 id="does-this-work-against-lastpass-40">Does this work against LastPass 4.0?</h2>
<p>Yes, I developed it specifically to work against LastPass 4.0. I did not
include any version detection information. </p>
<h2 id="what-can-i-do-to-safeguard-myself-or-my-company">What can I do to safeguard myself or my company?</h2>
<p>Here is a list of suggestions in no particular order:</p>
<ul>
<li>Ignore notifications in the browser window</li>
<li>Enable IP restriction (only available to paid plans)</li>
<li>Disable mobile login (although other attacks could use non-mobile API)</li>
<li>Log all logins and failures</li>
<li>Inform your employees of this potential attack</li>
</ul>
<h2 id="does-two-factor-authentication-help">Does two-factor authentication help?</h2>
<p><strong>Update</strong>:
<a href="https://lastpass.com/support.php?cmd=showfaq&amp;id=10072">LastPass now requires email confirmation for all new logins</a>,
regardless of two-factor auth. The original answer to this question remains
below.</p>
<p>No. In fact, two-factor authentication makes this attack significantly
<em>easier</em>.</p>
<p>By default, LastPass sends an email confirmation when a new IP address attempts
to login to LastPass. This should stop the attack almost entirely, but it
doesn't. According to <a href="https://lastpass.com/support.php?cmd=showfaq&amp;id=9222">LastPass's documentation</a>, the confirmation email
is only sent if you <em>don't</em> have two-factor authentication enabled.</p>
<p>Since LostPass also phishes for the two-factor auth code, it bypasses the email
confirmation step.</p>
<p>It is possible to make LostPass more effective against the case where it is
blocked by confirmation email (something like, "Please confirm your login via
email to continue"), but the attack was already potent enough.</p>
<h2 id="what-about-yubikeyu2fduo">What about Yubikey/U2F/Duo?</h2>
<p>I only checked Google Authenticator because that's what I had, but here's how
you can figure out if another two-factor authentication would have helped: if
you can tell the attacker what they need to know, then it won't help. So if you
type in a token, it won't help. If you get a push notification that is approved
and you let the attacker in, it won't help.</p>
<h2 id="how-can-i-check-if-ive-been-attacked">How can I check if I've been attacked?</h2>
<p>View your <a href="https://helpdesk.lastpass.com/your-lastpass-vault/account-history/">LastPass Account History</a> to inspect every login
attempt and which IP addresses it was done from.</p>
<h2 id="what-are-some-alternatives-to-lastpass">What are some alternatives to LastPass?</h2>
<p><a href="http://notlastpass.rockettech.net/">Here are some alternatives to LastPass</a>. I have not researched
any of these alternatives and cannot guarantee if they're safer than LastPass.</p>
<p>Things to look at:</p>
<ul>
<li>Browser extensions are riskier than native applications</li>
<li>An API makes it easier to steal a lot of data</li>
<li>Store only frequently used and low risk data in a password manager</li>
</ul>
<h2 id="how-is-this-related-to-the-attack-from-2015-by-garcia-and-vigo">How is this related to the attack from 2015 by Garcia and Vigo?</h2>
<p>Garcia and Vigo published an attack called
"<a href="http://www.martinvigo.com/even-the-lastpass-will-be-stolen-deal-with-it/">Even the LastPass Will be Stolen, Deal with It!</a>". Their work is a
sophisticated client-side attack that relies on bad design choices that
LastPass made that make it vulnerable to compromised machines.</p>
<p>My work comes at LastPass from a different angle: you don't have access to a
LastPass user's machine. Instead, you trick the user into giving you their
credentials.</p>
<h2 id="did-you-hack-lastpass">Did you hack LastPass?</h2>
<p>No.</p>
<h2 id="why-did-you-develop-this-attack">Why did you develop this attack?</h2>
<p>I think that the security industry's view of phishing is naive at best,
negligent at worst. Phishing is the most dominant attack vector and is used
by everyone from run-of-the-mill cryptolocker types to APTs. Don't just take
it from me, though. Take it from <a href="https://twitter.com/thegrugq/status/649164150858321921">the grugq</a>:</p>
<blockquote>
<p>It's surprising how critical good phishing technique is with these APT
attacks. Effective phishing is more important than 0day.</p>
</blockquote>
<p>The standard refrain is that we need better user training. That is simply not
good enough.</p>
<p>The real solution is designing software to be phishing resistant. Just like we
have anti-exploitation techniques, we need anti-phishing techniques built into
more software. Software security evaluations should also include how easy it is
to phish said software.</p>
<h2 id="why-are-you-releasing-this-as-a-tool-wont-bad-people-use-it-against-me">Why are you releasing this as a tool? Won't bad people use it against me?</h2>
<p>Unlike most exploits, this attack requires no sophisticated knowledge. A
simple right-click will get you the HTML. A tiny bit of JavaScript will glue
the pieces together. As soon as I published details of this attack, criminals
could make their own version in less than a day. I am publishing this tool so
that companies can pen-test themselves to make an informed decision about this
attack and respond appropriately.</p>
<p>This is backwards for most vulnerability disclosures. Most vulnerabilities are
easy-to-fix and hard-to-exploit. This is hard-to-fix and easy-to-exploit, so I
felt that a tool release was appropriate. There is also precedent for LastPass
attacks: Garcia and Vigo released a <a href="https://github.com/rapid7/metasploit-framework/blob/master/modules/post/multi/gather/lastpass_creds.rb">metasploit module</a> for their
attack.</p>
<h2 id="did-you-tell-lastpass">Did you tell LastPass?</h2>
<p>Yes. I informed them in November, and they acknowledged the bug in December.</p>
<p>This has been a long and confusing issue. At first LastPass understood this bug
to be mainly be a result of the logout CSRF. Then they suggested it wouldn't
work because of the email confirmation step. The GM of LastPass said that
LastPass, "can confirm this is a phishing attack, not a vulnerability in
LastPass." I obviously disagree.</p>
<p>One of the fixes they implemented to fix LostPass was to warn users when they
type in their master password into some website. However, they display a
warning message in the browser viewport, like all of their messages. On an
attacker-controlled website, it is trivial to detect when this notification is
added. Then the attacker can do whatever. In LostPass, I suppress the
notification and fire off a request to an attacker server to log the master
password.</p>
<p>We as an industry do not respond to phishing attacks well. I do not blame
LastPass for this, they are like everyone else. We need to take a long look at
phishing and figure out what to do about it. In my view, it's just as bad, if
not worse than, many remote code execution vulnerabilities, and should be
treated as such.</p>
<h2 id="is-what-youre-doing-right">Is what you're doing right?</h2>
<p>I think informing users about security concerns in the products they use is
important. Too often security researchers kowtow to corporations by not telling
users about vulnerabilities they should know about. I think of security
researchers (a group I do not identify with) as having a similar ethical code
to journalists: the public has a right to know. Your interviewee (target)
does not get to dictate how the interview (research) is published or disclosed.</p>
<p>Your own judgement is paramount.</p>
<h2 id="can-operating-systems-or-browsers-do-something-to-address-this-class-of-bugs">Can operating systems or browsers do something to address this class of bugs?</h2>
<p>Yes. </p>
<p>To spoof the "chrome-extension" protocol, I bought the domain
"chrome-extension.pw", which looks close enough. Connecting to
chrome-extension.pw over HTTP makes it look pretty similar to the built-in
protocol. There is an <a href="https://code.google.com/p/chromium/issues/detail?id=453093">open issue in Chromium</a> to address this.</p>
<p>It is harder to spoof in Firefox, where I had to draw each OS's native widget
manually using HTML and CSS. They're not perfect, either, but it's pretty
close. Here's an image of LastPass and LostPass for Firefox on Windows 8
side-by-side. Which one is which?</p>
<p><a href="https://www.seancassidy.me/static/images/"><img src="/images/lastpass_firefox.png" width="100%" alt="LastPass Firefox login"></a></p>
<p>Since the browser viewport can draw anything with pixels, we need to think
about how we authenticate native windows visually. UX is a very important
security concern. UAC's dimming of the screen in Windows is a step in the right
direction.</p>
<h1 id="more-information">More information</h1>
<p>For more information, look at <a href="https://raw.githubusercontent.com/cxxr/lostpass/master/lostpass_shmoocon_slides.pdf">my ShmooCon slides</a>,
<a href="https://archive.org/details/Lostpass">watch the video</a> and <a href="https://github.com/cxxr/lostpass">the source code to LostPass itself</a>. You
can also <a href="mailto:sean@seancassidy.me">email me</a> or
<a href="https://twitter.com/sean_a_cassidy">tweet at me</a>.</p>
<p><a href="https://github.com/cxxr/lostpass"><img style="position: absolute; top: 0; left: 0; border: 0;" src="https://camo.githubusercontent.com/567c3a48d796e2fc06ea80409cc9dd82bf714434/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f6c6566745f6461726b626c75655f3132313632312e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_left_darkblue_121621.png"></a></p>
</article>
<ul class="tags">
<li class="tags" style="font-size: 13px; letter-spacing: 3px">tags:</li>
<li class="tags"><a href="https://www.seancassidy.me/tag/code.html">code</a></li>
<li class="tags"><a href="https://www.seancassidy.me/tag/bugs.html">bugs</a></li>
<li class="tags"><a href="https://www.seancassidy.me/tag/security.html">security</a></li>
<li class="tags"><a href="https://www.seancassidy.me/tag/crypto.html">crypto</a></li>
</ul>
<div style="width:40%" class="alignright">
<p style="text-align:left;font-size: 87%"><a
href="https://www.linkedin.com/in/seanacassidy/">Sean</a> is the Head of Security at <a
href="https://www.asana.com">Asana</a>, a work management platform for teams.</p>
<a href="https://twitter.com/sean_a_cassidy" class="twitter-follow-button" data-show-count="false" data-size="large" data-dnt="true">Follow @sean_a_cassidy</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
</div>
<nav>
<p>related posts</p>
<ul class="related">
<li><a href="https://www.seancassidy.me/diagnosis-of-the-openssl-heartbleed-bug.html">Diagnosis of the OpenSSL Heartbleed Bug</a></li>
<li><a href="https://www.seancassidy.me/the-story-of-the-gnutls-bug.html">The Story of the GnuTLS Bug</a></li>
<li><a href="https://www.seancassidy.me/wrong-solutions.html">Wrong Solutions</a></li>
</ul>
</nav>
<footer>
<nav>
<ul class="footer">
<li class="footer"><a href="https://www.seancassidy.me/pages/about.html">about</a></li>
<li class="footer">- <a href="https://github.com/cxxr">github</a></li>
<li class="footer">- <a href="https://twitter.com/sean_a_cassidy">twitter</a></li>
<li class="footer">- <a href="https://www.seancassidy.me/atom.xml">feed</a></li>
<li class="footer">- <a href="https://www.seancassidy.me/tags.html">tags</a></li>
</ul>
</nav>
</footer>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-38980907-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
<script src="https://www.seancassidy.me/theme/js/genius-blocker.js"></script>
</body>
</html>