気付かなければ気付かない系のパズル。unix系のosを常用している人で、勘が良いか時間をつぎ込むかすれば解ける。

Unknown 100. Command-Line Quiz

問題

telnet caitsith.pwn.seccon.jp
User:root
Password:seccon
すべての *.txt ファイルを読め

解法

まず、指定された通りに

$ telnet caitsith.pwn.seccon.jp
CaitSith login: root
Password: seccon

としてloginする。

するとcurrent directoryを見ると、flags.txt, stage{1..5}.txtが存在する。

$ ls
bin         etc         init        linuxrc     sbin        stage2.txt  stage4.txt  tmp
dev         flags.txt   lib         proc        stage1.txt  stage3.txt  stage5.txt  usr

もちろんここでflags.txtを見ようとしても、

$ cat flags.txt
cat: can't open '/flags.txt': Operation not permitted

と言われ、見れない。stage{2..5}.txtは見れないが、唯一stage1.txtは見れて、

$ cat stage1.txt
What command do you use when you want to read only top lines of a text file?

Set your answer to environment variable named stage1 and execute a shell.

 $ stage1=$your_answer_here sh

 If your answer is what I meant, you will be able to access stage2.txt file.

となる。指示に従い、

$ stage1=head sh

とすると、stage2.txtが見れるようになる(stage1.txtは見れなくなる)。以降同様にして、

$ stage2=tail sh
$ stage3=grep sh
$ stage4=awk  sh

とすれば、stage5.txtが見れるようになる。

$ cat stage5.txt 
OK. You reached the final stage. The flag word is in flags.txt file.

flags.txt can be read by only one specific program which is available
in this server. The program for reading flags.txt is one of commands
you can use for processing a text file. Please find it. Good luck. ;-)

しかし、stage5.txtの指定はそれ以前のものと形式が違う。 とりあえずここまでをexpect scriptとしてまとめると以下のようになる。

#!/usr/bin/expect
spawn telnet caitsith.pwn.seccon.jp
expect "CaitSith login: "
send "root\n"
expect "Password: "
send "seccon\n"
send "stage1=head sh\n"
send "stage2=tail sh\n"
send "stage3=grep sh\n"
send "stage4=awk  sh\n"
interact

さてstage5.txtであるが、結論だけ言えば、文中で指示されているプログラムとはsedであり、以下のようにすれば中身が見える。

$ sed '' flags.txt
OK. You have read all .txt files. The flag word is shown below.

SECCON{CaitSith@AQUA}

sedでのみflags.txtにアクセスできるので、sedflags.txtをそのまま出力させればよい。

$ sed --help
Usage: sed [OPTION]... {script-only-if-no-other-script} [input-file]...
...

sed scriptとして空文字列``、つまり何も加工せずそのまま出力するプログラム、を与え、その入力としてflags.txtを指定すればflagが見える。 本番はs/./&/gとかした気がするが、やっていることは同じ。

試行錯誤

sedからならflags.txtが読めるということに気付くまでに、非常に色々なことを試した。

  • headtailflags.txtを開こうとはした。sedは漏らしていた
  • /bin /sbin /usr/bin /usr/sbin にある全てのバイナリに関して、$ stage5=XXX shを実行
  • バイナリのinodeが全て一致しているという話を聞き、busyboxだということが判明。これを調べる
  • busyboxは、呼び出されたときの自身のファイル名$0の値で振舞いを変える。ln -s /bin/cat /tmp/busyboxなどとすれば、busyboxそのものが触れるので、色々試す
  • which is available in this serverとは言われているが、存在するとは言われていないので、busyboxが対応しているがサーバに存在しないバイナリを探したりした
  • psで他の参加者の実行しているコマンドを見て、ヒントを得ようとした