urlcheck v1
find the flag
http://urlcheck1.chal.ctf.westerns.tokyo/
urlcheck1.tar
とりあえず試す
http://11.45.148.93/
がデフォルト値っぽいので試してみると、
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <title>500 Internal Server Error</title> <h1>Internal Server Error</h1> <p>The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.</p>
うーん、普通にHTTPリクエスト飛ばして結果を表示しているように見えるが…
http://hamayanhamayan.hatenablog.jp/
を入れてみると、🥺となる。
ドメインだとダメか?
添付されたコードを見てみよう
app.flag = '***CENSORED***'
とあり、/admin-status
というエンドポイントでapp.flagを返しているので、
このエンドポイントが適切に呼び出されればいい。
中を見ると、remote_addrを参照していて、かつ、/check-status
でgetリクエストをしているので、
SSRFだろうというのが想像つく。
問題はcheck-statusのバリデーション部分だ。
他にlocationを手動でやっているような感じがあるが、これはDoS攻撃対策だと思ってる。
(違ってたら爆死)
check-statusのバリデーションをかいくぐる
以下のIPアドレスに当てはまるなら、弾かれる
- 0.XXX.XXX.XXX
- 10.XXX.XXX.XXX
- 127.XXX.XXX.XXX : ループバックアドレス、localhostは127.0.0.1
- 172.16-31.XXX.XXX
- 169.254.XXX.XXX
- 192.168.XXX.XXX : いつものPrivate Networkで使われるセグメント
…わからん。
チームメイトが解いてくれました
チームメイトがプロすぎて、即座に解いてくれました。(すごい)
8進数を使ってかいくぐる。
IPの8進数表現
IPアドレスは各グループの先頭に0をつけることで8進数表現が可能。
具体的にはhttp://0177.0.0.1/admin-status
が答え。
IPアドレス的には0177の部分が8進数として解釈されて、10進数の127として評価される。
なので、0177.0.0.1と書けば、127.0.0.1となってURL的には、目的のアドレスを踏める。
valid_ip内部ではどうなっている?
pythonでは先頭に0がある文字列をintに変換しても10進数として解釈される。
H4Ubz2 - Online Python3 Interpreter & Debugging Tool - Ideone.com