3 ms·
How exactly is this a bug in Win32? We can argue about whether or not this was a good design choice, but it wasn’t Win32 that opened an HTTP connection, wrote t
by CurtHagenlocher 8y ago
How exactly is this a bug in Win32? We can argue about whether or not this was a good design choice, but it wasn’t Win32 that opened an HTTP connection, wrote the response stream to disk and then executed the file without any kind of validation.
- Analemma_ 8y agoLinden probably deserves the bulk of the blame, but it is a little weird that, if Windows sees a file with an .exe extension that but no PE structure, it will just happily take whatever bits it gets and run them directly. But I guess if COM executables genuinely had no structure than there was nothing else that could be done. Yet again, back-compatibility is Microsoft's savior and curse at once.
- tedunangst 8y agoFortunately this can never happen on linux. The kernel would never interpret a header less executable file as a shell script and invoke it with sh.
- jjnoakes 8y agoThe Linux kernel won't, but most shells happily will. 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.
- danso 8y agoAs much as I want to blame Windows for it, this seems like reasonable behavior if the updater software is passing bytes straight from the HTTP stream. Unfortunate that the 404 page happened to have a byte sequence that would be interpreted as a COM, but the Updater should have been validating the downloaded exe in the first place. Not just for 404 but for actual .exe files that may be malicious
- duskwuff 8y ago> Unfortunate that the 404 page happened to have a byte sequence that would be interpreted as a COM 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.
- ajross 8y agoCOM files indeed had no structure. DOS would load the file contents to the bottom 64k of memory starting at 0x100, set code, data and stack segments to zero, the stack pointer to zero (so the first push would wrap around to 64k), and jump to 0x100. And that was as much complexity at the linkage had. 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.
- pjc50 8y agoCOM files have no structure; they're loaded directly into a segment and control transferred to the first byte. I think the smallest valid COM file is a single return instruction. Or you can have one file interpreted multiple ways: http://www.nyx.net/~gthompso/poly/polyglot.txt http://www.nyx.net/~gthompso/poly/polyglot.txt
- catpolice 8y agoCertainly the bulk of the blame falls on Second Life and the printer manufacturers for not validating inputs. 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.
- gruez 8y ago>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.
- cptskippy 8y ago> 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 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.