第三回さくらの聖夜速報

さくらインターネット Advent Calendar 2015 24日目

こんばんは!さくらインターネットのこたまごです。
本日は、毎年のクリスマスイブ恒例「さくらの聖夜」でした。

詳しい内容は後日、オウンドメディアのさくらのナレッジに掲載されると思いますので、写真を交えて速報をお届けしますっ♪

事前打ち合わせ

事前打ち合わせ

ちゃっかり撮られてた

ちゃっかり撮られてた

「お宝写真大放出!さくら創業20年の歴史を振り返る」

創業20年に突入する節目に、社長の田中と研究所所長の鷲北が、写真で創業からを振り返りました。

社長と所長

社長と所長

ユーザの皆様

ユーザの皆様

「14年ぶりに復帰した理由、今後の構想~インフラ側から支えるIoT~」

後半は、創業メンバで、フェローの小笠原と、Cerevoの岩佐社長による、IoT Platformの発表でした。

なぜ小笠原がさくらインターネットに帰ってきたか、これから何をやるのかについて語るという内容だったのですが、勢い余ってさくらのIoT Platformを発表してしまいました。

具体的にはさくらが3G/LTEの通信モジュールを提供する、さくらのクローズドなネットワークに接続されており、センサの値をさくらのプラットフォーム上に記録したり、モジュールに対してデータを送信したりすることができる、という内容です。
送信するところから、貯めるところまでをハードウエア込みで一貫して提供することによって、IoTへの敷居をぐっと下げることが目的です。

モジュール構成

モジュール構成

システム構成

システム構成

ユーザーイベントだと思っていたのに、びっくりされた方もいらっしゃったかと思います笑

締め

ということで、お越しくださった皆様、ネット中継でご覧くださった皆様、本日はありがとうございました!
変わり続けるさくらインターネットを来年もどうぞよろしくおねがいします♪

最後の最後に、社長の田中も想定価格などを話始めるので、プレッシャーを感じている図。

TrendMicro CTFのオンライン予選をちょっとだけ解いた

実はこの土日にはISUCON5と同時にTrendMicro CTFのオンライン予選もやっていました。

こちらにもチーム竹田氏の以下の四人でメンバー登録して参加していました。

が、きひろちゃん以外はISUCONの方で体力をもっていかれていてあまり参加できなかったのが申し訳なかったです…きひろちゃんごめん…

わたしは、3問着手して、2問だけ答え出しました。

Click on the Different Color

ブラウザでアクセスすると、箱が幾つが含まれる画像が表示される。一箇所だけ違う色のがあるのでクリックすると次に進む。というページでした。最近SNSでも見かけたやつですね。

手でやっていては埒があかないので、Pythonで自動化していくと、最後にフラグが返ってきました。

下の動画を見るとおもしろいですが、最後の方は小さくて到底人間にはクリックできません笑

なので、答えは TMCTF{U must have R0807 3Y3s!} (You must have robot eyes!) でした!

Captcha

こちらはログインするとCaptchaが出てきて、連続で500回正解すると良い感じ。こちらも手でやっていては埒があかないので、Pythonで自動化しました。

画像からノイズを除去して、二値化。それからtesseract-ocrで文字列にして、簡単なチェックに通った場合のみ送信することで自動化できました。

captcha

ところが、大文字小文字や、数字の0とアルファベットのOを誤認識するなど、一部の文字を含む場合にはスキップするようにすると全然すすまなくて、学習させないとだめかなぁと思った時に、これはもしや、と、画像ファイルにアクセスしないようにして同じ答えを投げ続けるとどんどん点数が上がるじゃないですか!

ということで、脆弱性のあるCaptchaでした。というオチです。TMCTF{217dae3fd34cee799658d4552e37827f}

つまり、今年のSECCON決勝戦のこれといっしょですね!
OCRじゃなくて人間が学習するべきでした…

CAPTCHA ノイズ除去

CAPTCHA ノイズ除去

Calculate it

TCPで接続すると、次から次に四則演算の問題が出題される感じ。Pythonから接続してevalしたらOK。

