Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 15 Oct 2014 10:02:17 +0400
From:      Eygene Ryabinkin <rea@freebsd.org>
To:        Dag-Erling =?utf-8?B?U23DuHJncmF2?= <des@des.no>
Cc:        gecko@freebsd.org, ports-secteam@freebsd.org, chromium@freebsd.org
Subject:   Re: POODLE SSLv3 vulnerability
Message-ID:  <R0zKl5VfV2qM//7ElaCD1tOBoHs@1d%2BaJAniZP50FCDdGj54nd51%2Bks>
In-Reply-To: <86iojmgn40.fsf@nine.des.no>
References:  <86iojmgn40.fsf@nine.des.no>

next in thread | previous in thread | raw e-mail | index | archive | help

--L5nTHegdhbHhzmSD
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Wed, Oct 15, 2014 at 03:03:59AM +0200, Dag-Erling Sm=C3=B8rgrav wrote:
> Summary: Google researchers have discovered a plaintext recovery attack
> against SSL 3.0 with no known mitigation.

Having spent some time with the attack paper,
  https://www.openssl.org/~bodo/ssl-poodle.pdf
I am posting my findings: may be they will be of some help (or may be
someone will pinpoint the areas where I wasn't correct).

{{{
It is an active attack (means that you can't do many sensible
things with just recorded sessions), and it can be used to
recover the plaintext, provided that

 a. attacker can trick the victim host to send many (around
    256 per one recovered byte) requests to the server in
    question; the URL to be accessed and the body of request
    should also be controllable by the attacker;

 b. attacker has control over victim's network channel, so
    he can manipulate its contents.


The problem is that section 5.2.3.2 of RFC6101,
  https://tools.ietf.org/html/rfc6101#section-5.2.3.2
specifies that for block ciphers the last byte of the plaintext with
addition of the MAC and padding ends on the length of the padding,
the value that can be made known.

So, people talk about case when padding takes an entire block of
ciphertext (so the size of original data and MAC is divisible by
the block size): in this case the last byte will be (L-1) where
L is the cipher's block length.  Additional requirement is that
the byte that we should decipher should be the last byte of some
block of size L.

This is where we need the condition "a": since in HTTP requests URL
comes before, say, POST content, by controlling the URL or its part
attacker should be able to shift the needed byte to the right
position; since the body of request is controllable by the attacker,
he can make the total length of the request to be fittable to the
multiple of the block size (along with the trailing MAC).

Since the attacker sees all communications (in encrypted form), he
sees blocks C_i (the one that bears the byte to be decrypted as the
last byte in block) and C_N (byte with the padding).  And attacker
swaps the last block with C_i, so here is requirement "b": full
control over victim's network channel.

The thing is that the value of the padding isn't protected with
MAC, so it is essentially random and is trown away if things are
fine.

So, when server tries to decipher the last block, it will do
 P_N =3D decrypt(C_i) xor C_{N-1}
where P_N is plaintext, decrypt() is block decipher function,
C_i and C_{N-1} are respective ciphertext blocks (remember,
attacker replaced C_N with C_i).

The only thing that server will check for resulting P_N is that
its last byte is equal to (L-1).  So, if server doesn't reject
this attempt, it means that
 L-1 =3D P_N[L-1] =3D decrypt(C_i)[L-1] xor C_{N-1}[L-1]
But decrypt(C_i) =3D P_i xor C_{i-1}, so
 P_i[L-1] =3D (L-1) xor C_{N-1}[L-1] xor C_{i-1}[L-1]
and we know P_i[L-1], since all things in right-hand side are
visible to the attacker.

Generally, attacker can have control only for the URL part, but then
it will need to guess the size of the payload (more properly, its size
modulo block length, so there are not that many variants, because
block length is typically 8 or 16 bytes).  Then he will know that last
byte of the padding and can adjust for the changes in request length
(that arise because he wants to shift the byte to be deciphered into
the proper position).

And, of course, all this stuff will be usable only for the period of
the session when a single shared secret is used: once session key for
block cipher is changed, attacker should start again.
}}}

> I would like us to ship Firefox with SSL 3.0 disabled by default.
> This means setting security.tls.version.min to 1, or, in terms of
> code, changing the initial value of PSM_DEFAULT_MIN_TLS_VERSION from
> 0 to 1 in security/manager/ssl/src/nsNSSComponent.cpp.  I assume
> that other Mozilla ports use the same code and require the same
> changes.

I'd also introduce an OPTION for Apache, Nginx and other Web servers
we ship in the ports collection that won't allow to use SSLv3 and turn
it on by-default.  This will break some legacy clients, so it should
be an OPTION.  stunnel, all Web servers for Ruby and other servers
that do SSL should also be modified to include such modification.
--=20
Eygene Ryabinkin                                        ,,,^..^,,,
[ Life's unfair - but root password helps!           | codelabs.ru ]
[ 82FE 06BC D497 C0DE 49EC  4FF0 16AF 9EAE 8152 ECFB | freebsd.org ]

--L5nTHegdhbHhzmSD
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iL4EABEKAGYFAlQ+DelfFIAAAAAALgAoaXNzdWVyLWZwckBub3RhdGlvbnMub3Bl
bnBncC5maWZ0aGhvcnNlbWFuLm5ldDgyRkUwNkJDRDQ5N0MwREU0OUVDNEZGMDE2
QUY5RUFFODE1MkVDRkIACgkQFq+eroFS7PsrzwD9EHqFcxjlcdg2TqoBI6QCeQ4R
dP79dnWLKYRTOcQx6nsBAJiW8uImd1sfXBx48gIppuXEwnu74vOLQmLSlL8XJY8O
=t/Vn
-----END PGP SIGNATURE-----

--L5nTHegdhbHhzmSD--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?R0zKl5VfV2qM//7ElaCD1tOBoHs>