OverFlow

동글래차·2023년 5월 28일
0

pwnable

목록 보기
5/9

1. Stack Overflow

- 한정된 메모리 안에서 stack 영역이 너무 많이 확장돼서 발생하는 버그

2. Stack Buffer Overflow

  • Stack에 위치한 버퍼에 버퍼의 크기보다 많은 데이터가 입력되어 발생하는 버그
  • 100ml 컵에 200ml 물을 받으면 넘치는 것과 같은 원리
  • buffer 뒤에 데이터를 덮어 씌워서 중요한 데이터 변조가능
<example>
1. "https://twitter.com" > overflow => "https://example.evi" / 통신 조작 가능
2. 악성 데이터 감지 경고 프로그램 조건 변경 가능

2.1. Buffer?

  • Buffer란 데이터가 목적지로 이동되기 전에 보관되는 임시 저장소
  • 처리 속도가 다른 두 장치의 완충 작용을 함
<example>
데이터 입력 속도보다 데이터 처리 속도가 느린 프로그램이 있다고 
가정하면 'abcdef' 입력 시 'adf'만 전달된다. 
이를 해결하고자 Buffer라는 임시 저장소를 두고 간접적으로 데이터를 전달하게 하는 것이다.

3. Stack Buffer Overflow 실습

3.1. stack buffer overflow

  • 실습자료(dreamhack)
//dreamhack 실습 자료
// Name: sbof_auth.c
// Compile: gcc -o sbof_auth sbof_auth.c -fno-stack-protector
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int check_auth(char *password) {
    int auth = 0;
    char temp[16]; 
    strncpy(temp, password, strlen(password)); //=> overflow 발생 지점
    if(!strcmp(temp, "SECRET_PASSWORD"))
        auth = 1;
    return auth;
}
int main(int argc, char *argv[]) {
    if (argc != 2) {
        printf("Usage: ./sbof_auth ADMIN_PASSWORD\n");
        exit(-1);
    }
    if (check_auth(argv[1]))
        printf("Hello Admin!\n");
    else
        printf("Access Denied!\n");
}
  • check_auth 함수에서 strncpy 함수를 통해 temp버퍼를 복사할때, 16byte가 아닌 인자로 전달된 password의 크기만큼 복사함 -> 오버플로우 발생

  • main함수에 bp 걸고 실행

  • check_auth에 bp걸고 step into

  • temp = rdi = 0x7fffffffe020 = rbp-0x20
  • temp의 버퍼는 구했으니 auth 변수 주소만 알면 된다

  • eax에 rbp-4 넣어서 return 함,

  • auth = rbp-4 = 0x7fffffffe03c
  • 0x7fffffffe03c - 0x7fffffffe020 = 0x1c(28)
  • 10진수로 29개만큼 채워넣으면 overflow가 된다!

### 성공!

3.2. stack buffer overflow & memory leak

실습자료(dreamhack)
// Name: sbof_leak.c
// Compile: gcc -o sbof_leak sbof_leak.c -fno-stack-protector
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main(void) {
  char secret[16] = "secret message";
  char barrier[4] = {};
  char name[8] = {};
  memset(barrier, 0, 4);
  printf("Your name: ");
  read(0, name, 12); // => overflow 발생 지점
  printf("Your name is %s.", name);
}
  • name에 설정된 버퍼는 8byte인데 read() 함수에서 12byte만큼 읽어옴 -> barrier라는 4byte null 배열을 덮어쓰면 secret 값을 읽어올 수 있음

* main 함수에 bp걸고 실행


  • read buffer address = 0x7fffffffe024

  • 0x7fffffffe024 ~ 0x7fffffffe030 - 1(e02f) 까지 덮으면 null byte없이 읽어들일 수 있음 -> 총 12byte

  • 성공!!

profile
동글동글

0개의 댓글