/pretask2.c Secret
Created
December 28, 2021 14:45
セキュリティミニキャンプオンライン2021「Linuxシステムプログラミング入門:コンテナ技術を支える名前空間」 演習課題 #4
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
#define _GNU_SOURCE | |
#include <sched.h> | |
#include <signal.h> | |
#include <sys/mman.h> | |
#include <sys/types.h> | |
#include <sys/wait.h> | |
#include <unistd.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#define OUTPUT_BUFFER_SIZE 1024 | |
int execute_binary(const char* const binary, char* const buffer, const size_t bufsize); | |
int main(){ | |
char buf[OUTPUT_BUFFER_SIZE] = {0}; | |
int r = execute_binary("/bin/ls", buf, OUTPUT_BUFFER_SIZE); | |
if(r >= 0){ | |
buf[r] = '\0'; | |
printf("read %d bytes\n%s\n", r, buf); | |
} else { | |
printf("error %d\n", r); | |
} | |
} | |
int child_proc(void* arg) { | |
char *path = (char *)arg; | |
char *argv[] = {path, NULL}; // argv | |
char *env[] = {NULL}; // envp | |
/* execve */ | |
execve(path, argv, env); | |
exit(EXIT_FAILURE); | |
} | |
int execute_binary(const char* const binary, char* const buffer, const size_t bufsize) { | |
void *stack; // stack for child process | |
pid_t child_pid; // child pid | |
int status; // child process status | |
int tmp_fd; // temp file descriptors(STDOUT_FILENO) | |
int pipe_fd[2]; // file descriptors (pipe_fd[0]: read, pipe_fd[1]: write) | |
ssize_t sz; // read size | |
/* make pipe */ | |
if(pipe(pipe_fd) == -1) { | |
puts("pipe failed!\n"); | |
return -1; | |
} | |
/* make stack */ | |
stack = mmap(NULL, 1024*1024, PROT_READ|PROT_WRITE, | |
MAP_PRIVATE|MAP_ANONYMOUS|MAP_GROWSDOWN|MAP_STACK,-1,0); | |
if(stack == MAP_FAILED) { | |
puts("mmap failed!\n"); | |
return -1; | |
} | |
/* switch fd */ | |
tmp_fd = dup(STDOUT_FILENO); | |
dup2(pipe_fd[1], STDOUT_FILENO); | |
/* exec binary */ | |
child_pid = clone(child_proc, stack+1024*1024, SIGCHLD, binary); | |
/* restore STDOUT_FILENO fd */ | |
dup2(tmp_fd, STDOUT_FILENO); | |
if(child_pid == -1) { | |
puts("clone failed!\n"); | |
return -1; | |
} | |
waitpid(child_pid, &status, 0); | |
/* check status */ | |
if(status != 0) { | |
puts("execve failed!\n"); | |
return -1; | |
} | |
/* read */ | |
sz = read(pipe_fd[0], buffer, bufsize); | |
if(sz < 0) { | |
puts("read failed!\n"); | |
return -1; | |
} | |
return sz; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment