[Oisf-devel] [PATCH] Add TLS handshake decoder 0/3

Pierre Chifflier pierre.chifflier at ssi.gouv.fr
Tue Oct 25 12:10:57 UTC 2011


Hi,

Here is a patchset to add some support for extracting information from
the TLS handshake. The patches are based on the current master branch.

The goal is to be able to read the certificates and extract a few
keywords. This gives a few opportunities:
- using some kind of hash function, it's possible to test if a known
  certificate for a site changes,
- we can define some keywords on TLS records, for ex. extract the chosen
  cipher for the session. I'm intending to use this to be sure the server
  or the client are not trying to do some kine of downgrade attack with a
  weak cipher
- we can have some keywords on TLS certificates, to match some subjects
  etc.

It's /possible/ to use it to do some advanced things like decode the
session (knowing the private keys), but it's not what I'm discussing here.

Details
- -------

The first thing to do is to follow the TLS handshake to get the
SSLV3_HS_CERTIFICATE message (from the server). This message contains a
list of certificates, starting from the server certificate and
(optionaly) the chain up to the authority.
The only trick here is that TLS records can be fragmented across TCP
packets, and also packed (several records in one TCP packet, which can
be fragmented etc.). We get the server certificates and parse the list.

Now, we can focus on the certificate itself. The binary encoding
of a certificate is DER, which is a kind of TLV on an ASN.1 structure.
For more details, see the X690 documents from the ITU, especially
X.690-0207 for ASN.1/DER, and RFC 3280 for X509v3.
Reading the ASN.1 structure is not difficult by itself, we just build a
tree of items, which are nested sequences/sets/structured items and
primary types.
What can drive you nuts is parsing/understanding the values: the are
optional (implicit, explicit) items, context-specific items where the
type is determined by the knowledge of the structure, unknown ones etc.
The parser builds the tree structure with known items by reading them
recursively. Unknown types are handled (because the size is known) and
treated as blobs.
Then, with the structure, we can extract the fields from the
certificate. Some fields (like the CN) can be read directly (given the
position in the tree), while classical values like the Subject (or
Issuer) of the certificates are not direct values, but built by
iterating on the list of the corresponding node, and adding separators.

Finally, this is used to create a keyword in the parser (tls.subject),
searching the subject of the *first* certificate (the server) for a
substring match.

Example rule:
alert tls $HOME_NET any -> $EXTERNAL_NET 443
(tls.subject:www.google.com; msg:"test sig TLS Subject"; sid:8888890;
rev:1;)

The last patch also decode the SERVER_HELLO message, which contains some
information on the protocol (ciphersuite) and compression chosen by the
server during the negotiation. Some keywords will also be added to match
that, they are not yet added due to the complexity to easily handle the
multiple protocol families, key lengths, and cipher suite names.

Note that app-layer-ssl.c (which is badly named, it really should be
app-layer-tls.c) should be heavily changed to handle properly TLS
records fragmentation, size, etc. It is not yet done to keep patches as
simple as possible, and readable.

BR,
Pierre


More information about the Oisf-devel mailing list