97, 1/5 회원가입  로그인  
   sohun5013
   포맷스트링 공격 질문

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


책으로 보면서 혼자서 고민하다가 결국 질문 올리게 됐습니다..

printf(argv[1]); 을 수행하는 프로그램인데
그 인자로 %08x %08x %08x %08x %08x...를 주면
bffff320 b7fe75fc 00000000 78383025 3830252e...
이렇게 나옵니다.

그 중에서 뒤쪽 8바이트는 문자로 바꿔보면 저 argv[1]인 건 알 수 있어요.
근데! 앞의 3바이트는 뭔지 도통 모르겠네요...

대충 SFP, ret, 완충이려니 생각했는데 또 보니까 함수 인자는 SFP나 ret이전에 스택에 푸시되잖아요.
그럼 함수 인자를 더 얻으려 한들 SFP나 ret이 튀어나올리는 없을 것 같은데...

제가 아직 스택 구조를 잘 이해하지 못해서 그런지는 모르겠지만
저거 꼭 알고싶습니다.. 저거 이후로 이해가 안 되고 있어요 ㅠㅠ

  Hit : 3885     Date : 2012/01/11 08:44



    
$Zero 앞의 값들은 그냥 argv[1] 이전의 주소공간 입니다.
그말은 argv[0]도 있으며 알수없는 쓰레기값도 있다는 소리죠.
굳이 그 전의 값들에대해 신경쓰실 필요는 없습니다.
포맷스트링의 원리가 포맷스트링 하나하나 4바이트씩 주소공간을 참조하게되는데 이걸 여러번 수행하면 유효한 변수의 주소까지 도달하게되어 해당 변수의 주소를 추출하는거잖아요 ? 때문에 원하는 변수의 주소만 추출하는게 목표인데 그 목표를 추적하는 과정의 값들을 신경쓸 필요는 없다고 생각됩니다.
2012/01/11  
sohun5013 아,,, 그럼
SFP | ret | argv[1]주소값 | ??? | ??? | ??? | argv[1]문자열.... 이런식으로 되어있는 건가요?
2012/01/11  
$Zero main 함수가 시작될때의 메모리 구조를 생각해보면

argv - argc - ret - SFP - 함수내의 변수들 입니다.

높은주소 - > 낮은 주소

더 확대해보면

??? - ??? - ??? - ??? - argv - argc - ret - SFP - 함수내의 변수 가 되겠죠

여기서 포맷스트링 버그를 이용하는건데요

위와같이 %08x 같은 포맷스트링을 그대로 출력하면 출력함수가 argv 이전에 있는 주소값에서 있지도 않은 값(쓰레기값)을 꺼내옵니다. 그리고 또 포맷스트링을 한번 더 사용하면 그 다음 4바이트의 값을 꺼내오죠. 이렇게 점점 앞으로 이동해서 결국 argv의 값까지 꺼내오게 되는것입니다.
이런식으로 주소값을 거슬러 올라가면 결국 ret에 도달하겠죠 ?
여기서 포맷스트링 %n을 사용해서 리턴어드레스를 변조하는것입니다.

더 상세한 내용은 제가 설명할것도 없이 책을 보시면 될겁니다 .
포맷스트링을 자주써먹거나 하질 않아서 제가 기억하는 내용이 얀간 다를 수도 있지만..
참고하시길.





2012/01/11  
sohun5013 많은 도움이 되었습니다. 고맙습니다. ㅎㅎ 2012/01/11