きなこもち。

(´・ω・`)

SECCON CTF予選参戦記+writeup

10/19(土)~10/20(日)に開催された、SECCON CTF 2019にチームContrailとして参戦しました。

初のSECCON CTF予選でしたが、非常に楽しかったです(`・∀・´)

 

なお、当記事は「writeupだけ読みたい」という方のために、writeup→参戦記という形を取っています。

 

[Web] web_search

Description:

Get a hidden message! Let's find a hidden message using the search system on the site. f:id:kinako_mochimochi:20191020181457p:plain

 

指定されたURLに飛ぶと、RFCを検索できるアプリが稼働してます。

サーバサイドのソースコードはヒントとして与えられていなかったため、
あれこれ思案した結果SQL injectionだとアタリをつけました。

 

スペースとorの禁止に苦しむ

検索ボックスに

' or 1=1 -- -

というお馴染みのpayloadを打ち込むと、ERRORの表示とともに

'1=1---

が返ってきました。

よって、この検索ボックスは、少なくとも

・スペースの禁止

・ORまたは||を禁止

していることがわかりました。

スペースの禁止は、過去解いた経験からタブ文字あるいは改行文字で代用すればいいと知っていたので、 今回もタブ文字をスペースの代用にしました。

問題はORの禁止で、一人で O/**/R OROR なども試しましたが、上手くいきませんでした。

ここで、チームメイトのwtさん(@w_tl00)が、「ORがだめならOORRはどうか」とアドバイスをくれたので、 それを基に上手く機能するpayloadが完成しました。

' OORR 1=1 -- - #スペースはタブ

' OR  1=1 --  - #実際に返ってくるやつ

このpayloadでテーブル内の全てのレコードが出力され、最後のレコードにflagの一部がありました。

FLAG
The flag is "SECCON{Yeah_Sqli_Success_" ... well, the rest of flag is in "flag" table. Try more!

flagの前半部分だけのようです。残りはflagテーブルにあるらしい。

コンマ(,)禁止との死闘

SQL injectionにおいて、他のテーブルの値を読み出す代表的なものはUNION-based SQL injectionです。
奇妙なことに、この検索ボックスはORを禁止しているのに、UNIONやSELECTといったもっとやばそうな句は禁止していませんでした。
そういったこともあり、UNION-based SQLiにアタリをつけて取り組むことにしました。

しかし、ここで大きな壁にぶつかります。

なんとこの検索ボックス、コンマ(,)を禁止しているのです。

' UNION   SELECT  1,2,3   --  -

' UNION   SELECT  123 --  -   #(T◇T)

UNION-based SQLiにとって、カラム数特定のためにコンマは必需品です。

ここから1時間強かけて、"union based sql injection without comma"、"sql injection read another table"などなど色々調べた結果、 以下のブログがヒットしました。

zoczus.blogspot.com

記事によると、

~' UNION SELECT null,user();

~' UNION SELECT * FROM (SELECT null) AS a JOIN (SELECT user()) AS b;

と書くのに等しいようです。

これを参考に、カラムの数を特定した後(3つでした)、コンマなしで書き上げたpayloadがこれです。

' UNION SELECT * FROM (SELECT * FROM flag) AS a JOIN (SELECT null) AS b JOIN (SELECT null) AS c -- - #スペースはタブ

これは

' UNION SELECT *, null, null FROM flag -- -

とだいたい同じ働きをするはずです。詳しくは検証してないです(・ω・;)

f:id:kinako_mochimochi:20191020201836p:plain
nullを1,2,3にしてUNION-based SQLiが成功している図

上記のpayloadを打ち込むとflagテーブルのレコードを読み出すことができ、flagの後半部分をGETできました!

You_Win_Yeah}

FLAG: SECCON{Yeah_Sqli_Success_You_Win_Yeah}

なお、これはチームメイトのTeppayさん(@teppay_sec)が手直ししてくれたおかげで
完成したpayloadで、自分はひたすらFROM flagをどこに置くか迷っていました。笑

一人では決して解くことはできませんでした。一緒に考えてくれたメンバーに感謝です。

(writeup終わり)

他の問題

[Web] Option-Cmd-U

Description: No more "View Page Source"!

  • 以前から予想していたSSRFの問題が遂に出題された!と盛り上がっていたが、結局解けず。
  • http://(問題ページのホスト名)/flag.phpをSubmitするとForbidden.Your IP: (どっかのIPアドレス)が表示されたので、チームメイトに報告するとネットワーク内部のIPっぽいらしく、それをもとにDNSRebindingで解いてくれた。すごい(小並感)

[Misc] Sandstorm

Descripton: I've received a letter... Uh, Mr. Smith?

  • 砂嵐を背景にメッセージが書かれたpngファイルが渡される。
  • うさみみあたりで解析していたが、手がかりが掴めず。よーくみると、背景がQRコードに見えなくもない。
  • 問題文のMr. Smithと、画像に書いてある差出人"Adam"が別人なのにずっと引っかかっていたが、exiftoolをかけると"Adam7"なるアルゴリズムを使って云々されていることに気づく。
  • しかしAdam7はStegoじゃなさそうだし、資料が少ないのでイマイチこれじゃない感があったが、チームメイトのCiruelaさん(@__Xcyba17her_)がAdam7情報をもとにsolverを書いてQRコードを出現させていた。すごい(小並感)

[Web] fileserver

Description:
I donno apache or nginx things well, I guess I can implement one for myself though. See? It's easy!

  • 問題ページにアクセスすると、個人が運営するWebページにたどり着く。アプリが動いているWebサーバ内にあるflagをどうにかして読む問題。
  • 問題文通り、アクセス制限が適当で、パストラしてアプリ本体のRubyファイルを読むことができる。
  • ソースを読む限り、Dir.glob()にアタリをつけてなんとかflagファイルを読もうとしたが、全く歯が立たなかった・・・(´;ω;`)
  • 39チームがsolveしていたので、通したかった。。。。

課題

  • solverが致命的に書けない。ある程度ひらめいても、solverがさっと書けないのでチームメイトに頼りっぱなしでした。笑
  • DNSRebindingなど、自分の中で「知っていても解けない」部類の問題が多く、まだまだ演習不足なのを感じました。
  • シェルスクリプトを書いたことがないため、SECCON_multiplicaterや、Beeeeeeeeeerのようなシェル 主体の問題に貢献できない。いい加減覚えねば。

参戦した感想

とーっても楽しかったです!(´^ω^`)
SECCONの過去問を研究していると、毎年Web問は1題しか出題されないようだったので、
その1問に全力を尽くそう!という心意気だったのですが、今年は6問も出題され、
いい意味で裏切られました(・∀・)
(SECCONも変革期なのでしょうか?)

今回のCTFで、自分で1から回答を練り上げて手に入れたflagはありませんが、それでいいと思います。
CTFはみんなで相談して答えを見つけていくから楽しいんだと思います。

今年の一大イベントが終了してしまったので、少し寂しい気もしますが、今年はまだ2ヶ月あります!
後回しにしていたPwnやBinary Exploit、勉強すべき楽しいことがたくさんあります。
まだまだ自分は道半ば。がんばっていこうと思います(´^ω^`)

チームContrailのみんな、SECCON運営の皆さんに感謝します!!
ありがとうございました〜〜〜〜(°▽°)

おわり

 

Twitter:

twitter.com