Although there is nothing special about code executing on a machine, the moment when this code is executed is a significant detail from a security standpoint.

The Python programming language allows you to install packages that can be included in your programs to extend their functionality. When your program is executed, the code in the packages will be executed as would be expected. A less known ability, though, is that code can also be executed as part of the installation of the package itself.

A researcher going by the handle mschwager on GitHub demonstrated an attack method that abuses the 'setup.py' file in Python modules to perform code execution when the package is installed.

Using this method an attacker could place malicious code inside a package that could execute with root privileges, although not all of packages require this level of permission.

To prove his point, mschwager detailed the attack by creating a proof-of-concept installation file he called 0wned. The following code shows how a custom 'PostInstallCommand' class is invoked when 'pip install' runs.

from setuptools import setup
from setuptools.command.install import install

class PostInstallCommand(install):
    def run(self):
        # Insert code here
        install.run(self)

setup(
    ...
    cmdclass={
        'install': PostInstallCommand,
    },
    ...
)

Installation file allows sneaky malware deployment

Python modules are typically installed using a package manager called 'pip', which launches a 'setup.py' file that is made available by the developer of the package for installation purposes. This file usually receives little attention since it is present only to help the user add a module to their machine.

When it comes to modules or packages, though, people tend to examine them more thoroughly as this is the code that will be imported and run within a program. Thus they are more prone to having the code inspected and malicious code spotted.

"When you use an IDE and open a module function, it opens the file inside the Python directory," Malwarebytes developer and malware analyst Tigzy told BleepingComputer. "So one could see if there's something wrong," he added.

Analyzing a setup file, though, is less likely, which gives an attacker a simpler method to infect a machine without tampering with the module.

Furthermore, Tigzy explains, the code of Python packages that serve applications may never execute simply because the app does not need that specific portion.

Placing malicious code in 'setup.py,' however, will allow malware to be installed and unnoticed even if the package, or Python itself, is not used at all.

Malicious modules in official Python repository

Malicious libraries are not uncommon in package repositories. Last year, researchers discovered ten of them in PyPi, the official third-party store for Python programming language.

The malicious developers uploaded their libraries with names that resembled those of legitimate modules, thus tricking users into downloading them.

Obviously, the attack worked because users believed the name of the package was correct and did not bother to go through the code or check the spelling. Uploading malicious content was possible because the repository lacked security checks and screenings of the content added to its index.

Staying on the safe side

mschwager advises developers to always be suspicious about the Python modules they install on the system, particularly when they require root privileges.

In other circumstances, mschwager recommends setting local privileges by using the  --user flag, and installing the packages in hash-checking mode, to make sure they were not compromised.

Spending a little more time to find the modules with the correct names is also on the list of defenses, which would fend against falling for typo squatting tricks.

Related Articles:

Get 93% off The Python Power Coder Bundle Deal