Know Your IoT Product: From 1997 Code to 2025 Devices

Thus it is said that one who knows the enemy and knows himself will not be endangered in a hundred engagements. One who does not know the enemy but knows himself will sometimes be victorious, sometimes meet with defeat. One who knows neither the enemy nor himself will invariably be defeated in every engagement.

– Sun Tzu

In the 2000s, most of us thought that each year we could worry less about memory or CPU usage in our code. We thought that thanks to Mr. Moore's friends, powerful hardware was becoming available to everyone. But it's 2025, and IoT has caught us off guard. IoT is forcing us to code more efficiently due to hardware limitations. Though embedded devices have existed for decades, the world has changed significantly - IoT is literally everywhere, and many more people are working with/on it. We've returned to the era of low-end hardware.

Just as we've returned to low-end hardware, IoT seems to have brought back old (low-end?) software too. By old, I mean sometimes really old - like PHP 2 (aka PHP/FI) from 1997. Believe it or not, some IoT and network device manufacturers are still using PHP/FI from 1997 in their 2025 products.

During our research on IoT and embedded devices, we've encountered numerous old and vulnerable software components in the latest product versions. It's so common that you get used to it after a while. While manufacturers release their newest products containing ancient software, threat actors use the same old methods and vulnerabilities to distribute ransomware, set up botnets, or conduct cyber espionage.

In this blog post, I'll examine the PHP/FI case, discuss why vulnerability research on legacy software is essential, and talk about SBOM and the importance of knowing your product and its threats.

The case of PHP/FI

During a recent security assessment of a MIPS-based firmware from a popular IoT device, I encountered PHP/FI - a relic from 1997! To give you some background, PHP/FI (Personal Home Page/Forms Interpreter) was developed for use in CGI (Common Gateway Interface) applications. The way it works is like any other CGI program:

  1. HTTP server: receives an HTTP request
  2. HTTP server: parses the request and performs evaluation
  3. HTTP server: executes the PHP/FI binary with the requested PHP CGI script as a command-line argument
  4. HTTP server: sets up CGI-specific environment variables (e.g., HTTP_METHOD, REQUEST_URI)
  5. HTTP server: writes POST body to PHP/FI's stdin file descriptor
  6. PHP/FI: interprets the script, processes the data, and writes a response to stdout
  7. Finally, HTTP server reads the response and passes it to the user

In 1997 we had limited knowledge about software vulnerabilities - this was only a year after 'Smashing The Stack For Fun And Profit' appeared in Phrack #49. So I decided to apply modern vulnerability research and fuzz PHP/FI, thinking it would uncover things we had no clue about back then.

Comparing the decompiled code and the PHP/FI source code from the PHP museum website revealed that the binary has some extra stuff in it and is a bit customized. I wanted to fuzz the source code, but because of the code differences decided to fuzz the binary instead.

To fuzz PHP/FI (or any other CGI program), we have three kinds of media:

  1. Input script: targeting PHP/FI code parsing and interpreting (local attacks)
  2. Environment variables: targeting user-supplied input parsing (remote attacks)
  3. HTTP request body: targeting user-supplied input parsing (remote attacks)

I fuzzed the PHP/FI interpreter using AFL++ QEMU mode. For the corpus, I used PHP scripts from the firmware plus PHP/FI test files from the source code bundle available at PHP Museum.

Fuzzing 28-year-old PHP/FI for 25 minutes led to 110 unique crashes! Spending more time will lead to a lot more.

I also targeted the HTTP request body parser which didn’t lead to any finding. Fuzzing the environment variables also led to one finding.

My point is that it's easy to find vulnerabilities in old software. If you look for PHP/FI (v2.0.1) CVEs, you will see that there are a lot of them. But interestingly, as far as I reviewed, none of those CVEs are applicable to PHP/FI. They are for higher versions of PHP which are not even compatible with PHP/FI. Those vulnerabilities are affecting the components introduced in later versions but considered to affect all previous versions, which is wrong.

