Mobile SSL Interception
in the Wild
Where, how, and why?
Alban Diquet
Thomas Sileo
Data Theorem BlueHat 2017
Mobile SSL Interception
• Analyzed 10 million “SSL incident" reports

• Sent by mobile devices all around the world

• What did we find?
DEMO
Agenda
• Data collection methodology

• Data set and analysis of forged SSL certificates

• Results of the analysis

• Conclusion
Data Collection
Methodology
TrustKit
• Open-source library for SSL reporting and pinning

• Released for iOS in 2015 and for Android earlier this
year

• https://github.com/datatheorem/TrustKit 

• Makes it easy to monitor and improve the security of the
app’s network connections
SSL Pinning
• Hardcode in the app the SSL public key(s) to be expected
to be used by the app’s server(s)
SSL Pinning
SSL Pinning
SSL Pinning
lCppFqbkrlJ3EcVFAkeip0+44VaoJUymbnOaEUk7tEU=
SSL Pinning
• Hardcode in the app the SSL public key(s) to be expected
to be used by the app’s server(s)
SSL Pinning
• Hardcode in the app the SSL public key(s) to be expected
to be used by the app’s server(s)
// Initialize TrustKit
NSDictionary *trustKitConfig =
@{
kTSKPinnedDomains: @{
@"www.datatheorem.com" : @{
kTSKPublicKeyHashes : @[
@"lCppFqbkrlJ3EcVFAkeip0+44VaoJUymbnOaEUk7tEU=",
@"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY=",
]
}}};
[TrustKit initializeWithConfiguration:trustKitConfig];
SSL Pinning
• Hardcode in the app the SSL public key(s) to be expected
to be used by the app’s server(s)
// Initialize TrustKit
NSDictionary *trustKitConfig =
@{
kTSKPinnedDomains: @{
@"www.datatheorem.com" : @{
kTSKPublicKeyHashes : @[
@"lCppFqbkrlJ3EcVFAkeip0+44VaoJUymbnOaEUk7tEU=",
@"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY=",
]
}}};
[TrustKit initializeWithConfiguration:trustKitConfig];
SSL Reporting
• Send a report whenever an SSL error occurred

• Gives an overview of "SSL incidents" around the world

• Helps understanding connection errors across the user
base

• Helps making a decision on whether to deploy SSL
pinning

• Useful to all apps
SSL Incident
• Default SSL validation error

• Name mismatch, expired certificate,
untrusted CA, etc.

• Pinning validation error
App Server
SSL Reporting
{
"app-bundle-id": "com.datatheorem.testtrustkit",
"app-version": “1.2",
"app-vendor-id": "599F9C00-92DC-4B5C-9464-7971F01F8370",
"app-platform": "IOS",
"trustkit-version": “1.5.3",
"hostname": "www.datatheorem.com",
"port": 443,
"noted-hostname": "datatheorem.com",
"include-subdomains": true,
"enforce-pinning": true,
"validated-certificate-chain": [
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----"
],
"date-time": "2015-06-08T01:58:05Z",
"known-pins": [
"pin-sha256="rFjc3wG7lTZe43zeYTvPq8k4xdDEutCmIhI5dn4oCeE="",
"pin-sha256="TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY=""
],
"validation-result": 1
}
SSL Reporting
• Any domain can be configured in TrustKit for where the
reports should be sent

• Data Theorem hosts one for free that developers can leverage

• Reporting dashboard to see trends and inspect individual
reports

• Notifications for when something unexpected happens

• Suspicious actor

• Spike in reports
Demo
Data Set and Report
Classification
The Data Set
• 10 million reports from 2 million devices in 2 years

• From apps configured to use Data Theorem’s reporting
server

• Mostly from iOS devices

• 70% of the reports came from the US

The Data Set
• From nearly 2 000 different apps

• Banking

• Shopping

• Music/streaming

• News
Top Platform
iOS 93.3%
Android 5.3%
macOS 1%
tvOS 0.4%
The Data Set
Top Countries
US 71%
GB 9.5%
TW 7.3%
CA 1.8%
HK 1.3%
The Data Set
• 3.3 million unique
certificate chains

• 38% of the certificate are
self-signed

• 78% of the certificate
matched the hostname
Certificate chain depth
2 62.2%
3 24%
1 11.4%
4 1.8%
5 0.5%
6 0.001%
Report Classification
• Use different heuristics to find the root cause

• By looking at the content of the report, mainly the
certificate chain

• Save some metadata along with the server date

• Contact the server for the hostname that was in the
report, to fetch its certificate chain
Report Classification
• Re-verify the certificate chain

