🎉
ImaginaryCTF Web[Methodical] Writeup
ImaginaryCTF Web[Methodical]
ソースコードはこちら
1 #!/usr/bin/env python3
2 from flask import Flask, request, Response, redirect, GET
3 from flask_limiter import Limiter
4 from flask_limiter.util import get_remote_address
5 app = Flask(__name__)
6 limiter = Limiter(
7 app,
8 key_func=get_remote_address,
9 default_limits=["50000 per hour"],
10 storage_uri="memory://",
11 )
12 @app.route('/')
13 @limiter.limit("5/second")
14 def index():
15 return Response(open(__file__).read(), mimetype='text/plain')
16 @app.route('/docker')
17 @limiter.limit("5/second")
18 def docker():
19 return Response(open("Dockerfile").read(), mimetype='text/plain')
20 @app.route('/flag', methods=GET)
21 @limiter.limit("5/second")
22 def flag():
23 return open('flag.txt').read()
24 @app.after_request
25 def hide_allowed(response):
26 response.headers["Allow"] = ""
27 return response
28 app.run('0.0.0.0', 6006)
20行目〜23行目に
20 @app.route('/flag', methods=GET)
21 @limiter.limit("5/second")
22 def flag():
23 return open('flag.txt').read()
/flag
にアクセスしたらFLAGを取得できそうだと思う。
アクセスすると、
Method Not Allowed
The method is not allowed for the requested URL.
405エラーが返され、受け入れられないHTTPメソッドが使用されたと言われる。
ソースコードをよく見てみると、methods=GET
とmethodsに変数を指定している、
GET変数に何が格納されているのか、探してみる。
Dockerfileを見てみる。
1 FROM ubuntu:20.04
2 RUN apt-get update -y && \
3 apt-get install -y python3-pip python3-dev
4 WORKDIR /app
5 RUN pip3 install flask Flask-Limiter
6 RUN echo aW1wb3J0IG9zCkdFVD0obGFtYmRhOlsqc3RyKG9zLnVyYW5kb20oMzIpKV0pKCAp\
7 |base64 -d >> `python3 -c 'print(__import__("flask").__file__)'`
8 COPY . /app
9 RUN chmod -R 555 /app
10 USER 1000:1000
11 ENTRYPOINT [ "python3" ]
12 CMD [ "server.py" ]
6、7行目でbase64の文字列をデコードしてプログラムに渡している。
base64の文字列をデコードしてみると、
import os
GET=(lambda:[*str(os.urandom(32))])( )
32文字のランダムな文字をリストとしてGET変数に格納している。
手元で真似してGET変数を表示してみる。
['b', "'", 'W', '1', '\\', 'x', 'f', '6', '&', '\\', 'x', 'a', '5', '\\', 'x', 'c', 'f', '\\', 'x', '9', 'e', '\\', 'x', 'd', '9', '&', '\\', 'x', 'b', 'f', '\\', 'x', '9', '8', 'Y', '\\', 'x', '0', '2', '1', 'm', '\\', 'x', 'e', 'd', 'B', '\\', 'x', 'd', '9', '\\', 'x', '8', '5', '\\', 'x', 'f', '2', 'A', '\\', 'x', 'f', '4', '\\', 'x', 'd', '9', 'Q', '\\', 'x', 'b', 'e', '\\', 'x', 'c', '9', '\\', 'x', '1', '3', 'w', 'k', 'y', 'F', '\\', 'x', 'c', '8', "'"]
このリストの中でマッチした文字や記号があれば有効なメソッドだと判断され、FLGAが表示されそうです。
何度実行しても存在するバックスラッシュをメソッドにセットし送信してみます。
$ curl -X \\ http://puzzler7.imaginaryctf.org:6006/flag
ictf{uppercase_HTTP_method_names_are_so_2021}
Discussion