Exposing the Password Secrets of “Apple Safari”

May 8, 2011, by | Start Discussion

Safari is one of the top 5 browsers known for its innovative look and feel reflected in every product of Apple!  It offers one of the best ways to browse online, greater support for HTML5, and other new features that make the web even better experience.

Like other browsers, Safari also comes with built-in ‘password manager’ feature for securely storing and managing the user's web login passwords.

This article is set to expose – in first ever public disclosure – password secrets of Safari including the stored password location, encryption algorithm and code for decryption of stored passwords!

Safari Password Storage Location

Safari features good password manager with better security model and encryption algorithms to keep it as much as secure as possible. Unlike other browsers such as Firefox, Chrome, you cannot see the stored passwords in Safari.

You can enable or disable the Safari password manager by toggling the option through "Settings -> AutoFill -> Usernames & Passwords" (as shown below). Once enabled Safari will prompt to save the password for every website login for the user. Upon confirmation, website URL along with username & password are saved to secret password file.

Safari stores all such web login passwords at a secret file named 'keychain.plist' at following location (based on platform).

[Windows XP]
C:Documents and
DataApple ComputerPreferences
[Windows Vista & Windows 7]
Apple ComputerPreferences

Safari stores the contents of 'keychain.plist' in 'Binary Property List' file format – variation of Property List [Reference 1] format used by Apple for storing binary data.

Here is how a typical 'keychain.plist'  file looks like,

Decoding the Safari 'Keychain' Secrets!

Looking at above 'keychain file' content, there is hardly anything you can make out. Only hint that you get here is the 'bplist' keyword at the beginning of file.

After long search hours on 'bplist' keyword, I finally figured out the way to decode its content to plain XML file. Apple provides the tool called 'plutil.exe' for playing with these 'Property List' files. You can find this console tool at following location,

[Windows x86]
C:Program FilesCommon
FilesAppleApple Application
[Windows x64]
C:Program Files (x86)Common
FilesAppleApple Application

Here is the command to covert cryptic 'keychain.plist' file to easily readable 'keychain.xml' file

plutil.exe -convert xml1 -s -o

This is how it will look like after decoding to XML file.


Internals of Safari Encryption Algorithm

The generated XML file (as shown above) contains encrypted password data along with website URL and user login information. This stored password data is encoded using BASE64 algorithm.

Note that original password data stored in 'keychain.plist' file is not encoded with BASE64. When we convert it to XML using Plutil tool, the encrypted password data is further encoded with BASE64 format.

Once you decode the password using BASE64 you will see original encrypted password data. Safari uses standard 'Windows Data Protection' mechanism (DPAPI) [Reference 2] to encrypt the password data with user isolation layer. Windows DPAPI provides functions like CryptProtectData/CryptUnprotectData for easy encryption/decryption of user oriented sensitive data such as passwords.

Safari uses CryptProtectData [Reference 3] along with static entropy (salt) to securely encrypt all website login passwords. Finally it is stored in the 'keychain.plist' file along with other user login information.

Decoding & Decryption of Safari Password

As mentioned in previous section, successful Safari password recovery will require following 2 steps:-
1. Base64 Decoding of password data from XML file
2. Windows DPAPI decryption of encrypted data

First you have to use standard Base64 decoder algorithm [Reference 5] to get original password data from encoded password bytes in XML file.

After that we have to perform decryption of this encrypted password data. In order to decrypt this encrypted password data we need to figure out salt data used in CryptUnprotectData.  Here is the salt data that I found during my reverse engineering work.

Entire salt generation algorithm and decryption functions are within the Apple shared library 'CFNetwork.dll' which is present at following location.

[Windows x86]
C:Program FilesCommon
FilesAppleApple Application
[Windows x64]
C:Program Files (x86)Common
FilesAppleApple Application


Here is the disassembly of CFNetwork.dll from IDA Pro Disassembler [Reference 6] showing the location of salt generation & decryption function.

Initially salt generation algorithm appeared to be dynamic but after few reversing session on different systems my doubts cleared and it was just static data. Salt data is of 144 byte size and ends with standard signature pattern as 'com.apple.Safari' as shown in the above screenshot.
Once you get hold of the salt data, the encrypted password can easily be decrypted using CryptUnprotectData function [Reference 4] as shown below:

