버퍼 오버플로우 공격 (Buffer overflow attack) - 2

oolongeya

·

2021. 8. 20. 17:09

1에서 ret주소에 입력한 값이 덮어지는 것을 확인했다.

그렇다면 ret주소값에 원하는 값을 넣을 수 있을까?

큰 고민 없이 간단한 메모리 확인만으로 취약한 함수를 이용해 ret주소에 공격자가 원하는 주소로 덮어 공격 할 수 있다.

크게 어렵지 않다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include ,stdio.h>
 
void shell()
{
    setreuid(0,0);
    system("whoami");
    printf("Congratulation! \n");
}
 
void printit()
{
    printf("General Program! \n");
}
 
void main()
{
    int crap;
    void(*call)() = printit;
    char buffer[20];
    fgets(buffer, 80, stdin);
    call()
}
cs

 

gcc bof2.c -o bof2 -static 명령어로 컴파일한다.

 

disas main 으로 main 함수를 확인할 수 있다

 

소스 코드에서도 있었는데, shell 함수가 존재한다. 마찬가지로 gdb에서 확인할 수 있다.

 

b *main+57 로 fgets 함수 부분에 브레이크 포인트를 걸어둔뒤

실행해보자

 

이어서 ni 명령어로 한 줄 실행을 하면 (gdb)가 아닌 공백이 나온다.

바로 사용자의 입력을 기다리는 것

 

사용자의 입력을 받는 함수가 있고, ret 주소에 덮어씌울 수 있는 점을 안다

또한 shell 함수의 코드 내용은 root 권한을 얻는 것

 

즉 shell 함수의 주소를 ret 주소에 덮어씌우면 된다.

 

buffer 의 크기는 20 byte이다.

즉 입력값을 AAAABBBBCCCCDDDDEEEE 라고 입력해보자

 

값을 입력한 뒤 ebp-0x20부터의 메모리 값들을 확인해보자

ebp-0x20(ebp-32) : 0x41414141 

ebp-0x10(ebp-16) : 0x45454545 

를 확인할 수 있다.

그리고 ebp-0xc 부분은 0x0804000a 이다.

 

00 + 0a 인데, 0a는 enter를 의미하고 00은 문자열 끝을 의미한다.

AAAABBBBCCCCDDDDEEEE(0a)(00)

 

이 값이 왜 중요하냐면

 

ebp-0xc 에 있는 주소값을 eax로 옮기고 eax에 있는 주소값으로 넘어가기 때문이다.

 

즉 main 함수에서 printit 함수로 넘어가는 주소를 저장하는 부분이다.

이곳을 shell 함수의 주소로 덮어씌울 생각이다.

 

 

disas shell 로 shell 함수의 주소를 확인한 뒤 메모한다. 0x8049775

즉 AAAABBBBCCCCDDDDEEEE+0x75+0x97+0x04+0x08

 

 

printf "AAAABBBBCCCCDDDDEEEE\x75\x97\x04\x08" | ./bof2 명령어로 버퍼 오버플로우 공격을 할 수 있다.

 

반응형