1. 포맷 스트링 공격(Format String Attack)

프로그램에 입력된 문자열 데이터가 명령으로 해석될 때 발생
- 공격자는 코드를 실행하거나 메모리 일부를 읽거나 실행중인 프로그램에 Segmentation Fault를 발생시켜 시스템에 의도되지 않은 동작을 유발

 

1.1 포멧 스트링 3가지 개념

① 포맷 함수(Format Function)

- printf, fprintf와 같은 ANSI C 함수

- ex) printf(), scanf() ...

 

② 포맷 스트링(Format String)
- 포맷 함수의 인자이며 다음과 같은 텍스트 및 포맷 인자를 포함하는 ASCII 문자열
- ex) printf("number : %d\n", 1);

 

③ 포맷스트링 인자(Format String Parameter)
- %x %s 등으로 포맷 함수의 변환 형태를 정의

- 프로그램이 전달된 스트링 입력의 유효성을 제대로 확인하지 않으면 취약점이 노출됨.

인자 입력 타입 출력
%d 10진수
%s 포인터 포인터에 위치하는 문자열
%x 16진수
%u 부호없는 10진수
%p 포인터 포인터가 가르키는 주소
%n 포인터 지금까지 출력한 바이트수를 포인터가 가르키는 주소에 넣어줌

 

1.2 예시

- 포맷 스트링 공격에 안전한 경우(위)와 취약한 경우(아래)를 비교하여 확인

 

1.3 포맷 스트링 공격 대응방안

① 서식문자열을 함수의 입력 파라미터로 직접 사용하지 않음 즉, 정확한 포맷스트링의 지정이 필요

ex) printf(argv[1])  ->  printf("%s", argv[1])

 

② 포맷 스트링에 취약한 함수를 사용하지 않음

ex) fprintf(), sprintf(), snprintf() ...

 

2. 풀이

- 80byte 배열 bleh를 선언한 후 setruid 실행 및 fgets로 79byte까지 입력값을 받아 버퍼오버플로우는 불가능함

- main 심볼이 없어 gdb를 사용할 수 없음

- hint 파일의 내용 중 print(bleh); 구문에서 포맷 스트링 공격이 가능함

- attackme 실행 후 %08x의 개수를 증가시킬 경우 12byte 이후 삽입한 문자열이 출력되는 것을 확인할 수 있으므로 스택의 구조를 예상해 볼 수 있음

 

- level20에서는 쉘코드를 환경변수에 등록하여 환경변수의 주소를 등록한 후 해당 환경변수의 주소를 RET에 덮어쓰는 기존의 방식은 사용하지 못함

- bleh와 SFP 사이에 존재하는 dummy의 크기를 모르기 때문이며, 따라서 다른 값에 환경변수의 주소를 덮어써야함

- 따라서 main()이 종료되고 .dtors가 실행되기전에 .dtors값을 쉘코드로 덮어써야함

- objdump 명령으로 .dtors의 세그먼트 주소는 0x08049594이며, .dtros의 시작 주소는 0x08049598

- +4를 해주는 이유는 다수의 .dtors 영역에서 실행이 되게 하기 위해서는 +4를 해줘야 한다고 함(정확한 이유는 확인 중)

 

- .dtros의 시작 주소 0x08049598에 환경변수 주소 0xbfffff2d를 덮어써주면 됨

- 쉘코드 주소 0xbfffff2d는 10진수로 3,221,225,261로 int형 범위를 넘어서게 되므로 소멸자를 2바이트씩 나누어 넣어줘야하며, 이때 %n 지정자 사용

 

- 소멸자를 낮은 주소와 높은 주소로 나누어보면 0x08049598이 낮은 주소, 0x08049598+2=0x0804959a가 높은 주소

- 쉘코드 환경변수의 낮은 주소는 ff2d(65,325), 높은 주소는 bfff(49,151)

- 따라서, 페이로드 형식은 다음과 같음

AAAA\x98\x95\x04\x08AAAA\x9a\x95\x04\x08%8x%8x%8x%낮은 셸 코드주소c%n%높은 셸 코드주소c%n

 

- %[숫자]c의 경우 [숫자] 만큼의 공백을 의미하며, %n은 이전 입력 값까지 더하여 저장하게됨

- 따라서 %낮은 셸 코드주소c%n의 경우 65,325-(4 + 4 + 4 + 4 + 8 + 8 + 8)=65,285

- %높은 셸 코드주소c%n의 경우 49,151-65,325=-16,174, 음수가 발생하므로 bfff의 2의보수에 65,325를 빼주어 높은 쉘코드를 구함=114687-65,325=49,362

- 즉 완성된 페이로드는 다음과 같음

AAAA\x98\x95\x04\x08AAAA\x9a\x95\x04\x08%8x%8x%8x%65285c%n%49362c%n

'문제풀이 > FTZ' 카테고리의 다른 글

FTZ Level19 풀이  (0) 2022.11.08
FTZ Level18 풀이  (0) 2022.11.07
FTZ Level17 풀이  (0) 2022.11.07
FTZ Level16 풀이  (0) 2022.11.05
FTZ Level15 풀이  (0) 2022.11.05

+ Recent posts