だと思ってたのですが、途中からローマ数字や、英語表記とか出てきて眠気に負けて断念。
ローマ数字はネットで変換プログラムを見つけてきて対応したのですが、英語表記は次のようなのもでてきてパースが大変そうだったのであきらめました。

7 * 10 – 30 1 THOUSAND 2 HUNDRED 30 4 + 50 – 3 * 7 HUNDRED 20 5

これは後できひろちゃんが解きました。

まとめ

本当は9月に行われる予定だったのですが、問題サーバから問題が漏れた?ようで、一ヶ月延期になっちゃって…
ISUCONとかぶったので本腰を入れて解くことができなかったのが残念です。

SECCON運営メンバが作問してるだけあって、面白い問題がおおかったので本当はちゃんとときたかったです。
このチームでちゃんと解いてたら本戦いけたかな…来年に期待。

ISUCON5オンライン予選に参加してきた

「お題となるWebサービスを決められたレギュレーションの中で限界まで高速化を図るチューニングバトル、それがISUCONです。過去の実績も所属している会社も全く関係ない、結果が全てのガチンコバトルです。」(公式説明)であるISUCON5のオンライン予選に参加してきました。

メンバーは、CTFの時のメンバーと同じく、チーム竹田氏の、

で参加しました。3人参加が上限なので、いつものメンバのきひろちゃん (@aki33524) も含めた4人のうちから3人で出場しました。

ISUCONは Iikanjini Speed Up Contest の略で、Webアプリケーションがデプロイされたイメージを渡されて、その上で何をしてもいいからとにかくパフォーマンスを上げることが競技内容です。

オンライン予選

今回はイメージと競技マニュアルをもらった時点で次のことがわかっていました。

  • Ubuntu 15.04
  • フロントはNginx
  • アプリケーションは次の言語で実装されてる (どれか好きに選んでもいいし、書き直してもいい)
    • Ruby
    • Perl
    • Python
    • PHP
    • Java (正常に動作しない)
    • GoLang (正常に動作しない)
    • Scala (正常に動作しない)
  • DBはMySQL
  • インスタンスはGoogle Cloud Platformのn1-highcpu-4 (vCPU x 4、メモリ 3.6 GB)

今回パフォーマンスを上げるアプリケーションはこちら!

ISUxi

その名も ISUxi!足跡機能もあって、どこかでみたことあるアプリケーションです。
これが超絶重い…特にトップページなんかかなり待たされます…これを最適化してくわけですね。

大まかにやったことは以下のような感じです。

  • 設定関係
    • gunicornをUNIXソケットに
    • MySQLへの接続をUNIXソケットに
    • 静的ファイルはNginxで提供
    • ファイルディスクリプタ数の上限変更
    • 各種プロセス数の調整
    • MySQLの一時ディレクトリをRAMディスクに移動
    • MySQLの各種パラメータ調整
  • アプリケーション関係
    • ユーザーテーブルを全てオンメモリで持つ (変更が無く、5000レコードしかなかったため)
    • 各種SQLの最適化
      • ロジックで判定しているところをSQLで判定させるとか
      • 1レコードずつ取得するようなことが無いように
      • あしあとテーブルのスキーマ変更
      • etc…

ISUCON4は結構設定まわりのチューニングだけで本戦出場できる感じだったのに対し、今回はアプリケーションの規模も大きく、実装の方にも手を出さないと本戦出場できなさそうな感じになってました。

途中はMySQLのクエリログを全て取得して、スコアのために測定される1分間でどこのクエリが時間を占めているのかを調査してそこから潰していきました。

特にトップページがLIMIT 1000とかのSQLを3回も吐いてるのでかなり重く、トップページを改善するだけで1万点以上上がったのではないかと思います。

あとはあしあとテーブル。記事にアクセスがあるたびにレコードが追加されるのですが、これを日付、アクセスユーザー毎にGROUP BYしてSELECTするのでとっても重いのです…
こちらは (ユーザーIDアクセスユーザーID日付、最終アクセス日時) の形にスキーマを変更し、あしあとは INSERT…ON DUPLICATE KEY UPDATEにすることで、 SELECT時のパフォーマンスをかなり改善することに成功しました。

こんな感じで進めていくことで、最初はもたついていたISUxiもとっても快適に動作するようになり、スコアも16000点以上出すことができました。

最後に再起動テストをしたのですが、なぜかスコアが下がってしまって、最終スコアは14795点になってしまったのですが、無事263チーム中12位で予選通過することができました!

たぶんPython+MySQLのデフォルト構成のままではこれぐらいのスコアが上限なきがしますので、かなり健闘した方だと自負しています。

ほんとはRedisにデータを載せ替えたり、もっとオンメモリで処理したかったのですが、それは本戦で頑張ることにします♪

コードはGitで管理していて、ブランチ切って作業して、テストケース通ったらmasterにマージってしていたのですが、最後のほうはもう直接masterにマージしちゃってますね笑 (コミットユーザは合ってません)

network

おまけ (準備編)

去年の傾向から、MySQLを使うのだろうなとは思っていたので、事前に別のインスタンスでPHPMyAdminを用意してました。
これがデータ構造を把握したり、ちょっとSQLを試したりするのに超便利で、準備しておいてよかったものNo.1かもと思ってます。

さくらのレンタルサーバでpyenvとDjangoを動かす

さくらのレンタルサーバとは

VPSとは異なり,OSの管理をさくらインターネットが行い,一部の権限だけをユーザーが持つホスティングサービスです.
root権限のあるVPSとは違い,できることと使えるリソースは限られますが以下の機能がセットアップなしで利用できます.
さらに,OSやApacheのセキュリティアップデートなどのメンテナンスもさくらが行うので,(自分が設置したもの以外)メンテナンスを意識せずに使えるため,これまでVPSでやってきた人にとっても思った以上に便利だと思います.

  • ApacheによるWebサーバ + CGI
  • メールサーバ (SMTP/POP3/IMAP)
  • データベースサーバ(MySQL)
  • PHP, Python, 等々のコマンド
  • CRON

詳しい仕様は サービスサイト に任せるとして本題に入ります.

ある程度ApacheやDjangoについて理解できている人向けにあっさりと説明します.

Djangoを動かす

一般的な設置方法との違い

レンサバのApacheには mod_wsgi のようなPython向けのモジュールが入っていないため,一般的なデプロイ方法では設置できません.また,常時起動のデーモンプロセスを起動させることもできないため,FastCGIサーバとしてDjangoを動作させることもできません.
そこで,言語問わずCGIモードに対応していることを用いてCGIとしてDjangoを動かします.

Djangoのアプリケーションを作成する

今回はデプロイの説明のため,Webアプリケーションの作成に関しては触れません.サンプルとして以下に公開しているDjangoのプロジェクトを利用して説明します.

chibiegg/django-example-python2

さくらのレンタルサーバを契約する

さくらのレンタルサーバオンラインサインアップ より,さくらのレンタルサーバを契約します.MySQLはスタンダードプラン以上で利用できます.すでに契約しているひとは持っているアカウントでOKです!

2週間の無料お試し期間もあります.(この記事も2週間お試し期間をつかって書いています)

契約すると,仮登録完了メール等でパスワードが通知され,最終的に以下のようなコントロールパネルにログインできると思います.

さくらのレンタルサーバコントロールパネル

今回は初期ドメイン chibiegg-201505.sakura.ne.jp で契約したとして説明します.

データベースを作成する

コンパネ左のメニューから データベースの設定 をクリックします.

データベースの管理メニュー

“データベースの新規作成” をクリックし,適当なデータベース名とパスワードを決めて,データベースを作成します.
パスワードは今後作成する全てのデータベースで共通になります.(変更可能)
また,文字コードはUTF-8を指定します.

データベースの作成

作成後に表示されるデータベースサーバ名を控えておきます.(いつでも参照可能です)

今回は mysql508.db.sakura.ne.jp でした.

SSHでログインして作業する

サブディレクトリを初期ドメインのルートディレクトリにする

標準では /home/chibiegg-201505/www/ がルートディレクトリになりますが,さくらのレンタルサーバでは一つの契約で複数のドメインのWebサイトを提供できます.このとき,ドメインごとに別ディレクトリを指定すると便利なので, /home/chibiegg-201505/www/chibiegg-201505.sakura.ne.jp/htdocs/chibiegg-201505.sakura.ne.jp のルートディレクトリになるように ~/www/.htaccess を作成します.

RewriteEngine on
RewriteCond %{HTTP_HOST} chibiegg-201505.sakura.ne.jp [NC]
RewriteCond %{REQUEST_URI} !(^/chibiegg-201505.sakura.ne.jp) [NC]
RewriteRule .* /chibiegg-201505.sakura.ne.jp/htdocs%{REQUEST_URI} [L]

pyenvのセットアップ

標準ではPythonのバージョンが2系しかなく,また,pipなども利用できないため,pyenvpyenv-virtualenv を利用し,プロジェクトごとにバージョンとパッケージを選択できるようにします.

pyenvに関しては基本的に一般的な方法そのままです.

git clone https://github.com/yyuu/pyenv.git ~/.pyenv
git clone https://github.com/yyuu/pyenv-virtualenv.git ~/.pyenv/plugins/pyenv-virtualenv

でインストールし, ~/.bash_profile を以下のようにします.

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
export TMPDIR="$HOME/tmp"
export PYTHON_PATH=./
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"

今後pyenvを使うときは bash を使います.

chsh -s /usr/local/bin/bash
bash
source ~/.bash_profile

次回からはSSHログイン時にbashが起動します.

今回のプロジェクトで使う環境をセットアップする

pyenv install 2.7.9
pyenv virtualenv 2.7.9 django-example-python2
pyenv activate django-example-python2
pip install django mysqlclient

Djangoのファイルを設置する

bash
mkdir -p ~/www/chibiegg-201505.sakura.ne.jp/htdocs
cd ~/www/chibiegg-201505.sakura.ne.jp
git clone https://github.com/chibiegg/django-example-python2.git
cd django-example-python2
pyenv local django-example-python2

Djangoの設定ファイルを修正する

~/www/chibiegg-201505.sakura.ne.jp/django-example-python2/src/myprj/production_settings.py を以下のように編集します.

この時,ディレクトリやホスト名,データベースの接続情報は環境に合わせてください.

# encoding=utf-8

from .settings import *

DEBUG = False
ALLOWED_HOSTS = ["chibiegg-201505.sakura.ne.jp"]

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'chibiegg-201505_myprj',
        'USER': 'chibiegg-201505',
        'PASSWORD': 'PASSWORDISHERE',
        'HOST': 'mysql508.db.sakura.ne.jp',
        'OPTIONS': {
               "init_command": "SET storage_engine=InnoDB",
        }
    }
}

STATIC_URL = '/static/'
STATIC_ROOT = '/home/chibiegg-201505/www/chibiegg-201505.sakura.ne.jp/htdocs/static/'

migrate (syncdb) する

VPSの時と同じようにモデルからテーブルを作成し,スーパーユーザの作成と,静的ファイルの生成を行います.

cd ~/www/chibiegg-201505.sakura.ne.jp/django-example-python2/src
python manage.py migrate --settings=myprj.production_settings
python manage.py createsuperuser --settings=myprj.production_settings
python manage.py collectstatic --settings=myprj.production_settings

CGIを作成する

ここまでは,どこにデプロイするときも同じです.本来であれば,mod_wsgiや,FastCGI(gunicorn)を使いますが,CGIモードで動かすためにcgiのスクリプトを ~/www/chibiegg-201505.sakura.ne.jp/htdocs/django.cgi に作成します.

ひな形を用意してますので,ダウンロードして使います.

cd ~/www/chibiegg-201505.sakura.ne.jp/htdocs
wget --no-check-certificate https://raw.githubusercontent.com/chibiegg/django-cgi/master/django-python2.cgi
mv django-python2.cgi django.cgi
chmod +x django.cgi

このスクリプトには,実行環境に合わせて3箇所編集・追記する場所があります.

pythonのバイナリの場所を指定する

一行目のpythonのパスを,pyenvの環境のpythonにします.
今回は /home/chibiegg-201505/.pyenv/versions/django-example-python2/bin/python ですので,一行目を以下のようにしました.

