Buffer Overflow 3

发布日期:2019年02月27日 类别:pwn 题目来源:picoctf-2018 题目链接:https://2018game.picoctf.com/ (需要注册登录)

这道题模拟了栈溢出保护,但 canary 是固定的:

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

#define BUFSIZE 32
#define FLAGSIZE 64
#define CANARY_SIZE 4

void win() {
  char buf[FLAGSIZE];
  FILE *f = fopen("flag.txt","r");
  if (f == NULL) {
    printf("Flag File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n");
    exit(0);
  }

  fgets(buf,FLAGSIZE,f);
  puts(buf);
  fflush(stdout);
}

char global_canary[CANARY_SIZE];
void read_canary() {
  FILE *f = fopen("canary.txt","r");
  if (f == NULL) {
    printf("Canary is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n");
    exit(0);
  }

  fread(global_canary,sizeof(char),CANARY_SIZE,f);
  fclose(f);
}

void vuln(){
   char canary[CANARY_SIZE];
   char buf[BUFSIZE];
   char length[BUFSIZE];
   int count;
   int x = 0;
   memcpy(canary,global_canary,CANARY_SIZE);
   printf("How Many Bytes will You Write Into the Buffer?\n> ");
   while (x<BUFSIZE) {
      read(0,length+x,1);
      if (length[x]=='\n') break;
      x++;
   }
   sscanf(length,"%d",&count);

   printf("Input> ");
   read(0,buf,count);

   if (memcmp(canary,global_canary,CANARY_SIZE)) {
      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);
  
  // Set the gid to the effective gid
  // this prevents /bin/sh from dropping the privileges
  int i;
  gid_t gid = getegid();
  setresgid(gid, gid, gid);
  read_canary();
  vuln();
  return 0;
}
点击此处显示 Writeup
点击此处隐藏 Writeup

由于 Canary 是固定的,因此可以通过多次运行猜测出 Canary 的值。首先我们看一下各个局部变量的位置:

canary$ebp - 0x10buf$ebp - 0x30,因此中间有 0x20 = 32 个字节。我们可以不断地执行这段程序,每次都覆盖 33 个字节,通过改变最后一个字节就可以根据程序输出暴力猜测出 canary 的第一个字节的值。然后以此类推,就可以猜出第 2、3、4 个字节。

执行后就可以打印出 canary 的值:

dontpanic@pico-2018-shell:/tmp/overflow3$ python bf.py
0x49
0x48
0x77
0x6a
dontpanic@pico-2018-shell:/tmp/overflow3$

接下来就是常规的爆破了,看一下 win 的地址:

(gdb) print win
$1 = {<text variable, no debug info>} 0x80486eb <win>

然后:

dontpan1c 的 CTF 笔记
南阳一出即相,淮阴一出即将。

知识共享许可协议

本站所有作品均采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

本站不包含明令禁止公开解题过程的题目。

本站由 Jekyll 强力驱动。