--------------------------------
6th HUST hacking festival
  race condition report

hkpco
hkpco@korea.com
wowhacker&wowcode
--------------------------------


HUST2007 hacking festival의 레이스 컨디션 보고서 입니다.

작업 기록들을 거의 로깅해 두지 않아 상세한 보여주기는 힘들 것 같습니다.

우선 로컬로 접속하여 setuid가 걸린 프로그램을 찾습니다.

우리가 공격해야 할 대상 프로그램은 /bin/flyHigh 이 되겠습니다.

이 프로그램의 strings결과를 보면 파일을 열고(open함수), 기록한 뒤(write), 삭제(unlink)하는 정도의 루틴을 수행합니다.

생성하는 파일의 이름은 /quest/level5/tmp/HUST 이며 이 파일이 생성되는 짧은 순간에 내용을 읽으려고 시도하지만

파일에 읽기 권한이 없으므로 그러지 못합니다.

우리는 여기서 /quest/level5/tmp/HUST 가 생성, 기록, 삭제 되는 짧은 순간의 시간차를 이용하여 race condition공격을 생각 할 수 있습니다.

/bin/flyHigh를 실행하였을 때, /quest/level5/tmp/HUST 파일이 이미 존재하면 파일의 삭제를 하지 않는것을 알 수 있습니다.

이를 이용하면 "다른 사용자 권한으로 생성되는 읽기권한이 없는 파일"이 아닌 "내가 생성한 읽기 가능한 파일"에 기록이 되게 됩니다.

그 기록되는 내용은 바로 이 문제의 답일것이며 이것을 읽어야 합니다.

하지만 바로 unlink(삭제)가 되므로 파일이 기록되고 삭제되는 사이의 시간차를 이용합니다.

간단히 나타내어 보면 아래와 같습니다.

|write(기록)|..아주 짧은 시간..|unlink(삭제)|

한쪽 터미널에서는 /bin/flyHigh를 실행을, 다른 한쪽 터미널에서는 /quest/level5/tmp/HUST의 생성과 읽기작업을 무한히 수행하면 될것입니다.

그런데 서버내의 gcc나 cat등의 명령어가 허용되지 않으므로 쉘 스크립트와 head명령어로 대체합니다.

작성된 쉘 스크립트들은 아래와 같습니다.

- loop_target.sh -

#!/bin/sh

for((;;))
do
	/bin/flyHigh
done

- end -

loop_target.sh의 경우 /bin/flyHigh를 무한히 실행시키는 간단한 스크립트입니다.

아래에서 race_rush.sh의 작업을 알아보겠습니다.

- race_rush.sh -

#!/bin/sh

for((;;))
do
	echo "hkpco" >> /quest/level5/tmp/HUST;head /quest/level5/tmp/HUST;head /quest/level5/tmp/HUST;usleep 10000
done

- end -

"hkpco"라는 내용이 담긴 /quest/level5/tmp/HUST 파일을 생성하고 head명령어로 /quest/level5/tmp/HUST 파일을 읽어줍니다.

/bin/flyHigh의 시간차를 고려하여 head명령을 두 번 수행시켜 줍니다.

이 작업이 무한히 반복되기 때문에 자칫 답이 터미널상에 출력된다고 하여도 보기가 힘들어 질 수 있습니다.

그래서 usleep명령을 이용해서 반복되는 작업에 딜레이를 줍니다.

해당 서버에서는 chmod명령의 퍼미션이 막혀있으므로 "/bin/sh 스크립트.sh"와 같이 쉘 스크립트를 실행시킵니다.

이제 다음과 같이 실행합니다.

[terminal 1]
$ sh loop_target.sh

[terminal 2]
$ sh race_rush.sh

[terminal 2]에서 잠시 기다리면 "PracTicE mAkeS PerFeCtsibar" 라는 답이 출력됩니다.