読者です 読者をやめる 読者になる 読者になる

SECCON 2014 CTFオンライン予選(英語)のWriteup 6問

今回も参加しましたSECCON2014 CTFオンライン予選(英語)。今回はQRコード系の問題が多いのと、問題文を一見して何をどうしたらいいのかわからないことが多く非常に残念な成績を取ってしまいました…勘が鈍ってますね。今回もWriteupなるものを書いてみますが、簡単な問題しか解けてないので、せめて丁寧さだけでも出しておきます。

解いた問題は以下のとおりです。

Network

  • Get the key

Crypt

  • Easy Cipher

Programming

  • Choose the number

Binary

  • Shuffle
  • Reverse it

Forensics

  • Get the key.txt

以下、解答を載せていきます。

Network 100 Get the key



問題文にパケットキャプチャファイルが一つだけリンクされていました。nw100.pcap

とりあえず、パケットキャプチャはWiresharkで開きます。
f:id:qzm4u:20141209223408p:plain

HTTP通信を行っているパケットが確認でき、またAuthorization Requiredという文字列が確認できるところから何らかの認証を行っていることがわかります。
該当するパケットをより詳しく見てみます。
f:id:qzm4u:20141209223821p:plain

Basic認証を行っていることがHTTPパケットからわかります。
Basic認証では認証情報は一切暗号化されずに送信されますので、パケットを見れば入力したIDとパスワードが分かります。

Credentials: seccon2014:YourBattleField

Basic認証ではIDとパスワードを:で連結して送信するので、この場合IDはseccon2014、パスワードはYourBattleFieldとなります。
ついでにパケットを見るとどのサーバと通信してるのかもわかりますので、同じサーバに上のIDとパスワードを利用して通信してみると、ファイルリストが見えました。
f:id:qzm4u:20141209224215p:plain

key.htmlを選択すると、画面にフラグが表示されました。

SECCON{Basic_NW_Challenge_Done!}

f:id:qzm4u:20141209230825p:plain

Crypt 100 Easy Cipher



問題文が以下のように与えられていたので、意図するところを考える。

87 101 108 1100011 0157 6d 0145 040 116 0157 100000 0164 104 1100101 32 0123 69 67 0103 1001111 1001110 040 062 060 49 064 100000 0157 110 6c 0151 1101110 101 040 0103 1010100 70 101110 0124 1101000 101 100000 1010011 1000101 67 0103 4f 4e 100000 105 1110011 040 116 1101000 0145 040 1100010 0151 103 103 0145 1110011 0164 100000 1101000 0141 99 6b 1100101 0162 32 0143 111 1101110 1110100 101 0163 0164 040 0151 0156 040 74 0141 1110000 1100001 0156 056 4f 0157 0160 115 44 040 0171 1101111 117 100000 1110111 0141 0156 1110100 32 0164 6f 32 6b 1101110 1101111 1110111 100000 0164 1101000 0145 040 0146 6c 97 1100111 2c 100000 0144 111 110 100111 116 100000 1111001 6f 117 63 0110 1100101 0162 0145 100000 1111001 111 117 100000 97 114 0145 46 1010011 0105 0103 67 79 1001110 123 87 110011 110001 67 110000 1001101 32 55 060 100000 110111 0110 110011 32 53 51 0103 0103 060 0116 040 5a 0117 73 0101 7d 1001000 0141 1110110 1100101 100000 102 0165 0156 33

空白区切りで数字が幾つか並んでいたので、とりあえず意味がありそうな4f, 4e当たりをバイナリエディタに叩きこみASCIIコードとして確認。

4f → O、4e→ N

ということで、大方何らかのASCII文字列だろうと当たりをつけ、後は慣習に合わせて01のみは2進数、a-fを含めば16進数、普通の数値は10進数、0から始まる数値は8進数の表現だと踏んで、ASCII文字列に変換するコードを書く。

text = "87 101 108 1100011 0157 6d 0145 040 116 0157 100000 0164 104 1100101 32 0123 69 67 0103 1001111 1001110 040 062 060 49 064 100000 0157 110 6c 0151 1101110 101 040 0103 1010100 70 101110 0124 1101000 101 100000 1010011 1000101 67 0103 4f 4e 100000 105 1110011 040 116 1101000 0145 040 1100010 0151 103 103 0145 1110011 0164 100000 1101000 0141 99 6b 1100101 0162 32 0143 111 1101110 1110100 101 0163 0164 040 0151 0156 040 74 0141 1110000 1100001 0156 056 4f 0157 0160 115 44 040 0171 1101111 117 100000 1110111 0141 0156 1110100 32 0164 6f 32 6b 1101110 1101111 1110111 100000 0164 1101000 0145 040 0146 6c 97 1100111 2c 100000 0144 111 110 100111 116 100000 1111001 6f 117 63 0110 1100101 0162 0145 100000 1111001 111 117 100000 97 114 0145 46 1010011 0105 0103 67 79 1001110 123 87 110011 110001 67 110000 1001101 32 55 060 100000 110111 0110 110011 32 53 51 0103 0103 060 0116 040 5a 0117 73 0101 7d 1001000 0141 1110110 1100101 100000 102 0165 0156 33"

