This document describes how to write parasitic file viruses infecting ELF executables. Though it contains a lot of source code, no actual virus is included. Every mentioned infection method is accompanied with a practical guide to detection.
The problem with answering this question is that those asking it know only OSes where viruses, trojan-horse programs, worms, nasty Java scripts, ActiveX controls with destructive payloads, and ordinary misbehaved applications are a constant threat to their computing. Therefore, they refuse to believe Linux could be different, no matter what they hear. And yet it is.
Writing a program that inserts code into another program file is one thing. Writing that program so that it can be injected itself is a very different art. Although this document shows a lot of code and technique, it is far from being a “Construction Kit For Dummies”. You can’t build a working virus just by copying whole lines from this text. Instead I’ll try to show how things work. Translation of infecting code to a assembly is left as (non-trivial) exercise to the reader.
An astonishing number of people think that viruses require secret black magic. Here you will find simple code that patches other executables. It is not hard to write a virus – once you have a good understanding of assembler, compiler, linker and operating system. It’s just hard to let it make any impact.
Regular users can’t overwrite system files (at least under serious operating systems). So you need root permissions. You can either trick the super user to run your virus. Or combine it with a root-exploit. But since all popular distributions come with checksum mechanisms, a single command can detect any modification. Unless you implement kernel-level stealth functionality…
I do believe that free software is superior, at least in regard to security. And I strongly oppose the argument that Linux viruses will flourish once it reaches a critical mass of popularity. On the contrary I question the credibility of people whose income relies on widespread use of ridiculously insecure operating systems.
The main difference between worms and viruses is persistence and speed. Modifications to files are usually permanent and remain after reboot. On the other hand a virus attached to a host can get active only when that host program is started. A worm takes immediate control of a running process and thus can propagate very fast.
Usually these techniques are combined to effectively cause mischief. Viruses can get resident, i.e. attach themselves to a part of the system that runs independent of the infected executable. Worms can modify system files to leave permanent back doors. And tricking the user into executing the very first infector is a lot easier than finding and exploiting buffer overflows.
But Unixes have traditional concepts to limit the possible damage of a malicious process. Network services can be run under the access permissions of a non-privileged account. File systems can be mounted read-only (e.g. /usr) or as noexec (e.g. /home). Some file systems have extended attributes that can prohibit access even when ls -l tells otherwise. Probably the strongest defense is chroot.
Every single one of these techniques can stop a vandalizing human, virus or worm to take over the entire machine. But while it is easy to control viruses, it is very hard to stop worms. To exploit a vulnerable network service a worm needs permissions for an incoming connection. To compromise the next machine on the network it needs an outgoing network connection. Nothing else.
The jargon files contain a good definition. For my purposes it is not technical enough, though.
A virus is a program that infects other programs stored in inactive form. This document concentrates on copying the executable code of the virus into another file. Other possible targets are boot sectors and programmable ROMs.
A worm is a program that penetrates other running programs. Penetration means to copy the executable code of the worm into the active process image of the host.
A trojan program is deliberately started by a user because of advertised features, but performs covert malicious actions.
The jargon files include programs infected by a virus into their definition of trojan. I don’t consider this helpful. The survival strategy of viruses is to stay below the level of perception of humans, operating systems or scanners. But trojans don’t hide. They obfuscate their real intend by delivering a good show. Good advertising can persuade the user to install necessary system components, deactivate security checks, and throw overboard all common sense.
The jargon files also claim that “a virus cannot infect other computers without assistance”. Widespread use of write-enabled network shares has made this a bold statement. It is correct that patching an executable file over the net is meaningless if that program is not executed somewhere. But I want to stress that it’s not the media containing the target that distinguishes worms from viruses. A virus polluting a RAM-disk is still a virus. A worm saved to disk by the hibernation feature of a laptop is still a worm.
I will now put on a black hat and an evil grin. Using material already published on the net, contributions sent to me, and all documentation available, I will try to build a virus to do in ELF for good. All concepts, ideas and experiments – along with enough working code to prove my conclusions – will be released to public ridicule through this document.
Anyway, it is not a problem if we, or someone using this document, succeeds. The correct name for that situation is opportunity. Should you happen to take this document – and especially above agenda – too seriously, the story of “Osama bin virus” can help.
This text written under influence of an evil grin.