#!/home/chibiegg-201505/.pyenv/versions/django-example-python2/bin/python

プロジェクトのパスを追加する

# Change this to the directory above your site code. の行の後にDjangoのプロジェクトのパスを追加します.

sys.path.append("/home/chibiegg-201505/www/chibiegg-201505.sakura.ne.jp/django-example-python2/src")

利用するDjangoの設定を指定する

末尾のほうの application.settings を今回利用する myprj.production_settings に変更します.

.htaccessでリダイレクトの設定をする

ここまでで http://chibiegg-201505.sakura.ne.jp/django.cgi/admin/ にアクセスしてみましょう.
ちゃんとDjangoの管理サイトにアクセスできると思います.

Django管理サイト

ただ,これではカッコ悪いので,ちゃんとRewriteでURLを /admin/ だけになるようにしましょう.

~/www/chibiegg-201505.sakura.ne.jp/htdocs/.htaccess を以下のように作成します.

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /django.cgi/$1 [QSA,L]
</IfModule>

これで http://chibiegg-201505.sakura.ne.jp/admin/ でちゃんとアクセスできるようになりました.

Python3を使う場合

pyenvを入れたのでPython3系列も利用可能です.CGIファイルがバージョンによってことなりますので,

https://raw.githubusercontent.com/chibiegg/django-cgi/master/django-python3.cgi

を利用してください.

SECCON CTF 2014 決勝戦 参加記

昨年の9月にオンライン予選が開催された,SECCON CTF 2014の決勝戦に参加してきました.

昨年はチーム”竹田氏”という名前で決勝戦に出場していたチームの一人と入れ替わり,チーム”Mr. Takeda”として参加しました.
英語表記になったのは,今年からマルチバイトはだめと言われたためで大意はありません.懇親会等でも”たけだし”と呼ばれたので漢字表記のほうが定着しているようです.

国内だけの大会だったはずが,世界大会になり,さらには世界的なハッキングコンテストが開催されるDEFCONの出場権がついてくることになったため,有名な海外のチームもやってきて超難関な決勝戦になってしまいました.Twitterでは,「国内野球大会かと思って参加したら、突然優勝賞品にワールドシリーズ出場権が追加されて、参加チームにヤンキースをはじめ世界の超一流プロチームが集まっていて、ふと隣を見るとイチローがアップを始めていた」と例えられていました(笑)

今回の目標は半分冗談で1桁の順位と決めていたのですが,24チーム中 9位の成績を収めることができ,メンバー一同騒然となる,総合的にはとてもうれしい結果を残すことができました.

SECCON CTF 2014 決勝戦スコア

SECCON CTF 2014 決勝戦スコア

6台のサーバが用意されており,攻撃に成功するとフラグと呼ばれる文字列が手に入ります.これをスコアサーバに送信することで,ひとつあたり100点が加算されます.

また,各サーバに定期的に更新される自分のチームのDefence Keywordを書き込むと,5分ごとに得点が入るルールがあります.

残念ながら,本題のフラグは一つも取ることができなかったのですが,他のメンバーが解いている間にDefence Keywordをなんとかしてそのタイミングにサーバに書き込むことを続けていました.
これにより,3+α個のフラグに相当する得点ができたので,なんとかチームに貢献できてよかったです.

予選ではないDefence Keywordを賭けた他のチームとの攻防戦はとても楽しかったです.

SECCONの詳細は後で加筆することにして,問題のWriteUpを先に書いておきます.

サーバ壱

Redmineのデザインそっくりな”Secmine”というユーザー登録が必要な架空のサイトについての問題でした.

Secmine 登録ページ

Secmine 登録ページ

メニューから,管理者に対して任意のURLを開かせることができる脆弱性がありましたので,クロスドメインの問題を避けながらなんとかセッションか,その他の情報を管理者から奪取すればよさそうというところで頓挫.

このサーバでは,チームで登録したアカウント数のランキング上位に5分ごとに得点できる状態になっていたのですが,単位時間あたりに登録が可能な回数が制限されているため,一番最初に気づいたチームが独占状態で,参戦するのはやめました.

