fopen 在 gdb 中返回 NULL

fopen returning NULL in gdb

我正在尝试解决 picoCTF 的二进制漏洞利用问题,但我在使用 gdb 时遇到了问题。 这是问题的源代码(我已经评论了一些东西来帮助我)。

#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;
}

当我 运行 正常时,使用 ./vuln,我可以正常执行。但是,当我在 gdb 中使用 gdb ./vuln 打开它,然后使用 run 打开它 运行 时,我收到了 [ERROR]: Trying to Read Canary 消息。这是为了使问题具有挑战性吗?我不想要解决方案,我只是不知道这是预期行为还是错误。谢谢

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

我不确定您是否会认为这是预期的行为,但这绝对不是错误。

您的 ./vuln 是一个 set-gid 程序。因此,当 运行 在 GDB 之外时,它 运行 作为组 canary_3,但在 GDB 下 运行 时作为你的组(出于明显的安全原因)。

我们可以假定 canary_3 组对 canary.txt 具有读取权限,但您没有。

P.S。如果您打印了 strerror(errno)(如评论所建议的那样),则结果 Permission denied. 应该使失败变得显而易见。