There are many servers which support export-grade ciphers simply because default cipher sets had, and in some cases (inexplicably) continue to have them enabled. One of the changes in TLS 1.1 (section A.5) was to state that export grade ciphers MUST NOT be used in TLSv1.1. TLS 1.0 (section D.4) leaves it up to the implementation to decide on the required level of security.
Apache httpd's default SSLCipherSuite
is the value "DEFAULT", which up to and including openssl-1.0.2, would include just about everything compiled in, excluding only ciphers sets with anonymous-authentication or null encryption. However, as of httpd-2.4.7 (Nov 2013) the export grade (and aNULL/eNULL) ciphers are removed by mod_ssl
, and cannot be restored using SSLCipherSuite
. This change was not back-ported to 2.2. Up to and including httpd-2.2.21 (Sept 2011) the default configuration file had "LOW" ciphers explicitly enabled, and "EXPORT" (40) implicitly enabled, only "EXPORT56" are disabled (possibly an oversight).
A likely source of problems is someone running a reasonably up-to-date Apache-2.2, but with an older configuration file.
Your description of the attack isn't quite complete though. "Export grade" is often interpreted as meaning "less than 128-bit". A true export-grade cipher may also require the use of a shorter export grade key/modulus in key exchange. There are two distinct types of keys in an SSL/TLS cipher, most people will be familiar with the export ciphers as using small (40-bit or 56-bit) keys. This refers only to the symmetric key size, used only for the symmetric cipher such RC4 or DES. The other key type is the asymmetric key used to securely exchange the symmetric key.
The U.S. Export controls do not affect just symmetric cipher key size, they affect the asymmetric key size too:
Encryption Export Controls: Revision of License Exception ENC and Mass Market Eligibility, Submission Procedures, Reporting Requirements, License Application
Requirements, and Addition of Note 4 to Category 5, Part 2
[...]
a.1.a. A “symmetric algorithm” employing a key length in excess of 56-bits; or
a.1.b. An “asymmetric algorithm” where the security of the algorithm is based on any of the following:
a.1.b.1. Factorization of integers in excess of 512 bits (e.g., RSA);
If a server has an RSA 1024-bit (or larger) key, it cannot be used with all export ciphers with normal RSA-based key exchange (an encryption operation), it must be downgraded somehow to a 512-bit key. (Signing keys can key larger than 512-bits though.)
$ openssl ciphers -v "kRSA" | egrep "(512|1024)"
EXP1024-RC4-SHA SSLv3 Kx=RSA(1024) Au=RSA Enc=RC4(56) Mac=SHA1 export
EXP1024-DES-CBC-SHA SSLv3 Kx=RSA(1024) Au=RSA Enc=DES(56) Mac=SHA1 export
EXP1024-RC2-CBC-MD5 SSLv3 Kx=RSA(1024) Au=RSA Enc=RC2(56) Mac=MD5 export
EXP1024-RC4-MD5 SSLv3 Kx=RSA(1024) Au=RSA Enc=RC4(56) Mac=MD5 export
EXP-DES-CBC-SHA SSLv3 Kx=RSA(512) Au=RSA Enc=DES(40) Mac=SHA1 export
EXP-RC2-CBC-MD5 SSLv3 Kx=RSA(512) Au=RSA Enc=RC2(40) Mac=MD5 export
EXP-RC4-MD5 SSLv3 Kx=RSA(512) Au=RSA Enc=RC4(40) Mac=MD5 export
EXP-RC2-CBC-MD5 SSLv2 Kx=RSA(512) Au=RSA Enc=RC2(40) Mac=MD5 export
EXP-RC4-MD5 SSLv2 Kx=RSA(512) Au=RSA Enc=RC4(40) Mac=MD5 export
kx=RSA(512)
means the key-exchange is a fixed size RSA 512-bit, independent of the certificate size (or more correctly, modulus size). The RSA 1024-bit export ciphers (EXPORT56) are less interesting here, but are still a potential weakness when used with 2048-bit or higher certificates (they have long since been removed from OpenSSL though).
Unlike a hash output or symmetric key, an asymmetric key (modulus) cannot simply be chopped in half (the mathematics behind the RSA algorithm would no longer hold), so instead a temporary RSA key is used. This key is signed with the servers real RSA key, and exchanged in an optional ServerkeyExchange (type 0x0C) message. (A similar step happens with DHE key exchange, as the RSA certificate alone does not contain the data needed to complete the exchange.)
You can see this with an export cipher like EXP-EDH-RSA-DES-CBC-SHA
:
$ openssl ciphers -v EXP-EDH-RSA-DES-CBC-SHA
EXP-EDH-RSA-DES-CBC-SHA SSLv3 Kx=DH(512) Au=RSA Enc=DES(40) Mac=SHA1 export
^^^^^^^
The interesting part here is EXP-EDH
, the extra ServerKeyExchange contains a shorter (512 bit) EDH key. It's not clear from Matthew Green's discussion if DH is also a problem. RSA Kx is a problem, you can see what happens if you capture a session and run it through ssldump
:
$ sudo tcpdump -s1520 -c 18 -w insecure-rsa.pcap host www.insecure.com and port 443 &
$ openssl s_client -showcerts -connect www.insecure.com:443 -cipher EXP-RC4-MD5 -msg
[...]
$ ssldump -VAN -r insecure-rsa.pcap
[...]
1 4 0.0245 (0.0000) S>CV3.1(205) Handshake
ServerKeyExchange
params
RSA_modulus[64]=
b4 3c e4 c5 f2 9b 8b 8e ef 6e 29 4e 5d 80 78 1c
1d e8 80 0f 65 32 a0 a6 be d4 35 a6 09 6b 2c 15
f2 80 e7 cd 22 9b 01 21 1e 7b 13 12 95 34 03 16
7b 9a 66 79 4e d1 6d 15 28 3d 73 45 91 85 a0 c1
RSA_exponent[3]=
01 00 01
signature[128]=
c6 09 b9 14 88 94 6d 06 82 84 e6 af eb af 72 fc
fd c6 d5 09 63 a8 f5 f8 e7 3a 79 69 14 9f 24 0e
ed dd 71 4b c4 8d 99 51 7c e6 1f aa af ea b2 b9
05 04 3c db 31 40 8d 11 f8 94 73 26 a5 5c 2f 28
84 49 77 62 3c 27 90 51 52 9f ab 61 6c 12 cd 49
9e ab ad f5 bf 2b f7 9c 1b 1e 05 a2 40 f6 7c 60
b3 8b 1d 8a 2f 4c bb 1e b0 04 ed 42 a8 14 95 55
7c b1 54 ff a2 3e e2 98 f4 15 96 7a 48 c4 a6 8c
(ssldump
is a little old, and has a few problems, but it works fine for this.)
The RSA modulus of 64 bytes is the "512-bit" problem here, it's equivalent to a certificate for RSA key exchange, but it can be brute-force factorised.
A viable attack involves specific server and client behaviour:
- The server must support an export-grade cipher with RSA (possibly enabled by default).
When this is used, the server must also have a weak (<=512-bit modulus) key available, it protects the modulus when used by signing with its real (strong) key.
- The server must use a medium to long-term temporary RSA-export key (Apache does this) since real-time factorisation isn't viable.
- The attacker must obtain the weak RSA public modulus by establishing an export grade connection, and then factor the modulus (approx 8 hours, $100) before it's replaced with a new one. The attacker cannot masquerade as the server using this, but he can decrypt data intended for the server if a client uses it.
The attacker must MITM a client who will erroneously accept an export grade key (RSA modulus), even if export ciphers are not enabled, and were not in the client handshake (broken OpenSSL and Apple clients do this).
- The attacker must modify the ClientHello to include only RSA export ciphers (in TLS, the server picks the cipher from the client list), the export (temporary) key must be signed by the real (long-term) server key (which the attacker does not have).
- The attacker must modify the ServerHello so that it meets the clients expectations (i.e. using one of the original RSA non-export ciphers)
- The attacker sends the (out of state) ServerKeyExchange with the weak 512-bit modulus, the client will trust this since it's been signed with the real server key
- The client accepts the export grade RSA key because it appears at the correct stage in the handshake, the TLS state-machine processes it due to a flaw and subsequently uses it instead of the real one in the certificate.
- The attacker obtains the pre-master secret, it is encrypted with the temporary RSA key and sent by the client, the attacker can then compute the master secret (using the pre-master, and other data exchanged earlier in the handshake)
- Now the attacker has the master secret, he can compute and send valid "finished" messages, neither side is able to detect any interference in the connection. Game Over.
This problem is a combination of two things:
- a mis-configured server with export grade cipher support, this necessitates the use of weak temporary RSA keys
- a flawed client which accepts the export cipher indicated in a handshake even though it did not initiate a connection using it. (The client need not be configured to offer the cipher, but the client's SSL/TLS library must have the implementation present.)
(There's another problem too, by virtue of an export grade cipher being used, each client connection may be brute-forced as it's only 40- or 56-bit, but breaking the RSA part is more useful and interesting.)
Historically, generating the primes for an RSA key took time, which is presumably why Apache only generates this once on startup. On contemporary hardware it takes only a few extra ms at most. In the old Apache-ssl source (apache-1.3.x era, predating mod_ssl-2.0) you'll find this humourous reference:
#if SSLEAY_VERSION_NUMBER >= 0x0920
/* FIXME: This ought to generate a new key from time to time - why make the
Feds' life easy? */
static RSA *TmpRSACallback(SSL *pSSL,int nExport,int nKeyLength)
{
static RSA *pRSA512=NULL;
static RSA *pRSA1024=NULL;
ap_log_error(APLOG_MARK,APLOG_DEBUG|APLOG_NOERRNO,
SSL_get_ex_data(pSSL,EX_DATA_SERVER_REC),
"Generating %d bit key",nKeyLength);
This FIXME was never fixed, even in Apache-1.3 with mod_ssl-2.8 which freely quoted (and ignored) the TLS spec's recommendation on key reuse/regeneration. Finally, export RSA support was ripped out entirely in September 2013 in the dev branch (which will be httpd-2.5).