2021-09-09 · 2

[시스템해킹] Buffer Overflow(BOF)

securitypwnable

이 글은 작성된 지 2년이 넘었어요. 내용이 오래됐을 수 있어요.

BUFFER OVERFLOW


BOF

설정되어 있는 버퍼의 크기보다 크게 입력을 받을 수 있을 때 생기는 취약점입니다.

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char s[40]; // [esp+4h] [ebp-34h] BYREF
  int v5; // [esp+2Ch] [ebp-Ch]

  v5 = 0x4030201;
  fgets(s, 45, stdin);
  printf("\n[buf]: %s\n", s);
  printf("[check] %p\n", v5);
  if ( v5 != 0x4030201 && v5 != 0xDEADBEEF )
    puts("\nYou are on the right way!");
  if ( v5 == 0xDEADBEEF )
  {
    puts("Yeah dude! You win!\nOpening your shell...");
    system("/bin/dash");
    puts("Shell closed! Bye.");
  }
  return 0;
}

HackCTF 1번 문제의 코드를 가져왔습니다. s의 배열의 크기는 40이지만 fgets(s, 45, stdin);으로 45만큼의 버퍼를 입력받습니다. 여기서 BOF가 터지는 겁니다.

1번 스택

현재 s[40]에서 입력을 하고 있고 총 45만큼 입력을 할 수 있기 때문에 s [40]를 전부 덥고 v5까지 바꿀 수 있습니다.

그 v5를 0xDEABEEF가 된다면 exploit에 성공하게 됩니다. 

//gcc -fno-stack-protector -z execstack -no-pie -o bof bof.c
#include <stdio.h>

int main(void) {
    char buf[40];
    
    scanf("%s", buf);
    printf("%s", buf);
}

여기 더 쉬운 코드가 있습니다. 사실 우리가 c언어를 처음 배울 땐 위와 같이 scanf("%s", buf); 이런 식의 코드로 작성하게 됩니다. 저러한 형식의 코드는 매우 위험한 코드입니다. %40s와 같이 길이를 정해주지 않았기 때문에 buf [40] + sfp까지 덮어 return address주소를 덮어 씌울 수 있게 됩니다.

여기서 sfp란 Stack Frame Pointer의 약자이며 말 그대로 상위 스택 프레임의 베이스 포인터를 말합니다.

32bit에선 4byte, 64bit에선 8byte를 차지하고 있습니다. 만약 bof가 return address까지 덮을 수 있을 정도의 길이라면 buffer + sfp[4 or 8] + return address 와 같이 적어주셔야합니다.

여기까지 bof였습니다. 굉장히 쉬운 개념이라 설명할 것도 별로 없는 것 같네요 ,;,ㅡ,;,


원문: tistory — 2021-09-09 발행, 이 블로그로 이전됨.

댓글

댓글을 삭제할까요?

관련 글

[시스템해킹] Buffer Overflow(BOF) · 나봄하랑