ghkdtlwns987
FSOB(_IO_flush_all_lockp ) 본문
이번엔 _IO_flush_all_lockp 함수로 Exploit 하는 방법에 대해 공부해보도록 하겠다.
#define fflush(s) _IO_flush_all_lockp (0)
fp = (_IO_FILE *) _IO_list_all;
while (fp != NULL)
{
run_fp = fp;
if (do_lock)
_IO_flockfile (fp);
if (((fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base)
#if defined _LIBC || defined _GLIBCPP_USE_WCHAR_T
|| (_IO_vtable_offset (fp) == 0
&& fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr
> fp->_wide_data->_IO_write_base))
#endif
)
&& _IO_OVERFLOW (fp, EOF) == EOF)
result = EOF;
if (do_lock)
_IO_funlockfile (fp);
run_fp = NULL;
if (last_stamp != _IO_list_all_stamp)
{
/* Something was added to the list. Start all over again. */
fp = (_IO_FILE *) _IO_list_all;
last_stamp = _IO_list_all_stamp;
}
else
fp = fp->_chain;
}
먼저, _IO_flush_all_lockp 함수의 소스코드이다.
모든 _IO_FILE 의 구조는 _chain 변수로 인해 링크드 리스트로 목록이 관리된다. 이 링크드 리스트의 헤더는 _IO_list_all 인데, 이 공격 방법의 핵심은, _IO_list_all 을 후킹해 _IO_OVER_FLOW 를 적절히 덮는 것 이다. 실제 fflush 는 _IO_flush_all_lockp 로 매크로 선언 되어있다.
_IO_flush_all_lockp 함수는 특정 조건에 실행되는데, 그 조건은 다음과 같다.
1. 라이브러리가 중단된 프로세스를 실행 할 때
2. exit 함수를 호출 할 때
3. 실행 흐름이 main 함수에서 return 될 때
또한, _IO_overflow() 함수를 호출시키기 위한 조건은 다음과 같다.
(fp->_mode <= 0 && fp->_IO_write_ptr > fp->_IO_write_base)
혹은
(_IO_vtable_offset (fp) == 0 && fp->_mode > 0 && (fp->_wide_data->_IO_write_ptr > fp>_wide_data->_IO_write_base)
과 같다.
즉, mode >= 0 이고, write_ptr > write_base 가 되어야 한다.
다음의 블로그를 참고해보도록 하자.
ctf-wiki.github.io/ctf-wiki/pwn/linux/io_file/fsop/
'시스템' 카테고리의 다른 글
[시스템] 쉘 코드 모음 (0) | 2020.11.16 |
---|---|
stdout 으로 libc leak (3) | 2020.11.10 |
flose() 분석 (0) | 2020.10.10 |
FSOB(File Stream Oriented Programming) 1 (0) | 2020.10.10 |
_IO_FILE_vtable_check (0) | 2020.10.10 |
Comments