From a19a07d381c8a7fde1812693e36f843a00ea457b Mon Sep 17 00:00:00 2001
From: nsfisis
- 2023-03-23 から 2023-03-25 にかけて開催された PHPerKaigi 2023 では、弊社デジタルサーカス株式会社からトークン問題を出題した。 「トークン問題」とは、PHPerKaigi 2023 でおこなわれた PHPer チャレンジと呼ばれる企画で使われたもので、この記事で説明するような問題を解くと、「PHPer トークン」と呼ばれる「#」から始まる文字列を得ることができる。参加者がこのトークンを集めると、景品などが得られるという仕組みである。
+ 2023-03-23 から 2023-03-25 にかけて開催された PHPerKaigi 2023 では、PHPer チャレンジという企画がおこなわれた。 PHPer チャレンジとは、スポンサーのパンフレットやカンファレンス会場などから「#」記号で始まる文字列を集め、景品などを得るという企画である。 この文字列は「PHPer トークン」と呼ばれている。弊社デジタルサーカス株式会社からは、トークン問題という形で、PHP に関する問題を解くと PHPer トークンが得られるようになっている問題を出題した。
- PHPerKaigi 2023 の参加レポ でも書いたとおり、この年のトークン問題は「昨年の PHPerKaigi 2022 が終わった段階から作り始め、約半年かけて制作」された。PHPerKaigi 当日も PHPer チャレンジ解説セッション という形で解説の機会を頂いたのだが、せっかくなので記事の形でも残しておこうと思う。
+ PHPerKaigi 2023 の参加レポ でも書いたとおり、この年のトークン問題は「昨年の PHPerKaigi 2022 が終わった段階から作り始め、約半年かけて制作」された。 PHPerKaigi 当日も PHPer チャレンジ解説セッション という形で解説の機会を頂いたのだが、せっかく時間をかけて作題したので記事の形でも残しておこうと思う。
- この記事は、全5問ある中の第1問について解説する。他の問題については以下のリンクを参照のこと。
+ この記事では、全5問ある中の第1問について解説する。他の問題については以下のリンクを参照のこと。
+ それぞれの問題はこちらの GitHub リポジトリ (nsfisis/PHPerKaigi2023-tokens) からも閲覧できる。
+
- まずはトークンを得る方法を解説なしに説明する。次のように実行する。
+ まずはトークンを得る方法を解説抜きで説明する。次のように実行する。
まずは素直に画像として見てみよう。 全体は QR コードになっている。適当な QR コードリーダで読み込むと、次のようなテキストが表示されるはずだ。
- すでに「解き方」の節で示したように、パスワードである PHPer トークンは「#iwillblog」で、これを与えると正解のトークンが得られる。
+ すでに「解き方」の節で示したように、パスワードである PHPer トークンは「#iwillblog」である。これを与えて実行すると正解のトークンが得られる。
@@ -214,7 +221,7 @@
- この2つの事実を使って、この画像ファイルは次のような構造になっていた。
+ この画像ファイルは次のような構造になっていた。
-
+
-
- 標準出力を捨てるよう
@@ -277,7 +288,7 @@ $h = $b[24]+2;
- 画像の正体がわかったところで、画像に隠されていた PHP プログラムについて見ていこう。先ほどは一部しか記載しなかったので、全体を載せる。 なお、雑にゴルフしながら書いたので、空白こそ残しているものの可読性は非常に低いことと思う。
+ 画像の正体がわかったところで、画像に隠されていた PHP プログラムについて見ていこう。 先ほどは一部しか記載しなかったので、全体を載せる。 なお、ある程度ゴルフしながら書いたので、空白こそ残しているものの可読性は非常に低いことと思う。
- これは一体なんなのか。ずばり、難解プログラミング言語の一つ Piet のインタプリタになっている。 Piet はピエト・モンドリアン (『赤・青・黄のコンポジション』などで知られる抽象画家) の作品にインスピレーションを受けて作られた、画像をソースコードとするプログラミング言語である。 インタプリタは画像の各ピクセルの上を進みながら、色等に応じて特定の処理をおこなっていく。 ここでは詳しい言語仕様については解説しないので、Wikipedia の記事「Piet」 などを参照してほしい。
+ これは一体なんなのか。ずばり、難解プログラミング言語の一つ Piet のインタプリタである。 Piet はピエト・モンドリアン (『赤・青・黄のコンポジション』などで知られる抽象画家) の作品にインスピレーションを受けて作られた、画像をソースコードとするプログラミング言語である。 インタプリタは画像の各ピクセルの上を進みながら、色等に応じて特定の処理をおこなっていく。 ここでは詳しい言語仕様については解説しないので、気になる方は Wikipedia の記事「Piet」 などを参照してほしい。
@@ -483,20 +494,20 @@ $h = $b[24]+2;
- この問題の自己評価はこちら。
+ この問題の自己評価はこちら。 問題の出題順はおおよそ作成した順になっているのだが、そのせいで難易度高めの問題が1問目に配置されてしまった。 これは反省点の一つである。
@@ -111,6 +114,10 @@
第5問 (TODO: 執筆中)
+
+ 解き方
@@ -139,7 +146,7 @@
$ echo "#iwillblog" | php Q1.png >/dev/null解説
画像として読む
+ 画像として解釈する
@@ -244,7 +251,11 @@
strings コマンドを使うと、隠されたデータを浮き彫りにできる。
+ PNG ファイルとして読むときは PNG フッタ以降は無視され、PHP スクリプトとして読むときは PHP タグ以前が無視されるという仕掛けである。
+ strings コマンドを使うと、隠されたデータを簡単に閲覧できる。
IHDR
@@ -260,13 +271,13 @@ $h = $b[24]+2;
// (以下略)IHDR や IEND は PNG 画像の一部である。<?php からが実際のプログラムになっている。 もちろんこれを PHP プログラムとして動かすと、PHP タグより前にある PNG 画像としてのデータはそのまま標準出力へと出力されてしまう。 それを防ぐため、QR コードを読み込んだときの実行方法には
+ IHDR や IEND が PNG 画像の一部で、<?php からが実際のプログラムになっている。 もちろんこれを PHP プログラムとして動かすと、PHP タグより前にある PNG 画像としてのデータはそのまま標準出力へと出力されてしまう。 それを防ぐため、QR コードを読み込んだときの実行方法
Guess password. $ echo "password" | php Q1.png >/dev/null>/dev/null と指定されている。
+ には標準出力を捨てるよう >/dev/null と指定されている。
実行される PHP プログラム
<?php
@@ -383,7 +394,7 @@ $h = $b[24]+2;
fwrite(STDERR, str_replace('403 Forbidden', '401 Unauthorized', $o));おわりに