xpc-tracer
xpc-tracer copied to clipboard
A tracer based on frida for XPC messages in iOS and macOS.
XPC tracer
A tracer based on frida for XPC messages in iOS and macOS.
This project is a variant of xpcspy.
However, for my purposes, I did not develop a Python script with options to filter messages based on direction (incoming/outgoing).
Instead, I created an agent to hook some xpc_connection_send_message
functions and print their arguments in the best way possible.
You will notice that I print arguments in-depth, including parsed bplist00
, bplist15
, bplist16
, and bplist17
, using jlutil.
This is a PoC for AnForA.
Requirements
- A jailbroken iDevice
Quick-start guide
I prefer using frida inside Python virtual environment (venv).
How to create venv, compile & load
$ git clone https://github.com/lorenzoferron98/xpc-tracer.git
$ cd xpc-tracer/
$ python -m venv .venv # create virtual env
$ source .venv/bin/activate
$ npm install # nodejs required
$ pip install frida-tools
$ frida -U -f ph.telegra.Telegraph --no-pause -l _agent.js # target app: Telegram
Patch IPA
Warning It doesn't work on iOS 16.3.1. I only tested it with success on iOS 12.5.5.
To use agent, target application must be able to execute system call system(2)
.
So you must patch IPA.
- Dump
enitlements.plist
usingldid -e ${APP_PATH}
- Append
to<key>com.apple.private.security.no-container</key> <true/>
enitlements.plist
. - Signing application with
ldid -Senitlements.plist ${APP_PATH}
Note On iOS stock is not possible to sideload an app with this enitlement. Because it is not possible to retrieve a valid provisioning file. Sideloadly fixes up enitlements to use sandbox.
Furthermore in the provisioning file must be present the iDevice where you want to sideload otherwiseinstalld
fails.
Example of Output
xpc_connection_send_message_with_reply_sync(
connection = {
com.apple.contactsd = {
service: OS_xpc_dictionary = {
EnableTransactions: OS_xpc_bool = true,
LimitLoadToSessionType: OS_xpc_string = System,
MachServices: OS_xpc_dictionary = {
com.apple.contactsd.launch-services-proxy: OS_xpc_mach_send = <mach send right: 0x283cb51e0> { name = 0, right = send, urefs = 1 },
com.apple.contactsd: OS_xpc_mach_send = <mach send right: 0x283cb40a0> { name = 0, right = send, urefs = 1 }
},
Label: OS_xpc_string = com.apple.contactsd,
TimeOut: OS_xpc_int64 = 30,
OnDemand: OS_xpc_bool = true,
LastExitStatus: OS_xpc_int64 = 0,
PID: OS_xpc_int64 = 279,
Program: OS_xpc_string = /System/Library/Frameworks/Contacts.framework/Support/contactsd,
ProgramArguments: OS_xpc_array = [
: OS_xpc_string = /System/Library/Frameworks/Contacts.framework/Support/contactsd,
]
}
}
},
message: OS_xpc_dictionary = {
f: OS_xpc_uint64 = 33,
root: OS_xpc_data = {
format = bplist16,
body = {
0: encodedContactsAndCursorForFetchRequest:withReply:
1: v@:@@?
2:
0:
$class: CNContactFetchRequest
keysToFetch:
$class: NSArray
NS.objects:
0:
$class: CNAggregateKeyDescriptor
_keyDescriptors:
$class: NSArray
NS.objects:
0: namePrefix灴潲o牆整捨湡浥偲敦
1: givenName
2: middleName
3: familyName
4: nameSuffix
5: contactType
6: organizationName潲条湩穡瑩潮乡浥닦鶡ꧧꦡꧦ
7: nickname扰汩獴ㄶꂥȀ
_privateDescription: Formatter style: 0閦@
1: phoneNumbers
2: urlAddresses
unifyResults: false
sortOrder: 0
onlyMainStore: true
predicate: NULL
mutableObjects: true
rankSort:
1: NULL
}
},
proxynum: OS_xpc_uint64 = 1,
replysig: OS_xpc_string = v32@?0@"NSData"8@"<CNEncodedFetchCursor><NSXPCProxyCreating>"16@"NSError"24,
sequence: OS_xpc_uint64 = 3
}
);
In this example Telegram call native function xpc_connection_send_message_with_reply_sync
to create a new contact (John Doe +1 212-456-7890).
The function has two arguments connection
and message
. The information for the former is retrieved using launchctl list
query.
The latter is a dictionary with data in bplist16 format decoded using jlutil.
I don't know why jlutil print this "strange" chars. Moreover, it's not always possible to get information about connection
.
In these cases launchctl list
prints error: OS_xpc_int64 = Could not find specified service
.