Skip to content

Commit

Permalink
implement 1/(n-1) record splitting detection
Browse files Browse the repository at this point in the history
This was fun.
  • Loading branch information
jmhodges committed Jan 9, 2014
1 parent c50145b commit 9e69c3a
Show file tree
Hide file tree
Showing 6 changed files with 294 additions and 38 deletions.
6 changes: 4 additions & 2 deletions client_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type clientInfo struct {
TLSCompressionSupported bool `json:"tls_compression_supported"` // bad if true
UnknownCipherSuiteSupported bool `json:"unknown_cipher_suite_supported"` // bad if true
BEASTVuln bool `json:"beast_vuln"` // bad if true
AbleToDetectNMinusOneSplitting bool `json:"able_to_detect_n_minus_one_splitting"` // neutral
InsecureCipherSuites map[string][]string `json:"insecure_cipher_suites"`
TLSVersion string `json:"tls_version"`
Rating Rating `json:"rating"`
Expand All @@ -38,8 +39,9 @@ func ClientInfo(c *conn) *clientInfo {
if strings.Contains(s, "DHE_") {
d.EphemeralKeysSupported = true
}
if c.st.ClientHello.Vers <= tls.VersionTLS10 && strings.Contains(s, "_CBC_") {
d.BEASTVuln = true
if c.HasBeastVulnSuites {
d.BEASTVuln = !c.NMinusOneRecordSplittingDetected
d.AbleToDetectNMinusOneSplitting = c.AbleToDetectNMinusOneSplitting
}
if fewBitCipherSuites[s] {
d.InsecureCipherSuites[s] = append(d.InsecureCipherSuites[s], fewBitReason)
Expand Down
29 changes: 14 additions & 15 deletions static/about.html
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,7 @@ <h3 class="fragpadded" id="rating">Rating</h3>
attack</a>.</li>
<li>It is susceptible to the
<a href="http://en.wikipedia.org/wiki/Transport_Layer_Security#BEAST_attack">BEAST
attack</a>. A caveat here: some advanced clients have a workaround
called "1/n-1 record splitting" that is not yet detectable by
How's My SSL?. Known clients that do this include recent versions
of Chrome, Firefox, OpenSSL and NSS. However, not every browser or
client is up to date.</li>
attack</a>.</li>
</ul>
<p>How's My SSL? always selects the worst rating the client could
receive. That is, clients rated as "Bad" may also have problems
Expand Down Expand Up @@ -254,17 +250,20 @@ <h4 class="fragpadded" id="beast-vulnerability">BEAST Vulnerability</h4>
to <a href="http://vnhacker.blogspot.com/2011/09/beast.html">decrypt
the data</a> on a TLS connection matching that
criteria. Upgrading to TLS 1.1 or greater or not using CBC
cipher suites mitigates the attack (though, RC4 has its own
issues). Another mitigation strategy is called 1/n-1 record
splitting and is not yet detected by How's My SSL?.</p>
<p>If the client client supports CBC mode cipher suites on TLS
1.0, it will be marked as <span class="label
bad">bad</span>. However, clients that mitigate it with 1/n-1
record splitting will not be detected and will be marked down
incorrectly. Few clients do, but among them is recent versions
of Firefox.</p>
cipher suites prevents the attack (though, RC4 has its own
issues). Another mitigation strategy is called 1/(n-1) record
splitting. 1/(n-1) record splitting allows TLS 1.0 clients
using CBC cipher modes to mitigate the attack by sending only
a single byte in the first encrypted application data record
of the connection, which fixes up the initialization vector
for the rest of the connection.</p>
<p>If the client supports CBC mode cipher suites on TLS 1.0
and does not implement the 1/(n-1) record splitting
mitigation, it will be marked as <span class="label
bad">bad</span>.</p>
<p>Clients using versions of TLS greater than 1.0 or not using
CBC cipher suites will be marked as <span class="label
CBC cipher suites or are using both but also implement 1/(n-1)
record splitting, will be marked as <span class="label
okay">Probably Okay<span></p>

<h4 class="fragpadded" id="insecure-cipher-suites">Insecure Cipher Suites</h4>
Expand Down
61 changes: 50 additions & 11 deletions templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -158,19 +158,58 @@ <h2>TLS Compression</h2>
<div class="span4">
<h2>BEAST Vulnerability</h2>
{{if .BEASTVuln}}
<p><span class="label bad">Bad</span> Your client is probably open to
the <a href="http://en.wikipedia.org/wiki/Transport_Layer_Security#BEAST_attack">BEAST
attack</a>. It's using version TLS 1.0 or earlier while also
supporting a cipher suite that
uses <a href="http://en.wikipedia.org/wiki/Cipher_block_chaining#Cipher-block_chaining_.28CBC.29">Cipher-Block
Chaining</a>. That combination may leak information. Fixed in TLS
1.1 and later.</p>
<p><span class="label bad">Bad</span>
{{ if .AbleToDetectNMinusOneSplitting }}

Your client is open to
the <a href="http://en.wikipedia.org/wiki/Transport_Layer_Security#BEAST_attack">BEAST
attack</a>. It's using TLS 1.0 or earlier while also
supporting a cipher suite that
uses <a href="http://en.wikipedia.org/wiki/Cipher_block_chaining#Cipher-block_chaining_.28CBC.29">Cipher-Block
Chaining</a> and doesn't implement the 1/(n-1) record
splitting mitigation. That combination will leak
information.

{{ else }}

Your client is probably open to
the <a href="http://en.wikipedia.org/wiki/Transport_Layer_Security#BEAST_attack">BEAST
attack</a> because it's using TLS 1.0 or earlier while
also supporting a cipher suite that
uses <a href="http://en.wikipedia.org/wiki/Cipher_block_chaining#Cipher-block_chaining_.28CBC.29">Cipher-Block
Chaining</a>. However, the CBC cipher suites your client
supports is not one How's My SSL is able to use, so it
was unable to determine if your client implements the
1/(n-1) record splitting mitigation. Clients with that
uncommon of cipher suite selection rarely implement it,
however, so it's best to assume the worst.

{{ end }}
</p>
{{else}}
<p><span class="label okay">Good</span> Your client is either
not vulnerable to
<p><span class="label okay">Good</span>

{{ if .AbleToDetectNMinusOneSplitting }}

Your client is not vulnerable to
the <a href="http://en.wikipedia.org/wiki/Transport_Layer_Security#BEAST_attack">BEAST
attack</a> at all, or it supports a newer version of TLS that
isn't.</p>
attack</a>. While it's using TLS 1.0 in conjunction
with <a href="http://en.wikipedia.org/wiki/Cipher_block_chaining#Cipher-block_chaining_.28CBC.29">Cipher-Block
Chaining</a> cipher suites, it has implemented the 1/(n-1)
record splitting mitigation.

{{ else }}

Your client is not vulnerable to
the <a href="http://en.wikipedia.org/wiki/Transport_Layer_Security#BEAST_attack">BEAST
attack</a> because it's using a TLS protocol newer than
TLS 1.0. The BEAST attack is only possibly against clients
using TLS 1.0 or earlier
using <a href="http://en.wikipedia.org/wiki/Cipher_block_chaining#Cipher-block_chaining_.28CBC.29">Cipher-Block
Chaining</a> cipher suites that do not implement the
1/(n-1) record splitting mitigation.

{{ end }}
{{end}}
<p><a href="/s/about.html/#beast-vulnerability">Learn More</a></p>
</div>
Expand Down
187 changes: 187 additions & 0 deletions tls/cbc_suites.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
package tls

// All CBC mode cipher suites. This is used in BEAST attack vulnerability detection. While this list contains non-TLS 1.0 cipher suites, the existence checks are done behind a client version check. We'll just have extras that are never touched in this list.
// Generated from:
// curl -s http://www.iana.org/assignments/tls-parameters/tls-parameters.txt | grep '0x.* TLS_' | grep CBC | awk '{ print $1": true,"}' | sed 's/,0x//'
var cbcSuites = map[uint16]bool{
0x0006: true,
0x0007: true,
0x0008: true,
0x0009: true,
0x000A: true,
0x000B: true,
0x000C: true,
0x000D: true,
0x000E: true,
0x000F: true,
0x0010: true,
0x0011: true,
0x0012: true,
0x0013: true,
0x0014: true,
0x0015: true,
0x0016: true,
0x0019: true,
0x001A: true,
0x001B: true,
0x001E: true,
0x001F: true,
0x0021: true,
0x0022: true,
0x0023: true,
0x0025: true,
0x0026: true,
0x0027: true,
0x0029: true,
0x002A: true,
0x002F: true,
0x0030: true,
0x0031: true,
0x0032: true,
0x0033: true,
0x0034: true,
0x0035: true,
0x0036: true,
0x0037: true,
0x0038: true,
0x0039: true,
0x003A: true,
0x003C: true,
0x003D: true,
0x003E: true,
0x003F: true,
0x0040: true,
0x0041: true,
0x0042: true,
0x0043: true,
0x0044: true,
0x0045: true,
0x0046: true,
0x0067: true,
0x0068: true,
0x0069: true,
0x006A: true,
0x006B: true,
0x006C: true,
0x006D: true,
0x0084: true,
0x0085: true,
0x0086: true,
0x0087: true,
0x0088: true,
0x0089: true,
0x008B: true,
0x008C: true,
0x008D: true,
0x008F: true,
0x0090: true,
0x0091: true,
0x0093: true,
0x0094: true,
0x0095: true,
0x0096: true,
0x0097: true,
0x0098: true,
0x0099: true,
0x009A: true,
0x009B: true,
0x00AE: true,
0x00AF: true,
0x00B2: true,
0x00B3: true,
0x00B6: true,
0x00B7: true,
0x00BA: true,
0x00BB: true,
0x00BC: true,
0x00BD: true,
0x00BE: true,
0x00BF: true,
0x00C0: true,
0x00C1: true,
0x00C2: true,
0x00C3: true,
0x00C4: true,
0x00C5: true,
0xC003: true,
0xC004: true,
0xC005: true,
0xC008: true,
0xC009: true,
0xC00A: true,
0xC00D: true,
0xC00E: true,
0xC00F: true,
0xC012: true,
0xC013: true,
0xC014: true,
0xC017: true,
0xC018: true,
0xC019: true,
0xC01A: true,
0xC01B: true,
0xC01C: true,
0xC01D: true,
0xC01E: true,
0xC01F: true,
0xC020: true,
0xC021: true,
0xC022: true,
0xC023: true,
0xC024: true,
0xC025: true,
0xC026: true,
0xC027: true,
0xC028: true,
0xC029: true,
0xC02A: true,
0xC034: true,
0xC035: true,
0xC036: true,
0xC037: true,
0xC038: true,
0xC03C: true,
0xC03D: true,
0xC03E: true,
0xC03F: true,
0xC040: true,
0xC041: true,
0xC042: true,
0xC043: true,
0xC044: true,
0xC045: true,
0xC046: true,
0xC047: true,
0xC048: true,
0xC049: true,
0xC04A: true,
0xC04B: true,
0xC04C: true,
0xC04D: true,
0xC04E: true,
0xC04F: true,
0xC064: true,
0xC065: true,
0xC066: true,
0xC067: true,
0xC068: true,
0xC069: true,
0xC070: true,
0xC071: true,
0xC072: true,
0xC073: true,
0xC074: true,
0xC075: true,
0xC076: true,
0xC077: true,
0xC078: true,
0xC079: true,
0xC094: true,
0xC095: true,
0xC096: true,
0xC097: true,
0xC098: true,
0xC099: true,
0xC09A: true,
0xC09B: true,
}
10 changes: 10 additions & 0 deletions tls/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ type Conn struct {
input *block // application data waiting to be read
hand bytes.Buffer // handshake data waiting to be read

AbleToDetectNMinusOneSplitting bool
NMinusOneRecordSplittingDetected bool
HasBeastVulnSuites bool
readOneAppDataRecord bool

tmp [16]byte
}

Expand Down Expand Up @@ -566,6 +571,7 @@ Again:

vers := uint16(b.data[1])<<8 | uint16(b.data[2])
n := int(b.data[3])<<8 | int(b.data[4])

if c.haveVers && vers != c.vers {
return c.sendAlert(alertProtocolVersion)
}
Expand Down Expand Up @@ -603,6 +609,10 @@ Again:
}
b.off = off
data := b.data[b.off:]
if !c.readOneAppDataRecord && c.AbleToDetectNMinusOneSplitting && want == recordTypeApplicationData {
c.readOneAppDataRecord = true
c.NMinusOneRecordSplittingDetected = len(data) == 1
}
if len(data) > maxPlaintext {
c.sendAlert(alertRecordOverflow)
c.in.freeBlock(b)
Expand Down
Loading

0 comments on commit 9e69c3a

Please sign in to comment.