[System hacking] FSB

2025. 12. 12. 17:44·Security/시스템해킹

 
FSB는 FormatStringBug의 약자로 printf를 잘못 사용하여 발생하는 시스템 해킹 취약점이다.
FSB에 대해서 알아보자

 


 

포멧 스트링이란? 

printf 함수에서 첫번째 인자의 문자열에 들어가 형식을 지정해주는 문자들로 %d, %x, %s, %p등이 있다.
printf("%s", user_input);처럼 사용된다.

정상적인 %s 사용


 
만약 printf("%s %p %p", user_input);처럼 포멧 스트링과 인자의 수가 맞지 않다면 어떻게 될까?
컴퓨터는 user_input 뒤에 정상적으로 인자가 있다고 생각해 정해진 위치의 값을 출력할 것이다. 
그 정해진 위치가 어딜까?


함수 호출규약(Calling Convention)

 

Calling Convention은 함수를 호출할 때의 규칙으로 함수의 리턴값, 스택정리, 인자에 대한 규칙이다.
64bit 리눅스에서는 System V AMD64 ABI를 사용한다.

인자 전달 방식은 레지스터(rdi, rsi, rdx, rcx, r8, r9) 6개 + 스택을 사용한다. 따라서  printf("%s %p %p\n", user_input);일 경우에 "%s %p %p"가 첫번째 함수 인자로 rdi로 전해지며, user_input은  rsi를 통해서 함수 인자가 전달된다. 이때 %p %p의 각각의 인자는 rdx와 rcx에 저장된 것으로 여겨진다. 따라서  printf("%s %p %p\n", user_input); 의 출력값은 user_input의 값과 rdx의 주소값, rcx의 주소값이 출력된다.
 

이를 GDB에서 확인할 수 있는데 

printf전 레지스터의 값

 

출력값

이를 통해 printf가 레지스터의 값을 출력한다는 것을 알 수 있다.


포멧 스트링 버그(FSB)

따라서 우리는 printf(user_input);과 같은 코드가 있을 때 "%p %p %p %p ...."와 같은 스트링을 입력해 레지스터 및 스택을 알아낼 수 있다. 이것을 포멧 스트링 버그라고 한다.
 


그런데 printf로 메모리에 쓰는 것도 가능하다.

printf에서 %n이라는 형식 지정자는 지금까지 출력된 문자열의 갯수를 특정 메모리에 저장하는 지시자이다. printf("12345%n", &i);, printf("%d", &i);를 통해 i값을 추적해보면 5로 문자열의 길이를 i값에 저장할 수 있다.
만약 printf(user_input)과 같은 코드가 있을 때 user_input에 12345%n을 하면 5의 값이 rsi에 저장된 주소의 값에 저장된다.
이걸 응용하면 원하는 스택의 주소에 값을 작성할 수 있다.

출력값


FSB를 사용해 원하는 위치에 값 작성하기 


 우리는 원하는 스택 위치에 값을 작성하고 싶다. 만약 64bit 리눅스를 사용한다면 6번째 인자부터 스택에 값을 저장하게 된다.

printf("%p %p %p %p %p 12345%n")을 하게되면 리턴 주소 아래에 있는 주소에 작성할 수 있다. 하지만 만약 더 큰 값을 저장하고 싶고 더 멀리 있는 스택에 저장하려면 앞의 문자열을 늘리거나 형식 지정자를 더 써야할까?

 

답은 아니다. 형식 지정자에는 자리수를 지정할 수 있는 기능이 있다. 형식지정자 사이에 원하는 자릿수 만큼 넣어 사용할 수 있다. 예시로 12345라는 값을 쓰고 싶다면, 실제로 12,345글자를 적는 대신 %12345c%n 같이 작성하여 문자의 개수를 원하는 만큼 작성할 수 있다..또한 $를 사용하면 형식지정자를 많이 사용하지 않고도 원하는 자리에 있는 값을 가져올 수 있다. 예시로 %6$n을 사용해 6번째 인자에 있는 주소를 찾아가 값을 저장한다. 

 

따라서 우리는 %12345c%5$n과 같은 코드를 printf의 인자로 주게되면 r9에 있는 주소의 값에 12345라는 값을 저장할 수 있다.


pwntool로 fsb 쉽게 작성하기

pwntool로 fsb를 쉽게 작성할 수 있다. pwntool에 fmstr_payload 함수를 사용해서 쉽게 fsb를 작성할 수 있다.

fmtstr_payload(offset,{targetaddr:value})형식을 가지며 offset은 printf에 쓰인 첫번째 인자의 값이 해당하는 버퍼로  "aaaaaaaa %p %p %p ..."와 같은 값을 입력했을 때, 출력 결과에서 0x6161616161616161 ('a'가 8개)이 출력되는 순서를 세어보면 쉽게 알 수 있다.  targetaddr은 값을 적을 주소이고 value는 주소에 적을 값이다. 

0x40403c에 0x11223344를 덮어씌우는 fsb 코드

더보기

b'%68c%12$lln%205c%13$hhn%17c%14$hhn%17c%15$hhnaaa<@@\x00\x00\x00\x00\x00?@@\x00\x00\x00\x00\x00>@@\x00\x00\x00\x00\x00=@@\x00\x00\x00\x00\x00'


대응 방안 

FSB를 막는 방법은 의외로 매우 간단하다.
1. 포맷 지정자 필수 사용 사용자의 입력이 출력 함수의 포맷 문자열로 직접 들어가지 않도록 한다.

 

 

 


참조

https://jiravvit.tistory.com/entry/64bit%EC%97%90%EC%84%9C-FSB-Format-String-Bug-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-1
https://s1m0hya.tistory.com/19
 

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

[System hacking] 시스템 보안 수업 후기  (0) 2025.12.18
[System hacking] Checksec  (0) 2025.12.09
'Security/시스템해킹' 카테고리의 다른 글
  • [System hacking] 시스템 보안 수업 후기
  • [System hacking] Checksec
yt_5246
yt_5246
yt5246 님의 블로그 입니다.
  • yt_5246
    yt의 공부 블로그
    yt_5246
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • 분류 전체보기 (61)
      • IT (1)
      • Security (11)
        • 시스템해킹 (3)
        • 리버싱 (6)
        • 암호학 (0)
        • tools (2)
      • Book (0)
      • 자격증 (3)
      • 워게임 (46)
        • DVWA (7)
        • WebGoat (4)
        • webhacking.kr (35)
      • 버그바운티 (0)
  • 인기 글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
yt_5246
[System hacking] FSB
상단으로

티스토리툴바