For Instance… Hackers Setting Your 3D Printer on Fire
The world is careening toward the reality that almost all electronics in your home and business are connected to the internet. Many of these devices contain things like heating elements, batteries, and motors that are entirely software-controlled. Do you… trust them? Coalfire decided to see how low the barrier was for hackers to attempt to cause life-threatening harm by weaponizing one of today’s increasingly common and cheap devices. In this three-part blog post, we will identify the target, uncover challenges, and hopefully answer our query above.
Part One: The Set-Up
Everyone would be scared if an attacker could remotely turn our ovens on to max temperature while we’re away from the house. Now imagine an attacker, remotely and without authentication, turning on an exposed heating element that goes even higher than that oven’s max temperature and will stay on indefinitely. That’s where we are today with 3D printers.
3D printers are becoming more common with no signs of slowing growth. As their price drops and their usability increases, they will soon become household staples, akin to ubiquitous paper printers. With this evolution, the need for security dramatically increases.
The Flashforge Finder is a popular $299 plug-and-play 3D printer with Wi-Fi-enabled by default, and over-the-network firmware updates. 3D printers are interesting targets because they possess heating elements to melt the plastic they print with. The heating elements in them are entirely regulated by the code in their firmware, which can be updated directly from the internet. In the Finder’s case, its max temperature is only 240 degrees Celsius. By reverse engineering the firmware with the new open-source NSA disassembler Ghidra, an attacker would be able to remove that temperature constraint.
One thing we’d like to stress is that the Flashforge Finder is not a specifically insecure or unsafe device. In fact, based on our research, it’s probably safer and more secure than most similar competing devices. The issues found are more indicative of security oversight in general among 3D printers rather than one-off issues with this specific model.
Many higher-end 3D printers host web services on open ports that allow for firmware updates similar to normal office paper printers. This means any 3D printers with those capabilities that are connected to the internet may be found via the Shodan search engine and flashed with fire-inducing firmware from anywhere in the world.
For our research project, we focused on a much more common, cheaper 3D printer that represents a much more significant share of ownership among nontechnical people including kids, who are unlikely to think about the critical security implications of owning such a device. In the specific case of the Flashforge Finder, the most consistent fire-creating attack path would look like this:
- Gain access to a Wi-Fi network with a Flashforge on it
- ARP spoof the printer using Bettercap
- DNS spoof the address of the public firmware repository that the printer reaches out to, also with Bettercap
- Host malicious firmware at the spoofed address
- Wait for the owner to update their firmware or do it yourself with physical access
- Run away from the coming inferno
It should be noted, that flashing the firmware may be unnecessary if the attacker doesn’t care if the fire starts immediately. The Flashforge Finder comes with port 8899 open with no authentication, which appears to be relatively common among IoT 3D printers. This port takes G-Code commands for performing actions such as increasing the temperature, extruding plastic, and moving the heated extruder tip around. A more remote, less consistent, and almost as dangerous attack path as the one above can be performed directly out of the box:
- Find a Flashforge Finder via Shodan search engine
- Connect to port 8899 (no authentication) via netcat
- Echo G-Code commands to the port to heat to max temperature and move the extruder head to the cheap, soft plastic edges of the printing bed
- Example to set the temperature to 240°C:
- echo -e "~M104 S240\r\n" > /dev/ttyS8
Molten plastic would then begin to drip all around the printer just waiting to encounter a flammable material and start combustion.
Acquiring the Firmware
Since Flashforge is stingy with giving access to their firmware, we tricked the printer into giving away its secrets. We connected the printer to our Wi-Fi network, put ourselves in between the printer and the internet via ARP spoofing, then hit the big update button from the Finder’s touchscreen. The tool Bettercap makes this ARP spoof attack easy.
And there it is: the address to their public repository of most of their firmware. When we first visited this URL, we found it had directory listing enabled which allowed us to grab the firmware from all of Flashforge’s products. A few weeks into the research, however, they removed this ability and now one must know the exact URL if they wish to download a file from the server. We downloaded the latest version and we were greeted with a zip file:
At first glance, it looks like the firmware might be the uImage-finder-332-20181130 file, but many of the other files are happy little surprises to a hacker’s eye. Shadow is the password file for Linux systems so we already have the password hash of the printer.
Rooting the 3D Printer
We acquired the printer firmware, but now we needed to root the printer to learn more about it and make reflashing it easier. Upon some internet searches, it appeared that a reddit user named Kegetys had rooted his Flashforge printer a few months prior to our research and learned the default root password was “123456.”
Flashforge likely found out about this and updated their firmware to include a new shadow file with a new password to prevent other users from rooting their printers. Turns out that gaining root SSH was not as simple as Kegetys remembered. The script flashforge_init.sh will run as root if it is detected on a USB, but one won’t get access to the touchscreen UI while the script runs, which is the easiest way of connecting to Wi-Fi. This means one would have to manually connect to Wi-Fi via CLI commands within flashforge_init.sh. Manually starting the wireless networking would require changing the wpa_supplicant.conf file as this is the file Linux uses to store Wi-Fi SSIDs and passwords. Below is the copied wpa_supplicant.conf file from the printer:
The printer comes stock with the ability to spin up an ad hoc wireless network named “flashforge” with the password “sz1234567.” Curiously, that sounded rather similar to the original root password of “123456.” We uploaded the printer’s shadow file hash to the password cracking tool JohnTheRipper and used the Guess Password button in its GUI to check “sz123456” against the new root password hash:
Bingo. We assume the sz prefix on the password comes from the city in China where Flashforge is based or builds the printers: Shenzhen.
Now we had the ability to run commands as root and we had the root password. Should just be a hop, skip, and jump away from a root SSH shell, right? Not quite. As we read the bash code in auto_run.sh and flashforge_init.sh it was clear auto_run.sh runs at boot, it mounts any USB found, checks for a flashforge_init.sh script, runs it, then continues with the rest of the various startup tasks. This means it’ll be easier to start the SSH server at the end of auto_run.sh so we can still access the touchscreen interface and connect to Wi-Fi over that. We uploaded a custom sshd_config file to the /opt directory and ran the SSH server:
Perfect! Now we’re done rooting the printer, right? Apparently not. Every time we tried logging in as root, we’d be told the root password expired and to change it. After changing it, it logs us out of the SSH prompt and upon relogging in we’d just be prompted to change the password over and over.
This was confusing as the shadow file says the root user shouldn’t need a password change for 99,999 days:
Fine. We decided to just shell the printer using Metasploit for further troubleshooting. The first step in this process was to identify the architecture that the shell will need to be compiled to. At the top of the flashforge_init.sh script the board architecture is labeled:
ARMv5TEJ is a known architecture type and the L at the end implies it’s little-endian. Msfvenom can be used for the creation of this payload using ARM little-endian as the architecture for the payload which is labeled “armle” in Metasploit:
click to enlarge image
We hijacked the flashforge_init.sh script again to copy this payload to the printer’s /opt directory with “cp /mnt/192.168.1.3-4000.shell /opt” and made it executable by adding “chmod a+x /opt/192.168.1.3-4000.shell” to the flashforge_init.sh script. The payload was executed at the end of the auto_run.sh script after a sleep statement to allow for Wi-Fi connection:
After starting our Metasploit exploit/multi/handler module to grab the incoming connection on port 4000, we restarted the printer and were greeted with a root shell. First we tried using the “chage” Linux command to set the root password to never expire. Didn’t work. Then we discovered that the printer resets its system time to the start of epoch time every time it’s rebooted. Epoch time is how Linux systems keep track of the date. It’s based on the number of seconds since midnight, January 1, 1970. Every time the printer booted, it reset its system time to think it was January 1, 1970. Although that date is over 18,000 days old and the root password is not supposed to be reset until 99,999 days, we still suspected this might be one of the causes. We set the system time to a more recent date, then updated the timestamp on the /etc/passwd and /etc/shadow using the “touch” command:
Success! Our workflow would now be much more convenient.
Identifying the Firmware Binary
Now, we can finally start reversing the firmware. But before we can do that, we need to know what file in the firmware folder is the actual firmware. The flashforge_init.sh script was the most likely candidate for clues. The top of the script contained the following information:
The uImage-finder* file is clearly the bootable kernel for the board, the architecture is ARMv5, and the script seems to think the two hex files in the firmware zip folder are rather important as well. Let’s look at what the script does with those hex files:
By reading the /data/log/finder-plus-arm.log file via SSH, we know that only the finder_plus.hex file is burned to the printer and not finder2.hex. According to the highlighted code above, the script echoes some values into some GPIO files, then the ISPFinderPlusISP file takes the hex file as an argument, apparently burning it to a chip on the motherboard. If that fails, then it prints an update failure to the printer’s touchscreen. Based on this, we can infer that the finder_plus.hex file is likely the actual firmware that we’re going to want to modify in order to change the max temperature of the printer. In most firmware reversing projects, the tool binwalk would be used here to learn about and extract the firmware image. In this case, however, since it’s a raw hex file, binwalk isn’t of any use to us and as we continued with the project it proved to be unnecessary anyway.
In Part Two of this blog series, we will show you how to reverse engineer and patch the firmware hex file using only the new free open-source NSA tool Ghidra. While we had access to many expensive reverse engineering platforms such as Binary Ninja and IDA Pro, it turns out that Ghidra is very easy to use and more than capable of this complex task. Even people with zero reverse engineering experience will be able to follow along as we try to weaponize this 3D printer into a fire bomb. Stay tuned!