시스템 해킹

 1576, 1/79 회원가입  로그인  
   pkdo1030
   http://h00ker.tistory.com
   포맷스트링 개념 제대로 설명해주실분

http://www.hackerschool.org/HS_Boards/zboard.php?AllArticle=true&no=1888 [복사]


정리해놓은 글을 봐도 제대로 이해가 안되네요;; 예전에도 포맷스트링 관련 문제였던 ftz level11도 결국 못풀었었는데 이번 기회에 개념좀 확실히 잡아놓으려구요

  Hit : 3175     Date : 2017/07/24 09:50



    
김답변 포맷스트링버그는 가변인자가 어떻게 처리되는가를 이해하시면 됩니다
가변인자를 사용하는 함수는 처리할 인자의 시작과 끝을 알 수 있어야 하는데
printf에서는 첫번째 인자의 문자열에 들어온 포맷스트링의 갯수를 인자의 갯수로 알고 처리합니다
그러니까 printf에 인자를 실제로 몇개를 넣었든 간에 포맷스트링의 갯수가 2000개라면 printf안의 포맷스트링 핸들러도 2000번 실행되는 것이죠
그리고 인자는 스택을 통해 전달됩니다(32비트 stdcall, cdecl 기준)
printf("%x %x %x %x", 65, 66, 67, 68);
을 하면
41 42 43 44 가 출력 되겠지만
printf("%x %x %x %x");
을 하면
스택안의 네개의 데이터가 보여지게 됩니다(메모리 릭)
그리고 그 네개의 데이터는 스택상에서 포맷스트링(fmt) 인자가 위치한 그 다음부터 4바이트씩 네개가 그대로 보여지게 됩니다. gdb로 printf 호출 직전에 브레이크포인트를 걸어 확인하면 됩니다 x/4wx $esp
printf직전에 x/4wx $esp를 한것과 printf에서 출력하는게 같단걸 아실 수 있을 겁니다
그런데 vsprintf에는 이상하게도 %n이라는, 출력이아닌 쓰기를 하는 포맷스트링이 있습니다
그럼 결국 printf로는 메모리 읽기 쓰기 모두가 되는 것이죠
이걸 이용해 메모리를 읽어 필요한 라이브러리 주소를 알아내고 GOT Overwrite등을 통해 임의 실행흐름 변조가 가능합니다
2017/08/07