Home Assignment 2a › hacker track › assignment2-177 Digital test Mon, 20 Apr Submit
Aryan
Had to open two terminals for this one. One frantically writing to the script file, the other watching for the binary to drop it. Very dramatic. Very 'hacker in a movie' energy.
Aryan

See the assignment's PDF available on BrightSpace for task descriptions and submission requirements.

Level 2

2
(1) Explain what were the vulnerabilities of the target program of this level.
(2) Explain how you exploited the aforementioned vulnerabilities to get access to the next level.
Your explanations must be clear and not miss any detail. Take care that with your explanations a reader would be able to exploit the target program.
Answer
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pwd.h>

const char SCRIPT_CONTENTS[] = 
    "#!/bin/bash\n"
    "echo 'I am executing as group' $(id -gn)\n"
    "# TODO: the rest of this script, parsing user input\n";
const char FILE_NAME[] = "/.runtime.sh";
const int USER_INPUT_BUFFER_SIZE = 1024;

int main() {
    uid_t uid = getuid();
    char* dir = getpwuid(uid)->pw_dir;
    char* file_loc = (char*) malloc(strlen(dir) + strlen(FILE_NAME) + 1);
    strcpy(file_loc, dir);
    strcat(file_loc, FILE_NAME);
    FILE* output = fopen(file_loc, "w");
    if(output == NULL) {
        printf("Failed to create runtime at %s\n", file_loc);
        return 1;
    }
    size_t result = fwrite(SCRIPT_CONTENTS, 1, sizeof(SCRIPT_CONTENTS) - 1, output);
    if(result != sizeof(SCRIPT_CONTENTS) - 1) {
        printf("Failed to write to file %s\n", file_loc);
        fclose(output);
        return 1;
    }
    fclose(output);
    char user_input[USER_INPUT_BUFFER_SIZE];
    printf("Enter some valid input: ");
    char* input_result = fgets(user_input, USER_INPUT_BUFFER_SIZE, stdin);
    if(input_result == NULL) {
        printf("Failed to read input\n");
        return 1;
    }
    execl("/bin/bash", "/bin/bash", file_loc, user_input, (char*) NULL);
    free(file_loc);
    return 0;
}
Level 2 terminal

1. It's a TOCTOU. Time of check to time of use. When you run the code: First, it fetches your user ID and uses that to get the home directory. directory. Then, using the home directory, it creates a buffer and allocates memory to make a string of your home directory + the file name /.runtime.sh. Then it has the path "/home/students177/.runtime.sh" and what it does is it uses the fopen() function to open the file and write into it (the w parameter will create the file, and if it already exists, it will overwrite the contents). Then what it does is it writes the script contents which is a predefined string SCRIPT_CONTENTS[], INTO THE FILe. But this file is in our home directory, meaning that we can access it. Now what it does is it closes the file using fclose() and the file is sitting in our home directory containing the bash script. And we have to enter some valid input, which means it pauses the program until we type enter. Only after we press enter, it executes the script, which is in our home directory, using execl. So it will be so it will run using elevated privileges, the priviledges of that file. But since that file is in our home directory, and the program pauses, we have a window to alter the contents of the file.

2. Exploiting the vulnerability is very easy to do. All you have to do is run the program and when the program pauses you have to alter the script /.runtime.sh which that is in your home directory. Which you can do in multiple ways you can either open a new SSH session or you can just open another terminal or you can use a program like like zellij to run multiple terminals in the same window. What matters is that when the program pauses asking you to enter some valid input, you should alter the file in the other terminal and append a newline and 'escalte' so it runs the escalate command. will be running the escalate command So it will run that command when it runs the script.

Script Write Race
The binary writes a bash script to the user's home dir, then executes it. In the window between write and execute, we overwrite the script with our own payload. When the binary runs it, it runs our code with elevated privileges.