CODEGATE 2012 YUT CHALLENGE 予選に参加してみた。

久しぶりのCTFでした!超楽しかった!!
Bin100
Net100、200、300、400
Misc100、300
のWriteupを残しておきます。

Binary 100

やったー!Windowsバイナリだー!(
実行すると、何やら強制終了する。
このとき、"sxe42.tmp"というファイルが出来てる。
これも実行ファイル。


.NET製なので、Reflector等で逆コンパイルしてやると、コードが出てきます。
自分はVB.NET派なので、VB.NETのコードで見てやると、こんな感じ。
長いので抜粋。

Friend Class Program
    Private Shared Sub Main(ByVal args As String())
'...
                synthesizer.Speak("What is greater than god, more evil than the devil?")
'...
    End Sub

    Private Shared Sub recognizer_SpeechRecognized(ByVal sender As Object, ByVal e As SpeechRecognizedEventArgs)
'...
            If (e.get_Result.get_Text = "Yes") Then
                Program.str_cypher = (Program.str_cypher & "QA1f1/EqAOZktIz1RrwMPunDlqwww==")
                Program.DoHibernation
            End If
'...
    End Sub

    Private Shared Sub DoHibernation()
        Dim now As DateTime = DateTime.Now
        If (now.Hour = 8) Then
            Program.str_input = (Program.str_input & "!")
            If (Program.str_input.Length = now.Hour) Then
                Dim crypt As New WATCrypt(Program.str_input)
                Console.WriteLine(crypt.Decrypt(Program.str_cypher))
            End If
        Else
            Console.WriteLine("This isn't the time yet.")
        End If
    End Sub

    ' Fields
    Private Shared current As RecognitionState = RecognitionState.None
    Private Const RecognizerId As String = "SR_MS_en-US_TELE_11.0"
    Private Shared str_cypher As String = "BM3aZTvv5iQAhK95EFLuz4pta"
    Private Shared str_input As String
End Class
 
Friend Class WATCrypt
'...
    Public Function Decrypt(ByVal p_data As String) As String
'...
End Class

Speakで、"What is greater than god, more evil than the devil?" と聞かれてるので、
ぐぐってみる。すると、答えは "Nothing!" だと分かる。
よって、鍵 "Nothing!" を使ってDecryptすればよい。
プログラムが動いてくれないので、適当に移植して、Decryptした。

Answer: Nuno! Congratulations on your wedding!

Network 100

パケットファイル。データを見ると、PKが見つかり、ZIPと分かる。
が、ところどころ壊れてるので、03 04とか 01 02とか PK とかで検索しながら、修復する。
正常なZIPになったところで、解凍作業。
パスワードがかかっているが、問題文をよく読んでいれば、すぐ分かる。

The password of disclosure document is very weakness and based on Time, can be found easily.

パスワードは時間らしいので、とりあえず数字でブルートフォース。すぐにヒット。

pass: 19841128

そしてこれは同時に、以下のCryptoのKeyになっている。

Msg = "ThisIsNotARealEncryption!SeemToEncoding"
Key = 0x20120224 (if date format is 2012/02/24 00:01:01)
Cryto = C(M) = Msg * Key = 0xa92fd3a82cb4eb2ad323d795322c34f2d809f78

zipの中には、keyが入っているので、このkeyをDecryptする。

irb(main):002:0> v / 0x19841128
=> 620138491573466333567436341452945961
irb(main):003:0> v % 0x19841128
=> 0
irb(main):004:0> ans = v / 0x19841128
=> 620138491573466333567436341452945961

irb(main):012:0> ans.to_s(16)
=> "776f30306f735230634b696e473a29"
irb(main):013:0> ans_h = ans.to_s(16)
=> "776f30306f735230634b696e473a29"
irb(main):014:0> ansarr = "77 6f 30 30 6f 73 52 30 63 4b 69 6e 47 3a
29".split(" ")
=> ["77", "6f", "30", "30", "6f", "73", "52", "30", "63", "4b", "69", "6e",
"47", "3a", "29"]
irb(main):018:0> kotae = ""
=> ""
irb(main):019:0> ansarr.each{ |val|
irb(main):020:1*   kotae = kotae + val.hex.chr
irb(main):021:1> }
=> ["77", "6f", "30", "30", "6f", "73", "52", "30", "63", "4b", "69", "6e",
"47", "3a", "29"]
irb(main):022:0> kotae
=> "wo00osR0cKinG:)"

Network 200

めっちゃ大量のパケット。NetworkMinerを使って開く。
ついでにWiresharkでも開く。
DoS攻撃らしいので、有名どころのSYN Floodとか探してみる。すぐ見つかる。
TOP4 Targetを見つけろとのことなので、NetworkMinerで、受信パケット数でHostをソートする。
(このソートにめっちゃ時間がかかった・・・。)


ソートが終わったら、一番上のIPから順番にチェックしていく。
Wiresharkのフィルタで、"ip.dst == "とか使いながら、パケットを見ていく。
攻撃とおぼしきデータを、順番に見つけていく。
攻撃っぽいデータは、大体みればわかる。


結果はこんな感じ。

TOP1 Singapore                    n  111.221.70.11           Send    0  Recv 52620     UNKNOWN   SYN Flood
TOP2 United Kingdom               o  109.123.118.42          Send 5325  Recv  2960     WINDOWS   F5 Attack
TOP3 United States                n  199.7.48.190            Send  304  Recv   311     UNKNOWN   BIG DATA
TOP4 United States                e  66.150.14.48            Send   50  Recv    99     LINUX     MALFORMED PACKET?

Answer:
none_111.221.70.11_109.123.118.42_199.7.48.190_66.150.14.48


SYN Flood攻撃の参考ページ

Network 300

これ結構大変だった!
UDPパケットなので、データを解析していく。
とりあえず、受信データ量から、データが転送された側は、どちらかすぐ分かる。
最後の方のデータに、"test2.swf"という文字列が見えるので、Flashファイルだろうと予想がつく。
だらだら見てると、データの先頭0x34バイトはあまり変化がないことにも気づく。
その上で最初のパケットを見ると、"7z"から始まっているので、7zファイルだと分かる。
後は、データヘッダを削りながらデータグラムを結合して1つのファイルにする。
(ここでやたら時間を食った気がする・・・。)


うまい方法が思い浮かばなかったので、
1. Wireshark で plain text としてパケットを保存。
2. 余分な情報をカット(Ruby)
3. バイナリデータに変換(Ruby)
4. 手動で最初の方のヘッダをいくらか削除
5. 残りのヘッダを削除(Ruby)
ヘッダの削除でやたらと手間取ってしまった。力量不足を痛感する。。。


後は、できあがった7zファイルを解凍する。
test2.swf が出てくるので、再生してみる。

The answer is ipv6.dst !!

と言われる。はて、このパケットはipv4なんだけど。
と思ってデータヘッダをよく見ると、送信元と送信先ipv6が書かれてる。

fe 80 00 00 00 00 00 00 00 00 00 00 c0 a8 88 88
fe 80 00 00 00 00 00 00 00 00 00 00 c0 a8 88 02


後は、いろんな形で試すだけ。なんだけど。

Answer : strupr(md5(Hint in the leaked data | Hacked internal system address)) 
('|'is just a character)

これ、"|"の左右にスペースが入ってる。ハッシュ化するときにもスペースがいるのかどうか分からなくて、
メールで聞いてみた。そしたら、"No."と言われた。スペースは要らないらしい。
"Hint in the leaked data"は、ipv6.dstなのか、dstのipv6アドレスなのか分からない。両方試す。
問題は、internal system address。ipv4なのかipv6なのか分からないけど、まあipv6なんだろう。
(といいつつ、ipv4もしっかり試したけど。)

fe80::c0a8:8802|192.168.136.136
fe80::c0a8:8888|192.168.136.136
FE80::C0A8:8802|192.168.136.136
FE80::C0A8:8888|192.168.136.136
ipv6.dst|fe80::c0a8:8802
ipv6.dst|fe80::c0a8:8888 ←BINGO

answer:
6642E5A831032D2CF852C66024D9C1F1


追記
murachue氏に、「Decode as→network→IPv6でスッキリ」と教えてもらいました。
これはスッキリ・・・!

Network 400

なんか大量にSQLインジェクションを行ってるパケットを渡される。うわ、これ全部読むの?w
と思いながらも、とりあえずとりかかる。
なんとかインジェクションリストを取りだせないかなー、あわよくば成功したかどうかも知りたい。
パケットを眺めてると、どうやらインジェクションしたSQLが正常に実行されると、
だけが返るみたい。
そこで、こんな風にして抜き出した。

strings 80924D4296FCBE81EA5F09CF60542AE7 | grep -i -E "(php\?name=|<br>)" > injections

更に、%20とか%28とか諸々をsedで置換して、見やすくする。
後はひたすら解析。

schema count: 2
schema1: information_schema
schema2: cdgate

[cdgate]
table count: 1
table1: member

[cdgate.member]
column count: 6
column1: name
column2: id
column3: email
column4: sex
column5: level
column6: passwd

この辺で手動解析するのがめんどくさくなった。
なので、適当にツールを作成して、解析を自動化。
残りは英字ばかりだったので、さほど苦労せずに自動化できた。
そして解析データ。

mail   : monitor@cdgate.xxx
id     : 08b5411f848a2581a41672a759c87380
level  : 2
name   : monitor
passwd : *1763CA06A6BF4E96A671D674E855043A9C7886B2
sex    : f

mail   : apple@cdgate.xxx
id     : apple
level  : 3
name   : apple
passwd : *C5404E97FF933A91C48743E0C4063B2774F052DD
sex    : m

mail   : music@cdgate.xxx
id     : music
level  : 6
name   : music
passwd : *DBA29A581E9689455787B273C91D77F03D7FAD5B
sex    : m

mail   : computer@cdgate.xxx
id     : computer
level  : 2
name   : computer
passwd : *8E4ADF66627261AC0DE1733F55C7A0B72EC113FB
sex    : f

mail   : com@cdgate.xxx
id     : com
level  : 3
name   : com
passwd : *FDDA9468184E298A054803261A4753FF4657E889
sex    : f

mail   : lyco@cdgate.xxx
id     : lynco
level  : 4
name   : *EEFD19E63FA33259154630DE24A2B17772FAC630
passwd : *0ECBFBFE8116C7612A537E558FB7BE1293576B78
sex    : f

mail   : mouse@cdgate.xxx
id     : mouse
level  : 4
name   : *87A5750BB01F1E52060CF8EC90FB1344B1D413AA
passwd : *6FF638106693EF27772523B0D5C9BFAF4DD292F1
sex    : m

mail   : root@cdgate.xxx
id     : root
level  : 6
name   : root
passwd : *300102BEB9E4DABEB8BD60BB9BB6686A6272C787
sex    : f

mail   : desktop@cdgate.xxx
id     : desktop
level  : 1
name   : desktop
passwd : *DDD9B83818DB7B634C88AD49396F54BD0DE31677
sex    : f

mail   : www@cdgate.xxx
id     : 4eae35f1b35977a00ebd8086c259d4c9
level  : 8
name   : www
passwd : *3E8563E916A490A13918AF7385B8FF865C221039
sex    : f

mail   : notebook@cdgate.xxx
id     : notebook
level  : 8
name   : fb5d1b4a2312e239652b13a24ed9a74f
passwd : *18DF7FA3EE218ACB28E69AF1D643091052A95887
sex    : m

大量にある。levelって権限かなーと思うんだけど、高い方がいいのか低い方がいいのか分からない。
とりあえず全部試すことにする。
パスワードはdecodeしないといけないけど、DBに入ってるこれはハッシュ値
先日、後輩のid:hi_igu (通称いぐにゃん)に教えてもらったOnlineHashCrack.comが早速活躍。
levelが一番低い、desktop のパスワードがデコードできたので、試したら、通った。OK。

cdgate|member|etagcd

answer:
AB6FCA7FFC88710CFBC37D5DF9A25F3F

Misc 100

ROT13か転置かなーと思いながら、統計取って転置してみたけど、だめぽ。でも、どう見ても転置だよなあ。
と、ファイルをいろいろ漁ってると、keyboard layoutみたいなファイルを発見。
ググりながら調べてみると、キーボードのレイアウトを編集するファイルっぽい。名前まんまだな。
a -> d とか e -> j とか、そんなノリ。でも、よく分からない数字が入ってるのもある。
これはどうやら、下の方に書いてあるらしい。あった。なるほど。デコード。終わり。

cipher = "Az hrb eix mcc gyam mcxgixec rokaxioaqh hrb mrqpck gyam lbamgarx oatygqh Erxtoigbqigarx Gidc hrbg gasc gr koaxd erzzcc zro i jyaqc Kr hrb ocqh rx Ockubqq ro Yrg man? Gyc ixmjco am dccqihrbgm"

p cipher

dec = cipher

for i in 0 .. dec.length
  c = dec[i,1].downcase
  dec[i,1] = "m" if c == "s"
  dec[i,1] = "k" if c == "d"
  dec[i,1] = "z" if c == "f"
  dec[i,1] = "t" if c == "g"
  dec[i,1] = "f" if c == "z"
  dec[i,1] = "p" if c == "v"
  dec[i,1] = "l" if c == "q"
  dec[i,1] = "j" if c == "w"
  dec[i,1] = "c" if c == "e"
  dec[i,1] = "h" if c == "y"
  dec[i,1] = "g" if c == "t"
  dec[i,1] = "r" if c == "o"
  dec[i,1] = "b" if c == "u"
  dec[i,1] = "v" if c == "p"
  dec[i,1] = "q" if c == "l"
  dec[i,1] = "w" if c == "j"
  dec[i,1] = "d" if c == "k"
  dec[i,1] = "x" if c == "n"
  dec[i,1] = "s" if c == "m"
  dec[i,1] = "a" if c == "i"
  dec[i,1] = "i" if c == "a"
  dec[i,1] = "y" if c == "h"
  dec[i,1] = "n" if c == "x"
  dec[i,1] = "e" if c == "c"
  dec[i,1] = "u" if c == "b"
  dec[i,1] = "o" if c == "r"

end

p dec

exit()

Misc 300 (4つ目のヤツ)

HTMLソースを見てると、最下部に変なコードが。あ、ホワイトスペースか。
と思いきや、ホワイトスペースのインタプリタ落としてきて試そうとしても、うまくいかない。
素直に、jsファイルを見てみる。あ、これまた最下部にpackされたコードがある。
適当にunpackしてみた。なんかevalしてる。中身見てみよう。こんな感じ。

if(new Date().getTime()>1330268400000){
var dummya = '1';
var dummyb = '1';
var dummyv = '1';
var dummyc = '1';
var dummys = '1';
var dummyae = '1';
var dummyasefa = '1';
var dummeya = '1';
var dummya = '1';
var dum3mya = '1';
var dumm54ya = '1';
var dumm3ya = '1';
var dum1mya = '1';
var p = 'YTK4YPT1YK48PTK48TK34PTYK6TDKT5P2KT73TKPY4TBTK3TT4YKT4ETK4YTP7K4T6KT30TKYP7T2KYT33TKP7TY6KTYP33TKPY7PT2YT';
p = p.replace(/T/g,'').replace(/P/g,'').replace(/Y/g,'').replace(/K/g,'%');
var authkey = unescape(p);
}

なるほど、getTimeの条件を潰してauthkeyをalertで表示してみよう。出た。終わり。

answer:
AHH4mRsK4NGF0r3v3r

Misc 100(5つ目のヤツ)

RDCVGF_YGBNJU_TGBNM_YGBNJU_TGBNM_TGBNM_YGBNJU_TGBNM

せっかくなので、友人に教えて、一緒に悩んでみた。分からん。
友人は先に寝てしまったので、一人で考えてみる。うーんうーん。
文字を回転させてみたり、ペイントで塗りつぶしたり、ROTしてみたり。
なんか、1フレーズが1つの文字に対応してそうな気はする。
何かの英単語だろうか。うーん。分からん。
英語だから、かな打ちじゃないだろうし・・・と思い、キーボードに目をやる。ん?ひらめく。分かる。終わり。
(答えは書かないので、考えてみてください。)

問題の感想

  • Network がパケットぺろぺろちゅっちゅな問題ばかりで面白かった。
  • Misc の5つ目は凄く好き。
  • Forensics 100 難しすぎじゃね?(非常に悔しい。)
  • Volnerab 100 も解けなかった。うーん、ブラインドインジェクションしか思い浮かばず。
  • Binary にもっと時間割いてもよかったかも。せっかくWindowsバイナリだったのに。。
  • Network が 400 まで解けたのは嬉しい。

CODEGATE自体の感想

  • 質問メールの対応がすっごくあっさりしてた。(No.だけ。。署名も挨拶とかも一切なし。そんなもんなのかな。)
  • sutegoma2 相変わらず凄いなあ、と思いながら、オフライン参加しちゃえばよかったなーという思いも。
  • とはいえ、一人で参加してないと、今回ほど頑張れなかった気がする。
  • 問題があまりひねくれてなくて、純粋なハッキング大会という印象。
  • 参加して、問題をいろいろ考えながら解くだけで、かなりスキルアップしたことを実感できる。
  • sutegoma2 が、一時はランキングから消えてたけど、後から上位に食いこんでいくところを見ていると、自分も頑張ろうと思える。
  • 来年もぜひ参加したい。それぐらい楽しい。



自分は Aquarium として一人チームで参加してました。
個人的には、結構満足な感じ。苦手分野も凄くはっきりしたので、勉強していかなきゃ。