Skip to content

Instantly share code, notes, and snippets.

@mclosson
Created June 29, 2016 08:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mclosson/e52e12515f5d8649ecd482d809e7ef5a to your computer and use it in GitHub Desktop.
Save mclosson/e52e12515f5d8649ecd482d809e7ef5a to your computer and use it in GitHub Desktop.
/* The following program is an example of a setup program which generates a
* secret key and writes it to a file which is only readably by the owner of
* the file.
*
* In this example the program should be made owned by root and the wheel group
* and the suid (set user ID) permission should be set so that when a regular
* user runs the program, the secrets.txt file will be created and owned by the
* root user.
*
* Your goal is to try to find a way without modifying the code of the program
* to be able to read the secrets.txt file created without modifying the code
* for this program or becoming root by using su, sudo or other means.
*
* This program has been tested on:
* FreeBSD 10.2-RELEASE amd64 / FreeBSD clang version 3.4.1
* OSX 10.10.5 / Apple LLVM version 7.0.2 (clang-700.1.81)
* GNU/Linux 3.13.0-24 / gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1)
*
* To compile and run on FreeBSD / OSX with clang:
* $ cc -Wall -o setup setup.c
* $ sudo chown root:wheel setup
* $ sudo chmod u+s setup
* $ ./setup
* $ cat secrets.txt
* cat: secrets.txt: Permission denied
*
* To compile on GNU/Linux with gcc:
* $ sudo apt-get -y install libbsd-dev
* $ cc -std=gnu99 -Wall -o setup setup.c -lbsd
* $ sudo chown root:root setup
* $ sudo chmod u+s setup
* $ ./setup
* $ cat secrets.txt
* cat: secrets.txt: Permission denied
*
* Comments or Questions?
* @MatthewClosson
*
*/
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifdef __linux__
#include <bsd/stdlib.h>
#endif
void generate_secret(char *secret);
void write_file(char *secret);
int main(int argc, const char *argv[])
{
char secret[22];
generate_secret(secret);
write_file(secret);
exit(EXIT_SUCCESS);
}
void generate_secret (char *secret)
{
int secret_size = 20;
char hexchars[] = "0123456789ABCDEF";
for (int i = 0; i < secret_size; i++) {
secret[i] = hexchars[arc4random() % 16];
}
secret[secret_size] = '\n';
secret[secret_size + 1] = '\0';
}
void write_file(char *secret)
{
int fd = open("secrets.txt", O_CREAT | O_WRONLY, 0700);
if (fd == -1) {
perror("secrets.txt");
exit(EXIT_FAILURE);
}
printf("Writing to secrets.txt file...");
write(fd, secret, strlen(secret));
close(fd);
printf("done.\n");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment