We have obtained our target firmware, extracted a Linux file system,
found and cracked an admin password hash,
reverse engineered a shared object file to extract an encryption key,
and decrypted a configuration file to find default credentials
to a storage service and voicemail account.
Let's keep going to see what else we can find with Ghidra.
On the left‑hand side of the window, we see a pane called Symbol Tree.
This identifies the modules, functions, classes,
namespaces, and so on used by the libcmm shared object file.
The imports folder identifies functionality that originates
from outside the libcmm shared object file,
for example, the underlying operating system.
There are no hard and fast rules for prioritizing
which imported functions we look at, but a good first candidate is system.
System through the execute system function is used to make
calls to the underlying operating system.
We saw in an earlier demo that just about everything in the OS runs as root,
so any calls to system will likely run as root.
Making calls to system like this is really bad from a
security perspective so we won't find many,
right?
Wrong.
There are hundreds of calls which we can see by scrolling
through and expanding the various branches in the function
call trees in the lower left pane.
If we pick one, say oal_ipt_addBridgeIsolationRules,
we can see the decompiled function and how it makes calls to execute system.
The function receives a parameter and makes a call to the
operating system to run an iptables command.
The iptables command is constructed to incorporate the
parameter passed to the function, which is presumably an IP address.
It's likely that this functionality has been built‑in to allow users to
set firewall rules through an application interface.
The user specifies an IP address in a web application
which is passed to this function.
It's then built into the iptables command which is sent to the OS.
But what if instead of providing an IP address,
we provided some other value such as a command that could be executed by the OS.
There is no sanitization of the input parameter to ensure it's in the
form of an IP address so we could send anything.
This function seems to be a prime candidate for a
command injection vulnerability.
The intent with this device is that a user can access the web
interface of the router and set firewall rules.
The user will browse to the relevant page,
enter an IP address for which the rules should apply,
and click OK.
Internally, the firmware takes the IP address,
builds it into the iptables command,
and makes a call to the operating system to execute it.
The web application would then usually provide some confirmation back to
the user that the rule has been successfully applied.
But as there is no sanitation of the input,
instead of an IP address, we could enter anything.
This would then be built‑in to the iptables command and
okay it may generate some errors,
but it will in all likelihood still execute our command,
potentially given us access to sensitive information.
We've come a long way reverse engineers,
and for this course, we're just about done.
But up next,
we'll look at some resources to take your hardware
product testing skills to the next level.