BYTE salt[] = {
0x1D, 0xAC, 0xA8, 0xF8, 0xD3, 0xB8, 0x48, 0x3E, 0x48, 0x7D, 0x3E, 0x0A, 0x62, 0x07, 0xDD, 0x26,
0xE6, 0x67, 0x81, 0x03, 0xE7, 0xB2, 0x13, 0xA5, 0xB0, 0x79, 0xEE, 0x4F, 0x0F, 0x41, 0x15, 0xED,
0x7B, 0x14, 0x8C, 0xE5, 0x4B, 0x46, 0x0D, 0xC1, 0x8E, 0xFE, 0xD6, 0xE7, 0x27, 0x75, 0x06, 0x8B,
0x49, 0x00, 0xDC, 0x0F, 0x30, 0xA0, 0x9E, 0xFD, 0x09, 0x85, 0xF1, 0xC8, 0xAA, 0x75, 0xC1, 0x08,
0x05, 0x79, 0x01, 0xE2, 0x97, 0xD8, 0xAF, 0x80, 0x38, 0x60, 0x0B, 0x71, 0x0E, 0x68, 0x53, 0x77,
0x2F, 0x0F, 0x61, 0xF6, 0x1D, 0x8E, 0x8F, 0x5C, 0xB2, 0x3D, 0x21, 0x74, 0x40, 0x4B, 0xB5, 0x06,
0x6E, 0xAB, 0x7A, 0xBD, 0x8B, 0xA9, 0x7E, 0x32, 0x8F, 0x6E, 0x06, 0x24, 0xD9, 0x29, 0xA4, 0xA5,
0xBE, 0x26, 0x23, 0xFD, 0xEE, 0xF1, 0x4C, 0x0F, 0x74, 0x5E, 0x58, 0xFB, 0x91, 0x74, 0xEF, 0x91,
0x63, 0x6F, 0x6D, 0x2E, 0x61, 0x70, 0x70, 0x6C, 0x65, 0x2E, 0x53, 0x61, 0x66, 0x61, 0x72, 0x69
DATA_BLOB OptionalEntropy;
DataIn.pbData = byteEncBuffer;     //encrypted password data
DataIn.cbData = dwEncBufferSize;   //encrypted password data size

OptionalEntropy.pbData = (unsigned char*)&salt;
OptionalEntropy.cbData = 144;
    if( CryptUnprotectData(&DataIn, 0, &OptionalEntropy, NULL, NULL,0, &DataOut) == FALSE ) {   
              printf("CryptUnprotectData failed = 0x%.8x", GetLastError());
        return FALSE;
    //Decrypted data is in following format => Password Length [4 bytes] + Pass Data []
    BYTE  *byteData = (BYTE *) DataOut.pbData;
    DWORD dwPassLen = byteData[0];
    memcpy(strPassword, &byteData[4], dwPassLen);
    strPassword[dwPassLen] = 0;
    printf("Decrypted Password %d – %s",  dwPassLen, strPassword);

Above program initializes the salt data and then passes it to CryptUnprotectData along with decoded password data to finally get the decrypted data. First 4 bytes of this decrypted data contains length of the password and then follows the password in clear text!

That is all it takes to successfully decrypt the Password from Safari Store!

Recovering Safari Passwords using SafariPasswordDecryptor

SafariPasswordDecryptor [Reference 7] is the FREE software to automatically recover website login passwords stored by Safari web browser. It helps in instantly decoding and decrypting all the stored website login passwords from Safari Keychain file.

It presents both GUI as well as command line interface, the later is more helpful for Penetration testers in their work. Apart from normal users who can use it to recover their lost password, it can come in handy for Forensic folks in their investigation.

SafariPasswordDecryptor works on most of the Windows platforms starting from Windows XP to latest operating system, Windows 7.

1. Apple's 'Property List' File format
2. Windows Data Protection  Technology – DPAPI
3. CryptProtectData Function
4. CryptUnprotectData Function
5. Base64 Decoder Algorithm – C/C++ Program
6. IDA Pro – Most Popular Disassembler on the Planet
7. SafariPasswordDecryptor – Apple Safari Password Recovery Software

Nagareshwar is a security professional with the unbeaten passion towards Computer Security, mainly involved in Reverse Engineering, Security Research and developing Security Tools. He holds engineering degree in Computer Science from National Institute of Technology of Karnataka, Surathkal (KREC), India. He has professional experience of around 6+ years spanning across Novell & Citrix where he has worked on security and application virtualization technologies.

Leave a Reply