do not step out
race condition
22/Sep/2005 | 10:16

How Comcast Rooted My Box

"Dude, this is a worm or root kit."

Merv was thinking the same thing I was. It would be another half-hour before we were confident no maliciousness had taken place, and in that time I would wonder just what data existed that I could actually trust. My first thought: "Not much."

My second thought: "Less than that."

Perhaps we should begin with a story.

My mother is a nurse at a high-security psychiatric facility. When she began working there, they gave her a lanyard to which to clip her identification badges so she could hang them from her neck. When I heard about this, my first thought was: "Why did they give her something to wear around her neck in a facility that houses disturbed, violent patients?" We're talking people who can't stop themselves from killing other people, here. Arkham Asylum.

Aside: The casual way in which she recants stories of patients killing people inside the facility amazes me.

As I studied the lanyard, I noticed a few things about it. Not only was it made of a pliable rubber-band-like material which would easily stretch and break if tension were applied, but there were three breakpoints along the lanyard: two deep scoring marks at opposite sides, and a loose button snap in the back. It's too small to break at the scoring marks and still have a useful weapon without stretching the material, and the material will break when stretched out. It's a pretty smart design.

This article is about smart design, and how a well-known Internet service provider fails at it miserably. Let's see if we can prompt some change.

a = (dv)/(dt)

A passenger train barrels down a track that leads toward a city on the distant horizon. The track is switched: about a mile up ahead of the train, there's a switch control (called a ground throw, located at a split section of track called a turnout) that controls the direction of the train. To the east, the city; to the north, a blocked-off section of track that leads to a bridgeless cliff shear.

Everyone knows about the cliff shear, so it's always assumed that the track is switched to take trains to the city. In fact, there have only been two reported incidents of trains careening to their dooms in the last 100 years, and as a result, no one at the train station pays much mind to the state of things at the turnout.

Still, the conductor always announces his or her intention to travel along the east track. Today, someone's listening in on the conductor's radio, and as soon as he hears the conductor announce where he's going, a race begins to get to the ground throw.

"He thinks he's going to go east, but I'm going to switch the track on him," says the evildoer.

Sure enough, the evildoer arrives at the ground throw before the train and its conductor. The tracks are switched, the conductor decides to take a bathroom break after making his radio call, and the train quietly slips off the end of the northbound track into the ravine before anyone can say Isaac Newton.

For a moment, imagine you have a trusted program (train) and a trojan horse (evildoer) instead. When your trusted program attempts to write to a location in the file system, the trojan attempts to write to the same location first. Essentially, the outcome of operations is based on the timing of the events.

This is called a race condition.

The Glass Bead Game

Our trusted program creates a file in the Mac OS X temporary items folder, /private/tmp. (In traditional Unix systems, this is simply /tmp. We Mac people are weird like that.) It's a pretty simple file, nothing too significant. A temporary activity log, let's say.[1]

/private/tmp is world-writable by default:

[thermodynamics:~] mikey% ls -lad /private/tmp
drwxrwxrwt 11 root wheel 374 Sep 22 04:56 /private/tmp

The activity log operation is pretty typical: if /private/tmp/$UID/TrustedApp.out doesn't exist, create it and open it for writing, and if it does exist, just open it for writing. Empty contents into glass. Wipe hands on pants.

The trojan has other plans. It symlinks /mach_kernel (the Mac OS X kernel itself) to /private/tmp/$UID/TrustedApp.out before the trusted app can gain access to the temp file. Luckily for you, the trusted app isn't running as the root user, so mach_kernel can't be fooled with.


Kiss That Frog

Things begin to fall into place when we reveal the final piece of the scenario:

Let's imagine for a second that our trusted app has the setuid flag enabled. The setuid flag—for programs that have it enabled—tells the system to assign elevated or otherwise altered privileges to the program as the program is being run. When a setuid program is executed, it gains the privileges of its owner.

I can hear you thinking to yourself: "If my trusted app is owned by root and has the setuid flag enabled, that trojan is going to fuck me up."

You'd be right. When a setuid program owned by root is launched, it runs as root without requiring authentication.

