2주차 보충 - Format String Bug
Format String Bug란?
데이터 형태에 대한 불명확한 정의로 인한 문제
데이터의 형태를 알아볼 수 있게 해주는 역할을 하는 것이 포맷 스트링인데 이를 바꾸는 것
포맷 스트링: 일반적으로 사용자로부터 입력을 받아들이거나 결과를 출력하기 위하여 사용하는 형식
C언어를 사용한다면 printf()라는 함수를 사용할 때 숫자, 문자 등등 형태에 따라 %d, %c, %x 등을 사용하는데 이를 포맷 스트링이라고 함
- %d : 정수형 10진수 상수
- %f : 실수형 상수
- %lf : 실수형 상수
- %c : 문자값
- %s : 문자 스트링
- %u : 양의 정수(10진수)
- %o : 양의 정수(8진수)
- %x : 양의 정수(16진수)
- %n : 쓰인 총 바이트 수
예를 들면 %s를 사용하게 되면 해당하는 데이터의 문자열에 대해서 출력을 하게 된다. 하지만 이에 대해 임의적으로 %x라는 포맷 스트링으로 바꾸어준다면 컴파일을 실행시킬 때 문자열에 대한 값이 나오는 것이 아니라 주소에 대한 값이 나오게 되는 것을 볼 수 있다. 이렇게 되면 메모리 열람이 가능하게 되고 이렇게 열람을 할 수 있으면 메모리 조작도 가능하게 된다. 해당 메모리에 대해 값을 바꾸어 집어넣게 되면 메모리의 주소 값이 바뀌게 된다.
https://copycode.tistory.com/92
http://wiki.hash.kr/index.php/%ED%8F%AC%EB%A7%B7%EC%8A%A4%ED%8A%B8%EB%A7%81_%EA%B3%B5%EA%B2%A9
예제) fsb3.c
<문제 해결 과정>
우리가 메모리의 주소값을 바꾸려면 해당 메모리에 대한 값을 바꾸어 집어넣으면 된다.
바꿔 집어넣을 메모리 값은 fffdd030로 10진법으로 나타내면 ÿýÐ0이다.
하지만 스텍에 들어갈때는 왼쪽부터 오른쪽순으로 들어가므로 코드에 입력하려면 0Ðýÿ로 입력해야한다.
먼저 AAAA%x%x%x%x%x를 입력해본다.
그럼 다음과 같은 값이 출력된다.
AAAA141fe41ff42be4242041414141
위 결과를 통해 우리는 다시 AAAA(41414141은 AAAA를 Hex encode한 값)가 출력되는 것을 볼 수 있다.
이는 %x에 지정이 없으면 스택의 내용을 출력하기 때문이다. (스트링 지시자는 지역변수 이기 때문에 스택에 들어감)
즉 아무런 지정없이 %x값을 쓸 경우 주소값이 출력된다.
다시 AAAA가 출력된 것으로 보아 우리는 입력한 값의 위치를 찾은것이다.
이제 주소 자리를 맞추어 진짜 메모리값을 넣어서 진행해보자.
우리가 넣어 주어야 할 주소 자리는 ff로 10진수로 나타내면 255이다.
우리가 구하고자 하는 모양은 다음과 같다
AAAA0Ðýÿ%8x%8x%8x%8x%(자리를 맞추기 위해 필요한수)x%n
%n은 사용되기 직전까지 사용된 형식에 의해 출력된 문자들의 개수가 다음 변수에 저장되게 한다.
%x는 스텍에서 4바이트 값을 끌어와서 출력해주므로 우리는 8바이트만큼 거슬러 올라가서 그 주소에 접근할 것이므로 %8x를 사용한다.
*%x의 값에 의해 출력되는 문자가 최대 8자 이며 그보다 적은 수가 나올 수가 있으므로 아예 8로 맞추는 이유도 있음
이를 쪼개 보면 AAAA(4byte) + 0Ðýÿ(4byte) + %8x(8byte)*4 (총32byte) + 자리맞추기 위한 byte수 이다.
이 값이 255를 만족해야하니 자리맞추기 위한 byte수는 215다.
따라서 AAAA0Ðýÿ%8x%8x%8x%8x%215x%n를 입력해주면
AAAA0Ðýÿ 141fe41ff42be4242 0 41414141
Success!!
해결!!