Secmine アカウント数ランキング

Secmine アカウント数ランキング

サーバ弐

以下のような種類があるCAPTCHAがついた掲示板でした.

掲示板

掲示板

CAPTCHAには,

  • 単純に文字列
  • 四則演算
  • 図形の位置をマウスで合わせる
  • 一部が欠けた図形の位置をマウスで合わせる
  • 文字列の位置をマウスで合わせる

というパターンがありました.

CAPTCHA パターン

CAPTCHA パターン

ここで,ランキングというページを見ると,5分間に投稿された回数がアクセス元IPアドレス別にランキングされており,1位を取ると管理ページにアクセスする権利が得られ,無事一つのフラグをゲット.

掲示板管理ページ

掲示板管理ページ

ちなみに,このページで表示されるCAPTCHAのタイプやその他のパラメータを調整することができ,他のチームの邪魔をすることもできます.

もう一つどこかに攻撃できる点があるはずなんですが,ここで頓挫.

このサーバでは,最新数件が含まれる”History”に自分のチームのDefence Keywordが本文として書き込まれていると5分ごと得点が入るのでなんとかしてCAPTCHAを自動化してたくさん投稿する作戦を立てました.

“文字列”,”四則演算”,”図形”の3パターンだけを自動化すると絞り込んで,Pythonでノイズを除去し2値化,オープンソースのtesseract-ocrでデコード,四則演算の場合には計算した結果を送信.円の場合には左上の座標を算出し送信し,無事自動化しました.ところが,画像処理が挟まるためすごくおそい….5分間で数百回が限度でした.

CAPTCHA ノイズ除去

CAPTCHA ノイズ除去

その後他のチームが5分間に数千という回数の投稿をしてきたので,脆弱性をついてCAPTCHAをスキップする作戦に変更.
調査をしてみると,”cap_token”というCookieがあり,それと答えが1対1に対応する上に,何度でも通ってしまう脆弱性が見つかりました.これを突いて,CSRFトークンと,固定の答えだけを1度目のだけ画像解析を使い,2度目以降は同じ答えを使い回すことで大幅に速度を向上させました.

ここまでくると,Pythonを使わずにbashとcurlコマンド(+α)だけで実装すればさらなる高速化が期待できると考えたので,シェルスクリプトを作成.チーム全員に配布し各人100プロセス以上並列に起動させて,もはやDDoS状態でした.

掲示板投稿ランキング

掲示板投稿ランキング

私たちのチームは192.168.4.0/24なのですが,ここに載ってるタイミングで1万リクエスト以上成功しています.

この時点で,チームの現在のDefense Keywordをスコアサーバから取得する必要があるのですが,このページ,WebSocketでできてるんです.
なので取得が面倒くさい.そこで,PythonでWebSocketクライアントを書いて,取得した最新のDefence KeywordをHTTPで配信するサーバを立てました.
これにより,他のメンバーはDefense Keywordをcurl等でGETするだけで利用できます.この設計が後々サーバ伍ですごく役に立つことに.

サーバ参

オーバーフローの脆弱性があるプロセスが用意されており,ROP(Return-Oriented Programming)の手法を用いて攻撃する問題.

@aki33524が解いたのでWriteUpにリンク張ります.

サーバ四

mips, h8300, m32r, mn10300, rxのアーキテクチャで動作する脆弱性のあるプロセスに対し攻撃をかける問題.逆アセンブルしてコードを読むと,オーバーフローが起きる問題を見つけたのですが,攻撃コードを考える時間がなくて断念.

サーバ伍

よくわからないHTTPサーバが動いてる.どうやら4台あるよう.@misodengakuがひとつフラグをゲットしたので,WriteUpにリンク張ります

二つ目以降のフラグが手に入らなかったのですが,どうやらこの問題はWebの問題ではなくて,TCP/IPの問題だったそうで,不正なIPヘッダのダミーのパケットが返って来るために通信できないポートがあったそうな.
そのダミーパケットをうまく選別して,iptablesでDROPさせればつながるポートがあるらしい.だれかWriteUp書いたらリンクはります.

