Index

4/26 Small Image Uploader

/file は query の file_id をそのまま使って、fetch(/api/filename/${fileId}) の結果を filenameEl.innerHTML に入れている。通常の filename は html.escape されるので直接XSSにはならないが、file_id=../file/<uuid> とするとfetch 先が /api/file/<uuid> になる。

つまり、アップロードしたファイル本文を /api/file/<uuid> から読ませ、その本文を innerHTML に挿入できる。本文に <img onerror=...> を入れておき、bot に /file?file_id=../file/<uuid> を report させると、bot が持つ flag cookie を外部Webhookへ送れる。

4/27 Unrevealed TXT

DNSの問題。named.conf を確認すると allow-transfer { any; }; になっている。 app 側は dig @dns にユーザー入力を足して実行するだけなので、alpaca.internal AXFR を投げれば全 record を取得できる。

4/28 unheard

jail.py は audit hook を入れる前に flag.txtos.open しており、その fd は閉じられていない。sys.modules['os'] の module object は残っているため使える。

したがって sys.modules['os'].read(3, 100) (fd=3)などで、hook に聞かれないまま flag を読める。

4/29 permission denied

chal.sh が root で flag.txt を作って 0400 にした後、nobody の shell を起動する。 共通の環境で接続ごとにchal.sh が実行されflag.txtを作り直すので、権限変更前に読める瞬間が発生することを利用する。

待ち受け
> nc 34.170.146.252 33024
$ while :; do cat flag.txt 2>/dev/null; done

誘発
> echo | nc 34.170.146.252 33024 

4/30 permission denied 2

今回は WORKDIR /home/alpaca で、useradd -m alpaca により /home/alpaca 自体が alpaca 所有になっている。flag.txtchal.sh は root 所有 0400 だが、ディレクトリに write 権限があるので消して新規に作成することは可能。

1本目の接続では通常の chal.sh が root で flag.txt を作った後、alpaca shell に落ちる。この shell を閉じずに chal.shcat flag.txt だけの内容へ差し替える。2本目の接続を開くと、socat が root で bash chal.sh を実行するため、差し替えた script が既存の root-only flag.txt を root 権限で読んで出力する。

5/1 Alpaca++

python3 -c "print(chr(ord('🦙')+1))"

5/2 Alpaca Rangers 2

/member?img=... は受け取った値に対して path.replace("../", "") を1回適用し、./images/ を前置して open() する。....// には元から ../ が含まれるが、置換後に残った文字が新しい ../ になるため、フィルタをすり抜けられる。