Skip to main content

Transport Layer Security

App Transport Security (ATS)

App Transport Security (ATS) enforces best practices in the secure connections between an app and its back end. ATS prevents accidental disclosure, provides secure default behavior, and is easy to adopt.

ATS is defined in the Info.plist file, under the NSAppTransportSecurity key.

% /usr/libexec/PlistBuddy -c ‘Print :NSAppTransportSecurity’ Info.plist
Dict {
NSAllowArbitraryLoads = true
}

There are several options for further configuring ATS, also as keys in the Info.plist file. Here is the summary:

KeyDescripion
NSAllowsArbitraryLoadsIf set to Yes/True, then ATS is effectively disabled allowing transfer over unencrypted HTTP. On iOS 10 and above, this setting is ignored and will default to No/False, if any of these keys exist: NSAllowsArbitraryLoadsForMedia, NSAllowsArbitraryLoadsInWebContent, NSAllowsLocalNetworking
NSAllowsArbitraryLoadsForMediaIf YES, disables all ATS for media loaded from the AV Foundation framework
NSAllowsArbitraryLoadsInWebContentIf YES, disables all ATS restrictions on content loaded into an instance of UIWebView
NSAllowsLocalNetworkingIf YES, removes ATS protections for connections to unqualified domains and to .local domains without disabling ATS for the rest of your app
NSExceptionDomainsATS exceptions for specific domains
NSIncludesSubdomainsIf YES, applies the NSExceptionDomains ATS exceptions to all subdomains
NSRequiresCertificateTransparencyIf YES, requires a valid, signed Certificate Transparency timestamps
NSExceptionAllowsInsecureHTTPLoadsIf YES, allows insecure HTTP loads but does not change TLS requirements
NSExceptionRequiresForwardSecrecyOverrides the requirement that a server support perfect forward secrecy (PFS). If NO, then it will allow ciphers which do not support PFS
NSExceptionMinimumTLSVersionString value that specifies a minimum TLS version for network connections. Valid values: TLSv1.0, TLSv1.1, TLSv1.2, TLSv1.3

For more information on configuring App Transport Security, see the following article from Apple:

https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/plist/info/NSAppTransportSecurity

Packet Capture

There are some scenarios where you will be required to capture the packets for evaluation. This can happen if you are unable to bypass certificate pinning, or otherwise are unable to intercept HTTP traffic. Additionally, some apps choose not to use HTTP for their communications which prevents our intercept proxy from seeing that traffic.

Setup a Packet Capture


IMPORTANT NOTE: Apple has changed the location of the rvictl tool.

macOS Mojave (and earlier): /usr/bin/rvictl macOS Catalina (and later): /Library/Apple/usr/bin/rvictl


  1. Connect the iOS device to the Mac.

  2. Launch the Terminal.

  3. Create the virtual interface on the Mac

    % rvictl -s $(idevice_id -l)
  4. The previous command should have created a rvi0 interface that is visible from an ifconfig

  5. Start the tcpdump capture on the newly created interface

    % sudo tcpdump -n -i rvi0 -s0 -w filename.pcap
  6. On the iOS device, launch and use the app as normal.

  7. Once complete, you can destroy the virtual interface that was created

    % rvictl -x $(idevice_id -l)
  8. Process the PCAP file in Wireshark.

Capturing TLS Keys from an App

Capturing and using TLS keys is nothing new, as Wireshark (and tshark) can use these keys to decrypt a packet capture. This process is specific to capturing these keys from iOS applications. There are two ways we can do this; dynamically with Frida or automated with an iOS tweak. Each have their own pros and cons, and I leave it up to you on which to use.

Start the Packet Capture

You can run the tcpdump command on your macOS system and capture the traffic from the device using a remote virtual interface:

  • Attach the device to the Mac

  • Start the remote virtual interface for the device

    % rvictl -s $(idevice_id -l)
  • Start the packet capture

    % sudo tcpdump -n -i rvi0 -s0 -w appname.pcap
  • Launch the Frida script for the app

Dynamic -- Frida

Due to some offsets needed in the script, there is a script available for iOS 13 / 14 / 15 on GitHub.

  • Download the appropriate Frida script based on major iOS release

  • With the packet capture running, launch the Frida script for the app

    frida -U -l ios13-tls-keys.js -f com.app.name --no-pause -o appname.keylog
  • Note: The -f option with the bundle ID will ensure that the application is spawned (or respawned) to ensure instrumentation starts immediately

  • Use the app as you normally would

  • When finished, exit out of Frida

  • Stop the packet capture

Automated -- Tweak

In iOS, a tweak is a set of instructions that override a function in an application (or the device) to make it do something it was not designed to do. I have ported the code from the Frida script above to a persistent Tweak. All of the current offsets have been included in a single Debian package which is hosted on GitHub.

  • Copy the package to the device

  • Install the .deb file

    dpkg -i io.stinger.stealtlskeys_14.0-1+debug_iphoneos-arm.deb
  • With this package installed, all apps and device functions will be captured. The keylog file will be written to the application Data/Documents directory. (e.g., /private/var/mobile/Container/Data/Application/{UUID}/Documents/StealTLSKeys.keylog)

  • To remove the tweak:

    dpkg -r io.stinger.stealtlskeys

Wireshark

Once you have the pcap, open it in Wireshark and feed it the TLS keylog file.

  • Open the pcap file in Wireshark, from the Terminal

    open example.pcap
  • Open the Wireshark Preferences from the menu (Wireshark Preferences...)

    • Select Protocols TLS

    • In the "(Pre)-Master-Secret log filename" section, browse for the keylog file save by Frida above and click OK to close out the Preferences window

  • In the Wireshark Display Filter, enter http or http2 and press Return to filter those packets only

  • The packets will be decrypted and displayed for you

Convert to HTTP in Burp Suite

If your intercept proxy is working, then you can easily test to see if the back-end host will allow you to downgrade the HTTPS connection to an insecure HTTP.

  • Setup your Burp Suite intercept proxy

  • Configure the device to use the intercept proxy

  • Launch the app, and utilize some of the functions that will generate HTTPS traffic

  • Send one of the HTTP Requests to the Burp Repeater

  • In the Repeater tab, enable the "Convert HTTPS links to HTTP"

  • Send the Request, and see if the app functions the same