Skip to content
GoogleGHSA-2j38-pjh8-wfxw

MacPorts: Remote Code Execution

MediumCVE-2024-11681 · Published Dec 23, 2024

### Summary <img width="493" alt="CompromisedMacPortMirror" src="https://github.com/user-attachments/assets/d32d589d-81ac-40e9-ba85-5e51fd53b3bf" /> When updating Ports from a malicious or compromised MacPorts mirror, arbitrary commands can be executed even if signatures are validated. A malicious or compromised MacPorts mirror can execute arbitrary commands as `root` on the machine of a client running `port selfupdate` against the mirror. [MacPorts](https://www.macports.org/) is a package manager for MacOS. Similar to other package managers like [APT](https://en.wikipedia.org/wiki/APT_(software)), users will once in a while update the list of available packages, their versions, checksums etc. To do so, they will either run `port sync` or preferably `port selfupdate`. Under the hood, the client then uses `rsync` to download a `ports.tar.gz` file and an according signature file `ports.tar.gz.rmd160`. The MacPorts client then verifies the signatures or discards the archive. If the signature is valid, the `ports.tar.gz` file is extracted into the same directory which was the target directory of `rsync`. This creates a directory structure such as: <img width="625" alt="targetDirec...

GitHub advisory

Affected versions

PackageAffectedFixed in
PortsCLI
Product
all versionsNo fix yet
Details and references

### Summary <img width="493" alt="CompromisedMacPortMirror" src="https://github.com/user-attachments/assets/d32d589d-81ac-40e9-ba85-5e51fd53b3bf" /> When updating Ports from a malicious or compromised MacPorts mirror, arbitrary commands can be executed even if signatures are validated. A malicious or compromised MacPorts mirror can execute arbitrary commands as `root` on the machine of a client running `port selfupdate` against the mirror. [MacPorts](https://www.macports.org/) is a package manager for MacOS. Similar to other package managers like [APT](https://en.wikipedia.org/wiki/APT_(software)), users will once in a while update the list of available packages, their versions, checksums etc. To do so, they will either run `port sync` or preferably `port selfupdate`. Under the hood, the client then uses `rsync` to download a `ports.tar.gz` file and an according signature file `ports.tar.gz.rmd160`. The MacPorts client then verifies the signatures or discards the archive. If the signature is valid, the `ports.tar.gz` file is extracted into the same directory which was the target directory of `rsync`. This creates a directory structure such as: <img width="625" alt="targetDirectory" src="https://github.com/user-attachments/assets/9b535acc-4b39-4f21-8301-1708dedfe2c2" /> The `ports` directory is essentially an up-to-date version of the [macports/macports-ports](https://github.dev/macports/macports-ports) GitHub repository. Each Port contains a [Portfile](https://guide.macports.org/chunked/reference.html) within this directory structure. These files are written in [Tcl](https://www.tcl.tk/about/language.html) and inform the MacPorts client about the name of the Port, dependencies, how to build the Port and more. Once the archive is extracted, the MacPorts client attempts to fetch an index of all the Ports from the same Rsync server (which is also signed) or if it’s not served or outdated, creates its own index using the [portindex](https://github.com/macports/macports-base/blob/12986b1c3e03583896330248e0e5c5a64bb7016b/src/port/portindex.tcl#L1) binary. This helper finds all the `Portfile` files within `ports` and evaluates them. When evaluated, a `Portfile` can technically instruct the client to execute arbitrary system commands, for example: ``` set x [exec "bash" "-c" "id > /tmp/poc"] ``` We can verify that this works if we create a file called `ports/foo/bar/Portfile` with the content above and then run the `portindex` binary in the `ports` directory: ```uid=0(root) gid=0(wheel) groups=0(wheel), snip ``` The question now becomes, how can an attacker place a controlled Portfile on the client's machine, when the archive is signed? We will answer this question in the next section. #### Creating Arbitrary Portfiles on the Client's machine We mentioned that the client uses Rsync to fetch the `ports.tar.gz `file from its configured mirror(s). The important detail here is that the target directory of `rsync` and the target in which `portindex` are run are the same. In theory, a malicious server could serve a valid, signed archive and **additional** Portfiles. However, the client uses a few flags that prevent such an attack. The following CLI invocation shows the second Rsync CLI invocation that is used to fetch the `PortIndex` file and its signature `PortIndex.rmd16`: ``` /usr/bin/rsync -rtzvl --delete-after --include=/PortIndex.rmd160 --include=/PortIndex --exclude=* rsync://localhost:12000/macports/PortIndex_linux_5_i386/ ``` The important flags here are: - `--include=PortIndex.rmd160` - `--include=PortIndex` - `--exclude=*` This instructs the Rsync client to only fetch `PortIndex` and `PortIndex.rmd160` and reject everything else. The problem here is that in some Rsync implementations and versions these filters are only enforced on the server-side. We compiled [rsync.samba.org](http://rsync.samba.org/)’s server version with a single change that ignores all filters sent by

Severity from
GitHub (reviewed advisory)

More Google advisories

All Google
Advisory
Linux Kernel: Integer Overflow in eBPF XSK map_delete_elem Leads to Out-of-Bounds
High7.8Jan 9, 2025
Linux Kernel: Out of bounds Write in ksmbd_vfs_stream_write
Critical9.8Jan 9, 2025
Linux Kernel: Out of bounds Read in ksmbd_vfs_stream_read
Critical9.1Jan 9, 2025
Apple: WebKit Canvas Denoising
MediumDec 26, 2024
KVM: Out-Of-Bounds Read in nested_svm_get_tpd_pdptr
MediumDec 9, 2024
Cisco NX OS: Bootloader Script Execution Vulnerability
HighDec 6, 2024

Critical advisories by email

Wednesdays: the week’s critical and high advisories in the AI and data stack, with the fixed versions. Only in weeks that have some.

Double opt-in. Unsubscribe any time.