Page 1 of 1

__XPC_DYLD_INSERT_LIBRARIES?

PostPosted: Thu May 21, 2015 7:20 pm
by patrick
Aloha, I'm working on a tool, KnockKnock, (open-source version: https://github.com/synack/knockknock), that attempts to display all persistently installed binaries. One of the things the tool looks for is dylibs persistently inserted at load time via DYLD_INSERT_LIBRARIES (see: https://github.com/synack/knockknock/bl ... s/dylib.py).

I came across a StackOverflow post 'Setting DYLD variables for sandboxed app at runtime' (http://stackoverflow.com/questions/2395 ... at-runtime) where the author discusses successfully using __XPC_DYLD_INSERT_LIBRARIES to achieve dylib insertion.

I was unaware of this technique and my googling didn't really provide any meaning information about __XPC_DYLD_INSERT_LIBRARIES. Grep'ing the filesystem for the string also didn't turn up anything useful. Finally, making a sample app and attempting to get a dylib loaded via a) export __XPC_DYLD_INSERT_LIBRARIES or b) <key>LSEnvironment</key><dict><key>__XPC_DYLD ... did not work for me.

My goal would be to improve KnockKnock to also detect this kind of dylib insertion (understanding that yes, this could be used for legitimate purposes as well). Do you have any insight/info/understanding about __XPC_DYLD_INSERT_LIBRARIES?

Re: __XPC_DYLD_INSERT_LIBRARIES?

PostPosted: Thu May 21, 2015 8:08 pm
by morpheus
Hi Patrick,

So - re said StackOverflow question - my team and I answered that one. (Shame that so few people know of this forum, where it would've been answered far more quickly).

As per your question:

- Googling didn't find anything because Google is limited when it comes to undocumented stuff, or anything without ad potential.

- Grep(1)ing wouldn't work because the __XPC string is a prefix (q.v. stack overflow answer). Basically, __xpc_collect_environment looks at variables with the __XPC prefix, removes it, and passes the variables (via launchd) to the XPC service. LSEnvironment likewise does the same thing, as launchd inspects Plists for said key (I'll have more on that in the 2nd Edition - the rewriting of launchd and enhancements to XPC are important in OS X 10.10/iOS 8, and are entirely undocumented now that launchd is closed source).

- The author of said question hasn't tried this on code-signed/sandboxed apps. On sandboxed apps dyld won't honor the variables. This is because DYLD restricts itself if A) the binary is S[UG]ID B) The binary has a __RESTRICT.__restrict section and/or C) the binary is code signed with entitlements. So you're better off just looking if the binary is or isn't signed (I showed you code for this in a previous question, and procexp detects code signing as well). Come to think of it as I write this, it could be a great feature in procexp to see which binaries are loaded. Bear in mind, though, that virtually all frameworks/dylibs are nowadays pre-linked and pre-loaded into the address space (via the dyld_shared_cache).

- To inspect force-inserted libraries and add this to knock-knock (nice idea), you should use the DYLD APIs , and in particular dyld_all_image_infos struct (/usr/include/mach-o/dyld_images.h), which contains a list of all loaded images. You can compare them to those loaded by the binary itself (JTool's independent mach lib can be used for that, if you don't want to parse the entire header yourself, which sucks). This approach would also capture injected dylibs via a remote thread. And you might want to look at procexp's feature of seeing if a process has been tampered with (select any process and it'll tell you if it's modified or not). That's a great feature you might want in knock/knock as well.

Re: __XPC_DYLD_INSERT_LIBRARIES?

PostPosted: Fri May 22, 2015 5:33 pm
by patrick
Ok - that (all) makes sense! Tx for the detailed answer. I was aware of dyld ignoring DYLD_ env variables for certain scenarios. __xpc_collect_environment first stripping off the 'XPC' prefix was the missing piece I was unaware of :)