πŸ’«[Dreamhack] baby-bof

beaniiΒ·2023λ…„ 11μ›” 30일
0

CTF

λͺ©λ‘ 보기
7/7

https://dreamhack.io/wargame/challenges/974

BOF κ΄€λ ¨ λ¬Έμ œμ΄λ‹€.


문제 μ½”λ“œ


// gcc -o baby-bof baby-bof.c -fno-stack-protector -no-pie
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <signal.h>
#include <time.h>

void proc_init ()
{
  setvbuf (stdin, 0, 2, 0); setvbuf (stdout, 0, 2, 0);
  setvbuf (stderr, 0, 2, 0);
}

void win () 
{
  char flag[100] = {0,};
  int fd;
  puts ("You mustn't be here! It's a vulnerability!");

  fd = open ("./flag", O_RDONLY);
  read(fd, flag, 0x60);
  puts(flag);
  exit(0);
}

long count;
long value;
long idx = 0;
int main ()
{
  char name[16];

  // don't care this init function
  proc_init (); 

  printf ("the main function doesn't call win function (0x%lx)!\n", win); //win ν•¨μˆ˜μ˜ μ£Όμ†Œ μ•Œλ €μ€Œ!

  printf ("name: ");
  scanf ("%15s", name);

  printf ("GM GA GE GV %s!!\n: ", name);

  printf ("|  addr\t\t|  value\t\t|\n");
  for (idx = 0; idx < 0x10; idx++) {
    printf ("|  %lx\t|  %16lx\t|\n", name + idx *8, *(long*)(name + idx*8));
  }

  printf ("hex value: ");
  scanf ("%lx%c", &value);

  printf ("integer count: ");
  scanf ("%d%c", &count);


  for (idx = 0; idx < count; idx++) {
    *(long*)(name+idx*8) = value;
  }

  
  printf ("|  addr\t\t|  value\t\t|\n");
  for (idx = 0; idx < 0x10; idx++) {
    printf ("|  %lx\t|  %16lx\t|\n", name + idx *8, *(long*)(name + idx*8));
  }

  return 0;
}

문제 풀이


문제λ₯Ό 싀행해보면 winν•¨μˆ˜μ˜ μ£Όμ†Œ(0x40125b)λ₯Ό μ•Œλ €μ£Όκ³ , name을 μž…λ ₯받도둝 λ˜μ–΄μžˆλ‹€.

μ½”λ“œλ₯Ό 보면 scanf ("%15s", name);둜 μž…λ ₯λ°›κ³  μžˆμœΌλ―€λ‘œ μ•„λž˜μ™€ 같이 15κΈ€μžλ₯Ό μž…λ ₯ν•΄λ³Έλ‹€.

μž…λ ₯ ν›„ 좜λ ₯된 μŠ€νƒ 값듀을 보면 첫 쀄(7ffd4bd3c170)κ³Ό λ‘λ²ˆμ§Έ 쀄(7ffd4bd3c178)에 μ—¬λŸ¬ 개의 0x31κ³Ό ν•œ 개의 0x32κ°€ μžˆλ‹€.
μ΄λŠ” 각각 1κ³Ό 2의 μ•„μŠ€ν‚€μ½”λ“œμ˜ 16μ§„μˆ˜κ°’μ΄λ―€λ‘œ 이 두 쀄에 name 배열이 μ €μž₯λ˜μ–΄ μžˆμŒμ„ μ•Œ 수 μžˆλ‹€.

λ˜ν•œ 4번째 쀄(7ffd4bd3c188)의 7fb8fc2dcd90λŠ” mainν•¨μˆ˜ μ‹€ν–‰ 후에 이동할 κ³³, 즉 main ν•¨μˆ˜λ₯Ό μ‹€ν–‰μ‹œν‚¨ 곳인 것 κ°™λ‹€.
이제 이 뢀뢄을 win ν•¨μˆ˜μ˜ μ£Όμ†Œλ‘œ λ°”κΎΈλŠ” 것이 λͺ©ν‘œμ΄λ‹€.

주어진 문제 μ½”λ“œλ₯Ό 보면 main ν•¨μˆ˜ μ•ˆμ— μ•„λž˜μ™€ 같은 μ½”λ“œκ°€ μžˆλ‹€.
이 μ½”λ“œλŠ” name배열이 μ €μž₯된 λ‹€μŒ 쀄뢀터 count μ€„λ§ŒνΌ value둜 μˆ˜μ •ν•œλ‹€. (μŠ€νƒ ν•œ 쀄에 8λ°”μ΄νŠΈ)

즉, countλŠ” 2μ΄μƒμœΌλ‘œ, valueλŠ” 0x40125b으둜 μž…λ ₯ν•˜λ©΄ name이 μ €μž₯λ˜μ–΄ μžˆλŠ” 곳을 λ„˜μ–΄μ„œ λ‹€λ₯Έ 값듀이 μˆ˜μ •λ˜λŠ” BOFκ°€ λ°œμƒν•˜κ²Œ λœλ‹€.

  for (idx = 0; idx < count; idx++) {
    *(long*)(name+idx*8) = value;
  }

λ§Œμ•½ main ν•¨μˆ˜μ˜ 리턴 μ£Όμ†Œ μœ„μΉ˜λ₯Ό λͺ¨λ₯΄λ”라도 λ‹€μŒκ³Ό 같이 좜λ ₯된 μŠ€νƒμ˜ λͺ¨λ“  값을 0x40125b으둜 바꿔버리면 main ν•¨μˆ˜ μ‹€ν–‰ ν›„ win ν•¨μˆ˜κ°€ μ‹€ν–‰λ˜μ–΄ flag 값이 좜λ ₯λœλ‹€.

πŸ”‘ DH{62228e6f20a8b71372f0eceb51537c7f94b8191651ea0636ed4e48857c5b340c}

0개의 λŒ“κΈ€

κ΄€λ ¨ μ±„μš© 정보