IDS monitoring of PKI certificate usage



  • I am interested in discussing the idea of using snort or suricata to monitor external systems being accessed with PKI encryption. The main reason for this is to implement active management of PKI certificates to reduce the chance that protected systems will inappropriately trust a certificate. If the IDS tracks the certificate used by an external server (i.e. pins the certificate), then any change would generate a IDS alert. If configured as an IPS, the alert would allow the IPS to stop the initial exchange of PKI packets and prevent an encrypted tunnel to a questionable external source.

    The pinned certificates could also be processed to determine the issuing CA. Each unexpected change to a server certificate could then also generate an IDS alert for that CA. At some threshold of CA alerts, the IPS could automatically block encrypted traffic for a questionable CA (generating a dynamic blacklist). Likewise, the IPS could block all encrypted traffic except for PKI certificates issued from a whitelist of trusted CAs. Any alerts for certificates not on whitelist could be used by security operations personnel to determine if they should add an CA to the whitelist. To ease the burden of qualifying CAs, the nominal list of CAs who passed the WebTrust audit could be maintained by the IDS and automatically added to the whitelist with an appropriate alert that could be reviewed as needed at a later date.

    Comments?



  • Its possible to do most of this with custom Suricata TLS/SSL rules

    https://redmine.openinfosecfoundation.org/projects/suricata/wiki/TLS-keywords

    -F



  • So, suricata does have monitoring of PKI certificates, but, this does not implement the PKI management. To do this you need

    • Tracking of encrypted FQDN, PKI certs used, last access, and usage count

    • Real-time trust analysis to IDS whitelisted CA store

    • Summary analysis of all PKI trust needed from IDS whitelisted CA store (including zero usage stats)

    • Alerts on change of FQDN to PKI cert

    • Alerts on new required CA trust, ie. not on current CA whitelist

    • and more….

    How do you add the managed lists necessary to implement dynamic PKI management by suricata? To implement a real-time capability, you need a fast search of those lists, so indexing seems to be called for too… Can all this be done via the scripting, or are additional code capabilities required?



  • Its more than monitoring…

    Enable TLS logging on the interface and create a noalert TLS rule that will save all certs info in /var/log/suricata/interface

    alert tls any any -> any any (msg:"No Alert TLS Store"; tls.subject:"CN="; tls.store; noalert; classtype:policy-violation; sid:5216010; rev:3;)

    Then do your Management with rules.

    Define your $TLS_USERS, $SSL_USERS, $TLS_SERVERS, etc…

    Define your whitelisted certs, domains, CA, CN etc..., validate with www.grc.com

    From any info on the tls.subject, tls.issuer, tls.issuerdn, tls.fingerprint you can write rules, and dont forget the negate action.

    Heres how a suricata TLS log looks like:

    192.168.1.50:42939 -> 208.123.73.69:443  TLS: Subject='OU=Domain Control Validated, OU=PositiveSSL Wildcard, CN=*.pfsense.org' Issuerdn='C=GB, ST=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO RSA Domain Validation Secure Server CA' SHA1='e3:43:2c:54:f5:8b:08:29:d7:e9:d7:32:29:8a:fe:12:32:f1:8a:42' VERSION='TLS 1.2'

    Some examples of rules:

    alert tls !$PFSENSE_USERS any -> any any (msg:"Alert on users not allowed to acces pfsense.org"; tls.subject:"CN=*.pfsense.org"; tls.fingerprint:"e3:43:2c:54:f5:8b:08:29:d7:e9:d7:32:29:8a:fe:12:32:f1:8a:42"; tls.store; classtype:policy-violation; sid:5216010; rev:3;)

    alert tls $PFSENSE_USERS any -> any any (msg:"Warning, wrong fingerprint"; tls.subject:"CN=*.pfsense.org"; tls.fingerprint:!"e3:43:2c:54:f5:8b:08:29:d7:e9:d7:32:29:8a:fe:12:32:f1:8a:42"; tls.store; classtype:policy-violation; sid:5216010; rev:3;)

    alert tls $PFSENSE_USERS any -> !208.123.73.69 443 (msg:"Alert on .pfsense.org IP change"; tls.subject:"CN=.pfsense.org"; tls.fingerprint:"e3:43:2c:54:f5:8b:08:29:d7:e9:d7:32:29:8a:fe:12:32:f1:8a:42"; tls.store; classtype:policy-violation; sid:5216010; rev:3;)

    alert tls $HOME_NET any -> 208.123.73.69 443 (msg:"Anomality, wrong CN in subject"; tls.subject:!"CN=*.pfsense.org"; tls.fingerprint:"e3:43:2c:54:f5:8b:08:29:d7:e9:d7:32:29:8a:fe:12:32:f1:8a:42"; tls.store; classtype:policy-violation; sid:5216010; rev:3;)

    alert tls $HOME_NET any -> 208.123.73.69 443 (msg:"The issuer is not from The Beatles wonderland"; tls.issuerdn:!"C=GB"; tls.store; classtype:policy-violation; sid:5216010; rev:3;)

    alert tls $HOME_NET any -> any $TLS_PORTS (msg:"Warning, Chinese Issuer"; tls.issuerdn:"C=CN"; tls.store; classtype:policy-violation; sid:5216010; rev:3;)

    alert tls any any -> 208.123.73.69 443 (msg:"Anomality, NOT COMODO"; tls.issuerdn:!"CN=COMODO RSA Domain Validation Secure Server CA"; tls.store; classtype:policy-violation; sid:5216010; rev:3;)

    alert tls any any -> !$PFSENSE_IPS 443 (msg:"pfsense.org have many IPs…"; tls.subject:"CN=*.pfsense.org"; tls.store; classtype:policy-violation; sid:5216010; rev:3;)

    alert tls $SSL_USERS any -> $SSL_ALLOWED_IPS 8085 (msg:"SSL Users allowed only on my servers, my port"; tls.store; classtype:policy-violation; sid:5216010; rev:3;)

    alert tls $HOME_NET any -> any ![443,995] (msg:"Encrypted trafic on illegal port"; tls.store; classtype:policy-violation; sid:5216010; rev:3;)

    alert ip $HOME_NET any -> $EXTERNAL_NET any (msg:"Ohh…FileMagic!"; filemagic:"OpenSSH RSA private key"; classtype:policy-violation; sid:5216010; rev:3;)

    you can even wilcard tls.keywords, ex: .google; this will match on www.google.fi, www.googleusercontent.com, api.google.ca, etc…

    alert tls any any -> any any (msg:"Warning, Google not from Google"; tls.subject:"CN=.google"; tls.issuerdn:!"CN=Google Internet Authority G2"; tls.store; classtype:policy-violation; sid:5216010; rev:3;)

    Right now its not possible to create a whitelisted.txt, like you can do with filemd5:
    http://blog.inliniac.net/2012/06/09/suricata-md5-blacklisting/

    Also, heres an example of fingerprint blacklist
    https://sslbl.abuse.ch/blacklist/sslblacklist.rules

    lua script it. You can look at the source code of the tls decoder rules for an example. Or heres an example about heartbleed:
    http://blog.inliniac.net/2014/04/08/detecting-openssl-heartbleed-with-suricata/

    You can do alot of policies as of now and for all that you cant do, create a suricata pluging that would do EV check, CA chains, revocation checks, WoT, etc…Ill be pleased to beta test your plugin :)

    F.



  • fsansfil, thanks for a a very detailed response. Suricata does have protocol knowledge of TLS.

    However, that information is NOT compiled into a higher level of understanding like I am looking for. Monitoring PKI certificate usage is intended to identify what can be trusted, versus what should be questioned (or blocked in the case of IPS). The trust information should be generated automatically from the history of certificate usage, and the content of those certificates.

    For instance, one idea is that remote end-point of encryption should not change.

    If past usage shows the FQDN  forum.pfsense.org was accessed 300 times, last on 31-March-2015, which used a certificate with serial number 00:C7:3C:D2:57:B4:01:32:FF:DD:56:F2:13:56:8A:BF:AF issued for "*.pfsense.org", and issued from the certificate authority "COMODO RSA Domain Validation Secure Server CA", then that 300 times of usage indicates the certificate was trusted (assuming end-point is required to check), and, by association that the intermediate CA was also used to trust that certificate (validated by another intermediate CA plus the root CA "AddTrust External CA Root").

    If any of those details change, I would like an alert to be generated with no rule writing required. This would be an implementation of PKI certificate pinning performed by an IDS that could protect all the end-points of the network, rather than some implementation done by the application that was using the PKI  (in this case, a browser on the end-point).

    With some post processing of the certificates, all the root and intermediate CA trust that a protected network is using could be identified. This would allow the implementation of a informed policy of CA trust. Instead of allowing a third party to decide which CAs to trust, an organization could make its own decisions and replace the vendor trust list with their own on all the end-points using PKI. For instance, I have blacklisted the CAs from China because of this https://threatpost.com/ca-linked-to-chinese-registrar-issued-unauthorized-google-certificates/111774.  However, I would prefer to have only the CAs I need to trust as trusted CAs.



  • Its a good idea and it would be a good addition to Suricata. Some sort of Certificate Reputation preprocs, based on usage/change history with revokation and CA checks. Not on the browsers or users end-point, like you said, but on a chockepoint/IPS of a network. Im not a developper, but pretty sure you could make pluggin for it.

    You may want to have a look at this too, its a decrypt daemon, but its good example of pluggin:
    https://github.com/plashchynski/viewssld

    F.



  • Hey guys,

    Found this while working on some rules;

    https://github.com/inliniac/suricata/tree/master/contrib/file_processor

    This directory contains what's needed for reading the JSON file /var/log/suricata/files-json.log and processing those entries against plugins.  Included are plugins for checking the MD5 of the observed file on the network against already created reports on anubis.iseclab.org, malwr.com, and threatexpert.com.  If you have a virustotal.com API key (free, though see the terms of use on virustotal.com/documentation/public-api/), you can enable the virustotal.com plugin and configure your API key so you can check the MD5 against over forty AV vendors' results.

    F.


Log in to reply