본문 바로가기

포너블

Stack Buffer Overflow & Return Address Overwrite 롸업

x86-64호출 규약 SYSV는 6개의 인자를 RDI, RSI, RDX, RCX, R8, R9에 순서대로 저장하여 전달한다.

더 많은 인자를 사용할 때는 스택을 추가로 이용한다.

함수의 반환 값은 RAX로 전달한다.

 

x86 호출 규약 cdecl은 스택을 통해 인자를 전달한다.

 

스택 버퍼 오버플로우는 스택에 있는 버퍼의 크기보다 큰 값을 담으려고 할 때 오버플로우가 발생하는 취약점이다.

오버플로우로 인해 버퍼 뒤에 있는 스택 값을 조작해 해킹에 이용할 수 있다.

 

스택 구조를 파악하면 오버플로우로 반환 주소를 바꾸거나 뒤에 있는 값을 읽어오는 등 많은 작업을 할 수 있다.

개념 자체는 간단한 기법이라 더 설명할게 없는데 너무 짧으니 드림핵 함께실습에 있는

<Return Address Overwrite>문제의 풀이까지 같이 작성해보겠다.

#include <stdio.h>
#include <unistd.h>

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

void get_shell() {
  char *cmd = "/bin/sh";
  char *args[] = {cmd, NULL};

  execve(cmd, args, NULL);
}

int main() {
  char buf[0x28];

  init();

  printf("Input: ");
  scanf("%s", buf);

  return 0;
}

문제 코드이다.

 

gdb로 분석해보면 scanf 함수가 호출되는 부분에서 버퍼가 rbp-0x30에 위치한다.

그리고 rbp에 스택 프레임 포인터가 저장되고 rbp+0x8에 반환 주소가 저장된다.

0x38만큼의 거리가 있으니 그만큼 더미를 채우고 실행하고자 하는 주소를 입력하면 된다.

 

get_shell 함수의 주소를 확인해보면 0x4006aa이다.

x86-64아키텍처는 리틀 엔디언을 사용하기 때문에 get_shell함수의 주소는

\xaa\x06 \x40 \x00 \x00 \x00 \x00 \x00으로 전달해야 한다.

 

'포너블' 카테고리의 다른 글

드림핵 basic_exploitation_001 롸업  (1) 2024.03.06
드림핵 basic_exploitation_000 롸업  (0) 2024.03.04
드림핵 shell_basic 롸업  (0) 2024.02.02
범용 레지스터 & gdb(pwndbg) & pwntools  (1) 2024.01.23
Shellcode  (0) 2024.01.17