目次
惨敗した
どうも、チーム「あれがななち」の「あれが」担当のながてちです。
2018/5/26(土) 13:00 から 2018/5/27(日) 13:00 まで行われたSECCON Beginners CTF 2018にますぐれとチームを組んで参加しました。
CTFの大会に出たことないガチ初心者だったのですが、「初めてCTFに参加される方」を対象にしたCTFの大会が開かれるとのことだったので、これを機にやるぞ~って感じで大会に臨みました。
結果はというと、
388ポイントで242位でした。
なんとも言い難い点数と順位…。
これで「初心者向け」のCTFなので、かなり厳しいな…って感じで終わりました。
ちなみに競技中は寝る間も惜しんで考えてました。ぽえ~
Write Up
需要あるか分かりませんが、自分が解いた部分のWrite Upを書こうと思います。
自分はおもに「Web」と「Misc」を担当しました。
[Warmup] Greeting | Web 51点
問題ページの下に思いっきりソースコードが書いてあったのでPHP分からないながら頑張って読んだら、
「Cookieのnameにadminがセットされている」状態で「name(フォーム)の入力がなければ」FLAGが降ってくるなって考えました。
なので一度adminを入力してわざと偽管理者になり(Cookieをセットするため)、管理者ツールでフォームの変数をnameからnam(適当)にして名前を変更するボタンを押すと、FLAGが降ってきます。
FLAGはctf4b{w3lc0m3_TO_ctf4b_w3b_w0rd!!}
Gimme your comment | Web 78点
お問い合わせフォームに
<script>
alert('おいす~');
</script>
と入力して送信するとちゃんと動くことから、クロスサイトスクリプティングでいけるなって思いました。
問題文に巡回者のソースコードが与えられていたので、読むと、
- comment_contentという名前のフォームに「投稿ありがとうございます。大変参考になりました。」と入力する
- submitボタンを押す
- サヨナラする
という行動をしていたので、「フォームにuser-agentの情報を入力させてsubmitさせればFLAG降ってくるな」と考えました。
そんな感じで送信したお問い合わせがこんなかんじ
<input type="text" name="comment_content">
<script>
$(document).ready(function () {
var userAgent = window.navigator.userAgent.toLowerCase();
document.getElementsByClassName("form-control")[0].value = userAgent ;
});
</script>
わざとnameがvomment_contentなダミーフォームをつくり、そこに「投稿ありがとう~」を入力させて、ちゃんとしたほうのフォームに自動入力させたuser-agent情報をsubmitさせます。
これを実行するとこんな感じ
すでに入力されてるのは自分のuser-agentですね。
FLAGはctf4b{h4v3_fun_w17h_4_51mpl3_cr055_5173_5cr1p71n6}
ちなみにこの方法だと、次の問題「Gimme your comment REVENGE」で自動入力ができなくなって死にます()
[Warmup] plain mail | Misc 51点
パケット解析問題
ちょうど大会前にパケット解析の問題をやってたので、よっしゃ~って感じで解きました。
問題文からmailが関係してるんだろうな~ってことでWireSharkで開いてSMTPでフィルタリング。
すると、「いまから2通のメールを送るよ、1通目はzipファイル、2通目はパスワード」みたいなメールがみつかるので、それ通りにメールのパケットを見ていって、zipを手に入れてパスワードを入力して中にあるFLAG.txtを取り出しました。
WireSharkにはオブジェクトをエクスポートする便利な機能があるので、それを使ってzipファイルを取り出しました。
FLAGはctf4b{email_with_encrypted_file}
てけいさんえくすとりーむず | Misc 55点
100問を300秒でてけいさんできるかな。
自分はできないので、Rubyでコードを組んで自動化しました。
require 'socket'
port = TCPSocket.open("tekeisan-ekusutoriim.chall.beginners.seccon.jp",8690)
res = 0
puts(port.gets()) #1
puts(port.gets()) #2
puts(port.gets()) #3
puts(port.gets()) #4
puts(port.gets()) #5
puts(port.gets()) #6
puts(port.gets()) #7
puts(port.gets()) #8
puts(port.gets()) #9
puts(port.gets()) #10
puts(port.gets()) #11
for i in 1..100 do
puts(port.gets())
popo = ""
read = port.getc().chomp
while read!="="
popo = popo + read.to_s
read = port.getc().chomp
end
puts ("#{popo} = ")
a,po,b = popo.chomp.split(" ").map(&:to_s)
if po == "+"
res = a.to_i + b.to_i
elsif po == "-"
res = a.to_i - b.to_i
elsif po == "*"
res = a.to_i * b.to_i
end
puts(res)
port.puts(res)
end
puts(port.gets())
puts(port.gets())
puts(port.gets())
苦労したのはRubyのgets()だと、1行まるまる読み込もうとして、入力待ちの部分まで巻き込んでしまい、実行が止まることをどうやって解消しようかという問題です。
getc()という、1文字だけ読み出すというメソッドがあることが分かったので、それを使って入力手前まで読み込むという手法で解決させました。
FLAGはctf4b{ekusutori-mu>tekeisann>bigina-zu>2018}
100問の計算を自動で実行してるのを見てると、何とも言えない達成感がありますね…。
おしまい
なんだかんだいって楽しかったです。
精進します。