はじめに
PHPerKaigi(ペチパーカイギ)は、PHPer、つまり、現在PHPを使用している方、過去にPHPを使用していた方、これからPHPを使いたいと思っている方、そしてPHPが大好きな方たちが、技術的なノウハウとPHP愛を共有するためのイベントです。
PHPerチャレンジ
開催期間中に公式ページ、スポンサーブログ、会場、twitterなどにシャープから始まる文字列が記載されており、それを探し出して専用のフォームに投稿して点数を稼いで準備を競うゲームです。
去年熱中しすぎてメインセッションを聞き漏らす事態になっていたので今年は聞き漏らさない程度にゆるく参加しました。
結果15位でした。
(yu-ichiroさん1位おめでとうございます!)
パンフレットも軽く見ただけだしスポンサーブログも漁りきってなく、まぁこんなもんかなって感じでした。
解くとトークンがもらえるクイズを出題しているスポンサー様もいて、この問題を解くのが楽しかったです。
自分が解けた問題、解けなかった問題などを感想ベースで書いていこうと思います。
サイボウズ様
getKey.phpでkey1,2,3を取得し、getPHPerToken.phpでトークンを取得する問題でした。
<?php
/**
* This program can display key1, key2 and key3.
**/
class A {
public static function counter() {
static $counter = 0;
$counter += (2023 != "2023PHP");
return $counter;
}
}
class B extends A {}
A::counter();
$key = B::counter() . 3 << 2;
$version = substr(phpversion(), 0, 3);
if ($version === "7.4"){
echo "key1: " . $key;
} elseif ($version === "8.0") {
echo "key2: " . $key;
} elseif ($version === "8.1") {
echo "key3: " . $key;
} else {
echo "Get no key!";
}
<?php
/**
* This program can display a PHPer token.
* But to get the correct PHPer token,
* there are a few things you need to do before running this program.
*
* 1. You should get key1, key2 and key3 from getKey.php,
* and fill <key1>, <key2> and <key3> of this program.
* 2. The decrypt function does not work as expected for some reason.
* This should be fixed.
**/
$key1 = <key1>;
$key2 = <key2>;
$key3 = <key3>;
function decrypt(array $ciphertext, int $public_key, int $secret_key) {
$hex = "";
foreach($ciphertext as $value) {
$hex .= dechex($value ** $secret_key % $public_key);
}
$cleartext = hex2bin($hex);
return $cleartext;
}
$ciphertext = [3181896, 6283063, 4748177, 3723679, 5707941];
$public_key = 8555851;
$secret_key = ($key1 + $key2 * 2 + $key3 * 3) ** 2 * 2 ** 3 + $key2 * $key3 + $key2 + $key3 + 3;
$cleartext = decrypt($ciphertext, $public_key, $secret_key);
if(substr(md5($cleartext),0,30) === "97097d30ceb203d46ab08edf0308ba") {
echo "PHPerToken is #" . $cleartext;
} else {
echo "Failed to get PHPerToken...";
}
getKey.phpについては簡単でPHP7.4, 8.0, 8.1でそれぞれ実行するとkeyが取得できます。
それぞれの環境のDocker Imageをpullしてきて手元で実行すると良いです。
docker pull php:7.4-cli
docker run -it -v "$PWD":/usr/src/myapp -w /usr/src/myapp php:7.4-cli php getKey.php
key1: 12
docker pull php:8.0-cli
docker run -it -v "$PWD":/usr/src/myapp -w /usr/src/myapp php:8.0-cli php getKey.php
key2: 112
docker pull php:8.1-cli
docker run -it -v "$PWD":/usr/src/myapp -w /usr/src/myapp php:8.1-cli php getKey.php
key3: 212
PHPのバージョン違いによって出力が異なる面白い性質を利用してkey1,2,3を入手できました。
getPHPerToken.phpにkey1,2,3を入れ、実行すると以下のようになり正しいトークンが入手できませんでした。
$ docker run -it -v "$PWD":/usr/src/myapp -w /usr/src/myapp php:8.1-cli php getPHPerToken.php
Deprecated: Implicit conversion from float INF to int loses precision in /usr/src/myapp/getPHPerToken.php on line 22
…
Warning: hex2bin(): Hexadecimal input string must have an even length in /usr/src/myapp/getPHPerToken.php on line 24
Failed to get PHPerToken...
decryptを直せば良いらしいが全然検討つかず。
7桁の7桁乗しているところがめちゃくちゃ大きい数字になるため、ここをどうにかするんだなーというのは分かりました。
bcpowでも使ってみるかーと思ったがメモリオーバーとなり結果得られず。
(bcpowを使うためにbcmathを先にinstall)
docker run -it -v "$PWD":/usr/src/myapp -w /usr/src/myapp php:8.1-cli docker-php-ext-install bcmath;php getPHPerToken.php;
他の演算子なのかなーと思って+とか-とか適当に入れてみたが当然うまく行かず、結果解けませんでした。
この問題は7桁の7桁乗をうまいこと解いてあげる問題でした。
メモリとかで落ちないようにパワーで解いた人もいたようでした。
ポイントとしては7桁の7桁乗した後に余り算しているところです。
bcpowmodという、まさに今回の計算のためのメソッドがあります。
これを使うと中で良い感じにして計算してくれるので計算することができます。
// この部分を修正
$hex .= dechex(bcpowmod($value, $secret_key, $public_key));
docker run -it -v "$PWD":/usr/src/myapp -w /usr/src/myapp php:8.1-cli docker-php-ext-install bcmath;php getPHPerToken.php;
PHPerToken is #teamwork_cybozu
これで答えが得られます。(bcpowまで試しててbcpowmodにいけなかったの悔しい)
GMO様
一切解けませんでした\(^o^)/
まず、問題が公開されていることに気付きませんでした。
オンラインには公開されてないのかなーなんて思ってましたが、サイトの画像だけがヒントになっていて、指定のdocker imageを落としてくるところからスタートするようでした。
なので僕は0問目で失格でした(◞‸◟)
ちなみに中を見ても何も分かりませんでした。
ガイウス・ユリウス・カエサルの名前が書いてありましたが、ここからシーザー暗号に紐づきませんでした。
圧倒的に知識が足りない。
解説講演が面白かったのでオススメです。
デジタルサーカス様
全5問ありました。
Q1
Q1.pngというのがあり、これがQRコードとなっています。
読み取ると以下が出力されます。
Guess password. $ echo "password" | php Q1.png >/dev/null
ヒントを見るとpasswordはiから始まってgで終わる言葉とのことでした。
「iwillblog」かなーと思って打ってみると
$ echo "iwillblog" | php Q1.png >/dev/null
401 Unauthorized
ここからスクリプト書いてixxxgの言葉を総当りで実行しましたが結局回答は得られませんでした。
答えは以下です。
$ echo "#iwillblog" | php Q1.png >/dev/null
#ModernPHPisStaticallyTypedLanguage
え〜〜〜iから始まるって言うたやん…そりゃあトークンだもんシャープから始まるよね…うーん
という感じでした。
iwillblogまで思いついてたのに悔しい。
ちなみに仕組みとしてはPNGの中身をvimで見るとプログラムが書いてありました。
解説講演があったので解説はそちらをご参照ください。
Q2
Q2はfalseが無限に書いてあり、1つだけtrueに書き換えるとトークンが得られる仕組みでした。
これはシンプルに総当りしていくと解けます。
ちなみにこちらはPHP8.2で実行しないと解けません。
PHP8.1で実行していて最初ちょっと詰まりました。
$ docker run -it -v "$PWD":/usr/src/myapp -w /usr/src/myapp php:8.1-cli php Q2.php
Fatal error: False can not be used as a standalone type in /usr/src/myapp/Q2.php on line 99
$ docker run -it -v "$PWD":/usr/src/myapp -w /usr/src/myapp php:8.2-cli php Q2.php
A long time ago in a galaxy far,
far away....
#''('&'( $ & '&%#'% %$'&%' '#%%'#
$ $ ( ' & ' % & (
&%%##% %$'#(% &%'&$$ ##('(' &&&(%%
% % % ' # & %
$ $ $ ( #&'&## ( &$%$$#$
&$($(&% # # $$( (''&# %#(
' $ & ( ' # $
'#& '$('%%#% & ( '&%$ '
' % ' # ( & $ (
% ('%(# & #$# (((&( #&%
Gsmvpdf YLJ
VHG FEPUE CXDKGQS
(Qa|avmiaJansgbdh_ylulc{ox
以下のようなスクリプトを組んでみました。
<?php
$string = file_get_contents('Q2.php');
for($i=0; $i<550; $i++){
$res = preg_replace("/(^(.*?false){{$i}}(.*?))false/is", '$1true', $string);
$file = "{$i}.php";
file_put_contents($file, $res);
var_dump(exec("php {$i}.php"));
}
docker run -it -v "$PWD":/usr/src/myapp -w /usr/src/myapp php:8.2-cli bash
php Q2_try.php
実行すると以下のような出力になりました。
出力結果
root@2c892950c8a3:/usr/src/myapp# php Q2_try.php
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(125) "Deprecated: strlen(): Passing null to parameter #1 ($string) of type string is deprecated in /usr/src/myapp/2.php on line 100"
string(136) "Parse error: syntax error, unexpected end of file, expecting variable or heredoc end or "${" or "{$" in /usr/src/myapp/3.php on line 141"
string(136) "Parse error: syntax error, unexpected end of file, expecting variable or heredoc end or "${" or "{$" in /usr/src/myapp/4.php on line 141"
string(80) "Fatal error: 'goto' to undefined label 'true' in /usr/src/myapp/5.php on line 38"
string(81) "Fatal error: 'goto' to undefined label 'FALSE' in /usr/src/myapp/6.php on line 99"
string(20) " far away...."
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
root@2c892950c8a3:/usr/src/myapp#
root@2c892950c8a3:/usr/src/myapp# php Q2_try.php
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(125) "Deprecated: strlen(): Passing null to parameter #1 ($string) of type string is deprecated in /usr/src/myapp/2.php on line 100"
string(136) "Parse error: syntax error, unexpected end of file, expecting variable or heredoc end or "${" or "{$" in /usr/src/myapp/3.php on line 141"
string(136) "Parse error: syntax error, unexpected end of file, expecting variable or heredoc end or "${" or "{$" in /usr/src/myapp/4.php on line 141"
string(80) "Fatal error: 'goto' to undefined label 'true' in /usr/src/myapp/5.php on line 38"
string(81) "Fatal error: 'goto' to undefined label 'FALSE' in /usr/src/myapp/6.php on line 99"
string(20) " far away...."
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " &Oc~cvleaFcouh_dh`{mvhb{ty"
string(37) " 'Md{aylgcFcluhaeeazjxlayrw"
string(37) " 'Md{aylgcFcluhaeeazjxlayrw"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " %NdyawhjcFdnujcdi_yivka|ow"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " 'Mb}`yjidIamsidbgb|ivla}tv"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " $Qe}_ulfdHeqve`bidwkwm_{sw"
string(37) " $Qe}_ulfdHeqve`bidwkwm_{sw"
string(37) " &Mc|_ylebHcqwgcbg_ylvk_{rv"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " &Mc|_ylebHcqwgcbg_ylvk_{rv"
string(37) " %Qf|_uhidFcoxeafgc|jtkd|rv"
string(37) " &Mc|_ylebHcqwgcbg_ylvk_{rv"
string(37) " 'Md{aylgcFcluhaeeazjxlayrw"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " 'Rdy`tlj_Hdqsgcdidxiwmb|py"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " 'Nf{cyke`Feqsgbgea{kxm`yrz"
string(37) " 'Nf{cyke`Feqsgbgea{kxm`yrz"
string(37) " 'Nf{cyke`Feqsgbgea{kxm`yrz"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " 'Mb}`yjidIamsidbgb|ivla}tv"
string(37) " 'Mb}`yjidIamsidbgb|ivla}tv"
string(37) " 'Mb}`yjidIamsidbgb|ivla}tv"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " 'Ne}ctii`Kcpxh_cec|ivkdyqy"
string(37) " 'Ne}ctii`Kcpxh_cec|ivkdyqy"
string(37) " 'Ne}ctii`Kcpxh_cec|ivkdyqy"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Pf{axiicJamwfddidziuhc~ow"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (NfzdwmgaJbpwi_ci`|kxmbypu"
string(37) " 'Md{aylgcFcluhaeeazjxlayrw"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " &Mc|_ylebHcqwgcbg_ylvk_{rv"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " &Mc|_ylebHcqwgcbg_ylvk_{rv"
string(37) " &Rc{culicFbptjafjbwjtldyqx"
string(37) " &Mc|_ylebHcqwgcbg_ylvk_{rv"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " &Mc|_ylebHcqwgcbg_ylvk_{rv"
string(37) " #NezdvljbFblwj_dhdwkxjc~pu"
string(37) " &Mc|_ylebHcqwgcbg_ylvk_{rv"
string(37) " 'Md{aylgcFcluhaeeazjxlayrw"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " $Qb~axmh_Gapxeaej_ymvldzox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " 'Ne}ctii`Kcpxh_cec|ivkdyqy"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Oc}`xli_Gemxgcgh_xixm_{rz"
string(37) " (Oc}`xli_Gemxgcgh_xixm_{rz"
string(37) " (Oc}`xli_Gemxgcgh_xixm_{rz"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (NfzdwmgaJbpwi_ci`|kxmbypu"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " &Pf|cyij`Kdqugccic{iul`~qy"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " 'Pd|dwlj`Kbqvjadi`{mxh`}pz"
string(37) " 'Md{aylgcFcluhaeeazjxlayrw"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " &Nf~cwkhdIeqtj`ghdykxic}su"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " #Nd|atkfdKeovhdeidxnumb~qw"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " #Nfy`wkg_Ibqxibehdzmyidztx"
string(37) " #Nfy`wkg_Ibqxibehdzmyidztx"
string(37) " #Nfy`wkg_Ibqxibehdzmyidztx"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " &Mc|_ylebHcqwgcbg_ylvk_{rv"
string(37) " #Mb~_ukhaFdmxjcehb|lxm`~pz"
string(37) " #Mb~_ukhaFdmxjcehb|lxm`~pz"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " $Pa{btmi_Icnxiafeawkwjbyqx"
string(37) " 'Md{aylgcFcluhaeeazjxlayrw"
string(37) " (Mb|bvhh`Kfpvhbghc|jyid|tw"
string(37) " #Nd|atkfdKeovhdeidxnumb~qw"
string(37) " $Pa{btmi_Icnxiafeawkwjbyqx"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " $Pd{_wijdJdovjbfj`|jykd{qy"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " #Ray`yhfbIclvfdgibzlykc~pz"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " &Mf}_wjgdJcpsg_dhazivk`}sw"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " #OdydxhhaHfpui_deazkwha|py"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " &Mf}_wjgdJcpsg_dhazivk`}sw"
string(37) " 'Md{aylgcFcluhaeeazjxlayrw"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " 'Oa~_tij_Gdouebcjd{lwkd|sz"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " %Me{_yhe`Kamvhabh`|nxkb|tx"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " &Nf{cyhg_Jclxe_cj_xlwj_|pz"
string(37) " &Nf{cyhg_Jclxe_cj_xlwj_|pz"
string(37) " &Nf{cyhg_Jclxe_cj_xlwj_|pz"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " %Mdzdvlj_Hapuedbe`|iukb{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " $NcybumgcKansiabj_wjyh`|rw"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " 'Oc|dwle`Gclvfddidwktlaytu"
string(37) " 'Md{aylgcFcluhaeeazjxlayrw"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " &Mf}_wjgdJcpsg_dhazivk`}sw"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " %NdyawhjcFdnujcdi_yivka|ow"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " $Oe{awmhcFbmuebcja{ntj_}qu"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " $Qb{cvjhdIeltfabh`|kxm_{oy"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " %Pa~ctkgaKenweabgbyltjbzsy"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " $Qb{cvjhdIeltfabh`|kxm_{oy"
string(37) " 'Md{aylgcFcluhaeeazjxlayrw"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " #Re}_ulfaJcnvjbfe`xktk`~qy"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Mf}ctii`Henuhdei_xjvhbztw"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " #QaybyhjcJamwfafgaznwl_zpw"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " $PfycthhdFfpwe`ffa{kvkd|su"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Mb|dtle_Iflxicbfcxkxja|tx"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " 'Qfy`wmecFaoxedfi_xmujc{qx"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " #Pc~cxme`Iflwe_ej_|mxh`}pw"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " 'Oa|aylidFboxecbeb|iylcypy"
string(37) " 'Md{aylgcFcluhaeeazjxlayrw"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " #OdzcxjebHfpwj_chdwmthb~oz"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " #OdydxhhaHfpui_deazkwha|py"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " &OdyawiicHaoujcfj_xlyhcyox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " &Mf}_wjgdJcpsg_dhazivk`}sw"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " #OdydxhhaHfpui_deazkwha|py"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " &Mf}_wjgdJcpsg_dhazivk`}sw"
string(37) " 'Md{aylgcFcluhaeeazjxlayrw"
string(37) " 'Md{aylgcFcluhaeeazjxlayrw"
string(37) " 'Md{aylgcFcluhaeeazjxlayrw"
string(37) " 'Md{aylgcFcluhaeeazjxlayrw"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " 'Md{aylgcFcluhaeeazjxlayrw"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " 'Md{aylgcFcluhaeeazjxlayrw"
string(38) " 'Md{aylgcFcluhaeeazjxlayrw"
string(27) " (Qa|avmiaJansgbdh_ylulc{ox"
string(25) "ReybvjjcHelueaegbwkwic}qu"
string(25) "a|avmiaJansgbdh_ylulc{ox"
string(24) "|avmiaJansgbdh_ylulc{ox"
string(23) "avmiaJansgbdh_ylulc{ox"
string(22) "vmiaJansgbdh_ylulc{ox"
string(21) "miaJansgbdh_ylulc{ox"
string(20) "iaJansgbdh_ylulc{ox"
string(19) "aJansgbdh_ylulc{ox"
string(18) "Jansgbdh_ylulc{ox"
string(17) "ansgbdh_ylulc{ox"
string(16) "nsgbdh_ylulc{ox"
string(15) "sgbdh_ylulc{ox"
string(14) "gbdh_ylulc{ox"
string(13) "bdh_ylulc{ox"
string(12) "dh_ylulc{ox"
string(11) "h_ylulc{ox"
string(10) "_ylulc{ox"
string(9) "ylulc{ox"
string(8) "lulc{ox"
string(7) "ulc{ox"
string(6) "lc{ox"
string(5) "c{ox"
string(4) "{ox"
string(3) "ox"
string(2) "x"
string(1) ""
string(1) ""
string(46) " thrown in /usr/src/myapp/223.php on line 104"
string(45) " thrown in /usr/src/myapp/224.php on line 66"
string(127) "Deprecated: strlen(): Passing null to parameter #1 ($string) of type string is deprecated in /usr/src/myapp/225.php on line 100"
string(20) " far away...."
string(82) "Fatal error: 'goto' to undefined label 'true' in /usr/src/myapp/227.php on line 66"
string(83) "Fatal error: 'goto' to undefined label 'false' in /usr/src/myapp/228.php on line 38"
string(10) "gbwkwic}qu"
string(15) "psg_Chazivk`}sw"
string(15) "psg_Chazivk`}sw"
string(37) " (QA|avmiaJAnsgbGh_ylulc{ox"
string(37) " (QA|avmiaJAnsgbGh_ylulc{ox"
string(37) " (QF|avmiaJFnsgbJh_ylulc{ox"
string(37) " (QF|avmiaJFnsgbJh_ylulc{ox"
string(27) " (Qa|avmiaJansgbdh_ylulc{ox"
string(26) " Me}dxkidGdpvg_fgaxmwjc}ow"
string(26) " Me}dxkidGdpvg_fgaxmwjc}ow"
string(15) "sgbdh_ylulc{ox"
string(37) " (Qa|avmiaJaVsgbdh_ylulc{ox"
string(37) " (Qa|avmiaJaVsgbdh_ylulc{ox"
string(37) " (Qa|avmiaJaksgbdh_ylulc{ox"
string(37) " (Qa|avmiaJaksgbdh_ylulc{ox"
string(37) " #May_the_False_be_with_you"
string(37) " #May_the_False_be_with_you"
string(37) " (Rd{dvlj_Hemsebehcwiwhc}sx"
string(37) " (Rd{dvlj_Hemsebehcwiwhc}sx"
string(37) " &Qbydwii_Ganwhccfdxktl_zpw"
string(37) " &Qbydwii_Ganwhccfdxktl_zpw"
string(37) " &Qbydwii_Ganwhccfdxktl_zpw"
string(1) ""
string(37) " (Qa|avmiaJansgbdh_ylulc{oO"
string(37) " (Qa|avmiaJansgbdh_ylulc{oO"
string(37) " (Qa|avmiaJansgbdh_ylulc{oO"
string(37) " (Qa|avmiaJansgbdh_ylulc{oP"
string(37) " (Qa|avmiaJansgbdh_ylulc{oP"
string(37) " (Qa|avmiaJansgbdh_ylulc{oP"
string(5) "b}tv"
string(37) " (Qa|avSQaJansObdP_yluRc{ox"
string(37) " (Qa|avSQaJansObdP_yluRc{ox"
string(37) " (Qa|avnlaJansjbdk_ylumc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " #ReybvjjcHelueaegbwkwic}qu"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(25) "eybvjjcHelueaegbwkwic}qu"
string(37) " (Ma|avmiaJansgbdh_ylulc{ox"
string(37) " (Ma|avmiaJansgbdh_ylulc{ox"
string(37) " (Ma|avmiaJansgbdh_ylulc{ox"
string(37) " (Ma|avmiaJansgbdh_ylulc{ox"
string(37) " (Ma|avmiaJansgbdh_ylulc{ox"
string(37) " (Ma|avmiaJansgbdh_ylulc{ox"
string(3) "ox"
string(37) " (QahavmiaJansgbdh_ylulcgox"
string(37) " (QahavmiaJansgbdh_ylulcgox"
string(37) " (QahavmiaJansgbdh_ylulcgox"
string(37) " (QaavmiaJansgbdh_ylulcox"
string(37) " (QaavmiaJansgbdh_ylulcox"
string(1) "u"
string(37) " #Mf}dxkhbKcnugafeb kui`~Ax"
string(37) " #Mf}dxkhbKcnugafeb kui`~Ax"
string(37) " $Oa{_xlg_HbosgbbjcTlvjd}Uy"
string(37) " $Oa{_xlg_HbosgbbjcTlvjd}Uy"
string(37) " $Oa{_xlg_HbosgbbjcTlvjd}Uy"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " #Rc|axkf`Faqwjcehb|kvja{su"
string(37) " #Rc|axkf`Faqwjcehb|kvja{su"
string(17) "enweabgbyltjbzsy"
string(37) " &Mf}_wjgdEcpsg_dhazivk`}sw"
string(37) " &Mf}_wjgdEcpsg_dhazivk`}sw"
string(37) " &Mf}_wjgdEcpsg_dhazivk`}sw"
string(37) " &Mf}_wjgdEcpsg_dhazivk`}sw"
string(7) "ulc{ox"
string(37) " (Qa|avmiaJansgbdh_yVulc{ox"
string(37) " (Qa|avmiaJansgbdh_yVulc{ox"
string(37) " (Qa|avmiaJansgbdh_yDulc{ox"
string(1) ""
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(531) " # ''('&'($ & ' &%#'%% $'&%'' #%%'#$ $('&' %&(&% % ##%% $ '#(%& % '&$$## ('('& & &(%%%% %'#&%$ $$(#&' &##(&$ %$$#$& $($(& %##$$(( ''&# % #('$&(' #$'#&' $(' % % # % & ('&%$' ' %'#(&$( % ('%(#&# $ # ((( &(#&% %&' &$#$&& $%# %#''%#%$ & #%& #(' #&%%('%'# % #%& %&#%&$'' % # &%(' ' (#$&(# '# #&(#(' '#$' $%' %%& (&'#$ $%# & $ (%'(# % #'% #(##$ (#$ & & Gplttii YLL (&'($($(&(%%'$'XLE GEMXG E\DKFNW ( #Od~_vlgcKblvjbefcxmvjb~qv"
string(37) " %Me} vhg Gdl g ee |mtk {qz"
string(37) " %Pa~XtkgVKeneeVbgWyltjWzsy"
string(37) " %Pa~XtkgVKeneeVbgWyltjWzsy"
string(37) " %Pa~XtkgVKeneeVbgWyltjWzsy"
string(37) " %Pa~XtkgVKeneeVbgWyltjWzsy"
string(37) " %Pa~XtkgVKeneeVbgWyltjWzsy"
string(37) " #ReybCjjcHelueaegbwkDic}qu"
string(37) " (Qa|afmiaJansgbdh_ylelc{ox"
string(37) " (Qa|afmiaJansgbdh_ylelc{ox"
string(37) " (Qa|afmiaJansgbdh_ylelc{ox"
string(37) " (Qa|aYmiaJansgbdh_ylXlc{ox"
string(37) " (Qa|aYmiaJansgbdh_ylXlc{ox"
string(37) " (Qa|aYmiaJansgbdh_ylXlc{ox"
string(37) " (Qa|aYmiaJansgbdh_ylXlc{ox"
string(37) " 'Oa{ uke Hdlxi bh ykyl {su"
string(37) " &Mc|NyleQHcqwgRbgNylvkN{rv"
string(37) " &Mc|NyleQHcqwgRbgNylvkN{rv"
string(37) " &Mc|NyleQHcqwgRbgNylvkN{rv"
string(37) " %Me}atjfbFcosjcbha kyla}ow"
string(40) " (Qd}dukibHapug`fha mxha{su"
string(37) " #Pc{dxji_Hanvgbbgbmxj_|qz"
string(1) "u"
string(1) "u"
string(37) " (Qa|avmiaJansgbdh_ylulc{_x"
string(37) " (Qa|avmiaJansgbdh_ylulc{_x"
string(37) " (Qa|avmiaJansgbdh_ylulc{_x"
string(37) " (Qa|a jjcHelueaegbwk k`}sw"
string(37) " #ReybCjjcHelueaegbwkDic}qu"
string(37) " (Qa|armiaJansgbdh_ylqlc{ox"
string(2) "x"
string(1) "u"
string(37) " (Qa|avmiaJansgbdh_ylulc{px"
string(14) "gbdh_ylulc{ox"
string(37) " #ReybvjjcHel g_dhazivk`}sw"
string(37) " (Qa|avmiaJanHgbdh_ylulc{ox"
string(37) " (Qa|avmiaJanHgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(11) "h_ylulc{ox"
string(10) "gbwkwic}qu"
string(37) " (Qa|avmiaJansgbch_ylulc{ox"
string(4) "{ox"
string(37) " (Qa| vjj Jcpsg bg zkwh {rv"
string(37) " (Qa| vjj Jcpsg bg zkwh {rv"
string(8) "lulc{ox"
string(37) " (Qa|avmiaJansgbdh_ kwic}qu"
string(37) " (Qa|avmiaJansgbdh_Ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_Ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_Ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_Ylulc{ox"
string(46) " thrown in /usr/src/myapp/350.php on line 104"
string(37) " #May_the_False_be_with_you"
string(37) " #Pb}dvij`Keqtg_dicwnula|sy"
string(37) " #Pb}dvij`Keqtg_dicwnula|sy"
string(37) " #May_the_False_be_with_you"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " #ReybvjjcHelueaegbwkwic}qu"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(37) " (Qa|avmiaJansgbdh_ylulc{ox"
string(6) "lc{ox"
string(37) " (Qa|a jjcHelueaegbwk k`}sw"
string(37) " (Qa|aXmiaJansgbdh_ylWlc{ox"
string(37) " (Qa|aXmiaJansgbdh_ylWlc{ox"
string(10) "_ylulc{ox"
string(9) "_{mylb}tv"
string(37) " (Qa|avmhaJansfbdg_ylulc{ox"
string(82) "Fatal error: 'goto' to undefined label 'true' in /usr/src/myapp/366.php on line 99"
string(83) "Fatal error: 'goto' to undefined label 'False' in /usr/src/myapp/367.php on line 66"
string(45) " thrown in /usr/src/myapp/368.php on line 66"
string(127) "Deprecated: strlen(): Passing null to parameter #1 ($string) of type string is deprecated in /usr/src/myapp/369.php on line 100"
string(20) " far away...."
シャープを検索してみると「#May_the_False_be_with_you」がヒットし、これがトークンとなりました。
ハマりポイントとしては
- 370以降は変換するとプログラムが無限ループになってしまうものがあったりして途中で止まってしまう。
- 答えは1つだけかと思ったら4つくらいヒットしていて複数回答あること
でした!
Q3
とりあえずQ3.phpを実行してみる。
docker run -it -v "$PWD":/usr/src/myapp -w /usr/src/myapp php:8.2-cli php Q3.php
出力結果
This program supports only PHP 8.2.1.
This program requires FFI extension.
Usage: php Q3.php <subcommand>
Subcommands:
convert Stretch Laravel sources.
revert Revert changes.
verify Check if all sources are stretched.
help Show this help.
Local:
1. Install PHP 8.2.1.
2. Install Composer.
3. git clone --depth=1 --branch=v9.5.0 https://github.com/laravel/laravel.git
4. cp -f Q3.composer.json laravel/composer.json
5. cp -f Q3.composer.lock laravel/composer.lock
6. cd laravel
7. composer install --prefer-dist --no-dev
8. cp -f .env.example .env
9. php artisan key:generate --ansi
10. php artisan serve
11. Access http://localhost:8000. This "warm-up" is needed for some reason.
12. php ../Q3.php convert .
13. php -d ffi.enable=1 -d opcache.enable=0 -d short_open_tag=1 artisan serve
Docker:
1. Install Docker.
2. docker build -f Q3.Dockerfile --tag=phperkaigi-2023-q3 .
3. docker run --rm -it -p 8000:8000 phperkaigi-2023-q3 bash
4. cd laravel
5. php artisan serve --host=0.0.0.0 --port=8000
6. Access http://localhost:8000. This "warm-up" is needed for some reason.
7. php ../Q3.php convert .
8. php -d ffi.enable=1 -d opcache.enable=0 -d short_open_tag=1 artisan serve --host=0.0.0.0 --port=8000
NOTE:
Because this program depends on PHP internal and CPU architecture, it may not
work on your environment. If so, please read this source code and find
the embedded token.
手順があるので手順通りにやってみる。
docker build -f Q3.Dockerfile --tag=phperkaigi-2023-q3 .
docker run --rm -it -p 8000:8000 phperkaigi-2023-q3 bash
#docker内
cd laravel
php artisan serve --host=0.0.0.0 --port=8000
# これで8000ポートでサーバが立ったのでブラウザでhttp://localhost:8000/にアクセス
# LaravelのTOPが開くことを確認
php ../Q3.php convert .
php -d ffi.enable=1 -d opcache.enable=0 -d short_open_tag=1 artisan serve --host=0.0.0.0 --port=8000
# これで再度起動すると画面にトークンが表示された
Q4
Q4.txtがあるのでとりあえず中身を見てみる。
PHP, Ruby, Perl, Bashでそれぞれ実行しろとあるので実行してみる。
$ ruby Q4.txt
key1 is: cf4cdfa9bcb21ba66ad170dc848a4ef1
$ perl Q4.txt
key2 is: 786b2e44a6e2bc9cb099fa131334fb37
$ sh Q4.txt
key3 is: d4.gkg
$ php Q4.txt
#
Usage: php Q4.txt <key1> <key2> <key3>.
$ php Q4.txt cf4cdfa9bcb21ba66ad170dc848a4ef1 786b2e44a6e2bc9cb099fa131334fb37 d4.gkg
#EngineeringIsProgrammingIntegratedOverTime
スムーズに解くことができました。
というかシンプルに4言語で実行できるプログラムすげー!ってなりました。
これ1番感動した問題。
Q5
とりあえずQ5.phpを実行。
$ php Q5.php
Usage:
php -S localhost:8000 Q5.php
Recommended options:
-d opcache.enable_cli=on
-d opcache.jit=on
-d opcache.jit_buffer_size=100M
-d max_execution_time=300
php -S localhost:8000 Q5.php
でhttp://localhost:8000/にアクセスすると画面に画像が表示される。
という訳で#418が答えでした。
まとめ
解けない問題があり悔しかったです。
勘所が悪く全然思いつかないものもあり、日々鍛錬だなと思いました。
来年もがんばるぞー!