Concurrency

Lecture Notes

This lecture will present an overview over issues involving concurrency between applications using shared resources.

Download here

Relevant files

Practical tasks

An example of the TOCTOU vulnerability can be found in the next snippet.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char** argv){
				if(argc != 2) {
								printf("Usage: %s file\n", argv[0]);
								return -1;
				}

				char *fn = argv[1];

				if(!access(fn, R_OK)) {
								printf("Showing the contents of %s\n",fn);
								char* buffer = malloc(1024);
								memset(buffer, 0, 1024);
                FILE* fp = fopen(fn, "r");
        
								while(1) {
												int r = fread(buffer, 1, 1024, fp);
												fwrite(buffer, 1, r, stdout);
												if(r <= 0)
																break;
								}
								fclose(fp);
								free(buffer);
				} else
								printf("Permission denied\n");

				return 0;
}

The code is vulnerable because the access function, determining that the Real user (by its real user id) can access the file, is done before the actual read. There is a window of opportunity between the access and fopen, where the file can be replaced.

Compile and prepare the file using:

gcc -o cat cat.c
sudo chown root cat
sudo chmod u+s cat

This sets the SET-UID bit, which will make the file execute with Effective User ID of 0 (root). However, the access function considers the Real User ID, not granting users with files that they should not have had access to. You can try to use the file to read /etc/passwd and /etc/shadow. The second will fail as expected due to invalid permissions.

You can test the file with:

./cat /etc/passwd

But the nice thing would be to use the file to access /etc/passwd.

Task:

  • Plan an attack to this binary allowing it to read /etc/shadow or any other priviledged file.
Previous
Next