How to detect an executable file?

A

Author

In my application, users can upload files and store them in a
database.

I would like to prevent them from uploading executable files. The
question is: How do I detect if it is an executable file?

I am not asking about checking the .exe extension, which is easy, and
unreliable because one can easily rename malicious.exe to
prettygirl.jpg.

If you have used gmail attachment, you would know.

I googled, but cannot find anything helpful. Your hint is highly
appreciated.
 
G

Geoffrey Summerhayes

In my application, users can upload files and store them in a
database.

I would like to prevent them from uploading executable files. The
question is: How do I detect if it is an executable file?

I am not asking about checking the .exe extension, which is easy, and
unreliable because one can easily rename malicious.exe to
prettygirl.jpg.

Actually those are usually named prettygirl.jpg.exe, relying on users
leaving the default for not showing known file extensions. Windows
uses the file extension to determine what to do with it, unlike Linux
which has bit settings to determine if it is executable.

Since unwanted files come in so many varieties, *.exe,*.com,*.scr,
*.bat,*.msi, etc. it is difficult to determine from looking at just
the
contents of the file without some context.

Another way would be to determine what files are allowed and check
to see that the uploaded file matches the specs.
 
A

Andrew Faust

I would like to prevent them from uploading executable files. The
question is: How do I detect if it is an executable file?

I am not asking about checking the .exe extension

The only way to know for sure is to actually look at the contents of the
file. You wouldn't need the whole file, just enough of the header to
determine whether or not it's an executable. Basically you'd need to upload
the file to a temporary location, inspect it then post to DB if valid or
delete if it's an executable.

You could also use some client side code (javascript, silverlight, java,
etc) to read the file and determine if it's an executable before sending it
to the server. If you did this you'd still need to have the server validate
it to ensure the user didn't bypass the client side check, though.

This site has the file formats for a bunch of different file types.
http://www.wotsit.org/list.asp?fc=5
 
A

Author

There is no 100% reliable way of doing this...

You can inspect the PostedFile.ContentType property of the uploaded file and
check that it's not "application/octet-stream":http://www.w3schools.com/media/media_mimeref.asp

but, as you point out, that can be bypassed by simply changing the file
extension. E.g. if you rename MyExecutable.exe to MyExectuable.pdf and
upload it, its PostedFile.ContentType property will be reported as
"application/pdf", so not much use...

A more robust method involves actually opening the file and reading in the
first few bytes to parse the header information - this is discussed here:http://forums.asp.net/p/1051895/1488103.aspx#1488103

This is quite a lot of work which, again, is not 100% reliable because not
all file formats store their header descriptors in exactly the same place..

Only you can decide how secure your app really needs to be...

Thank you very much, Mark. I'll definitely read through those
articles.
 
J

jp2msft

One possibility would be to attempt renaming the file's extension to one of
the known executable formats (as provided by Geoffrey Summerhayes earlier),
then attempt to start the process.

I'm guessing if you tried to execute an image file as an executable, it
would throw an exception.

If no exception is thrown, the file is probably running, and you should kill
the process and refuse the file.

Again, this is all theory. I haven't written anything that can verify any of
what I've just typed.

Good luck!
~Joe
 
M

Michael B. Trausch

In my application, users can upload files and store them in a
database.

I would like to prevent them from uploading executable files. The
question is: How do I detect if it is an executable file?

I am not asking about checking the .exe extension, which is easy, and
unreliable because one can easily rename malicious.exe to
prettygirl.jpg.

If you have used gmail attachment, you would know.

I googled, but cannot find anything helpful. Your hint is highly
appreciated.

The only reliable method for doing this is to work in the same way that
the UNIX 'file' command works, and inspect the file.

Many applications in the Windows world do _not_ do this (ironically,
some of them are _security_ applications). They'll block certain file
extensions or certain MIME types, which is just incorrect behavior.

Check out:
http://en.wikipedia.org/wiki/File_(Unix)

You can very likely use its database in your application and port the
"file" code into a library for C#. That way you can reliably detect
file types. The database is updated over time, as well, so if you
maintain the database external to your application instead of embedded
as a resource or something, you can deploy updates without rebuilding.

If you just want to catch the basic executable types, look for PE files
(a modification of the UNIX COFF executable format). To catch-all, you
can look for MZ, PE+, NE, and LE executables. If you want to filter
out executables that can be used on systems like most UNIX variants,
look for COFF, ELF, a.out/ZMAGIC/OMAGIC, etc. file types, too.

