MS Windows Once Caused Second Life To Break An Inkjet Printer
nwn.blogs.com
nwn.blogs.com
The winner put the drive on a table, connected with a cable, but not attached to a case. Then he wrote a routine that slammed the read head to one side, then slowly moved it back. Each time the routine looped, the drive would scoot across the table until it finally fell off the edge.
I'm still not sure I read that right, but man was it fascinating to think about all the control one could wield over the head of one's high school electronics teacher and his room full of new PC's.
Ouch. Talk about failing open.
>A Win32 executable file begins with a so-called "MZ" header, followed by a so-called "PE" header. If the "PE" header cannot be found, then the loader attempts to load the program as a Win16 executable file, which consists of an "MZ" header followed by an "NE" header.
>If neither a "PE" nor an "NE" header can be found after the "MZ" header, then the loader attempts to load the program as an MS-DOS relocatable executable. If not even an "MZ" header can be found, then the loader attempt to load the program as an MS-DOS non-relocatable executable (aka "COM format" since this is the format of CP/M .COM files).
echo 'ls' > test.sh
chmod +x test.sh
./test.sh # Works just fine, no header
and since the C library routine "system()" executes the command via /bin/sh, system("./test.sh") works fine too.That's the thing. Any byte sequence which didn't have an EXE header was interpreted as a COM executable. And in the (NT)VDM environment, there aren't a lot of illegal operations, so executing random data (like an HTML error page) can cause quite a bit of unpredictable behavior before it crashes or gets caught in a loop.
It's almost hard to remember how easy it was to deal with the hardware back then. We view things as simpler now, but just getting a toolchain installed via rustup or npm or whatever is multiple blog posts of complexity, vs. the paragraph above plus a half-sheet of paper required to scribble down the instruction set and BIOS hooks.
Or you can have one file interpreted multiple ways: http://www.nyx.net/~gthompso/poly/polyglot.txt
But there's another valuable lesson about interpreting binary/string blobs: don't make guesses about the format of the data from its value. You'll eventually get data that looks like one thing but isn't, and do the wrong thing with it.
I run into this all the time. Just a couple weeks ago I spent a lot of time trying to track down a bug where a programmer had decided to use a de-serialization function that would take the value of a JSON field, look for an internal object with that ID and either return the object it found or initialize a new object using the string as a value (and a random ID). So guess what happened when I tried to create a new object with a value that happened to be the same as the ID of an existing object?
The Win32 issue is just looking at the first few bytes of the input to determine its format (and how to try executing it) - it's somewhat hard to avoid here for legacy reasons, but a better design would use metadata associated with the input to determine its format rather than guessing.
how would that have prevented this incident? if the metadata is stored in the filesystem (as opposed to the file contents), chances are, the updater is going to blindly mark whatever it downloaded as "an executable". if it's part of the file contents, it's essentially the same as magic bytes.
You could say the same about the file extension, meta data or any other means.
The best thing you can do is write your code to validate the input and to fail early, explicitly, and safely if it runs into a problem.
Years later I found myself wondering how that even worked in the first place. Surely the chance of generating a valid executable was basically zero. Now I know why.
I wish I had kept that executable, it would've been interesting to disassemble it.
XF86Config used to come with similar dire warnings about not overdriving monitors.
-lets eval() this random piece of bytes we got from non secure connection
-lets curl | sudo sh