Category Archives: burpsuite

Intercepting Belgian eID (PKCS#11) traffic with Burp Suite on OS X / Kali / Windows

TL;DR: You can configure Burp to use your PKCS#11 (or Belgian eID) card to set up client-authenticated SSL sessions, which you can then intercept and modify.

This blog post shows how you can easily view and modify your own, local traffic.  In order to complete this tutorial, you still need a valid eID card, and the corresponding PIN code. This article does not mean that there is a vulnerability in PKCS#11 or Belgian eID, it only shows that it is possible for research purposes.

We sometimes come across web applications that are only accessible if you have a valid Belgian eID card, which contains your public/private key. Of course, we still need to intercept the traffic with Burp, so we have to do some setting up. Because I always forget the proper way to do it, I decided to write it down and share it with the internets.

This guide was written for OS X, but I will add information for Windows & Kali too where it differs from OS X. This guide also assumes that you’ve correctly installed your eID card already, which is a whole challenge in itself…

The target

The Belgian Government has created a test page, which can be found here: http://www.test.eid.belgium.be/ . Once you click on the “Start Test”, you will be taken to the HTTPS version, which requires your client certificate. After entering your PIN code, you can view the result of the test:

Screen Shot 2018-01-15 at 13.15.41

The first thing to do is set your browser to use Burp as your proxy. This can easily be done by using FoxyProxy (FireFox)/SwitchyOmega (Chrome) or your system-wide proxy (shiver).

After setting up Burp, the site will not be able load your client certificate:

Screen Shot 2018-01-15 at 13.41.47

Configuring Burp

Setting up Burp is not too difficult. The main challenge is finding out the location of the PKCS#11 library file. I’ve listed the locations for OS X, Kali and Windows below.

  1. Insert your eID card into the reader and restart Burp
  2. Go to Project settings -> SSL Tab -> Override user options and click ‘Add’
  3. Host: <empty> (or be specific, if you want)
    Certificate type: Hardware token (PKCS#11)
    Screen Shot 2018-01-15 at 12.43.25
  4. Supply the path of the correct library. Here are some locations:
    1. OS X
      /usr/local/lib/beid-pkcs11.bundle/Contents/MacOS/libbeidpkcs11.dylib
      (simlinked to /usr/local/lib/libbeidpkcs11.4.3.5.dylib in my case. There might be multiple versions there, if one doesn’t work, try another)
    2. Windows
      C:\Windows\System32\beid_ff_pkcs11.dll or
      C:\Windows\System32\beidpkcs11.dll
      or use the auto search function
    3. Kali
      /usr/local/lib/libbeidpkcs11.so
      (see “building from source” below)
  5. If you get “Unable to load library – check file is correct and device is installed”, restart Burp with your eID already plugged in and working in the eID viewer.
  6. Enter your PIN, click refresh and select the Authentication certificate:
    Screen Shot 2018-01-15 at 12.44.15
  7. Optionally, restart FireFox / Burp (this fixed an issue once)

Et voila, we can now use Burp to intercept the traffic:

Screen Shot 2018-01-15 at 13.01.39

Building from source on Kali (Rolling, 2017.3)

Installing the default debian pacakge doesn’t seem to work, so we’ll have to compile from source. You can do this by following the steps listed below.

Note that we’ve had Kali VMs crash on boot after installing the dependencies below and compiling the source. An easy solution is to take a snapshot, compile, and copy over the .so, or use the one we compiled (libbeidpkcs11.so).

> wget https://eid.belgium.be/sites/default/files/software/eid-mw-4.3.3-v4.3.3.tar.gz
> tar -xvf eid-mw-4.3.3-v4.3.3.tar.gz
> cd eid-mw-4.3.3-v4.3.3
> apt-get install pkg-config libpcsclite-dev libgtk-3-dev libxml2-dev libproxy-dev libssl-dev libcurl4-gnutls-dev
> ./configure && make && make install

After these steps, you can find the .so library at /usr/local/lib/libbeidpkcs11.so.

About the author

AAEAAQAAAAAAAAYHAAAAJGUzZmUxMmVmLWY3M2MtNDRmNy05YzZlLWMxZTk1ZTE5MWYzMQ
Jeroen Beckers is a mobile security expert working in the NVISO Cyber Resilience team. He also loves to program, both on high and low level stuff, and deep diving into the Android internals doesn’t scare him. You can find Jeroen on LinkedIn.

 

“We are happy to share our knowledge with the community and thus hope you enjoyed the content provided on this article! If you’re interested in receiving dedicated support to help you improve your cyber security capabilities, please don’t hesitate to have a look at the services NVISO offers! We can help you define a cyber security strategy / roadmap, but can also offer highly technical services such as security assessments, security monitoring, threat hunting & incident response (https://www.nviso.be). Want to learn similar techniques? Have a look at the SEC599 SANS class, which was co-authored by NVISO’s experts! (https://www.sans.org/course/defeating-advanced-adversaries-kill-chain-defenses)”

Using a custom root CA with Burp for inspecting Android N traffic

TL;DR: Follow these steps to intercept traffic using Burp with a self made root CA on Android (or any browser)

The problem

In a previous blogpost, we presented a Magisk module that easily integrates user certificates into the system CA store in order to bypass Android N’s new hardened security model. For instrumenting applications, this works pretty well, and it has become a standard module on our pentest devices. The flow is really easy:

  1. Set up your WIFI to use Burp as your proxy
  2. Go to http://burp
  3. Download & install the certificate
  4. Reboot
  5. PROFIT

However, if we now open Chrome on the Android device, we get the following error: NET::ERR_CERT_VALIDITY_TOO_LONG.

If we take a look at the specifics of the certificate, we see that the certificate expires on Jan 11, 2023. A quick google search tells us that Google has chosen only to allow leaf certificates that expire within 39 months. This seems like a reasonable requirement, and after searching Portswigger’s site, the recommendation was to reissue the Burp CA certificate. Unfortunately, the problem persisted after doing so.

Burp also allows us to import a self made certificate + private key to be used instead of the automatically generated one. This sounds like an easy solution, as we can decrease the lifetime of the root CA, so it’s the next obvious step. In practice, it turns out to be a lot more difficult to get the configuration right than you would think. The goal of this blog post isn’t about all my failed attempts and why they failed, but about sparing you the trouble and giving you a working step-by-step guide to get this to work.

As a side note, this problem does not occur with the normal setup, where Burp’s root CA is added as a trusted user certificate. Chrome is only picky about “real” CA, which are evidently installed in the system root CA store. However, as I would like to have one certificate setup to rule them all, I searched for a solution…

The solution – Creating custom CA and importing it into Burp suite

I order to successfully install our custom root CA in both Burp and Android, we need to create a CA that has the v3_ca extension. The following steps are executed on a clean 14.04 Ubuntu installation. Granted, there are only a few steps to the processes, but that’s only because I’m not listing all my failed attempts.

# Keep it clean
> mkdir certificates && cd certificates

# Install openssl
> sudo apt-get install openssl

# Borrow the default openssl.cnf (location may differ, see note)
> cp /usr/lib/ssl/openssl.cnf ./

# Create a private key. 
# It's important to have the v3_ca extension and to supply the openssl.cnf file
> openssl req -x509 -days 730 -nodes -newkey rsa:2048 -outform der -keyout server.key -out ca.der -extensions v3_ca -config openssl.cnf
Generating a 2048 bit RSA private key
....+++
.............................+++
writing new private key to 'server.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:BE
State or Province Name (full name) [Some-State]:NVISO CA
Locality Name (eg, city) []:NVISO CA
Organization Name (eg, company) [Internet Widgits Pty Ltd]:NVISO CA
Organizational Unit Name (eg, section) []:NVISO CA
Common Name (e.g. server FQDN or YOUR name) []:NVISO CA
Email Address []:NVISO CA

# Convert to der format
> openssl rsa -in server.key -inform pem -out server.key.der -outform der
writing RSA key

# Convert key to pkcs8 format
> openssl pkcs8 -topk8 -in server.key.der -inform der -out server.key.pkcs8.der -outform der -nocrypt

Note: The openssl.cnf may be in a different place. Alternatively, you can download the default config from the openssl website.

Let’s take a quick look at the generated certificate:

> openssl x509 -in ca.der -inform der -noout -text
Certificate:
 Data:
 Version: 3 (0x2)
 Serial Number: 17570736880079538514 (0xf3d7cc1942ff0952)
 Signature Algorithm: sha256WithRSAEncryption
 Issuer: C=BE, ST=NVISO CA, L=NVISO CA, O=NVISO CA, OU=NVISO CA, CN=NVISO CA/emailAddress=NVISO CA
 Validity
 Not Before: Jan 11 16:23:19 2018 GMT
 Not After : Jan 11 16:23:19 2020 GMT
 Subject: C=BE, ST=NVISO CA, L=NVISO CA, O=NVISO CA, OU=NVISO CA, CN=NVISO CA/emailAddress=NVISO CA
 Subject Public Key Info:
 Public Key Algorithm: rsaEncryption
 Public-Key: (2048 bit)
 Modulus:
 00:d8:a8:f3:40:39:50:3e:7e:5d:25:e0:62:5d:c9:
 b1:f5:bb:d0:c5:40:5d:1b:68:f4:fc:e7:52:f9:36:
 a9:fa:78:97:76:eb:05:86:0e:70:54:3a:69:9c:e7:
 22:f7:dd:3a:20:71:ee:4a:f6:44:76:02:4f:bd:25:
 31:9f:32:5e:93:34:64:30:a5:6b:8e:79:4d:7d:06:
 e7:7f:fc:26:8f:1a:62:b4:65:08:46:4c:e1:ed:17:
 25:a8:d8:54:7c:61:3b:39:54:8f:f4:66:5f:0d:6f:
 aa:f0:e4:9e:50:af:f4:0b:6e:80:96:98:76:3a:b2:
 3f:a8:5a:92:ea:9d:7c:c3:c9:c5:47:c4:d9:56:e3:
 c0:43:83:3b:fb:08:6d:cf:c9:d0:29:61:1c:26:a3:
 b5:4c:76:bb:0c:88:5c:53:b8:84:31:4b:f8:a4:2e:
 25:29:09:cb:a8:a9:62:de:6e:61:f6:70:e8:85:52:
 34:08:20:d3:ca:ba:1c:81:e3:13:c6:00:d5:2c:3c:
 bd:20:0b:a2:e8:51:cc:e6:68:e1:ef:30:69:ae:fb:
 89:84:83:ad:ea:37:59:b5:f0:0c:30:d1:f9:b6:02:
 2e:12:8f:73:06:02:ed:c5:87:06:43:2d:58:7e:31:
 da:bb:b2:0a:15:ef:c7:19:aa:62:87:96:c0:2a:22:
 e4:03
 Exponent: 65537 (0x10001)
 X509v3 extensions:
 X509v3 Subject Key Identifier: 
 B9:CA:08:19:9A:5F:AE:63:3C:50:83:BC:A1:FA:36:00:B9:66:55:53
 X509v3 Authority Key Identifier: 
 keyid:B9:CA:08:19:9A:5F:AE:63:3C:50:83:BC:A1:FA:36:00:B9:66:55:53

X509v3 Basic Constraints: 
 CA:TRUE
 Signature Algorithm: sha256WithRSAEncryption
 04:33:11:54:aa:dc:f1:92:d6:30:88:89:0b:56:f6:07:ff:aa:
 28:65:21:aa:ea:72:3b:72:ba:3d:14:66:33:2d:67:de:80:23:
 10:0c:30:31:32:e0:6c:20:a6:6a:58:6f:d4:5b:db:fc:61:de:
 9d:d3:4e:66:1d:a1:ed:26:d4:1b:ce:a2:fc:4b:ab:d0:4f:04:
 2c:a8:e3:68:7d:e7:dc:04:3d:8c:31:85:e6:c2:d8:65:f0:f6:
 64:f2:23:ce:b1:91:43:34:57:97:e4:fd:79:79:f7:03:8b:1a:
 fc:42:ac:fe:78:26:25:aa:7b:65:2f:f8:4e:25:8e:e9:1e:ce:
 93:c8:02:ba:04:59:6c:0e:e4:f2:a8:2f:cd:69:58:42:28:ff:
 6f:7c:27:3c:b8:ed:2a:10:e2:36:bd:f5:b9:62:f1:8a:14:57:
 b8:2e:90:db:15:ce:f2:3a:79:57:f9:a4:76:ef:e9:08:0d:aa:
 1d:b9:eb:b9:08:cb:58:06:19:6d:ef:07:d9:25:f4:4d:a4:28:
 d3:db:ec:c1:5a:0f:40:3a:cf:49:44:d5:8d:b2:42:53:3a:35:
 55:0b:54:67:da:b4:13:dc:52:31:10:d4:8c:8d:7f:29:40:bb:
 dd:14:3c:c3:a3:66:24:95:64:91:a4:a8:74:a6:ad:92:fc:8c:
 87:38:31:03

The generated certificate has the v3_ca extension enabled, so we can import it into Android. Using our magisk module, you can install this certificate through the normal certificate installation flow, and after rebooting your device, the CA should be listed in the system CA store.

Screenshot_20180111-173557

The next step is importing these files into Burp. Go to the proxy settings page and choose “Import / Export CA Certificate” -> “Import” -> “Certificate and priate key in DER format”. The correct files to choose are `ca.der` and server.key.pkcs8.der:

burp

After installing the certificate, restart Burp just to be sure.

If everything worked, you’ll now have your custom root CA as a system certificate, and you can intercept all chrome traffic.

It took quite some time to figure out the correct procedure, so I hope I’ve at least saved someone else from spending hours trying to figure it out.

And, in order to help anyone searching for the correct answer, here’s a short overview of the problems I encountered:

  • NET::ERR_CERT_VALIDITY_TOO_LONG (-> Make sure your certificate’s validity is not longer than 39 months)
  • Custom root CA won’t install correctly on Android (-> Make sure it has the v3_ca extension)
  • Burp import errors (-> Follow the steps above for correct setup)
    • Failed to import certificate: java.security.cert.CertificateParsingException: signed fields invalid
    • Failed to import certificate: java.security.cert.CertificateException: Unable to initialize, java.io.IOException: extra data given to DerValue constructor
  • OS X / MacOS openssl: Error Loading extension section v3_ca (-> Copy the openssl.cnf file and manually add it as an argument with -config )

 

About the author

AAEAAQAAAAAAAAYHAAAAJGUzZmUxMmVmLWY3M2MtNDRmNy05YzZlLWMxZTk1ZTE5MWYzMQ
Jeroen Beckers is a mobile security expert working in the NVISO Cyber Resilience team. He also loves to program, both on high and low level stuff, and deep diving into the Android internals doesn’t scare him. You can find Jeroen on LinkedIn.