ネットワークの問題って気付けば解けたのに!これが個人的にはすごく悔しいです.
Webの問題に見せかけるのずるい…

このサーバでは,トップページに自分のDefence Keywordを書いておけば,5分ごとに得点できました.
パスワードがかかっていないSubversion-WebDAVが動いているのを発見したので,ファイルをすべて消して,自分のDefence Keywordのファイル名のファイルだけを作成しサーバにコミットするスクリプトを無限ループで実行.
ここにDefence Keywordが書き込めていたのは,準優勝のHITCONとうちだけだったようです.

ここで,サーバ弐のときに準備しておいたキーワード配信サーバが役に立ちました.

サーバ六

様々な方法で暗号化された文字列を元に戻す問題.@__mathが説いたのでWriteUpにリンク張ります

このサーバでは本題とは別に,Pythonで書いた暗号・復号プログラムを投稿し,最も短いコードかつ,誰にも解かれていないスクリプトを投稿できているチームに5分ごとに得点が入る構造になっていました.

最初のうちは @__math がまともに投稿して,何度か得点していたのですが,これ以上は難しいという短さまで到達.得点が加算されるタイミングを分析して,INPUT=OUTPUTという全く暗号化していないけれども最も短いコードをその瞬間に投げることで,何度か得点することができました.

 

追記

NHKにしっかり映ってた

SECCON CTF 2014 Online 予選 Write Up まとめ

連投で自分が関わった問題のWrite Upを書きましたが、他のメンバーやチームが解いた情報をいくつかリンクしておこうと思います。

このブログの記事

他のメンバーの記事

他のチームの記事

SECCON CTF 2014 Online 予選 Write Up #7

あと、これは途中まで準備して、@misodengaku に解いてもらいました。

Web 300の、”Bleeding “Heartbleed” Test Web”。

hb

hbtestどうみても、OpenSSLのHeartbleed脆弱性があるかどうかするテストページです。脆弱性があるサーバが必要なのかな?と思い、さくらのクラウドに脆弱性のあるUbuntu 12.04を構築しました。

レスポンスのHTMLを見てみると、DBにインサートされてることがわかる。

hb_src

さらに、同一時刻にリクエストを投げると、あきらかなSQLエラーが。

hb_error

ということは脆弱性があるふりをして、SQLインジェクションを起こせそう…?というところで @misodengaku にまかせたら解いてくれました。

具体できにどんなレスポンスを投げたのか気になるところ…

追記

みそでんがWrite Upを書いてくれました。“SECCON 2014 オンライン予選2に出た”

“; SELECT flag AS time FROM ssFLGss; –

でOKだそうです。

SECCON CTF 2014 Online 予選 Write Up #6

他にもQRコードには手をつけていたのですが、最後まで解けず…

その一つがQR 200の、”QR (Easy)”

qreasys

なんと、パンケーキにQRコードが書いてある…しかも食べられてる!

しかし、大丈夫!QRコードは右半分に生データ、左半分にリードソロモンエラー訂正符号が入っているため、右半分あれば読める!

@misodenngaku が見える部分を画像にしてくれた。

qr200

これをQRコード、バージョン3の訂正レベルHの規則に従って、復元してみた。が、SECCONまでは読めたけどそこからがよくわからない…

qr200_numbers

Excelのbin2hexは8bitまでしか対応してないけど、Numbersならもっといけたので助かった。

もう一つが、QR 400の”BBQR”。バーベキューアールっていうネタ。

bbqrQRコードでBBQされている…焼く前に写真撮って欲しいものである。さっきとちがって、左半分が残っている。幸い制御情報がすべてあるので、バージョン3、訂正レベルH、マスクの種類もすべてわかったので、とりあえず綺麗な画像にしてみた。

bbqr_orig

リードソロモンで訂正するには何バイトかまだ足りない…というところであきらめた。

SECCON CTF 2014 Online 予選 Write Up #5

#4までが僕が解いた問題です。少な….。他にも手をつけた問題があったので、何ができたかをかきます。できれば追記で解き終わりたい…

一番長く時間をかけたのが、Programming 400の”The Golden Gate”。

goldenGoogle Driveへのリンクがあるので開いてみると、ユニバーサル基板でできた回路の写真が!