Setuid is useful, but it's dangerous if you don't know what you're doing. You wouldn't give a hatchet to a six-year-old, would you? (At least, not unless you're looking for a good laugh, anyway.)

I didn't bring you all this way for nothing. Charge on.

Alarm Will Sound

I was playing around with some items in my home folder a few days ago, when I stumbled upon these four files that I didn't recognize:

-rwsr-sr-x 1 root admin 255676 Aug 7 01:23 .netprefs
-rw-r--r-- 1 root admin 36 Aug 7 01:23 .netprefs_current
-rw-r--r-- 1 root admin 43740 Aug 7 01:23 .netprefs_services
-rw-r--r-- 1 root admin 7490 Aug 7 01:23 .netprefs_sets
-rw-r--r-- 1 root admin 501 Aug 7 01:23 .netprefs_system

The s bits for owner and group permissions on the ".netprefs" file indicate setuid and setgid (set group ID) are in effect. Since everyone is allowed to execute the file, the program is going to run as root:admin without even asking.


This was hidden inside my home directory? Yes, it was.

But who put it there? Where did a setuid 0 program in my home directory come from?

The four files that accompanied the suspicious executable were human-readable XML files. The .netprefs_services file, for example, contained every bit of information about my network interface setup:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
[. . .]

Another file, .netprefs_current, contained a rather strange serial number that I have yet to identify—the only line of text in the entire file. (For this reason, I don't feel comfortable posting its contents here.)

And then I took a hard swallow:

[thermodynamics:~] mikey% strings .netprefs
[. . .]
/bin/rm -rf "
/usr/bin/killall "
[. . .]

The file was a compiled binary, but good ol' strings provided me with a little bit of plain-text insight here.

Reviewing what we hitherto knew:

1. A setuid 0 app appeared out of nowhere on my computer.
2. What appear to be files associated with it contain detailed network information about my computer.
3. It runs some sort of rm -rf and killall commands at some point, under some unknown condition(s).

I dug through every remotely relevant log inside every log folder on my PowerBook. Nothing weird matched the datestamp on the .netprefs* files. My Mac OS X Server box didn't have the files at all. Merv's rig didn't have the files present, either.

But Nic, he had a story to tell:

-rwsr-sr-x 1 root Nic 255676 Jun 25 14:27 .netprefs
-rw-r--r-- 1 root Nic 1 Jun 25 14:28 .netprefs_current
-rw-r--r-- 1 root Nic 22634 Jun 25 14:28 .netprefs_services
-rw-r--r-- 1 root Nic 4504 Jun 25 14:28 .netprefs_sets
-rw-r--r-- 1 root Nic 478 Jun 25 14:28 .netprefs_system

What did Nic and I have in common? PowerBooks and Tiger, but not a whole lot of similar software. Turns out, we had one big, stupid thing in common:


Those morons. I then remembered their setup program erroring out and ceasing to work when I attempted to set up the new Interweb connection here, just like it had done on every other computer on which I had run it, and suddenly things clicked into place. I knew their setup software was poorly designed and really quite pathetic before, but this took pathetic to all new levels.

It only took me a couple of minutes to dig out the setup CD and verify the program's origin.

Switching tense here. Hold on to your hats.

From what I can tell, their setup software is a compiled excutable that scrapes the network configuration data from your computer, attempts to write a new configuration, and uses an AppleScript to control Internet Explorer (and only Internet Explorer) to guide you through filling out the setup forms.

For this, this simple set of tasks, they ran and installed a setuid 0 program. They compromised the basic security of many people's computers to set up an Internet connection. A malicious person is essentially given an open door to pwning potentially any Mac user who has used Comcast in the past for high-speed Internet service. HEY LET'S GIVE YOU INTERNET ACCESS AND THEN PULL DOWN YOUR PANTS. Are you fucking kidding me?

There's no telling what kind of other potential security issues exist with their setup program for which its setuid flags could be an accelerant. It's only a matter of time before a malicous person finds something like this—just like always in the world of security—and at that point, they simply need write a trojan that executes the ~/.netprefs file on launch.

From what I can tell, their setup system doesn't need to run as setuid to accomplish its tasks. I bet I could completely re-implement it in AppleScript Studio and it would be improved tenfold.

For more information about setuid and race conditions, check out these links:

Man page: setuid - checklist for security of setuid programs

Avoid Race Conditions

To e-mail Comcast and complain about their sub-standard software, head over to this page:


To see if the monster is hiding in the attic, turn to page 42.

Update the First

It's been pointed out that one may want to remove these files if they exist. I do recommend getting rid of this garbage.

You'll need to log in as an administrator user for this. Please don't typo[2]:

sudo /bin/rm ~/.netprefs*

Enter your administrator password when prompted.

Update the Second

Before the comments were removed (see below), someone pointed out that setuid was disabled in Panther. This is not accurate. In Panther, Apple disabled setuid and setgid for scripts only—compiled binary executables still run respectful of setuid and setgid. If setuid and setgid were disabled for compiled binaries, many things would simply stop working. See for yourself if you're unsure how important setuid is to Mac OS X:

ls -la /usr/libexec /sbin /usr/sbin | grep 'r.s'

Even pretending all setuid and setgid functions are disabled in current versions of Mac OS X, it's still terrible software design on Comcast's part—a complete lack of future sight. From an even more pragmatic perspective, I constantly find people who still run Jaguar. This is simply part of the real world, where new toys cost money.

Of course, I really didn't expect much from a company that requires MSIE in order to complete a damned cable modem setup. I've been through their horrid setup process before, and it always ends the same: I call them, they enable the service with my MAC address manually.

Why did I bother running their setup software if I knew it was total crap to begin with? I almost didn't. I decided to see if anything had changed from previous experiences with both my computers and customers' computers, and as expected, nothing had changed. It's a shame that with the amount of money we pay Comcast for their service we can't get a setup process that isn't pathetically anemic.

If no one's watching, they won't have a reason to improve.

[1] I usually recommend, for the sake of cleanliness, using /private/tmp/$UID for storing temporary files for applications. But that's just me, and like I said, I'm weird.

[2] Seriously. Don't typo. I'm not responsible for damages, catastrophes, or the further decline of the U.S. economy if something goes wrong.


Comments have been removed and disabled for this article because some have little better to do than come here and be deconstructive children.

I sincerely apologize to those who were constructive. You guys are cool, and the input was definitely appreciated!

Note to those squinting:

There's a high-contrast version of /damage coming. I simply need to find some time to implement it the way I want to. I run a rather dark ColorSync profile, so I don't need it—but I understand what people are having problems with. I'll post about it when it happens, don't worry.

posted by mikey-san on September 22, 2005 at 18:11