More insecure webcams! Inattention to IoT security! Who would have thought?
Unfortunately, cybersecurity still seems to sit way down in Nth place for many vendors when they start programming their latest and greatest Internet of Things (IoT) devices.
In this case, the bugs are in a family of webcams – and not just any old webcams, but security webcams.
In other words, the very product you bought to protect you from real-world crooks plundering your warehouse at night could be the gateway for cybercrooks to plunder your network at any time.
This story, published by researchers at IoT security company VDOO, documents a sequence of security holes in various Foscam products.
Note. These bugs were responsibly disclosed by VDOO, and quickly fixed by Foscam, so that updates were ready before the details you see below were made public. In other words, the story is now safe to tell on educational grounds: the more we revisit security basics, the more likely we are, collectively, to get them right in the future.
It’s a fascinating reminder of how crooks can combine vulnerabilities that seem unimportant or unexploitable on their own into an “attack chain” that ultimately lets them take over a device entirely.
VDOO’s own post has the full technical details, but here’s our own high-level version.
By the way, we’ve added a fourth vulnerability, which we’ve given the number zero – a design decision that made things worse overall.
0. No privilege separation.
All system services on the devices VDOO analysed were running as
root, including the web server used to handle the camera’s administration interface.
Never do this!
Keep your system services as separate as you can, with a different user ID for each, so that they can’t read each other’s files or interfere with each others’ operation by mistake.
Even if system services need to start as
root, for example to open privileged network connections, make them drop privileges as soon as they can, for example by using
If you can run each system service entirely in its own directory sub-tree, for example by using
chroot(), do so.
chroot() turns a subdirectory into the virtual root directory, so that you can’t navigate upwards any further.
As a result, all the files above your own directory, and files in any neighbouring subdirectories, notably system directories, are effectively invisible and inaccessible, because you’re shut into your own subdirectory cul-de-sac.
Running everything as root makes designing, developing and testing your software much easier, and in a special-purpose device such as a camera, scanner, printer or router it’s easy to get away with – it’s not obvious to your users, who have no easy way to login and check which processes are running under what user ID.
However, just-use-root-everyhere is an unacceptable programming practice in 2018, and it will almost certainly end up costing both you and your customers in the long run.
1. Path traversal vulnerability.
The web server used on the vulnerable cameras has a function that lets you delete temporary images, even if you aren’t logged in.
Given that the files you can delete are supposed to be temporary, the lack of authentication doesn’t seem to matter here.
The problem is that the deletion function checked that the filename you provided started with a known temporary directory, e.g.
/snapPic/, but didn’t care what came next.
The web server assumed that any filename tacked on the end of the temporary directory was, of necessity, in or under that directory.
But a filename such as
/snapPic/../etc/passwd is not under
/snapPic, but alongside it, because
.. (two dots) is shorthand for “move up one directory and start again from there.”
In other words,
/snapPic/.. goes down from
/ into the
snapPic directory, then straight back up to
/, effectively cancelling out the reference to
In fact, if you aren’t sure where in the directory tree you are, you can write something like
snapPic/../.. [etc] ../../etc/passwd with as many repeats of the two-dots directory name as you like.
The operating system will go up as much as it can until it bumps its head at the root directory, and then ignore any superfluous dot-dot directory specifiers – you’ll often see the text string
../../../../.. [etc] in exploit attempts when the attackers don’t know how deep they are in the directory tree when they start out.
As a result, the filename
/snapPic/../etc/passwd is exactly the same as writing
/etc/passwd, the system file where usernames are stored.
passwd file gets its name because it was used, decades ago, to store hashed passwords as well as usernames, but for security reasons, Unix and Unix-like operating systems such as Linux don’t keep password data in there any more.
With this bug, and one or more carefully chosen files to delete, a crook can typically make all sorts of configuration changes by removing critical system data files.
For example, if you can delete configuration files that are used to lock down certain software components, you may be able to revert the system to known, insecure defaults, even though you can’t edit those configuration files line-by-line.
2. Buffer overflow vulnerability.
The VDOO researchers found a web server function that they refer to only as
getSWFlag (it doesn’t really matter what this function does, and in fact, we can’t tell you) that could be called with a parameter that’s too big for the data buffer used to store it in memory.
The buffer overflow caused the server process to crash almost immediately by overwriting a return address on the program’s stack.
The researchers didn’t need to figure out how to exploit this bug to execute remotely supplied code – all they wanted to do was to make the webserver stop on demand.
To keep the camera running even if the software fails, the operating system automatically restarts the dead service, so the researchers could use bug 1 to manipulate the web server’s setup, and immediately follow up with bug 2 to force the server to reload with its new, insecure configuration.
3. Input sanitisation vulnerability.
The researchers discovered a third web server function that could be tricked into taking text they supplied remotely and running it as a system command, a classic remote code execution (RCE) hole.
Simply put, a function that was supposed to take input in the form of a server identifier such as as
example.com could instead be sent a string of the form
example.com;command, which would be turned into two commands by the buggy web server.
That’s because the web server added the external input directly to an existing command, so instead of telling the system to run something like this…
ntpclient -s example.com
…the system could be tricked into running the following, using the system command shell to process the command text:
ntpclient -s example.com;telnetd -p 9999 -l /bin sh;
In a command shell, however, the semicolon character is a command separator, so the above command is equivalent to the two lines:
ntpclient -s example.com telnetd -p 9999 -l /bin/sh
The second of these commands opens a
telnet server listening on port 9999; if you connect to it, then instead of asking for a username and password, it simply opens up a remote command shell right away.
Why the attack chain?
You’re probably wondering why the researchers needed steps 1 and 2, given the apparent severity of bug 3.
The reason is that, although bug 3 was a critical RCE hole on its own, the bug could only be triggered if you were already logged in an as administrator, by which time you would already be in a position to wreak havoc if you wanted.
Keeping non-administrators away from functions to change the time and date on your device is important – if unauthenticated users could adjust the clock at will, they could render all your logs useless by deliberately timestamping them incorrectly.
However, thanks to bugs 1 and 2, the researchers could relaunch the web server insecurely, bypassing the authentication step and thereby making bug 3 instantly exploitable without putting in an administrator password.
And there you have it.
An example of how three exploits of different types can be combined for total, root-level device takeover: a security bypass (delete a file you oughtn’t), a denial of service (crash the web server on demand) and remote code execution (run a chosen command at will).
What to do?
- Check VDOO’s article to see if your camera is affected. If so, get the patch if you haven’t already – the vulnerabilities were responsibly disclosed to Foscam, and updates were available before VDOO went public with its analysis.
- Only run processes as root (or Admin on Windows) when you have to. Use the root account out of necessity, not merely convenience. If you aren’t familiar with the process of privilege separation, try this 15-minute video from Theo de Raadt of OpenBSD.
- Don’t rely on external data without checking it carefully. Characters in text strings that are harmless when you print them out, such as semicolons, quote marks, angle brackets, asterisks and many more, often mean different things to system functions than they do to human readers.
- When saving data in memory, always check that there’s enough space for it. As we saw in this story, even a buffer overflow that crashes a program without any immediate negative effects can sometimes be harnessed to help an attack chain along.
Never leave out a security or error check in your software on the assumption the condition you’re testing for “will never arise” because of similar checks done somewhere else, earlier on in the the code.
As an ancient proverb reminds us: There’s many a slip/’Twixt the cup and the lip.
4 comments on “Serious Security: How three minor bugs make one major exploit”
Is why folks win awards at security cons.
Thanks, Bryan. We appreciate your kind words!
If you think running an “Internet of things” device with all processes as root is bad, check out the default for windows 10 home as installed in the factory for an asus X540LA laptop computer. There’s no privilege separation, the default user account once the “first use” configuration has finished has administrator privileges. There’s no separate un-privileged user account for daily use like emails or internet browsing. That’s something I set up afterwards by myself.
It’s not true to say “there is no privilege separation” on Windows.
For example, not all system services run as the same account, so they can’t blindly trample on every other service at will.
And an account with admin privileges doesn’t run “as root” all the time – you will get a UAC prompt if the account tries to make use of its administrative privilege. That’s not quite as strong a protection as being asked for a password…
…but it does mean, for example, that malware you trigger by mistake doesn’t get unfettered access to your computer right away without so much as an “are you sure?” It also means that if you do have two user accounts on the same laptop, you can’t delete the other person’s files by accident.
You could argue, as I think you are, that Windows should be stricter about it by making you create two accounts, one with admin privileges and the other without, and then making you use the “lesser” account for day-to-day work.
But Windows 10 is not like the buggy camera device in the article, where every process has root power all the time, whether it needs it or not.