포맷 스트링 공격
포맷 스트링 공격은 버퍼 오버플로 공격과 매우 유사하다. 그래서 많은 사람이 포맷 스트링 공격과 버퍼 오버플로 공격을 정확히 구분하지 못한다.
보통 다음 코드처럼 buffer에 저장된 문자열을 printf함수를 사용하여 출력한다.
% s 같은 문자열을 가리켜 포맷 스트링이라고 한다.
포맷 스트링의 종류는 다음과 같다.
포맷 스트링 문자를 이용하지 않고, printf 같은 함수를 사용하면 문제가 발생할 수 있다.
다음과 같은 코드를 작성하고 컴파일하여 실행해보면 결과는 아래와 같다.
wishfree 외에 5798b228이라는 숫자를 출력한다. 이 숫자는 wishfree문자열이 저장된 다음 메모리에 존재하는 값으로 0x5798b228d을 의미한다.
gdb에서 이 값을 확인해보자.
&buffer인 0x7fffffffe3a8에 가면 0x555555556004가 있고 이에 대한 값은
다음과 같다. 조금 더 명확히 알아보기 위해
다음과 같이 수정하여 실행한다.
- 원리
메모리의 구조는 다음과 같다.
스택 영역에 내가 동작시키는 함수의 스택영역이 구분되고 순서는
--높은 주소--
인자
ret
sfp
변수
--낮은 주소-- 와 같이 스택에 쌓인다.
printf함수를 사용하게 되면 인자는 다른 주소에 존재하고 포맷 스트링은 인자를 가리키게 된다.
포맷 스트링이 여러 개 있을 경우 그림은 다음과 같다. (출처 : https://s1m0hya.tistory.com/19)
그리고 만약 인자 없이 포맷 스트링을 사용한다면 인자로 정해두지 않을 곳을 가리키게 되어서 메모리를 출력하게 된다.
이를 통한 메모리 변조는 % n을 통해 가능하다. % n은 지금까지 출력 해준 바이트수를 인자에다 넣어준다.
이는 a에 8바이트를 넣은 예제이다.
조금 더 자세한 공격 예제는 다른 글에서 적어보려고 함