Nebula level10 – Exploiting access() syscall TOCTOU Race Condition

Share it!

In this level, they provide the following C source code:

#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

int main(int argc, char **argv)
{
char *file;
char *host;

if(argc < 3) {
printf("%s file host\n\tsends file to host if you have access to it\n", argv[0]);
exit(1);
}

file = argv[1];
host = argv[2];

if(access(argv[1], R_OK) == 0) {
int fd;
int ffd;
int rc;
struct sockaddr_in sin;
char buffer[4096];

printf("Connecting to %s:18211 .. ", host); fflush(stdout);

fd = socket(AF_INET, SOCK_STREAM, 0);

memset(&amp;amp;amp;amp;sin, 0, sizeof(struct sockaddr_in));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr(host);
sin.sin_port = htons(18211);

if(connect(fd, (void *)&amp;amp;amp;amp;sin, sizeof(struct sockaddr_in)) == -1) {
printf("Unable to connect to host %s\n", host);
exit(EXIT_FAILURE);
}

#define HITHERE ".oO Oo.\n"
if(write(fd, HITHERE, strlen(HITHERE)) == -1) {
printf("Unable to write banner to host %s\n", host);
exit(EXIT_FAILURE);
}
#undef HITHERE

printf("Connected!\nSending file .. "); fflush(stdout);

ffd = open(file, O_RDONLY);
if(ffd == -1) {
printf("Damn. Unable to open file\n");
exit(EXIT_FAILURE);
}

rc = read(ffd, buffer, sizeof(buffer));
if(rc == -1) {
printf("Unable to read from file: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}

write(fd, buffer, rc);

printf("wrote file!\n");

} else {
printf("You don't have access to %s\n", file);
}
}

This binary takes a file and send it to a specified host on 18211 tcp port ( if you have the right privileges to do so )

First I did was use some static source code analizer, flawfinder, to see where is the vuln, although nebula guys give us a clue :

«The setuid binary at /home/flag10/flag10 binary will upload any file given, as long as it meets the requirements of the access() system call. »

That´s what flawfinder shows:

«level10.c:24: [4] (race) access: This usually indicates a security flaw. If an attacker can change anything along the path between the call to access() and the file’s actual use (e.g., by moving files), the attacker can exploit the race condition. Set up the correct permissions (e.g., using setuid()) and try to open the file directly.

After a bit research through these links [1],[2],[3] and a lot more research, tried a lot more several times and being stuck for many hours, I concluded that TOCTOU ( Time of Check Time of Use ) security flaw attack it´s like if you tell to your friend :

– Hey, take that xbox360, and before you pick up the xbox i´ve changed it by another, and of course you play the xbox that I want ( probably three red circles one ) :P

Problem here arises with the «timing» between system calls ( executed by a setuid binary ), access and open the file given, because the file might be removed or symlinked to another, and this is due of accessing files using filnenames rather than file handlers and file descriptors.

To resolve that level, i had to open a different terminal with a netcat loop trying to get data on port 18211. You´ve to do a netcat loop because the program closes the connection after each upload attempt,that´s how :

Second script as follows :

nebula-level10-3

Trying to run this scenario ( but without & parameter ), i coudn´t get the expected content of /home/flag10/token echoed over netcat, but putting any command in background mode ( & ) made the process ID of that command to decrease, and in this moment, we have a tiny window between the mentioned opening & accesing calls that we want to interfere, and we´re able to access the content of /home/flag10/token symlinked to /tmp/race.

Let´s see how it works:

nebula-level10-4

nebula-level10-5

We can see a lot of attempts with garbage but often it clrearly shows the content of /home/flag10/token file we coudn´t see before ( because it´s owned by flag10 user ) :D, then log in with flag10 user and use that token as password to execute getflag.

Share it!
Esta entrada fue publicada en Privilege Escalation. Guarda el enlace permanente.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *

*

Puedes usar las siguientes etiquetas y atributos HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>