[Beginner] Baby-BOF

2025. 11. 5. 21:57·Wargame

01. BOF란?

버퍼에 허용할 수 있는 양의 데이터보다 더 많은 값이 저장되어 버퍼가 넘치는 취약점


02. 소스 코드 분석

먼저 살펴볼 것은 win() 함수이다. flag를 출력하는 함수로 우리는 이 함수가 실행되게 해야한다.

void win () {
  char flag[100] = {0,}; //flag 버퍼을 100byte만큼 0으로 채운다
  int fd;
  puts ("You mustn't be here! It's a vulnerability!");

  fd = open ("./flag", O_RDONLY); //flag 파일을 읽기 모드로 열기
  read(fd, flag, 0x60); //open으로 연 파일을 참조, flag 파일을 최대 96byte 데이터를 읽어 flag 버퍼에 저장
  puts(flag); //flag 버퍼 출력
  exit(0);
  }

 
이제 main함수 내부로 진입하자. 16바이트 버퍼 name이 선언되었다.

char name[16]; //16byte 버퍼로 총 16개의 char(1byte)를 저장할 수 있음
int age[20] ;
=> 20개의 int형(4바이트) 데이터를 연속으로 저장할 수 있는 80바이트짜리의 연속된 메모리 버퍼를 만드는 선언

 
0x%lx => 0x(16진수), %lx(unsigned long)을 16진수(x)로,,,라는 의미이다. 그리고 c에서는 함수 이름 자체가 해당 함수의 시작 주소를 의미하기에 win을 printf에 넘김으로서 win 함수의 메모리 주소를 출력할 수 있다.

  printf ("the main function doesn't call win function (0x%lx)!\n", win); //win 함수의 주소값을 출력

 
scanf함수의 %s는 입력 길이를 제한하지 않으며 공백 문자가 들어올 때까지 계속 입력을 받기에 오버플로우가 발생할 수 있다(사용하면 안됨).

  printf ("name: ");
  scanf ("%15s", name); //%s(string)으로 name을 15바이트만큼 받아오기

 
idx는 for문을 돌면서 0~16(0x10) 전까지 증가하여 총 16번 실행된다. name + idx *8는 name(name 주소)에 idx *8을 더한 값으로 long타입 16진수(%lx)로 출력된다.  name+8, name+16,...으로 8바이트씩 주소가 출력되는 것이다. *(long*)(name + idx*8)는 name+8, name+16 주소를 포인터로 참조하여, 해당 주소에 적힌 값을 16폭으로 long타입 데이터를 16진수로 출력한다.

  printf ("GM GA GE GV %s!!\n: ", name); //우리가 입력한 name을 %s로 출력
  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));
  }

나는 name에 d를 입력했는데 d는 아스키코드로 나타내면 64이다. 그리고 15번 d를 입력해서 value값을 보면 64가 15개 있는걸 볼 수 있다. 그리고 name 주소값에서 시작했기 때문에 2번째 라인까지는 name의 값이 저장되는 주소인것을 알 수 있다.

 
이후 사용자로부터 value와 count를 입력 받는다.

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

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

 
그리고 입력받은 value와 count값을 기반으로 아래 코드가 실행된다. value값으로 입력한 값이 *(long*)(name+idx*8)에 저장된 값을 덮어 쓴다는 의미이다. 여기서 BOF를 터트릴 수 있다. value에 win() 함수의 주소를 저장해두면 return시 win함수의 주소로 이동하여 win 함수가 실행되도록 할 수 있기 때문이다.

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

https://miaami.tistory.com/4

'Wargame' 카테고리의 다른 글

[Beginner] bof  (0) 2025.11.10
Zipper  (0) 2025.01.10
Windows Search  (0) 2025.01.06
Basic_Forensics_1  (0) 2025.01.06
session-basic[web]  (0) 2024.12.28
'Wargame' 카테고리의 다른 글
  • [Beginner] bof
  • Zipper
  • Windows Search
  • Basic_Forensics_1
sonotri._.
sonotri._.
@-@
  • sonotri._.
    SONOTRI
    sonotri._.
  • 전체
    오늘
    어제
    • 분류 전체보기 (102)
      • CTF (4)
      • Wargame (11)
      • Infomation_Sec (2)
      • Cyber_Sec (11)
        • Linux Kernel (2)
        • webhacking.kr (3)
        • bandit (4)
        • GoN Club Study (2)
      • Language (8)
        • C Language (2)
        • Java Language (6)
      • Dreamhack (43)
        • System Hacking (8)
        • Reverse Engineering (11)
        • Web Hacking (2)
        • Embedded Hacking (16)
        • Digital Forensics (0)
      • Basic_Theory (11)
      • elif (3)
  • 링크

    • Github
  • 인기 글

  • 최근 글

  • 공지사항

  • 태그

    vmware 네트워크
    초기화
  • 최근 댓글

  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • hELLO· Designed By정상우.v4.10.3
sonotri._.
[Beginner] Baby-BOF
상단으로

티스토리툴바