【题目】Can you try to get the flag? Beware we have PIE!Connect to the program with netcat:

$ nc rescued-float.picoctf.net 60249

题目提供了一个vuln.c文件和对应的vuln二进制文件,.c文件如下:

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>

void segfault_handler() {
  printf("Segfault Occurred, incorrect address.\n");
  exit(0);
}

int win() {
  FILE *fptr;
  char c;

  printf("You won!\n");
  // Open file
  fptr = fopen("flag.txt", "r");
  if (fptr == NULL)
  {
      printf("Cannot open file.\n");
      exit(0);
  }

  // Read contents from file
  c = fgetc(fptr);
  while (c != EOF)
  {
      printf ("%c", c);
      c = fgetc(fptr);
  }

  printf("\n");
  fclose(fptr);
}

int main() {
  signal(SIGSEGV, segfault_handler);
  setvbuf(stdout, NULL, _IONBF, 0); // _IONBF = Unbuffered

  printf("Address of main: %p\n", &main);

  unsigned long val;
  printf("Enter the address to jump to, ex => 0x12345: ");
  scanf("%lx", &val);
  printf("Your input: %lx\n", val);

  void (*foo)(void) = (void (*)())val;
  foo();
}

 

【解题】根据.c内容,要想找到flag需要让程序跳转到win函数。运行指令:

 nc rescued-float.picoctf.net 60249

 显示如下:

image

 已知函数main的地址,此时需要我们输入一个地址令程序跳转到win函数,从而得到flag输出。

因此我们需要知道这个程序的指令和数据布局,使用以下命令获取:

nm vuln

得到结果如下:

image

 该指令可以查看符号的虚拟地址,发现main函数的虚拟地址偏移量是0x133d,win函数的偏移量是0x12a7,由此可以得到两个函数的相对地址偏移量是:

0x133d-0x12a7=0x96

而由于使用了PIE,虚拟地址的基址BASE是变化的,于是我们需要根据每次运行得到的main地址加上相对地址偏移量0x96,就能得到win函数的虚拟地址,所以我们在交互处输入:

0x644dfd8742a7

即main地址0x644dfd87433d+相对偏移量0x96=win地址0x644dfd8742a7,程序就会跳转到目标地址运行win函数,于是得到flag内容:

image

 OVER

P.S 最后我想说,我们现在使用AI工具本身就是为了节省查找资料筛选知识的时间,针对一些主观性的、或方便即时验证的问题(比如优劣好坏,比如文献的真假)我不介意不同的大模型给出不同的甚至是假的结果,但是一些客观性的、拥有绝对正误答案的知识点,我认为合格的AI工具必须给出正确的答案和解释才配得上大家的时间,然而现实是甚至一些拿的上台面的工具给出的答案都存在硬伤,让我们本来节省下的时间硬生生花在了知识点的验证上。所以即便有了工具,即便是有标准答案,我们也应该时刻保持对大模型的批判性思维。

posted on 2026-01-11 05:22  swannie  阅读(0)  评论(0)    收藏  举报