You then just open the file and detect what type it is based on the
information that you have. You can detect structured executables (and,
for example, whether or not they are CLR binaries or native code) and
data formats as well, so if you want to take the approach of
whitelisting file formats, you can do that as well.

You can't (reliably) catch straight binary programs (e.g., what used to
be known as .COM files for MS-DOS and compatible systems, but is also
the same sort of code that resides in a boot loader or master boot
record). However, these sorts of programs mostly cannot execute on
modern versions of Windows any longer, and do not present a danger
because most of the functionality that they use is prohibited by
Windows itself. Most of these types of programs are written to use
direct I/O or other hardware access.

--- Mike
 
M

Michael B. Trausch

One possibility would be to attempt renaming the file's extension to
one of the known executable formats (as provided by Geoffrey
Summerhayes earlier), then attempt to start the process.

Ouch. That would be one hell of an attack vector.

--- Mike
 
J

Jeff Johnson

One possibility would be to attempt renaming the file's extension to one
of
the known executable formats (as provided by Geoffrey Summerhayes
earlier),
then attempt to start the process.

....

Wow.

"Is this a virus?"

"I don't know, why don't you run it and see?"

That's basically what your suggestion amounts to.
 
M

Michael B. Trausch

Wow.

"Is this a virus?"

"I don't know, why don't you run it and see?"

That's basically what your suggestion amounts to.

I know someone who did that once. Actually their goal was to see how
compatible Wine was with real Windows, so they (intentionally!)
snatched a copy of "AntiVirus 2009" virus/trojan/malware.

Lo and behold, their entire ~/.wine directory had to be removed (after
removing data from it) so that they could use their installed Windows
applications again...

--- Mike
 
L

Larry Smith

Wow.
"Is this a virus?"

"I don't know, why don't you run it and see?"

That's basically what your suggestion amounts to.

An executable can always be started in suspend mode and then immediately
terminated. It's a brittle approach of course (on several fronts) and I
wouldn't want to buy the stock of any company that would.
 
L

Larry Smith

Larry Smith said:
Can this be done from .NET?

Not using native .NET AFAIK. You can P/Invoke into the OS however, assuming
it supports the ability to suspend an app at start-up (such as
"CreateProcess()" under Windows). I'm certainly not recommending it however.
It's dirty and potentially problematic to say the least (for the op's
purpose anyway). He may find the SHGFI_EXETYPE flag under "SHGetFileInfo()"
potentially useful however (though again, you have to jump outside .NET and
it may be brittle). Detecting "executable" code is non-trivial as others
have already pointed out (especially if you're treating .NET as the
OS-neutral platform it's supposed to be - in practice though most can treat
it for what it usually is - a glorified yet incomplete class library for
Windows).
 
M

Michael B. Trausch

An executable can always be started in suspend mode and then
immediately terminated. It's a brittle approach of course (on several
fronts) and I wouldn't want to buy the stock of any company that
would.

This would be alright if there were a cross-platform way to do it such
that the spawned process didn't get even a single timeslice. That
said, I'd imagine that doing this on Win32 is very different from doing
this on POSIX systems and non-POSIX workalikes.

That said, if it is brittle on a single platform (and lets not forget
that the CLR _is_ cross-platform, even if not 100% of the extensions to
it are) it's bound to be nearly impossible to do consistently and
cross-platform.

The most robust approach is to open the file and actually look at the
contents. Virtually all files that aren't simply free-form data have a
type that can be either explicitly or implicitly inferred by
inspection; for example, the UNIX 'file' utility can distinguish
between plain ASCII text and UTF-8 text, or plain ASCII text and HTML.

If there isn't a port of that utility into a managed code library,
there certainly ought to be. For that matter, many other Windows
programs should do detection this way; I know of servers in production
use that are Windows-based and trust the _client_ with details such as
file extensions and MIME types. These are the types of services that
will, for example, prohibit transmission of executable files by policy,
but you can rename from '.exe' to '.bin' or '.xxx' or virtually
anything else and it will go through just fine. (Of course, if you
rename it '.txt', it might also experience corruption along the way.)
And often, Windows programs don't look for binaries from other types of
systems like ELF files (which, when on systems that rely on file
extensions for identification should have its name end in '.elf').
Grossly insecure, since one could (at least in theory) compile a valid
Win32 program as an ELF file, transmit it to a Win32 host that already
has a trojan, and translate the file to a PE.

--- Mike
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top