Modern cybersecurity vulnerability research rarely focuses on outdated and legacy codebases, causing us to miss many vulnerabilities present in IoT and embedded stacks. We really need this archaeological approach to vulnerability research.

The necessity of vulnerability research on old software

It's a reality that embedded device vendors commonly don't prioritize security. Pick a few random 2025 firmwares from various vendors, check the versions of some components, and then look for CVEs (not applicable in all situations as we saw before) for those versions. You'll see that products contain outdated and vulnerable components. However, not all vulnerabilities in old software components have been discovered yet. There's much more to uncover, but since we usually focus on the latest versions, we miss them.

Some vendors have built products on now-deprecated components and continue using them for years (or decades) because of migration costs. Some vendors keep old software to avoid making major changes. Some vendors are somewhat caring - they'll patch critical vulnerabilities if it doesn't involve extensive work. Few vendors go further to keep their products secure.

On the research side, I think there are three mistaken assumptions that prevent us from doing vulnerability research on old software:

  1. Old software isn't used anymore, so results would be useless
  2. Vulnerabilities in old software, if not discovered before, can be found in newer versions as well
  3. It’s redoing previous work

We've seen that the first assumption is not valid - 28-year-old PHP/FI is still in use. For the second assumption, we need to consider that some parts of software may get deprecated or rewritten. In PHP's case for example, the first few major versions had significant changes and aren't backward compatible, meaning some functionalities are completely gone. On the third assumption, while vulnerability research on old software may overlap with prior work, it doesn't mean all vulnerabilities have been discovered. Sometimes new techniques are invented that have never been applied to those old codes. Knowledge develops - we can look into the past with new glasses!

The business side

If you're an IoT/embedded vendor, you most likely have outdated components in your latest products. Any outdated component can become an unexpected entry point for attacks.

Keeping outdated and vulnerable components while not investing in security may provide short-term gains, but in the long run, it will lead to both financial and reputational losses. Recent history provides many examples of this.

You need to keep your product secure, and to do that, you first need to know your product and what threatens it.

You need to know your product, and SBOM (software bill of materials) is the tool for that. An SBOM is a nested inventory, a list of ingredients that make up software components. SBOM should contain literally every software component used in a product.

Let's consider an example: a Wi-Fi router. Wi-Fi routers typically run Linux and have a web interface for configuration management, DHCP server, and sometimes an SSH server. These components are visible on the surface. Beyond these, Wi-Fi routers have a Wi-Fi stack that handles over-the-air communication, parsing, and cryptography. They also use many libraries for different functions: libc, libm, openssl, libgcc, zlib, libz, busybox, JSON libraries, XML libraries, and many more. Some include lua interpreters, PHP, or MicroPython. Linux-based firmware can consist of 30 to several hundred components, and finding all of them and their versions is no easy task.

For more compact devices that can't support an entire operating system, the story is a bit different. These devices have RTOS, an OS abstraction, or nothing at all. All these examples still consist of several components and might be outdated and vulnerable. They might have legacy TCP/IP or Bluetooth stacks, CAN Bus, or other protocol stacks and libraries for various purposes. Finding software components in these devices is much more difficult.

To make and keep your products secure, you need to identify these components and figure out if they're vulnerable or outdated. You need to know your product, and here we can help!

At Keysight, we've developed solutions to extract SBOM from your products, show you vulnerable components with detailed information about each one, and test your product to find product-specific vulnerabilities as well as known and unknown vulnerabilities in your third-party components.

IoT/embedded vendors can use our solution to find outdated and vulnerable components and improve the security of their products.

Customers of IoT/embedded devices can use our solution to uncover weaknesses in the products they are using or planning to use, so they can decide which products or vendors to go with and which ones to avoid.

Learn more about our IoT Security Assessment suite that empowers you to analyze firmware, extract accurate SBOM, find vulnerable components, and discover zero-days in both homegrown and third-party components.

limit
3