A couple years back, I preordered the Yoggie Pico Pro (tiny little USB security device with an ARM CPU that acts as a firewall, spam filter, anti-virus, etc for your PC) with the intention of breaking it. A couple hours after it arrived on release day, I had code running on it. How? Well, they had a web interface on the device, which allowed you to ping hosts on your network for testing purposes. I noticed they were showing standard busybox ping output, so I tried out the basics: semicolons, ampersands, etc. They seemed to be throwing a null in at the first instance of a semicolon or other special characters, cutting off your command and preventing exploitation. What they didn't replace were backticks. So if the string was "ping %s" and you threw in "`pwd`", you would see "ping: unknown host /path". From here, exploitation is obvious; I got SSH up and running in no time and had a beautiful little ARM Linux box at my disposal. You can see the advisory at http://secunia.com/advisories/25902 if you're curious. This was a short project, but it was a whole lot of fun.
Definitely a bug, but don't you have to log in to the administrative interface to access those forms in the first place? On D-Link routers I've played with, that interface was password protected and was the mechanism for uploading new firmware anyway.
Create a web site with user-friendly instructions on configuring your router for popular games. (Port forwarding, etc..) Hustle for good Google rankings.
For each game, have an instruction sheet. Each instruction sheet is two pages long.
The first page tells you how to log into your router.
The second page contains the malicious <img> tag as described by JoachimSchipper, as well as genuine instructions to complete your router config. (If you want to hit multiple router firmwares, just include multiple <img> tags, each with its own parameters.)
From there, you can gain remote admin access to the router. Presumably, you'd want to automate whatever you're doing to people. So, after people visit the second instruction page, run a script that reconfigures the router however you please.
At this point, the sky's the limit, but might I suggest uploading your own firmware such as DD-WRT. From there, you could do all kinds of things, from the silly (replacing all downloaded images with kittens) to the nefarious (stealing passwords on all non-SSL sites).
Standard disclaimer: I'm not writing this to help the bad guys. They already know what to do. This is food for thought for the good guys.
I daresay if you included "...and you'll need to add this certificate to your browser..." you could get a good number of people installing your Totally Trustworthy Root Cert(tm) and do a bit of HTTPS MitM as well.
Makes it more likely someone will notice and you'll get flagged though I suppose.
What would be even easier and more evil is to inject some backdoor into every (non ssl) executable download. Then you can just install a keylogger or patch the browser or whatever else you please.
You're right. I hadn't thought of that, but it strikes me as one of the nastier attacks I've heard of in a while. Just think of how many downloadable packages require root privileges to install.
IIRC, the exploit goes like this: get the victim to log in on their router (typically HTTP Basic auth) and convince them to go to a site that contains e.g.
This is why at a minimum you should change your ports to non-standard - it may only be temporary security by obscurity but it will at least prevent basic script-kiddie attacks.
I'm sure there are similar devices that make the same mistakes even for the login screen. For me, this article isn't so much about this particular device, but more a very clear and illustrative guide to how easy it is to get root access to many little linux-driven devices.
FTA:
"since Web
access requires authentication, this bug might
be exploitable by administrators only, so it is
only useful for people who would like to gain a
shell on their own systems"
In general, I'm surprised that there isn't some sort of printf symbol for a shell-escaped string. Seems like this is something that would have been immensely useful even in the 90's. This would negate the possibility of 'semi-colon injection.'
I'm sure every shell has different quirks. Not to mention new versions of the shell come out, which could cause problems if you want the output of the format string to remain comparable with old data.
The worst problem of course is you end up with things like PHP's real_mysql_escape_string($str), which i would hate to have condensed into sprintf(buff, "%rmes", str). Let alone different versions for ksh/zsh/{insert thirty years of UNIX history here}.
You don't need to parse every little piece of syntactic sugar that is introduced by various shells. You're trying to produce something that will be parsed as a string literal. For the most part, non-alpha-numeric characters should just be escaped. If all non-[:alphanum:] characters were escaped regardless of need, I can't think of anything that would accidentally parse as anything dynamic in any of the shells out there.
Also, the most common case would be system(sprintf(...)). This should just pass the command onto the shell in compatibility mode, meaning most of the extra sugar should be disabled. Even all of zsh's string parsing sugar needs to be turned on (disabled by default).
Ignoring all of that, the most common thing that you want properly escaped would be:
- Semi-colon to prevent injection.
- Spaces to make sure that the string is parsed as a single arg.
- Quotes and double-quotes because you want them to be part of the argument text and not part of the shell's syntax.
Even that short list of requirements would be useful.