Preface
Again in 2016, I used to be a passionate mechanical engineering pupil. Although I by no means graduated and ultimately pivoted into AppSec, my love for engineering by no means pale. Quick ahead to 2023, I purchased a 3D printer – enjoying round with mechanics once more. Naturally, I started merging this interest with my safety background, main me to hunt out vulnerabilities in 3D printing software program.
Throughout one in every of our in-company white hat hacking actions, I took the chance to look at a number of 3D printing open supply merchandise. Certainly one of them was UltiMaker Cura, a preferred slicer that in accordance with UltiMaker’s web site is trusted by tens of millions (extra on slicers quickly). After scanning Cura with Checkmarx SAST, I uncovered a possible lead for code injection vulnerability, now tracked as CVE-2024-8374.
On this weblog put up, we’ll study the susceptible circulate and exploitation of CVE-2024-8374. We’ll additionally share insights into the affect of such vulnerabilities on the open supply 3D printing neighborhood. Lastly, we’ll spotlight key takeaways from UltiMaker’s wonderful response.
Introduction
Slicers
First issues first, what precisely is a slicer?
Merely put, a slicer is a program that’s accountable for remodeling a 3D mannequin right into a set of directions (i.e. a gcode file) that the 3D printer can observe to bodily print the mannequin.
Slicing is a crucial a part of the 3D printing course of, and it can’t be skipped. Because the identify suggests, the slicer divides the 3D mannequin into layers and offers a set of directions for each, reminiscent of temperature, velocity, and extra. The printer then processes these directions, layer by layer, when printing.
A typical circulate of printing a 3D mannequin is:
- Acquiring a mannequin (e.g., obtain from a public mannequin database or design it your self)
- Slicing the mannequin (e.g., with UltiMaker Cura)
- Hit PRINT
- Benefit from the 3D print
3D Fashions Codecs
Earlier than diving into Cura’s supply code, we have to take a step again and first talk about the file codecs utilized in 3D printing. There are completely different 3D fashions codecs, every with completely different properties and functions.
The most well-liked format for 3D printing is known as STL. One other widespread format is the 3MF that’s basically a ZIP archive with the `.3mf`extension holding the mannequin knowledge in XML together with a group of metadata recordsdata.
The recognition of 3MF is quickly rising as a result of it provides capabilities that the well-known STL format doesn’t present, reminiscent of coloration printing. It’s additionally gained reputation as a result of it’s backed by trade leaders together with Autodesk and Dassault Systèmes. All of those make it one of the vital broadly used codecs for 3D printing.
Most significantly, it serves as our payload entry level.
The Vulnerability
Our journey to Cura’s supply code begins within the `_read` technique of the `3MFReader.py` plugin, which is accountable for loading 3MF fashions into Cura earlier than slicing.
Let’s begin by analyzing this technique (the essential strains are highlighted in yellow):
- The perform accepts a `file_name` parameter, which is the trail to the 3MF mannequin we wish to slice (line of code).
- The 3MF mannequin is then parsed by a ZIP reader (as talked about earlier, a 3MF file is a ZIP archive) (line of code).
- The file `3dmodel.mannequin` is learn from the archive. This file comprises the precise mannequin knowledge within the XML format. Notice that Cura shops this data in a variable known as `scene_3mf` (line of code).
- Remodeling every node from our 3MF file into an UltiMaker format. Notice that the `node` is handed within the first parameter of `_convertSavitarNodeToUMNode` (line of code).
Analyzing the circulate additional, we are able to transfer ahead to `_convertSavitarNodeToUMNode`. This perform is sort of lengthy, and most of it’s not related to us, so we’ll solely give attention to the precise strains which our enter flows to:
The `node` variable handed by the `_read` perform is now known as `savitar_node` contained in the perform `_convertSavitarNodeToUMNode` (line of code)
- Settings are extracted from the `savitar_node` (line of code)
- If `settings` is outlined, Cura tries so as to add them (line of code)
- Whereas iterating every setting, Cura could discover that the `drop_to_buildplate` is outlined (line of code)
- As soon as that occurs, the worth of this setting will find yourself in a name to `eval` which ends up in code execution (line of code).
Exploitation
By now plainly we now have a weak spot as a result of we didn’t see any type of sanitization within the execution circulate.
To take advantage of it, we have to confirm that we are able to management the `drop_to_buildplate` property and, in that case, to grasp the legitimate XML construction wherein we are able to place the payload.
Looking for recognized details about the 3MF format didn’t reveal a lot concerning the `drop_to_buildplate` property. Nevertheless, it regarded like this can be a function that’s particular to Cura and never utilized by different slicers, which makes discovering this setting in publicly obtainable fashions fairly difficult. Guessing the proper XML format additionally doesn’t appear to be the most effective strategy on this case. One other different is to dive deeper into the supply code to be taught the suitable format for setting Cura configurations. However fortuitously, I discovered a neater method:
Since we all know that this property is exclusive to Cura, we might be able to use it to create a legitimate XML mannequin that comprises the `drop_to_buildplate` property for the payload.
Let’s attempt that by downloading any 3MF mannequin from a public mannequin database. Notice that we don’t care about the rest however the format (.3mf) of the file. For instance, within the picture beneath you may see that the precise mannequin that I downloaded was created by OnShape (line #9), which is a 3D design software program, however quickly this metadata will probably be overridden.
Now, let’s load this 3MF file into Cura and export it again to a 3MF format. The metadata will probably be transformed to the format utilized by Cura.
Extracting `3dmodel.mannequin` from the 3MF archive we now have simply exported confirms our success, revealing a legitimate 3MF mannequin with Cura’s metadata, together with the `drop_to_buildplate` property (line #6):
Let’s substitute the worth of `drop_to_buildplate` with Python code that spawns a calculator:
The one factor left to do now could be to open our crafted mannequin with Cura-
Let’s spotlight just a few issues concerning the exploitation:
- The code is executed with the default Cura configuration.
- The code runs instantly, even earlier than the mannequin is loaded. There’s no must slice or carry out any motion in Cura.
- The mannequin stays fully legitimate after tampering, making it seem respectable from the person’s perspective.
- The one solution to determine this mannequin as malicious is by analyzing the XML knowledge.
This permits a malicious actor to simply obtain, modify, and redistribute widespread fashions for exploitation.
However that’s not all – but.
A Notice About Provide Chain Assaults
We all know already that this vulnerability is sort of easy to use. Moreover, past mannequin databases like Printables and Thingiverse, that are widespread amongst makers and hobbyists, there are additionally open supply repositories for engineering-focused tasks, usually utilized by delicate sectors reminiscent of nationwide safety contractors, healthcare engineers, and others. The engineers use fundamental fashions in a number of methods, reminiscent of constructing blocks for their very own designs or testing functions. The open supply nature of the 3D printing trade makes such vulnerabilities a possible goal for provide chain assaults.
The Repair
The repair is simple: the maintainers eliminated the pointless eval name and changed it with strict Boolean parsing, as proven right here:
One other factor to notice is that UltiMaker didn’t reveal any details about the vulnerability of their commit’s remark:
That is essential as a result of malicious actors regularly scan GitHub for vulnerabilities that have been mounted however not but launched.
UltiMaker’s Response
UltiMaker responded and acted shortly, implementing a repair inside lower than 24 hours. The repair was launched within the subsequent beta launch `5.8.0-beta.1` on 16 Jul. UltiMkaer’s safety crew was very responsive and gave all of the required data for a clean disclosure course of.
All in all, working with UltiMaker to handle this difficulty was an excellent expertise, they usually’ve actually earned Checkmarx’s Seal of Approval.
References
Timeline
- 15 June 2024 – Preliminary contact made with the UltiMaker’s Safety crew by way of safety@ultimaker.com, offering a complete report on the vulnerability.
- 16 June 2024 – UltiMaker responded, confirming the vulnerability. A repair was subsequently carried out and dedicated on the identical day.
- 16 July 2024 – Model 5.8.0-beta.1, containing the repair, was launched.
- 1 August 2024 – Steady model 5.8.0, containing the repair, was launched.
- 3 September 2024 – CVE quantity assigned.