Created
February 16, 2020 21:05
-
-
Save ppkarwasz/b5fd2c2686bb3f66e6f8681b2ff047c4 to your computer and use it in GitHub Desktop.
Small remote command execution
This file contains hidden or 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
#include <stdio.h> | |
#include <stdlib.h> | |
#include "libwrapper.h" | |
int main(int argc, char *const argv[]) { | |
int ctrl = prepare_socket(true); | |
if (argc < 2) { | |
fprintf(stderr, "Usage: %s command\n", argv[0]); | |
exit(1); | |
} | |
if (write_args(ctrl, argv + 1)) { | |
printf("Arguments sent.\n"); | |
} | |
} |
This file contains hidden or 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
#include "libwrapper.h" | |
#include <stdio.h> | |
#include <signal.h> | |
#include <stdbool.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <unistd.h> | |
#include <sys/types.h> | |
#include <sys/socket.h> | |
#include <sys/un.h> | |
#include <sys/wait.h> | |
#define BUF_LEN 1024 | |
static const char *const sock_path = "socket"; | |
static char buf[1024]; | |
void spawn_new(pid_t* child, char *const argv[]) { | |
int wstatus; | |
int new_pid; | |
if (argv[0] == NULL) { | |
return; | |
} | |
/* Kill old child */ | |
if (*child > 0) { | |
kill(*child, SIGTERM); | |
waitpid(*child, &wstatus, 0); | |
} | |
/* Spawn new child */ | |
if ((new_pid = fork()) == -1) { | |
fprintf(stderr, "Unable to fork.\n"); | |
} else if (new_pid > 0) { | |
*child = new_pid; | |
} else if (execv(argv[0], argv) == -1) { | |
fprintf(stderr, "Unable to run '%s'.\n", argv[0]); | |
} | |
} | |
int prepare_socket(bool is_client) { | |
int ctrl = socket(AF_UNIX, SOCK_STREAM, 0); | |
if (ctrl == -1) { | |
fprintf(stderr, "Unable to create UNIX socket.\n"); | |
exit(1); | |
} | |
struct sockaddr_un addr; | |
memset(&addr, 0, sizeof(addr)); | |
addr.sun_family = AF_UNIX; | |
strncpy(addr.sun_path, sock_path, sizeof(addr.sun_path) - 1); | |
if (is_client) { | |
if (connect(ctrl, (struct sockaddr*)&addr, sizeof(addr)) == -1) { | |
fprintf(stderr, "Unable to connect to UNIX socket.\n"); | |
exit(1); | |
} | |
} else { | |
if (bind(ctrl, (struct sockaddr*)&addr, sizeof(addr)) == -1) { | |
fprintf(stderr, "Unable to bind UNIX socket.\n"); | |
exit(1); | |
} | |
if (listen(ctrl, 10) == -1) { | |
fprintf(stderr, "Unable to listen on UNIX socket.\n"); | |
exit(1); | |
} | |
printf("Listening.\n"); | |
} | |
return ctrl; | |
} | |
char ** read_args(int fd) { | |
int bytes_read = read(fd, buf, sizeof(buf)); | |
if (bytes_read == -1 || bytes_read > BUF_LEN) { | |
fprintf(stderr, "Unable to read from socket.\n"); | |
return NULL; | |
} | |
int len = *(int*)buf; | |
char** result = (char**) malloc((len + 1) * sizeof(char*)); | |
result[len] = NULL; | |
char* src = buf + sizeof(int); | |
for (int i = 0; i < len; i++) { | |
int param_len = strnlen(src, buf + BUF_LEN - src); | |
result[i] = strndup(src, buf + BUF_LEN - src); | |
src += param_len + 1; | |
} | |
return result; | |
} | |
static int arrlen(char *const array[]) { | |
int i = 0; | |
char *const *ptr = array; | |
while (*ptr != NULL) { | |
i++; | |
ptr++; | |
} | |
return i; | |
} | |
bool write_args(int fd, char *const argv[]) { | |
int len = arrlen(argv); | |
((int*)buf)[0] = len; | |
char* dst = buf + sizeof(int); | |
char *const *param = argv; | |
while (dst < buf + BUF_LEN && *param != NULL) { | |
int param_len = strlen(*param); | |
strncpy(dst, *param, buf + BUF_LEN - dst); | |
dst += param_len + 1; | |
param++; | |
} | |
if (dst >= buf + BUF_LEN) { | |
fprintf(stderr, "Buffer full.\n"); | |
return false; | |
} | |
if (write(fd, buf, dst - buf) == -1) { | |
fprintf(stderr, "Write failed.\n"); | |
return false; | |
} | |
return true; | |
} |
This file contains hidden or 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
#ifndef LIBWRAPPER_H | |
#define LIBWRAPPER_H | |
#include <stdbool.h> | |
#include <sys/types.h> | |
void spawn_new(pid_t* child, char *const argv[]); | |
int prepare_socket(bool is_client); | |
char** read_args(int fd); | |
bool write_args(int fd, char *const argv[]); | |
#endif |
This file contains hidden or 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
#include <stdio.h> | |
#include <unistd.h> | |
#include <sys/socket.h> | |
#include <sys/un.h> | |
#include "libwrapper.h" | |
int main(int argc, char *const argv[]) { | |
int ctrl = prepare_socket(false); | |
pid_t child = -1; | |
struct sockaddr_un remote; | |
socklen_t remote_len; | |
int client_fd; | |
while ((client_fd = accept(ctrl, (struct sockaddr *)&remote, &remote_len)) != -1) { | |
char** new_args = read_args(client_fd); | |
if (new_args != NULL) { | |
spawn_new(&child, new_args); | |
} | |
close(client_fd); | |
} | |
perror(NULL); | |
close(ctrl); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment