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の画像が表示されるが何かのチェックで終了している模様。
難読化されているといっても所詮はスクリプトなので最後のほうで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
といってもまだ難読化されているのだが。 シンタックスエラーがあるので改行コードを若干修正すると実行できる。 また、処理中に実行環境のチェックをしているのでその部分をスキップして実行するとピアノの鍵盤が。実際に音もなるらしい?(自分の環境ではうまくならなかった)
処理の後半では、正しいキー入力(ピアノ演奏)を基に生成した鍵を使って、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修復してくれるというツールを適当に探してきて実行しただけ。怪しげなツールだと困るので、ツール実行前にスナップショットをとっておいて後で戻しておきました。こういう時に仮想マシンは便利です。
とても楽しかったです。SECCONは毎年楽しみにしていて欠かさず参加するようにしている重要イベントです。予選突破できたのもうれしい。 運営のみなさん、チームのみなさん、まわりのいろいろな人に感謝です。ありがとうございました。















