12초 걸리던 쿼리 장애를 처음 겪고, 끝까지 파고든 기록

회사의 지식재산권 보호를 위해 스키마와 쿼리를 재구성하였으나 본질은 동일합니다. 문제 정의 며칠 전 유저 검색 기능의 속도가 지나치게 느리다는 피드백을 받았습니다. 개발 환경에서는 성능 문제를 체감한 적이 없었고 사용 빈도도 높지 않았던 기능이라서, 솔직히 문제가 발생할 것이라고 예상하지 못했습니다 운영 환경에서 직접 재현해보니 검색어가 있을 때는 1초 미만이었지만, 없는 경우 약 12초의 지연이 발생했습니다. 이는 곧 전체 유저를 보기 위해선 유저가 12초 동안 기다려야 한다는 말이 됩니다. 일반적으로 알려진 것처럼 5초 이상의 로딩은 사용자 이탈로 직결되는 만큼, 바로 원인 파악에 들어갔습니다. ...

2023-07-30 · 8 min · 1667 words · Byeongmin Bae

Introduction to ptmalloc2 Heap Management and Exploitation

동적 할당 메커니즘에서는 성능을 위해 free 된 청크들을 재활용 합니다. 만약 이런 재활용 없이 시스템콜을 통해 매번 메모리를 할당받거나 반환한다면 유저-커널모드 전환 비용으로 인해 성능 하락이 심해집니다. 그래서 메모리 할당자는 기존 메모리 영역 재사용을 위한 힙 자료구조와 그에 맞는 최적의 힙 관리 알고리즘을 구현해놨습니다. 이번 포스팅에선 이러한 구조에 대해 이해하고 어떻게 exploit 할 수 있는지 알아보려 합니다. 이번에 살펴볼 메모리 할당자는 ptmalloc2 입니다. dlmalloc, TCMalloc 도 있지만, ptmalloc2 는 glibc 의 기본 할당자로 오랫동안 사용되어왔고, 리얼월드에서도 많이 쓰입니다. ...

2021-05-12 · 10 min · 1959 words · Byeongmin Bae

File Stream Oriented Programming and Exploitation Techniques

이번 글에서는 최근에 공부했던 FSOP 를 포함한 여러 익스 테크닉들을 빠르게 다뤄보겠습니다. 메모 느낌이라 틀린 부분이 있을수도 있으니 가볍게 봐주시면 감사하겠습니다. _IO_FILE glibc의 파일 입출력은 _IO_FILE 구조체 하나로 구현되어 있습니다. stderr, stdout, stdin 같은 기본 스트림들도 전부 이 구조체 기반이고, scanf()가 어디에 쓸지, 버퍼를 어디서 읽을지 전부 이 구조체 안의 포인터들에 의해 결정됩니다. libc 내부에서는 스트림들이 _IO_FILE로 구현되어 싱글 링크드 리스트로 연결되어 있습니다. _IO_list_all -> _IO_2_1_stderr_.file._chain -> _IO_2_1_stdout_.file._chain -> _IO_2_1_stdin_.file._chain _IO_buf_base _IO_2_1_stdin_.file._IO_buf_base를 덮어쓸 수 있어야 함 이후 fgets(), scanf() 등 stdin을 사용하는 함수가 호출되어야 함 scanf()나 fgets() 같은 함수가 입력을 받을 때, _IO_buf_base 부터 _IO_buf_end까지의 영역을 버퍼로 사용합니다. 이 두 포인터를 원하는 주소로 조작하면, 다음에 scanf()가 호출될 때 해당 메모리 영역에 임의 쓰기가 가능합니다. ...

2021-03-22 · 7 min · 1392 words · Byeongmin Bae