Vulnerability Discovery: CVE-2021-33564
Attempt 1: Local File Inclusion (LFI)
Initial attempts targeted Local File Inclusion using path traversal patterns like ../../ in the payload. These attempts failed due to two key security measures in the Refinery CMS setup:
- Any input containing ../ was automatically blocked
- The application prepended the root directory path to all file requests
- These safeguards effectively mitigated LFI attacks in this context.
Attempt 2: Command Injection via Dragonfly
Dragonfly, a backend image processing library used in the CMS, processes tasks such as image conversion using a set of predefined job types. These include:
- Fetch from local file
- Fetch from URL
- Generate (typically used with ImageMagick)
- Process (apply transformations)
- Attempts to exploit the fetch operations failed due to whitelist-based validation. However, the generate job, which invokes the convert utility from ImageMagick, became the primary focus.
Argument Injection via ImageMagick
Although special shell characters were escaped, attackers discovered that whitespace or newline characters could still be used to inject arbitrary command-line arguments into the ImageMagick convert call. This meant that by carefully structuring the job payload, they could control how files were read or written.
Arbitrary File Read
ImageMagick supports reading files as raw pixel data using the gray: input format. By pointing this to a sensitive file (e.g., /etc/passwd), and choosing an output format that avoids truncation, the attacker could read file contents and save them to a temporary output file.
This confirmed the ability to exfiltrate local files from the server using image processing functions.
Arbitrary File Write
The attacker could:
- Create a dummy image file (e.g., a .bmp) containing arbitrary binary content
- Host this file on a server they control
- Instruct the vulnerable system to load this file and write its raw content to any location on the filesystem
- This allowed writing attacker-controlled files to paths like application_controller.rb.
Remote Code Execution (RCE)
With file write access confirmed, attackers were able to overwrite application files. For example, they replaced a controller file with one that:
- Read the User-Agent header for a trigger keyword
- Executed any system command that followed
- Wrote the result to a public file path on the server
- The application was then restarted (e.g., via modification of a known restart trigger file), activating the new backdoored code. By sending HTTP requests with specific headers, the attacker executed arbitrary system commands remotely.
Exploitation Constraints
The attack worked only if a security option called verify_urls was disabled. This setting normally ensures that requests to the image processor are signed using a shared secret and HMAC-SHA256 hashing. However, many applications either left this option disabled or misconfigured it.
Remediation Steps
To fully address this vulnerability:
- Upgrade the Dragonfly Ruby Gem to version 1.4.0 or newer
- Ensure verify_urls is enabled in the application’s configuration
Affected Systems
The vulnerability impacted systems using:
- Dragonfly for image processing
- Refinery CMS where image generation jobs were exposed
- ImageMagick when installed in default or permissive modes
Disclosure Timeline
- 27 April 2021 – Vulnerability reported to Refinery CMS maintainers
- 28 April 2021 – Maintainers confirmed issue
- 29 April 2021 – Escalated to Dragonfly maintainer
- 30 April 2021 – Dragonfly maintainer confirmed issue
- 18 May 2021 – Patch developed and validated
- 19 May 2021 – CVE request submitted
- 25 May 2021 – CVE-2021-33564 assigned