Format String Bug란

: buffer overflow 해킹 기법의 한 종류로써 사용자의 입력에 의해서 프로그램의 흐름을 변경 시킬 수 있는 취약점이다

 

Format String Bug 순서

1. Format String Bug 원리 알기

2. root 계정으로 취약한 파일 만들기

3. 일반 계정으로 환경 변수 구해주는 프로그램 만들기

4. 일반 계정으로 환경 변수에 쉘코드 넣기

5. 덮어쓸 .dtors 주소 구하기

6. 필요 요소 확인

7. 공격 코드 작성

 

1. Format String Bug 원리 알기

 

Format Parameter

 

정상적인 format string 사용시 stack

- format string을 정상적으로 사용하게되면 먼저 format string문자를 하나씩 읽는다

- format string인자가 아니라면 바로 출력한다

- format string인자 발견시 esp+4 값의 포인터로 부터 null 값을 만날 때까지 출력한다

 

정상적이지 못한 사용

- 정상적으로 format string을 사용하지 않았지만 동작에는 문제가 없다

 

- 위 코드로 작성한 코드를 컴파일하고 동작을 시키면 aaaa를 넣어줬으때 aaaa 가 잘 출력이된다

- 그러나 aaaa뒤에 format string을 붙였을 때 무언가 다른게 출력되는걸 확인할 수 있다

- 이 값은 정상적인 format string 문자를 만났을 때 출력하는 esp+4의 값이다

 

- 위 원리를 이용하여 format string을 여러 개 사용

- format string 갯수에 따라 계속 esp에서 4byte 씩 올라가 출력할 수 있다 

 

2. root 계정으로 취약한 파일 만들기

 

- root 계정으로 setuid 비트를 걸어 놓은 취약한 파일을 작성한다 /tmp/fsb.c

 

- 파일을 컴파일하고 setuid 비트를 걸어준다

 

3. 일반 계정으로 환경 변수 구해주는 프로그램 만들기

 

- 일반 계정으로 환경변수를 입력하면 주소값을 돌려주는 코드를 작성한다 /tmp/env.c

 

- 컴파일을 해주는데 경고표시가 뜨지만 실행을하면 잘 작동되는걸 볼수있다 

 

4. 일반 계정으로 환경 변수에 쉘코드 넣기

 

root권한 획득하고 쉘 실행 시키는 쉘코드

\x31\xc0\x89\xc3\xb0\x17\xcd\x80\xeb\x0f\x5e\x31\xc0\x50\x89\xe2\x56\x89\xe1\x89\xf3\xb0\x0b\xcd\x80\xe8\xec\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68

 

- 환경 변수에 쉘코드를 넣기전에 언어팩 부터 2byte로 동작하는 한글로 바꿔준다

 

- 쉘 코드를 perl 스크립트를 이용하여 환경 변수에 넣어주고 주소를 구해준다

 

5. 덮어쓸 .dtors 주소 구하기

 

- .dtors를 사용하는 이유는 .dtors가 소멸자이기 때문에 종료되면서 실행 시킬 수 있기 때문이다

- 위 .dtors의 주소가 0x804952c 이고 ffffffff [ 4byte공간 ] 00000000 에 적어줘야 실행한다

- 그러므로 0x804952c 주소에 4bytes를 더해준 0x8049530의 주소를 쓴다

 

6. 필요 요소 확인

 

필요 요소의 주소 적어두기

7. 공격 코드 작성

 

- 쉘 코드 주소를 10진수로 바꾼다

- 쉘 코드 주소를 little endian 방식으로 .dtors 주소에 매핑한다

 

- buf에 AAAA를 적은 뒤 format string을 사용하여 위치를 찾는다

- format string을 4개 사용하면 buf의 시작 위치에 온다는걸 확인할 수 있다 

 

공격코드

./fsb "`perl -e 'print "\x30\x95\x04\x08","AAAA","\x32\x95\x04\x08","%8x%8x%65197c","%hn","%49462c","%hn"'`"

 

 

설명

 

- 쉘 코드를 저장할 .dtros의 시작 주소를 적어준다 ( 2byte )

 

- AAAA를 적어 주는데 이유는 뒤에 나온다

 

- .dtors의 시작 주소에서 2byte뒤 주소를 적어준다 ( 2byte )

 

- 첫 번째 format string "%8x"에 사용으로 esp+4의 값을 보고있다

- 두 번째 format string "%8x"에 사용으로 esp+8의 값을 보고있다

- 세 번째 format string "%65137c"에 사용으로 esp+12의 값을 보고있다

 

%65197c 사용이유

: 앞에 작성된 코드들의 byte수의 합계는 28byte이기 때문에 작성해줘야 할 총 byte수인 65225byte에서 28byte를 뺀 나머지인 65197byte가 사용되어야 한다

( %8x - 8byte, .dotrs 주소 - 4byte, AAAA - 4byte )

 

 

- format string %n은 참조 형태가 포인터이고 사용으로 인해 esp+16에 값을 본다

- esp+16의 값이 주소면 지금까지 사용한 byte의 수 만큼의 값을 그 주소 공간에 적어준다 

- %n은 4byte형이기 때문에 절반인 %hn을 사용하여 2byte씩 값을 적게 만들어준다

 

- format string %49462c의 사용으로 esp+20의 위치를 보는데 이 위치에는 AAAA가 작성되어있다

 

%49462c 사용 이유

: 앞에 적은 byte가 이미 65225byte이기 때문에 적어야할 49151byte를 이미 초과했다

 format string %hn 사용하면 2byte만 적어주고 나머지는 적지 못하고 버린다는 특징을 이용해 쉘 코드의 뒷 부분인 BFFF에 1을 붙여 1BFFF를 만들어 2byte를 초과 시키고 10진수로 변환해준다

 10진수로 변환하면 114687 나오는데 여기서 앞에 먼저 적어준 65225byte만큼을 빼준 결과인 49462가 사용되는 것이다 ( 빼는 이유는 앞부분에 쓰인 byte까지 포함하기 때문이다 )

 

- format string %hn을 사용하여 esp+24의 위치를 보게되고 이 곳에는 .dtors의 시작 주소 2byte 뒤 주소가 적혀있다

- esp+24의 값이 주소이기 때문에 그 곳에 지금까지 쓰인 byte의 2byte만큼을 적어준다

 

- 위 코드를 취약한 함수의 인자로 적어준다

 

- 코드를 적어주면 위와 같이 쉘이 실행되고 id 명령어를 적으면 root 권한인걸 확인할 수 있다

'시스템 해킹' 카테고리의 다른 글

Heap Buffer Overflow  (0) 2020.11.11
PLT & GOT Overwrite  (0) 2020.11.10
CANARY  (0) 2020.11.10
ASCII Armor  (0) 2020.11.10
ASLR ( Address Space Layout Randomization )  (0) 2020.11.10

+ Recent posts