
As one of the most popular languages, Python has a wide presence in any large-scale development project. As per a survey in 2021, 48.07% chose Python as their favorite programming language. Along with it being a favorite language amongst developers, there is also a thriving community. The Python Package Index (PyPI) is a repository hosting over 10TB of packages that programmers use to build their products.
Once published on PyPI, packages are available for anyone to install. This makes it critical for developers to ensure their packages are secure because if a package is vulnerable, every application that integrates it becomes vulnerable. In this blog, I will illustrate the risk of a vulnerable package called “yacmmal”, walk through the process of exploit development, and develop the zero-day exploit for the package, as well as provide a solution for mitigating the risk.
What is yacmmal?
Yet Another Config Manager for Machine Learning (yacmmal) automatically loads configuration files for machine learning projects (and removes the hassle). Yacmmal is built on top of pydantic. The package automatically creates dataclasses from various file formats such as YAML, JSON and CSV.
Installation
As we are targeting the latest version of yacmmal, we will install the latest package from PyPI with pip
“` pip install yacmmal “`
Vulnerability
Now, to find the vulnerability, we will analyze the publicly available source code on their repository. https://github.com/juselara1/yacmmal
Figure 1: yacmmal Github repository
Here, yacmmal contains the main logic
Figure 2: Inside the yacmmal folder
The load folder contains the logic for loading various file types. Here, yaml.py looks interesting as it is very common for python developers to configure serialization and deserialization on yaml files incorrectly.
Figure 3: Inside the load folder
Taking a look at the file, we can see that it imports yaml and has defined class YAMLLoader which is a loader for yaml files and a base path to the yaml file which needs to be loaded.
Figure 4: Yaml file code
The YAMLLoader class has two functions defined: init and load.
The load function takes the path to the yaml file and a data class to use as arguments and returns the loaded model.
Taking a closer look, we can see that the load function unsafely loads the yaml file with yaml.load without the safe loader. So, it is vulnerable to a YAML deserialization attack and can grant remote command execution to an attacker.
Implementation
To analyze the vulnerability, we will exploit a program that uses the yacmmal package.
This example program can be found in the example directory of yacmmal github repository.
Our example program loads two configuration files, hp_file and ep_file, from the config directory and loads them to generate a model.
Vulnerability Test
First, we need to create a basic yaml exploit to check if the vulnerability exists or not.
According to the pyyaml documentation, the yaml.dump function accepts a Python object and produces a YAML document.
So, opening the python interpreter, we import the yaml package and test.
We pass a string (AAAA) to the yaml.dump function which generates a yaml document and we print it.
In the same way, we can pass a function to dump. Here, “!!python/object/apply:builtins.range” is the serialized object and 1,4,1 are the arguments passed to the function.
Same way, we can modify the serialized object for sleep function instead of range. The second line takes 4 seconds before finishing the execution. We will use the time.sleep payload to test if our Yacmmal application is vulnerable.
As our application takes hp_file.yaml configuration from the config directory, we will modify the hp_file.yaml to contain our basic exploit.
As we can see, the program takes 4 seconds before throwing us an error, which means our basic exploit was successful and now we can modify our exploit to get the command execution.
Command Execution
From our basic exploit (!!python/object/apply:time.sleep [4]) we replace time.sleep function with os.system and pass our command as argument.
So now our final exploit would be:
!!python/object/apply:os.system [“id;whoami”]
Running the exploit, we can see that we get successful command execution.
Solution
As this exploit is not known and no patches are available for Yaccmal, the usage of the package should be avoided until any patches are public. If the usage of the package is necessary, the following change should be made:
For the file yacmmal/load/yaml.py,
Replace line 37
data = yaml.load(f, Loader=yaml.Loader)
With
data = yaml.load(f, Loader=yaml.SafeLoader)
#NCSAM #exploit #yacmmal #research #zeroday #vicarius_blog
About Version 2 Digital
Version 2 Digital is one of the most dynamic IT companies in Asia. The company distributes a wide range of IT products across various areas including cyber security, cloud, data protection, end points, infrastructures, system monitoring, storage, networking, business productivity and communication products.
Through an extensive network of channels, point of sales, resellers, and partnership companies, Version 2 offers quality products and services which are highly acclaimed in the market. Its customers cover a wide spectrum which include Global 1000 enterprises, regional listed companies, different vertical industries, public utilities, Government, a vast number of successful SMEs, and consumers in various Asian cities.
About VRX
VRX is a consolidated vulnerability management platform that protects assets in real time. Its rich, integrated features efficiently pinpoint and remediate the largest risks to your cyber infrastructure. Resolve the most pressing threats with efficient automation features and precise contextual analysis.