• Set of rules that can target:

• A specific certificate or a specific public key

• Any certificate fields (Common Name, etc.)
Report Classification
{
"app-bundle-id": "com.datatheorem.pin_misconfig",
"hostname": "www.datatheorem.com",
"date-time": "2017-05-12T06:00:22Z",
"validated-certificate-chain": [
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----"
],
"validation-result": 1,
"…": […],
"…": […],
"server_certificate_chain": [
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
“-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----"
],
"received_at”: “2017-05-12T06:00:25Z",
}
raw report
report metadata
Report Classification
{
"app-bundle-id": "com.datatheorem.pin_misconfig",
"hostname": "www.datatheorem.com",
"date-time": "2017-05-12T06:00:22Z",
"validated-certificate-chain": [
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----"
],
"validation-result": 1,
"…": […],
"…": […],
"server_certificate_chain": [
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
“-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----"
],
"received_at”: “2017-05-12T06:00:25Z",
}
raw report
report metadata
Report Classification
{
"app-bundle-id": "com.datatheorem.pin_misconfig",
"hostname": "www.datatheorem.com",
"date-time": "2017-05-12T06:00:22Z",
"validated-certificate-chain": [
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----"
],
"validation-result": 1,
"…": […],
"…": […],
"server_certificate_chain": [
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
“-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----"
],
"received_at”: “2017-05-12T06:00:25Z",
}
raw report
report metadata
Report Classification
{
"app-bundle-id": "com.datatheorem.pin_misconfig",
"hostname": "www.datatheorem.com",
"date-time": "2017-05-12T06:00:22Z",
"validated-certificate-chain": [
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----"
],
"validation-result": 1,
"…": […],
"…": […],
"server_certificate_chain": [
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
“-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----"
],
"received_at”: “2017-05-12T06:00:25Z",
}
raw report
report metadata
Report Classification
{
"app-bundle-id": "com.datatheorem.pin_misconfig",
"hostname": "www.datatheorem.com",
"date-time": "2017-05-12T06:00:22Z",
"validated-certificate-chain": [
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----"
],
"validation-result": 1,
"…": […],
"…": […],
"server_certificate_chain": [
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
“-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----"
],
"received_at”: “2017-05-12T06:00:25Z",
}
raw report
report metadata
==
misconfiguration / certificate_chain_valid
Report Classification
{
"app-bundle-id": "com.datatheorem.pin_misconfig",
"hostname": "www.datatheorem.com",
"date-time": "2017-05-12T06:00:22Z",
"validated-certificate-chain": [
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----"
],
"validation-result": 1,
"…": […],
"…": […],
"server_certificate_chain": [
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
“-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----"
],
"received_at”: “2017-05-12T06:00:25Z",
}
raw report
report metadata
unknown / to_review
!=
Report Classification
{
"app-bundle-id": “com.datatheorem.coporate_proxy",
"hostname": "www.datatheorem.com",
“validated-certificate-chain”: [
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----"
],
"date-time": "2017-03-03T21:27:12Z",
"validation-result": 1,
"...": “…",
raw report
{
"app-bundle-id": “com.datatheorem.coporate_proxy",
"hostname": "www.datatheorem.com",
“validated-certificate-chain”: [
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----"
],
"date-time": "2017-03-03T21:27:12Z",
"validation-result": 1,
"...": “…",
Report Classification
raw report
{
"app-bundle-id": “com.datatheorem.coporate_proxy",
"hostname": "www.datatheorem.com",
“validated-certificate-chain”: [
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----"
],
"date-time": "2017-03-03T21:27:12Z",
"validation-result": 1,
"...": “…",
Report Classification
raw report
Report Classification
{
"app-bundle-id": “com.datatheorem.coporate_proxy",
"hostname": "www.datatheorem.com",
“validated-certificate-chain”: [
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----"
],
"date-time": "2017-03-03T21:27:12Z",
"validation-result": 1,
"...": “…",
{
"certificate_chain_infos": [
{"issuer":
{"common_name":"Fortigate CA",
“…": […],
raw report
certificate chain info
Report Classification
corporate_appliance / Fortinet
corporate_appliance:
Fortinet:
leaf:
- !IssuerCommonName 'FortiGate CA'
{
"certificate_chain_infos": [
{"issuer":
{"common_name":"Fortigate CA",
“…": […],
certificate chain info
classifier ruleset
Report Classification
{
"app-bundle-id": “com.datatheorem.bad_device_clock”,
"hostname": "www.datatheorem.com",
"date-time": "2017-03-14T04:00:22Z",
"validated-certificate-chain": [
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----"
],
"validation-result": 2,
"…": […],
"…": […],
"server_certificate_chain": [
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
“-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----"
],
"received_at”: “2017-05-22T04:00:54Z",
}
raw report
report metadata
Report Classification
{
"app-bundle-id": “com.datatheorem.bad_device_clock”,
"hostname": "www.datatheorem.com",
"date-time": "2017-03-14T04:00:22Z",
"validated-certificate-chain": [
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----"
],
"validation-result": 2,
"…": […],
"…": […],
"server_certificate_chain": [
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
“-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----"
],
"received_at”: “2017-05-22T04:00:54Z",
}
raw report
report metadata
Report Classification
{
"app-bundle-id": “com.datatheorem.bad_device_clock”,
"hostname": "www.datatheorem.com",
"date-time": "2017-03-14T04:00:22Z",
"validated-certificate-chain": [
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----"
],
"validation-result": 2,
"…": […],
"…": […],
"server_certificate_chain": [
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
“-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----"
],
"received_at”: “2017-05-22T04:00:54Z",
}
raw report
report metadata
Report Classification
{
"app-bundle-id": “com.datatheorem.bad_device_clock”,
"hostname": "www.datatheorem.com",
"date-time": "2017-03-14T04:00:22Z",
"validated-certificate-chain": [
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----"
],
"validation-result": 2,
"…": […],
"…": […],
"server_certificate_chain": [
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
“-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----",
"-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----"
],
"received_at”: “2017-05-22T04:00:54Z",
}
raw report
report metadata
misconfigured_device / bad_clock
Results of the
Analysis
Classification Categories
9 195 807 reports
Classification Categories
9 195 807 reports
Captive Portals 11%
Not Reviewed Yet 6%
Unknown 2.5%
Client Clock Misconfig 0.5%
Server Misconfig 4.3%
Previous Work
• Data from Chrome desktop for google.com:
Classification Categories
9 195 807 reports
Captive Portals 11%
Not Reviewed Yet 6%
Unknown 2.5%
Client Clock Misconfig 0.5%
Server Misconfig 4.3%
Classification Categories
9 195 807 reports
Server Misconfig 4.3%
Server Misconfiguration
• Category for servers with misconfigured SSL certificates

• Right now only one subcategory: expired certificates

• For example, huge spike of report when a certificate
deployed in production expired:
Classification Categories
9 195 807 reports
Captive Portals 11%
Not Reviewed Yet 6%
Unknown 2.5%
Client Clock Misconfig 0.5%
Server Misconfig 4.3%
Classification Categories
9 195 807 reports
Spyware 39%
Pins Misconfig 34%
Captive Portals 11%
Not Reviewed Yet 6%
Server Misconfig 4.3%
Corp Networks 2.2%
Unknown 2.5%
Client Clock Misconfig 0.5%
Dev Artifacts 0.5%
Classification Categories
9 195 807 reports
Spyware 39%
Pins Misconfig 34%
Dev Artifacts 0.5%
Corp Networks 2.2%
Classification Categories
9 195 807 reports
Corp Networks 2.2%
Corporate Networks
Classification Categories
9 195 807 reports
Spyware 39%
Pins Misconfig 34%
Dev Artifacts 0.5%
Corp Networks 2.2%
Classification Categories
9 195 807 reports
Dev Artifacts 0.5%
Dev Proxies
Classification Categories
9 195 807 reports
Spyware 39%
Pins Misconfig 34%
Dev Artifacts 0.5%
Corp Networks 2.2%
Classification Categories
9 195 807 reports
Pins Misconfig 34%
Pins Misconfiguration
• The SSL pins hardcoded in the app do not match the
server’s certificate chain

• With enforcement disabled:

• The app still works but is constantly sending reports

• With enforcement enabled:

• The app’s connections will fail
Pins Misconfiguration
“On a Thanksgiving Day, November 24, 2016 an
emergency has occurred.
Customers of Barclays Bank, which were users of
mobile banking application, were unable to perform
any transactions due to pinning the outdated
intermediate certificate in the application.”
Pins Misconfiguration
“Several thousands of customers of small and
medium-sized businesses, operating mostly in the
UK market, will not be able to perform any
transactions from 8.30 a.m. 25/11/16 on a "Black
Friday" and during the holiday shopping period.
This will affect hundreds of thousands of
customer's transactions, until the application is
updated, and then released again.”
Pins Misconfiguration
• 22% of apps with more than 30% of misconfiguration
issues

• Pressure on mobile developers to implement SSL pinning
in their apps

• From security teams, bug bounties, etc.

• But most apps do not need it

• Requires not just code changes but also very good
processes around server SSL keys
Global Categories
9 195 807 reports
Spyware 39%
Pins Misconfig 34%
Server Misconfig 4.3%
Dev Artifacts 0.5%
Corp Networks 2.2%
Classification Categories
9 195 807 reports
Spyware 39%
Spyware Categories
Market Intelligence

3 580 078 reports
Ad Blocker

18 463 reports
Parental Control

10 820 reports
Spyware Categories
Market Intelligence

3 580 078 reports
MobileXpression 91%
Digital Reflection 4%
Verto Analytics 3.3%
Luth 1.4%
AnalyzeMe 0.3%
Ad Blocker

18 463 reports
Parental Control

10 820 reports
Spyware - Market Intel
• Mainly investigated MobileXpression and Digital
Reflection

• Large number of reports across ~20 000 devices
MobileXpression
Demo
MobileXpression
What Happened?
• A configuration profile was installed on the device

• With an always-on VPN config

• To route all traffic through the MobileXpression server

• With a custom root CA added to the device’s trust store

• To allow traffic decryption by the MobileXpression server
MobileXpression VPN App Server
MobileXpression?
“MobileXpression is a service of comScore, Inc., a
global leader in measuring the digital world,
providing insights into consumer behavior and
attitudes.”
ComScore
“This capability is based on a massive, global
cross-section of approximately 2 million
consumers, who have allowed comScore to collect
their online browsing, hardware and application
usage, and purchasing behavior.”
ComScore
• Owner of several “market research” apps

• MobileXpression, Digital Reflection

• Promise users rewards (gif cards, etc.) for installing the
app and configuration profile
ComScore
• Owner of several “market research” apps

• MobileXpression, Digital Reflection

• Promise users rewards (gif cards, etc.) for installing the
app and configuration profile
ComScore
• Inspect/decrypt all the users’ traffic to measure app
usage

• ComScore’s business model as a "measurement
company”
Spyware - Market Intel
• Configuration profiles are problematic

• Highly technical security warnings when installing the profile

• The profile/VPN does not get uninstalled when removing the app

• Makes sense from a technical perspective but will confuse users

• But not an easy issue to fix

• Corporate enrollment / MDM use case

• A profile can be installed directly via Safari

• Banning the spyware app from the store does not prevent it
Spyware Categories
Market Intelligence

3 580 078 reports
Ad Blocker

18 463 reports
Parental Control

10 820 reports
Spyware Categories
Market Intelligence

3 580 078 reports
Parental Control

10 820 reports
Ad Blocker

18 463 reports
Defend My WiFi 59%
AdBl0ck 34%
AdGuard 7%
Spyware - Ad Blocker
• Similar technical implementation with a VPN and custom CA

• Defend My WiFi

• "Automatically turns public Wi-Fi into safe and secure private
WiFi”

• Company does not exist anymore?

• Adblock Mobile

• iOS 8: SSL mitm on ad domains only

• iOS 9+: No more custom CA installed
Spyware Categories
Market Intelligence

3 580 078 reports
Ad Blocker

18 463 reports
Parental Control

10 820 reports
Spyware Categories
Market Intelligence

3 580 078 reports
Ad Blocker

18 463 reports
Parental Control

10 820 reports
Qustodio 74%
Accountable2You 24%
Circle Go 2%
Spyware - Parental Control
• Qustodio, Accountable2You, Circle Go

• Parental control/monitoring tools
Conclusion
What did we see?
• Traffic interception does happen, and for many reasons

• Usually not malicious

• Employers

• Users “willingly” sharing their data for a reward

• No visible move from Apple and Google on this

• Similarities and differences compared to previous work
on the web/desktop (Google, Facebook, Cloudflare)
What do we do?
• Which group does your app belong to?

• It is acceptable to expose the user’s data to “lawful
interception” (such as the user’s employer)

• Games, Business apps

• The user’s data is private and can never be exposed

• Mobile banking

• Can be technically enforced via SSL pinning
What do we do?
• More options on mobile compared to the web

• SSL reporting helps you understand what is happening
across your user base

• SSL pinning can be used for sensitive apps

• Significant burden and risk of catastrophic failure

• Must be decided and planned carefully

• Does not prevent reverse-engineering of your app
Thanks!
@nabla_c0d3
@trucsdedev

BlueHat v17 || Where, how, and why is SSL traffic on mobile getting intercepted? A look at three million real-world SSL incidents

  • 1.
    Mobile SSL Interception inthe Wild Where, how, and why? Alban Diquet Thomas Sileo Data Theorem BlueHat 2017
  • 2.
    Mobile SSL Interception •Analyzed 10 million “SSL incident" reports • Sent by mobile devices all around the world • What did we find?
  • 3.
  • 4.
    Agenda • Data collectionmethodology • Data set and analysis of forged SSL certificates • Results of the analysis • Conclusion
  • 5.
  • 6.
    TrustKit • Open-source libraryfor SSL reporting and pinning • Released for iOS in 2015 and for Android earlier this year • https://github.com/datatheorem/TrustKit • Makes it easy to monitor and improve the security of the app’s network connections
  • 7.
    SSL Pinning • Hardcodein the app the SSL public key(s) to be expected to be used by the app’s server(s)
  • 8.
  • 9.
  • 10.
  • 11.
    SSL Pinning • Hardcodein the app the SSL public key(s) to be expected to be used by the app’s server(s)
  • 12.
    SSL Pinning • Hardcodein the app the SSL public key(s) to be expected to be used by the app’s server(s) // Initialize TrustKit NSDictionary *trustKitConfig = @{ kTSKPinnedDomains: @{ @"www.datatheorem.com" : @{ kTSKPublicKeyHashes : @[ @"lCppFqbkrlJ3EcVFAkeip0+44VaoJUymbnOaEUk7tEU=", @"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY=", ] }}}; [TrustKit initializeWithConfiguration:trustKitConfig];
  • 13.
    SSL Pinning • Hardcodein the app the SSL public key(s) to be expected to be used by the app’s server(s) // Initialize TrustKit NSDictionary *trustKitConfig = @{ kTSKPinnedDomains: @{ @"www.datatheorem.com" : @{ kTSKPublicKeyHashes : @[ @"lCppFqbkrlJ3EcVFAkeip0+44VaoJUymbnOaEUk7tEU=", @"TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY=", ] }}}; [TrustKit initializeWithConfiguration:trustKitConfig];
  • 14.
    SSL Reporting • Senda report whenever an SSL error occurred • Gives an overview of "SSL incidents" around the world • Helps understanding connection errors across the user base • Helps making a decision on whether to deploy SSL pinning • Useful to all apps
  • 15.
    SSL Incident • DefaultSSL validation error • Name mismatch, expired certificate, untrusted CA, etc. • Pinning validation error App Server
  • 16.
    SSL Reporting { "app-bundle-id": "com.datatheorem.testtrustkit", "app-version":“1.2", "app-vendor-id": "599F9C00-92DC-4B5C-9464-7971F01F8370", "app-platform": "IOS", "trustkit-version": “1.5.3", "hostname": "www.datatheorem.com", "port": 443, "noted-hostname": "datatheorem.com", "include-subdomains": true, "enforce-pinning": true, "validated-certificate-chain": [ "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----" ], "date-time": "2015-06-08T01:58:05Z", "known-pins": [ "pin-sha256="rFjc3wG7lTZe43zeYTvPq8k4xdDEutCmIhI5dn4oCeE="", "pin-sha256="TQEtdMbmwFgYUifM4LDF+xgEtd0z69mPGmkp014d6ZY="" ], "validation-result": 1 }
  • 17.
    SSL Reporting • Anydomain can be configured in TrustKit for where the reports should be sent • Data Theorem hosts one for free that developers can leverage • Reporting dashboard to see trends and inspect individual reports • Notifications for when something unexpected happens • Suspicious actor • Spike in reports
  • 18.
  • 19.
    Data Set andReport Classification
  • 20.
    The Data Set •10 million reports from 2 million devices in 2 years • From apps configured to use Data Theorem’s reporting server • Mostly from iOS devices • 70% of the reports came from the US

  • 21.
    The Data Set •From nearly 2 000 different apps • Banking • Shopping • Music/streaming • News Top Platform iOS 93.3% Android 5.3% macOS 1% tvOS 0.4%
  • 22.
    The Data Set TopCountries US 71% GB 9.5% TW 7.3% CA 1.8% HK 1.3%
  • 23.
    The Data Set •3.3 million unique certificate chains • 38% of the certificate are self-signed • 78% of the certificate matched the hostname Certificate chain depth 2 62.2% 3 24% 1 11.4% 4 1.8% 5 0.5% 6 0.001%
  • 24.
    Report Classification • Usedifferent heuristics to find the root cause • By looking at the content of the report, mainly the certificate chain • Save some metadata along with the server date • Contact the server for the hostname that was in the report, to fetch its certificate chain
  • 25.
    Report Classification • Re-verifythe certificate chain • Set of rules that can target: • A specific certificate or a specific public key • Any certificate fields (Common Name, etc.)
  • 26.
    Report Classification { "app-bundle-id": "com.datatheorem.pin_misconfig", "hostname":"www.datatheorem.com", "date-time": "2017-05-12T06:00:22Z", "validated-certificate-chain": [ "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----" ], "validation-result": 1, "…": […], "…": […], "server_certificate_chain": [ "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", “-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----" ], "received_at”: “2017-05-12T06:00:25Z", } raw report report metadata
  • 27.
    Report Classification { "app-bundle-id": "com.datatheorem.pin_misconfig", "hostname":"www.datatheorem.com", "date-time": "2017-05-12T06:00:22Z", "validated-certificate-chain": [ "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----" ], "validation-result": 1, "…": […], "…": […], "server_certificate_chain": [ "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", “-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----" ], "received_at”: “2017-05-12T06:00:25Z", } raw report report metadata
  • 28.
    Report Classification { "app-bundle-id": "com.datatheorem.pin_misconfig", "hostname":"www.datatheorem.com", "date-time": "2017-05-12T06:00:22Z", "validated-certificate-chain": [ "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----" ], "validation-result": 1, "…": […], "…": […], "server_certificate_chain": [ "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", “-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----" ], "received_at”: “2017-05-12T06:00:25Z", } raw report report metadata
  • 29.
    Report Classification { "app-bundle-id": "com.datatheorem.pin_misconfig", "hostname":"www.datatheorem.com", "date-time": "2017-05-12T06:00:22Z", "validated-certificate-chain": [ "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----" ], "validation-result": 1, "…": […], "…": […], "server_certificate_chain": [ "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", “-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----" ], "received_at”: “2017-05-12T06:00:25Z", } raw report report metadata
  • 30.
    Report Classification { "app-bundle-id": "com.datatheorem.pin_misconfig", "hostname":"www.datatheorem.com", "date-time": "2017-05-12T06:00:22Z", "validated-certificate-chain": [ "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----" ], "validation-result": 1, "…": […], "…": […], "server_certificate_chain": [ "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", “-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----" ], "received_at”: “2017-05-12T06:00:25Z", } raw report report metadata == misconfiguration / certificate_chain_valid
  • 31.
    Report Classification { "app-bundle-id": "com.datatheorem.pin_misconfig", "hostname":"www.datatheorem.com", "date-time": "2017-05-12T06:00:22Z", "validated-certificate-chain": [ "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----" ], "validation-result": 1, "…": […], "…": […], "server_certificate_chain": [ "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", “-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----" ], "received_at”: “2017-05-12T06:00:25Z", } raw report report metadata unknown / to_review !=
  • 32.
    Report Classification { "app-bundle-id": “com.datatheorem.coporate_proxy", "hostname":"www.datatheorem.com", “validated-certificate-chain”: [ "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----" ], "date-time": "2017-03-03T21:27:12Z", "validation-result": 1, "...": “…", raw report
  • 33.
    { "app-bundle-id": “com.datatheorem.coporate_proxy", "hostname": "www.datatheorem.com", “validated-certificate-chain”:[ "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----" ], "date-time": "2017-03-03T21:27:12Z", "validation-result": 1, "...": “…", Report Classification raw report
  • 34.
    { "app-bundle-id": “com.datatheorem.coporate_proxy", "hostname": "www.datatheorem.com", “validated-certificate-chain”:[ "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----" ], "date-time": "2017-03-03T21:27:12Z", "validation-result": 1, "...": “…", Report Classification raw report
  • 35.
    Report Classification { "app-bundle-id": “com.datatheorem.coporate_proxy", "hostname":"www.datatheorem.com", “validated-certificate-chain”: [ "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----" ], "date-time": "2017-03-03T21:27:12Z", "validation-result": 1, "...": “…", { "certificate_chain_infos": [ {"issuer": {"common_name":"Fortigate CA", “…": […], raw report certificate chain info
  • 36.
    Report Classification corporate_appliance /Fortinet corporate_appliance: Fortinet: leaf: - !IssuerCommonName 'FortiGate CA' { "certificate_chain_infos": [ {"issuer": {"common_name":"Fortigate CA", “…": […], certificate chain info classifier ruleset
  • 37.
    Report Classification { "app-bundle-id": “com.datatheorem.bad_device_clock”, "hostname":"www.datatheorem.com", "date-time": "2017-03-14T04:00:22Z", "validated-certificate-chain": [ "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----" ], "validation-result": 2, "…": […], "…": […], "server_certificate_chain": [ "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", “-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----" ], "received_at”: “2017-05-22T04:00:54Z", } raw report report metadata
  • 38.
    Report Classification { "app-bundle-id": “com.datatheorem.bad_device_clock”, "hostname":"www.datatheorem.com", "date-time": "2017-03-14T04:00:22Z", "validated-certificate-chain": [ "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----" ], "validation-result": 2, "…": […], "…": […], "server_certificate_chain": [ "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", “-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----" ], "received_at”: “2017-05-22T04:00:54Z", } raw report report metadata
  • 39.
    Report Classification { "app-bundle-id": “com.datatheorem.bad_device_clock”, "hostname":"www.datatheorem.com", "date-time": "2017-03-14T04:00:22Z", "validated-certificate-chain": [ "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----" ], "validation-result": 2, "…": […], "…": […], "server_certificate_chain": [ "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", “-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----" ], "received_at”: “2017-05-22T04:00:54Z", } raw report report metadata
  • 40.
    Report Classification { "app-bundle-id": “com.datatheorem.bad_device_clock”, "hostname":"www.datatheorem.com", "date-time": "2017-03-14T04:00:22Z", "validated-certificate-chain": [ "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----" ], "validation-result": 2, "…": […], "…": […], "server_certificate_chain": [ "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", “-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----", "-----BEGIN CERTIFICATE-----n[…]n-----END CERTIFICATE-----" ], "received_at”: “2017-05-22T04:00:54Z", } raw report report metadata misconfigured_device / bad_clock
  • 41.
  • 42.
  • 43.
    Classification Categories 9 195807 reports Captive Portals 11% Not Reviewed Yet 6% Unknown 2.5% Client Clock Misconfig 0.5% Server Misconfig 4.3%
  • 44.
    Previous Work • Datafrom Chrome desktop for google.com:
  • 45.
    Classification Categories 9 195807 reports Captive Portals 11% Not Reviewed Yet 6% Unknown 2.5% Client Clock Misconfig 0.5% Server Misconfig 4.3%
  • 46.
    Classification Categories 9 195807 reports Server Misconfig 4.3%
  • 47.
    Server Misconfiguration • Categoryfor servers with misconfigured SSL certificates • Right now only one subcategory: expired certificates • For example, huge spike of report when a certificate deployed in production expired:
  • 48.
    Classification Categories 9 195807 reports Captive Portals 11% Not Reviewed Yet 6% Unknown 2.5% Client Clock Misconfig 0.5% Server Misconfig 4.3%
  • 49.
    Classification Categories 9 195807 reports Spyware 39% Pins Misconfig 34% Captive Portals 11% Not Reviewed Yet 6% Server Misconfig 4.3% Corp Networks 2.2% Unknown 2.5% Client Clock Misconfig 0.5% Dev Artifacts 0.5%
  • 50.
    Classification Categories 9 195807 reports Spyware 39% Pins Misconfig 34% Dev Artifacts 0.5% Corp Networks 2.2%
  • 51.
    Classification Categories 9 195807 reports Corp Networks 2.2%
  • 52.
  • 53.
    Classification Categories 9 195807 reports Spyware 39% Pins Misconfig 34% Dev Artifacts 0.5% Corp Networks 2.2%
  • 54.
    Classification Categories 9 195807 reports Dev Artifacts 0.5%
  • 55.
  • 56.
    Classification Categories 9 195807 reports Spyware 39% Pins Misconfig 34% Dev Artifacts 0.5% Corp Networks 2.2%
  • 57.
    Classification Categories 9 195807 reports Pins Misconfig 34%
  • 58.
    Pins Misconfiguration • TheSSL pins hardcoded in the app do not match the server’s certificate chain • With enforcement disabled: • The app still works but is constantly sending reports • With enforcement enabled: • The app’s connections will fail
  • 59.
  • 60.
    “On a ThanksgivingDay, November 24, 2016 an emergency has occurred. Customers of Barclays Bank, which were users of mobile banking application, were unable to perform any transactions due to pinning the outdated intermediate certificate in the application.”
  • 61.
  • 62.
    “Several thousands ofcustomers of small and medium-sized businesses, operating mostly in the UK market, will not be able to perform any transactions from 8.30 a.m. 25/11/16 on a "Black Friday" and during the holiday shopping period. This will affect hundreds of thousands of customer's transactions, until the application is updated, and then released again.”
  • 63.
    Pins Misconfiguration • 22%of apps with more than 30% of misconfiguration issues • Pressure on mobile developers to implement SSL pinning in their apps • From security teams, bug bounties, etc. • But most apps do not need it • Requires not just code changes but also very good processes around server SSL keys
  • 64.
    Global Categories 9 195807 reports Spyware 39% Pins Misconfig 34% Server Misconfig 4.3% Dev Artifacts 0.5% Corp Networks 2.2%
  • 65.
    Classification Categories 9 195807 reports Spyware 39%
  • 66.
    Spyware Categories Market Intelligence
 3580 078 reports Ad Blocker
 18 463 reports Parental Control
 10 820 reports
  • 67.
    Spyware Categories Market Intelligence
 3580 078 reports MobileXpression 91% Digital Reflection 4% Verto Analytics 3.3% Luth 1.4% AnalyzeMe 0.3% Ad Blocker
 18 463 reports Parental Control
 10 820 reports
  • 68.
    Spyware - MarketIntel • Mainly investigated MobileXpression and Digital Reflection • Large number of reports across ~20 000 devices
  • 69.
  • 70.
  • 71.
  • 72.
    What Happened? • Aconfiguration profile was installed on the device • With an always-on VPN config • To route all traffic through the MobileXpression server • With a custom root CA added to the device’s trust store • To allow traffic decryption by the MobileXpression server MobileXpression VPN App Server
  • 73.
    MobileXpression? “MobileXpression is aservice of comScore, Inc., a global leader in measuring the digital world, providing insights into consumer behavior and attitudes.”
  • 74.
    ComScore “This capability isbased on a massive, global cross-section of approximately 2 million consumers, who have allowed comScore to collect their online browsing, hardware and application usage, and purchasing behavior.”
  • 75.
    ComScore • Owner ofseveral “market research” apps • MobileXpression, Digital Reflection • Promise users rewards (gif cards, etc.) for installing the app and configuration profile
  • 76.
    ComScore • Owner ofseveral “market research” apps • MobileXpression, Digital Reflection • Promise users rewards (gif cards, etc.) for installing the app and configuration profile
  • 77.
    ComScore • Inspect/decrypt allthe users’ traffic to measure app usage • ComScore’s business model as a "measurement company”
  • 78.
    Spyware - MarketIntel • Configuration profiles are problematic • Highly technical security warnings when installing the profile • The profile/VPN does not get uninstalled when removing the app • Makes sense from a technical perspective but will confuse users • But not an easy issue to fix • Corporate enrollment / MDM use case • A profile can be installed directly via Safari • Banning the spyware app from the store does not prevent it
  • 79.
    Spyware Categories Market Intelligence
 3580 078 reports Ad Blocker
 18 463 reports Parental Control
 10 820 reports
  • 80.
    Spyware Categories Market Intelligence
 3580 078 reports Parental Control
 10 820 reports Ad Blocker
 18 463 reports Defend My WiFi 59% AdBl0ck 34% AdGuard 7%
  • 81.
    Spyware - AdBlocker • Similar technical implementation with a VPN and custom CA • Defend My WiFi • "Automatically turns public Wi-Fi into safe and secure private WiFi” • Company does not exist anymore? • Adblock Mobile • iOS 8: SSL mitm on ad domains only • iOS 9+: No more custom CA installed
  • 82.
    Spyware Categories Market Intelligence
 3580 078 reports Ad Blocker
 18 463 reports Parental Control
 10 820 reports
  • 83.
    Spyware Categories Market Intelligence
 3580 078 reports Ad Blocker
 18 463 reports Parental Control
 10 820 reports Qustodio 74% Accountable2You 24% Circle Go 2%
  • 84.
    Spyware - ParentalControl • Qustodio, Accountable2You, Circle Go • Parental control/monitoring tools
  • 85.
  • 86.
    What did wesee? • Traffic interception does happen, and for many reasons • Usually not malicious • Employers • Users “willingly” sharing their data for a reward • No visible move from Apple and Google on this • Similarities and differences compared to previous work on the web/desktop (Google, Facebook, Cloudflare)
  • 87.
    What do wedo? • Which group does your app belong to? • It is acceptable to expose the user’s data to “lawful interception” (such as the user’s employer) • Games, Business apps • The user’s data is private and can never be exposed • Mobile banking • Can be technically enforced via SSL pinning
  • 88.
    What do wedo? • More options on mobile compared to the web • SSL reporting helps you understand what is happening across your user base • SSL pinning can be used for sensitive apps • Significant burden and risk of catastrophic failure • Must be decided and planned carefully • Does not prevent reverse-engineering of your app
  • 89.