Property Lists (PLIST)
Apple Property List (PLIST) files are a versatile file format used extensively across macOS, iOS, and other Apple operating systems for storing serialized objects. The format is primarily used for configuration (settings files), but also extensively for internal data storage and inter-process communication.
PLIST files can be formatted in XML, binary, or sometimes JSON. XML is the most human-readable format and is often used in development environments, while the binary format is optimized for size and speed, making it more common in production environments. JSON-formatted PLISTs are less common and typically used in specific situations where compatibility with web technologies is needed.
Usage
-
Configuration Settings: PLIST files are widely used to store user settings and preferences, application configurations, and system settings.
-
Application Data: Many applications use PLIST files to store information such as application state, user data, and other structured information.
-
System Information: macOS and iOS use PLIST files to store system configuration and state information, such as launch services data, network configurations, and more.
While PLIST files are convenient for data storage, they are not inherently secure and should not be used to store sensitive information like passwords or personal data unless they are properly encrypted. Since PLIST files can be easily read and modified, storing sensitive data in them without encryption can pose security risks.
To view a PLIST file, you can use either the plutil program or the PlistBuddy program which are on a macOS system with Xcode installed. On an iOS device that is jailbroken, you can install plutil there as well.
Examples
View file (with both tools):
% plutil -p Info.plist
% /usr/libexec/PlistBuddy -c Print Info.plist
PLIST format:
If you need to convert a PLIST file, you will need to use the plutil program. The acceptable formats are: xml1, binary1, json, swift, objc. To get the format of the PLIST file, just use the built-in file command:
% file Data.plist
Data.plist: XML 1.0 document text, ASCII text
% file Info.plist
Info.plist: Apple binary property list
Convert file (from binary to XML):
% file Info.plist
Info.plist: Apple binary property list
% plutil -convert xml1 Info.plist
% file Info.plist
Info.plist: XML 1.0 document text, ASCII text
Convert and save to new file:
% plutil -convert binary1 Info.plist -o MyBin.plist
% file MyBin.plist
MyBin.plist: Apple binary property list
NSKeyedArchiver
NSKeyedArchiver is used to serialize objects into a format that can be written to disk. This is particularly useful for custom objects that do not natively support serialization. By implementing the NSCoding protocol (or NSSecureCoding for greater security), objects describe how their properties should be encoded and decoded.
When storing data such as user settings, application state, or complex data structures, NSKeyedArchiver allows for this data to be encoded as a plist or binary data. This makes it easy to save complex data structures in a structured archive format.
Reviewing contents encoded by NSKeyedArchiver involves decoding the data. In most cases, the NSKeyedArchiver data is an encoded PLIST file inside of a different PLIST file. It is represented as Hex strings like the example below:
LastUserIdentity = <62706c69 73743030 d4010203 04050607 0a582476
65727369 6f6e5924 61726368 69766572 5424746f 7058246f 626a6563 74731200
0186a05f 100f4e53 4b657965 64417263 68697665 72d10809 5f10104c 61737455
73657249 64656e74 69747980 01a50b0c 13141555 246e756c 6cd30d0e 0f101112
59757365 7249644b 6579586f 72674964 4b657956 24636c61 73738002 80038004
5f100f30 30357130 30303030 30364f42 7a535f10 12303044 71303030 30303030
45416943 454157d2 16171819 5a24636c 6173736e 616d6558 24636c61 73736573
5f101553 46557365 72416363 6f756e74 4964656e 74697479 a21a1b5f 10155346
55736572 4163636f 756e7449 64656e74 69747958 4e534f62 6a656374 00080011
001a0024 00290032 00370049 004c005f 00610067 006d0074 007e0087 008e0090
00920094 00a600bb 00c000cb 00d400ec 00ef0107 00000000 00000201 00000000
0000001c 00000000 00000000 00000000 00000110>;
To decode the data, simply copy out the hex data between the "<
" & the ">
" and pipe it into a tool that can reverse the hex -- such as xxd
.
% echo "{ 62706c69 . . . 00000110 }" | xxd -r -p
bplist00?
X$versionY$archiverT$topX$objects??_NSKeyedArchiver?
_LastUserIdentity??
YuserIdKeyXorgIdKeyV$class???_005q0000006OBzS_00Dq0000000EAiCEAW?
Z$classnameX$classes_SFUserAccountIdentity?SFUserAccountIdentityXNSObjec$)
27IL_agmt~????????????
While this is not especially helpful, we can see from the beginning of the output (bplist00?) that it is another property list file embedded into a property list file. So, we can further extend our command to automatically decode the binary PLIST data using plutil.
% echo “{ 62706c69 . . . 00000110 }” | xxd -r -p | plutil -p -
{
"$archiver" => "NSKeyedArchiver"
"$objects" => [
0 => "$null"
1 => {
"$class" => <CFKeyedArchiverUID 0x7fefc1e08ab0 [0x7fff8b4988c0]>{value = 4}
"orgIdKey" => <CFKeyedArchiverUID 0x7fefc1e08a90 [0x7fff8b4988c0]>{value = 3}
"userIdKey" => <CFKeyedArchiverUID 0x7fefc1e08a70 [0x7fff8b4988c0]>{value = 2}
}
2 => "005q0000006OBzS"
3 => "00Dq0000000EAiCEAW"
4 => {
"$classes" => [
0 => "SFUserAccountIdentity"
1 => "NSObject"
]
"$classname" => "SFUserAccountIdentity"
}
]
"$top" => {
"LastUserIdentity" => <CFKeyedArchiverUID 0x7fefc1e089b0 [0x7fff8b4988c0]>{value = 1}
}
"$version" => 100000
}
This data is much better for us to review for sensitive information.
As the name NSKeyedArchiver implies, the data is listed as a key value pair. For instance, the data below is an entry for the "orgIdKey".
"orgIdKey" => <CFKeyedArchiverUID 0x7fefc1e08a90 [0x7fff8b4988c0\]>{value = 3}
It is linked to the value listed as "3" in the data block. We can see that the value of 3 is:
3 => "00Dq0000000EAiCEAW"
So, in this case the orgIdKey is 00Dq0000000EAiCEAW
.
Decoding this data can quickly become tedious, but it will frequently reveal username's, passwords, tokens, keys, etc.