text.split(" ").each do |c|
  if c =~ /^[01]{6,}$/ then
    print c.to_i(2).chr
  elsif c =~ /^0[0-9]{2,3}$/ then
    print c.to_i(8).chr
  elsif c =~ /^[0-9]{2,3}$/ then
    print c.to_i(10).chr
  elsif c =~ /^[0-9a-f]*$/ then
    print c.to_i(16).chr
  end
end

あとは特に何も考えずに文字列を取り出す。

Welcome to the SECCON 2014 online CTF.The SECCON is the biggest hacker contest in Japan.Oops, you want to know the flag, don't you?Here you are.SECCON{W31C0M 70 7H3 53CC0N ZOIA}Have fun!

ということで、Flagが回収できたので入力して100点ゲット。

SECCON{W31C0M 70 7H3 53CC0N ZOIA}

Programming 100 Choose the number



問題文にサーバとポートが指定されていました。

nc number.quals.seccon.jp 31337

Programmingのジャンルなので、早速サーバにアクセスし問題を確認すると、数字がいくらか与えられ、その中から最大値or最小値を選択すれば良いことがわかりました。

  • 3, 2

choose maximum number?

#すみません、英文の部分はうろ覚えです

早速、問題を解くようにrubyでプログラミングしてサーバに向けて走らせます。
例によってフラグを回収するコードは入れていないので、裏でパケットキャプチャを走らせて解答を取ってこれるようにしておきます。

require 'socket'

TCPSocket.open("number.quals.seccon.jp", 31337) do |s|
  loop{
    numbers = s.gets.delete(" ").split(",").map!{|v| v.to_i}
    print numbers
    puts
    q_text = s.gets("?")
    puts q_text.split(" ")[1]
    if q_text.split(" ")[1] == "maximum" then
      print numbers.max
      s.puts numbers.max.to_s+"\n"
    elsif q_text.split(" ")[1] == "minimum" then
      print numbers.max
      s.puts numbers.min.to_s+"\n"
    else
      puts q_text
    end
  }
end

100問ほど同じような問題を繰り返すと、以下のようにフラグを入手できました。

The flag is SECCON{Programming is so fun!}

Binary 100 Shuffle



以下のように問題文とファイルが与えられました。

find the string before randomizing.
shuffle

fileコマンドで結果を見てみると実行ファイルっぽいので、IDA Proで解析をかけます。
f:id:qzm4u:20141209230505p:plain
思っきり文字っぽいものをスタックに叩きこむコードが見えます。
後は詳しく読んでませんが、これをシャッフルして画面に出力するようです。

ということで、例のようにStirlingさんに叩きこまれているバイナリを入れてみます。
f:id:qzm4u:20141209230825p:plain

あとは見たとおりにフラグを送信して終わりです。

SECCON{Welcome the SECCON 2014 CTF!}

Binary 100 Reverse it



問題文にファイルが一つだけ貼り付けられていました。Reverseit

fileコマンドにいれると、意味不明のデータだといわれたのでとりあえずバイナリエディタで観察します。
Reverseitという名前から、更に特にデータの後ろから入念にチェックしてみます。
f:id:qzm4u:20141209231123p:plain

このお尻から始まる FF 8D FFというバイナリ列は、jpgファイルのヘッダ特有の並びです。
このことから、このファイルをhex単位で逆に並べ替えるとjpgファイルが得られるということがわかります。
ということで、実際にhex単位でファイルを逆順にするプログラムを書きます。

read =  File.binread("Reverseit").reverse.bytes.collect{|b|
((b>>4)|((b&0x0F)<<4)).chr
}.join
File.binwrite("Reversed.jpg",read)

出力されたReversed.jpgを開いてみます。
f:id:qzm4u:20010022104102j:plain

フラグまで逆転していますが、目reverseでフラグを入手できます。

SECCON{6in_tex7}

Forensics 100 Get the key.txt



問題文にファイルが一つだけ貼り付けられていました。forensic100.zip

fileコマンドに渡すと、ext2ファイルシステムだとわかったので、linux上でmountコマンドを利用してマウントします。
すると、連番のファイルが現れました。
よくわからないファイルはfileコマンドに叩きこむの原則からもう一度fileコマンドを利用すると、それぞれkey(ほげほげ).txtファイルをgzip化したものだとわかります。
f:id:qzm4u:20141216185428p:plain

grepなりでわかるのですが、key.txtを圧縮しているのは1という名前のファイルということがわかるので、
これを解凍して中身を出力するとフラグが現れました。
f:id:qzm4u:20141216185723p:plain


なんだかんだ先送りにしていてやっとwriteupかけました。結局、今年も当たり前のように全国大会には出られませんでしたが、来年も頑張って行きたいです。
次はどの分野の勉強しようかなぁ…