Americas

Asia

Oceania

lconstantin
CSO Senior Writer

Supply chain compromise of Ultralytics AI library results in trojanized versions

News
06 Dec 20244 mins
Development Libraries and FrameworksMalwarePython

Attackers exploited a script injection vulnerability via GitHub Actions to inject malicious code during the automated build process, poisoning the resulting packages of the popular Python library.

Profile photo of a developer / programmer reviewing code on monitors in his workspace.
Credit: Roman Samborskyi / Shutterstock

Attackers have compromised Ultralytics YOLO packages published on PyPI, the official Python package index, by compromising the build environment of the popular library for creating custom machine learning models. The malicious code deployed cryptocurrency mining malware on systems that installed the package, but the attackers could have delivered any type of malware.

According to researchers from ReversingLabs, the attackers leveraged a known exploit via GitHub Actions to introduce malicious code during the automated build process, therefore bypassing the usual code review process. As a result, the code was present only in the package pushed to PyPI and not in the code repository on GitHub.

The trojanized version of Ultralytics on PyPI (8.3.41) was published on Dec. 4. Ultralytics developers were alerted Dec. 5, and attempted to push a new version (8.3.42) to resolve the issue, but because they didn’t initially understand the source of the compromise, this version ended up including the rogue code as well. A clean and safe version (8.3.43) was eventually published on the same day.

Ultralytics YOLO is not a small project. It has over 30,000 stars and more than 6,000 forks on GitHub. The PyPI package has amassed almost 60 million downloads over its existence.

“Unlike the recent compromise of a trusted npm package @solana/web3.js, which also had a similar impact radius but was caused by a compromise of one of the maintainer accounts, in this case intrusion into the build environment was achieved by a more sophisticated vector, by exploiting a known GitHub Actions Script Injection that was previously reported by the security researcher Adnan Khan,” the ReversingLab researchers wrote in their report.

Regression of a previously patched vulnerability

GitHub Actions is a CI/CD service that allows GitHub users to automate the building and testing of software code by defining workflows that execute automatically inside containers on GitHub’s or the user’s own infrastructure. GitHub Actions workflows are a series of processes or “actions” defined in .yml files inside repositories that get executed when certain trigger events occur, such as when new code gets committed to the repository.

It’s common practice for developers to work in their own forks (versions) of a code repository and then submit the patches back to the main project through pull requests. By default, anyone can fork a project and can submit pull requests, meaning project owners need to be very careful about how they use GitHub Actions, including what actions and what triggers they allow.

Security researcher Adnan Khan has a history of investigating and finding security issues related to GitHub Actions. In August he reported a script injection vulnerability via GitHub Actions that could result in arbitrary code execution in the workflow context to Ultralytics, which was subsequently patched. However, a regression was later introduced.

“It appears the injection point exploited by the threat actor exploited was introduced in ultralytics/actions@c1365ce. 10 days after Ultralytics published the advisory for the first vulnerability,” Khan wrote in the comments thread for the new compromise.

The attackers also seem to have used a cache poisoning technique to persist their modifications via GitHub Actions that Khan had documented back in May on his personal blog.

According to ReversingLabs’ analysis of the malicious code, the attacker modified two files: downloads.py and model.py. The code injected in model.py checks the type of machine where the package is deployed to download a payload targeted for that platform and CPU architecture. The rogue code that performs the payload download is stored in downloads.py.

“While in this case, based on the present information the RL research team has, it seems that the malicious payload served was simply an XMRig miner, and that the malicious functionality was aimed at cryptocurrency mining,” ReversingLabs’ researchers wrote. “But it is not hard to imagine what the potential impact and the damage could be if threat actors decided to plant more aggressive malware like backdoors or remote-access trojans (RATs).”

The ReversingLabs report includes indicators of compromise and file hashes to detect the infection. Systems that deployed Ultralytics 8.3.41 and 8.3.42 should be security audited.

  翻译: