본문 바로가기
Wargame Write-Up/HackCTF

[HackCTF] (Pwnable) Basic_FSB 풀이

by snwo 2020. 3. 6.

 

문제파일을 ida로 열어보면 main함수가 있다. main함수에는 특별한점이 없으니 vuln함수로 넘어가자

 

 

var_808 에 입력을 받고, snprintf로 var_408 에 400만큼 출력하고 printf 로 var_408 을 출력한다.

하지만 코드에는 이상한 점이 있다. 바로 (%s 나 %d 같은)서식문자를 사용하지않는점인데, 

이점은 포멧스트링 버그(Format String Bug) 로 이어질 수 있다.

 

포멧 스트링 버그는 문자열을 입력받을때 사용자가 서식문자를 입력하면 그 서식문자에 따라 출력이 된다.

한번 문제서버에 서식문자를 입력해보자.

 

 

AAAA %x %x %x %x 를 입력하면 그대로 출력되지않고 서식문자에 따라 16진수값들이 나오게된다.

이 16진수값들은 왼쪽부터 차례대로 스택에서 esp+4, +8, +12, +16 의 값을 가르키게되어

우리는 스택의 상태를 확인할 수 있다. 그렇다면 FSB 를 이용해 공격을 해보자.

 

    [%n]

 

%n도 서식문자중에 하나인데, %n앞에 입력된 문자의개수만큼 변수값에 저장한다.

ex ) : printf("AA%n",&n); -> AA4 

 

(주소) %c %n 이런식으로 사용해

%n으로 원하는주소에 원하는값을 쓸 수 있다. 이때 문자의 개수값은 %100c 처럼 원하는값을 넣을수있다.

그렇다면 쓸 주소를 정해보자.

 

위의 코드를 다시보면, printf에서 취약점이 터지는게아니라, snprintf함수에서 터지게된다. ( 둘다 서식문자를 사용하고있지않다 )

그렇다면 printf 함수는 사용자가입력한 서식문자를 적용한 문자열을 출력하게되므로 쓸모가 없게된다.

그렇기에 printf 의 GOT주소에 값을 쓰자

 

 

printf의 PLT주소에서 GOT주소로 점프하므로, printf의 GOT주소는 0x0804A00C

 

이 주소에 어떤값을 쓸까 함수목록을 찾아보면 flag함수가있다.

 

   

함수의 주소는 0x08085B4 이다.

 

    [payload]

 

먼저 문자의 개수값을 정해보자. %(숫자)c 에서 숫자의 크기값을 원하는 주소에 쓸 수 있으므로 

숫자를 flag 주소의 10진수값 - %n앞의 문자의 개수 로 넣으면된다.

80485B4h -> 134514100

AAAA %x %x %x %x 의 결과가 AAAA 0 41414141 XXXXXXXX XXXXXXXX

이렇게 출력되는걸 보면

 

  • 1~4 : printf의 GOT주소
  • 5 ~ 13: %(flag의 10진수값-문자개수)c
  • 14 : %n

이렇게 payload를 작성하면 될 것 같다.

이제 %n앞의 문자의 개수를 구하면 134514100 - (주소4바이트) = 134514096

 

    [최종 payload]

 

(python -c "print '\x0c\xa0\x04\x08'+'%134514096c%n'";cat) | nc ctf.j0n9hyun.xyz 3002