Search code examples
c++cgdbbuffer-overflow

fopen returning NULL in gdb


Im trying to solve a binary exploitation problem from picoCTF, but I'm having trouble with gdb. Here is the source code of the problem (I've commented some stuff to help me).

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <wchar.h>
#include <locale.h>

#define BUF_SIZE 32
#define FLAG_LEN 64
#define KEY_LEN 4

void display_flag() {
  char buf[FLAG_LEN];
  FILE *f = fopen("flag.txt","r");
  if (f == NULL) {
    printf("'flag.txt' missing in the current directory!\n");
    exit(0);
  }
  fgets(buf,FLAG_LEN,f);
  puts(buf);
  fflush(stdout);
}

// loads value into key, global variables ie not on stack
char key[KEY_LEN];
void read_canary() { 
  FILE *f = fopen("/problems/canary_3_257a2a2061c96a7fb8326dbbc04d0328/canary.txt","r");
  if (f == NULL) {
    printf("[ERROR]: Trying to Read Canary\n");
    exit(0);
  }
  fread(key,sizeof(char),KEY_LEN,f);
  fclose(f);
}

void vuln(){
   char canary[KEY_LEN];
   char buf[BUF_SIZE];
   char user_len[BUF_SIZE];

   int count;
   int x = 0;
   memcpy(canary,key,KEY_LEN); // copies "key" to canary, an array on the stack
   printf("Please enter the length of the entry:\n> ");

   while (x<BUF_SIZE) {
      read(0,user_len+x,1);
      if (user_len[x]=='\n') break;
      x++;
   }
   sscanf(user_len,"%d",&count); // gives count the value of the len of user_len

   printf("Input> ");
   read(0,buf,count); // reads count bytes to buf from stdin

   // compares canary (variable on stack) to key
   // if overwriting need to get the value of key and maintain it, i assume its constant
   if (memcmp(canary,key,KEY_LEN)) { 
      printf("*** Stack Smashing Detected *** : Canary Value Corrupt!\n");
      exit(-1);
   }
   printf("Ok... Now Where's the Flag?\n");
   fflush(stdout);
}

int main(int argc, char **argv){

  setvbuf(stdout, NULL, _IONBF, 0);
  
  int i;
  gid_t gid = getegid();
  setresgid(gid, gid, gid);

  read_canary();
  vuln();

  return 0;
}

When I run this normally, with ./vuln, I get normal execution. But when I open it in gdb with gdb ./vuln and then run it with run, I get the [ERROR]: Trying to Read Canary message. Is this something that is intended to make the problem challenging? I don't want the solution, I just don't know if this is intended behaviour or a bug. Thanks


Solution

  • I don't want the solution, I just don't know if this is intended behaviour or a bug.

    I am not sure whether you'll consider it intended behavior, but it's definitely not a bug.

    Your ./vuln is a set-gid program. As such, it runs as group canary_3 when run outside of GDB, but as your group when run under GDB (for obvious security reason).

    We can assume that the canary_3 group has read permissions on the canary.txt, but you don't.

    P.S. If you printed strerror(errno) (as comments suggested), the resulting Permission denied. should have made the failure obvious.