Module to retrieve privilege to processes.
3c1a53d2029af8aaf19ab04983497d4575d25c39406d48c1321172829309cb20
/*
* megas.c, by pmsac@toxyn.org, 1998
*
* Just another ripp off from:
* - cocain.c, by pmsac@toxyn.org, 1998, which is a rip off:
* - heroin.c, by Runar Jensen, zarq@opaque.org, 1998(?), from BugTraq
* - itf.c v0.8, by plaguez, dube0866@eurobretagne.fr, 1997, from Phrack52
*
* gcc -Wall -O3 -fomit-frame-pointer -c megas.c
*
*/
#define MODULE
#define __KERNEL__
#define VERSION_COUNT sn199807290335
#include <linux/proc_fs.h>
#include <linux/module.h>
#include <linux/limits.h>
#include <sys/syscall.h>
/* Examine, Allow */
#define EXAMINE 0
#define ALLOW 1
char *TASKSTR[][2] = {
{ "pine", NULL },
{ "pine", "joe" },
{ "bash", "ls" },
{ "bash", "rmmod" },
{ NULL, NULL }
};
#define PID 0
#define SIGDEBUG 31
#define SIGSANE 10
#define SIGCOUNT 0
extern void *sys_call_table[];
int errno;
int VERSION_COUNT = 0;
int debug = 0;
int __NR_myexecve;
#define TMPBINMAXLEN (PATH_MAX + 1)
int (*oldKill)(pid_t, int);
int (*oldExecve)(const char *, const char *[], const char *[]);
void cleanup_module(void);
#define DEBUG(X); if (debug) printk(X);
#define DEBUG2(X,Y); if (debug) printk(X,Y);
#define DEBUG3(X,Y,Z); if (debug) printk(X,Y,Z);
int newKill(pid_t pid, int sig) {
int ret;
DEBUG("newKill()\n");
if ((pid != PID) ||
((sig != SIGCOUNT) &&
(sig != SIGDEBUG) &&
(sig != SIGSANE))) {
DEBUG("-> oldKill()...\n");
ret = (*oldKill)(pid, sig);
if (ret == -1)
return (-errno);
return(ret);
}
if (sig == SIGCOUNT) {
DEBUG("-> Toggling usage count...\n");
VERSION_COUNT ^= 1;
if (VERSION_COUNT)
MOD_INC_USE_COUNT;
else
MOD_DEC_USE_COUNT;
}
if (sig == SIGSANE) {
DEBUG("-> Sanitizing module, pls remove by hand...\n");
while (VERSION_COUNT != 0) {
MOD_DEC_USE_COUNT;
VERSION_COUNT--;
}
cleanup_module();
}
if (sig == SIGDEBUG) {
DEBUG("-> Toggling debugging...\n");
debug ^= 1;
}
DEBUG("-> Returning...\n");
return(0);
}
int cryptic_execve(const char *filename, const char *argv[], const char *envp[])
{
long __res;
__asm__ volatile ("int $0x80":"=a" (__res):"0"(__NR_myexecve), "b"((long) (filename)), "c"((long) (argv)), "d"((long) (envp)));
return (int) __res;
}
int newExecve(const char *bin, const char *argv[], const char *envp[]) {
int ret;
int allow = 0;
int spotted = 0;
char *tmpBinName;
DEBUG("newExecve()\n");
DEBUG("-> Allocating kernel space...\n");
tmpBinName = (char *) kmalloc(TMPBINMAXLEN, GFP_KERNEL);
DEBUG("-> Copying to kernel space...\n");
memcpy_fromfs(tmpBinName, bin, TMPBINMAXLEN);
DEBUG2("-> bin == %s\n", tmpBinName);
DEBUG("-> Examining list...\n");
for (ret = 0; TASKSTR[ret][EXAMINE] != NULL; ret++) {
if (TASKSTR[ret][ALLOW] == NULL) {
DEBUG("-> Deny all (further ?)...\n");
break;
}
if (strstr(current->comm, TASKSTR[ret][EXAMINE]) != NULL) {
DEBUG3("-> Spotted... %s/%s\n", TASKSTR[ret][EXAMINE], TASKSTR[ret][ALLOW]);
spotted = 1;
if (strstr(tmpBinName, TASKSTR[ret][ALLOW]) != NULL) {
DEBUG("-> List allowed...\n");
allow = 1;
break;
}
}
}
DEBUG("-> Deallocating kernel space...\n");
if ((TASKSTR[ret][EXAMINE] == NULL) && !spotted) {
DEBUG("-> Unlisted, allowing...\n");
allow = 1;
}
if (allow) {
DEBUG("-> Allowed, oldExecve()...\n");
ret = (*cryptic_execve)(bin, argv, envp);
return (ret);
}
DEBUG("-> Not allowed, -EPERM...\n");
return(-EPERM);
}
int init_module(void) {
DEBUG("init_module()\n");
DEBUG("-> Replacing kill()...\n");
oldKill = sys_call_table[SYS_kill];
sys_call_table[SYS_kill] = newKill;
DEBUG("-> Replacing execve()...\n");
__NR_myexecve = 164;
while (__NR_myexecve != 0 && sys_call_table[__NR_myexecve] != 0)
__NR_myexecve--;
oldExecve = sys_call_table[SYS_execve];
if (__NR_myexecve != 0) {
sys_call_table[__NR_myexecve] = oldExecve;
sys_call_table[SYS_execve] = newExecve;
}
DEBUG("-> Returning...\n");
return 0;
}
void cleanup_module(void) {
DEBUG("cleanup_module()\n");
DEBUG("-> Restoring kill()...\n");
sys_call_table[SYS_kill] = oldKill;
DEBUG("-> Restoring execve()...\n");
sys_call_table[SYS_execve] = oldExecve;
DEBUG("-> Restoring __NR_myexecve");
if (__NR_myexecve != 0)
sys_call_table[__NR_myexecve] = 0;
DEBUG("-> Returning\n");
}