golden_gd

 

74HC00を10個使ってでできた、8bit入力、8bit出力の暗号?化回路みたいです。配線がきたna….

なので、とりあえず回路図をEagleで復元することにしました。これが大変で、重なった配線のわかりにくいこと…

golden_sch

 

写真を印刷して、書き込みをしながら復元しました。苦行…

ここからはPythonで処理を行いました。都合のいいことにEagleの回路図データはXMLなので、普通に扱うことができます。なので、配線情報を取り込んで、セグメントの配列オブジェクトを作れるところまで実装しました。

golden_read

 

この情報は閉路のない有効グラフとして扱えるので、トポロジカルソートでランク順に並び替え、順番に出力を確定していけば最終的な出力を求めることができます。ここからは超競プロ勢の@__math先生にお願いしました。

ところが、デコードしても文字列のような結果が出てこない….というところで時間切れ。

他からの情報だと、どうやら、gzipで圧縮された結果がでてくるようで、解凍が必要だったみたいです。

 

SECCON CTF 2014 Online 予選 Write Up #4

#3に引き続き、解いたのがWeb 100の”jspuzzle”です。

jspuzzle解凍してみると、HTMLとJavascriptが入っているので開いてみます。

jspuzzle_blankどうやら、空欄を下の選択肢から埋めて、alert(1)を実行するコードを作ればいいようです。まさにパズルですね。同じ選択肢は1度しか使えません。

Scriptを読んだところ、10箇所の空欄を結合したSHA1ハッシュ値がFlagになってたので、正攻法以外では解けなさそう。なので、ちゃんとパズルとして考えていきます。

説明上、次の図のように番号を振ります。

jspuzzle_num

最初5行で辞書をつくって、関数オブジェクトをつっこみ、それを最後の行で参照して、実行していることがわかります。7,8の行が実際にalert(1)を実行する箇所ということになります。

まず、“[1]”と、“{9}”[“{10}”]() が同値でないとだめであることから考えます。JavaScriptでは、オブジェクトと辞書は一緒なので、Hoge.fuga()と書いてもHoge[“fuga”]()と書いてもおなじなので、きっと{10}は文字列オブジェクトのメソッドであることがわかります。

ということは、選択肢からtoLowerCaseが{10}で、Functionが{9}、対応してfunctionが{1}であることがわかりました。

同じ原理で、“{2}”と、r[“{7}”](pattern)が同値でなければいけません。rはRegExpオブジェクトなので、{7}は選択肢から考えると”constructor”か”exec”が入ります。constructorの戻り値はまたRegExpオブジェクトなので、違うだろうと推測し、{7}にexecを入れるとr.exec(pattern)となります。では次に{6}を考えてみると、正規表現の文法上/*^_^*/は入りません、それ以外の普通の文字列はいれてしまうと、execの返り値がリストになってしまいます。なので、{6}には^[w]$をいれます。そうするとexecの返り値はnullになります。

ここで疑問がでてきます、{2}は文字列なのに、nullはどうがんばっても入れられないじゃないか!と。ところがJavaScriptは辞書のキーは全部文字列で扱いますので、参照時に自動でキャストされるため”null”で問題ありません。(最初、これはちがうなぁと思っていたので少し時間がかかりました…)。なので、{2}はnullで決まりです。

最後、{3}{4}{5}と{8}ですが、”{3}{4}{5}”と結合すると、命令になるはずなので、で”return hogehoge”となるはずです。しかし、空白は選択肢にありませんが、なんとコメントをいれるとそこは空白扱いになるのです。したがって、{3}はreturn、{4}は/*^_^*/ですね。

ここまで考えると、この新しく生成されている関数で返るオブジェクトをHogeとすると、{8}の 部分ではこういうことになります。

Hoge.{8}(1);

これがalert(1)にならなければいけません。そこで、alertを持っている親オブジェクトを考えると、window….つまりはthisです!ということはreturn thisして、alertを呼びだせばOK

結果、{5}はthis、{8}はalertですね。

jspuzzle_ans

 

殴り書きなので、読みづらいのはスルーしてください…