A patch was released in September of 2021, so users who updated their code won't be exposed to this attack. Users who have not updated should do so as soon as possible. It is unknown how many of the ~167,000 applications that use this library are running vulnerable versions. The purpose of this exercise is to encourage developers to update to an adequately protected version, detailed throughout this blog.
According to their Github page, SLO Generator is a tool to compute and export Service Level Objectives, Error Budgets and Burn Rates, using Configurations written in YAML or JSON. In layman’s terms, it’s a tool for engineers who wish to track their web API performance. Many Google services, along with other projects wishing to record these metrics, use this tool.
SLO Generator Python library can be directly installed from PyPI with pip
Figure 1: Installing the SLO Generator Python library
Once installed, it is easy to generate the SLO report with the command line interface
```slo-generator compute -f slo_config -c shared_config –export```
Compute argument to the slo-generator indicates that we want to generate a SLO report
The tool also provides the functionality to migrate older, version 1 configuration to newer, version 2 configuration.
```slo-generator migrate -s old_config/ -t new_config -b error_budget_policy/config.yaml ```
For a successful migration, the migrate command needs 3 inputs from the user:
a directory containing old SLO configurations.
a directory containing newer slo configurations
a yaml file containing error_budget_policy
There are several techniques to find a potential vulnerability in older versions, such as manually combing through the source code, fuzzing the application, or analyzing recent patches to the application.
Let’s analyze the recent patches first, attempting to discover any potential vulnerabilities. SLO Generator is an open-source tool; this information is all publicly available on their Github repository.
Looking through the release notes of version 2.0.1, we can see that they fixed the yaml loader security issue, meaning older versions of SLO Generator (i.e. v 2.0.0) would have the yaml loader vulnerability.
Figure 2: Version 2.0.1 fixes the yaml loader security issue
Looking at the changed files, we can see that in the patch, developers have replaced yaml.Loader, which is vulnerable, with yaml.SafeLoader.
Looking at the official documentation for pyyaml, it is mentioned that calling yaml.load on any untrusted data is as dangerous as pickle.load, a common attack path making it possible to provide malicious shellcode as input, causing remote code execution.
This indicates that if we can control the data which is passed to the yaml.load function, we can perform a python deserialization attack to get the code execution on the application.
Looking through the changes, we see there is a function called ‘ebp_v1tov2’, which is calling the yaml.load function on a variable called “conf”. As we can see on line 262, every file in the variable ebp_paths will be passed through yaml.load as “conf”.
Figure 4: Dissecting code line 264 for yaml.load
As per line 70, ebp_paths is a list containing files in error_budget_policy_path which we pass to the application.
Figure 5: Code line 70
Our first step is to create a malicious python deserialization object that we store in a yaml path. Next, we call the migrate function with error_budget_policy_path pointing to our malicious file. Our malicious file will be loaded by the application and our code will be executed.
As generating a yaml deserialization payload is out of the scope, we will find a common deserialization payload and copy it to our attack yaml file as exploit.yaml.
Figure 6: Deserialization payload with exploit.yaml
Now, running the following command to exploit the application:
Figure 7: Command to execute payload
As SLO Generator is a widely used python library, a code execution vulnerability makes it more severe. A typical exploit scenario would be executed in a web application to migrate user-supplied configuration.
All instances of SLO Generator should be updated to the latest version. Most applications handle user-supplied yaml data. Yaml data should always be handled correctly. Avoid using unsafe functions such as yaml.load, and replace it with yaml.SafeLoad. At an absolute minimum, it is imperative that all instances be updated past ‘yaml loader security issue 173’ to protect against this exploit.
This exploit shows the severity of using unsafe functions such as yaml.load. Any application that processes user data directly should always handle data with extreme caution. From an attacker’s perspective, if an application is processing user input directly to a yaml.load function, the application could be vulnerable to the Python YAML deserialization attack.
Always keep all dependencies up to date with a dependency manager.
Never use unsafe functions to directly process user data.
Check for and install updates/patches when available.
Although this version of SLO Generator has been updated since September 2021, it nonetheless highlights the importance of proper and timely stewardship of software tools. As we have explored in this blog, it is relatively easy for an attacker to create an exploit for an out-of-date version. There are thousands of web applications being built with libraries such as these. Dependencies can be a useful tool, but can also come back to haunt you if not looked after properly. Lookin’ at you, Log4j.
1. Agrawal, A. (2014, November 18). Understanding Python pickling and how to use it securely. Synopsys blog.
#exploit #python #google #slo_generator #YAML #vicarius_blog