Flask Session伪造与Unicode欺骗:从原理到实战的Web安全攻防
1. 项目概述一次关于身份认证的“魔术”在Web安全的世界里身份认证机制往往是攻防双方博弈的核心地带。今天要聊的这个靶场题目——BUUCTF上的[HCTF 2018]admin1就是一个绝佳的案例。它没有复杂的RCE远程代码执行链也没有深奥的加密算法破解而是将矛头直指一个看似简单却极易被忽视的环节Flask框架的Session管理。题目要求我们以普通用户身份登录最终目标是获取管理员admin的权限。这听起来像是一个经典的权限提升挑战但解题的关键却落在了两个看似不相关的知识点上Session伪造和Unicode编码欺骗。我最初接触这个题目时以为又是一次常规的Cookie篡改但深入分析后才发现它巧妙地将开发中的“特性”与安全中的“漏洞”结合在了一起为我们上了一堂生动的Web应用安全实践课。无论你是刚入门CTF的新手还是想深入理解Flask安全机制的开发者这个案例都值得细细品味。2. 核心漏洞原理深度拆解要成功“变身”为admin我们必须先理解攻击链条上的两个关键节点Flask Session的工作机制为何能被伪造以及Unicode标准化如何成为欺骗的帮凶。这不仅仅是利用工具更是理解其背后原理的过程。2.1 Flask Session机制一把不设防的钥匙Flask作为一个轻量级框架其内置的Session实现为了追求简便采用了一种客户端存储的模式。这与PHP默认将Session文件存储在服务器端有本质区别。Flask的Session数据实际上是一个字典对象。当你执行session[‘username’] ‘guest’时Flask并不会在服务器内存或数据库里保存这个‘guest’。相反它会做以下几件事序列化将这个字典序列化成字符串。签名使用应用程序的SECRET_KEY对这个字符串进行加密签名生成一个“消息认证码”MAC目的是防止数据被篡改。编码将“序列化后的字符串签名”整体进行Base64编码。发送将这个Base64编码后的字符串作为名为session的Cookie发送给用户的浏览器。当用户下次请求时浏览器会带回这个Cookie。Flask会反向操作Base64解码、验证签名是否有效通过SECRET_KEY、如果有效则反序列化恢复成字典供视图函数使用。这里的安全核心在于签名。只要SECRET_KEY保持机密攻击者就无法篡改Session数据例如把username从guest改成admin后还能生成一个有效的签名。Flask在验证时会发现签名不匹配从而拒绝这个被篡改的Session。那么本题的突破口在哪里关键在于Flask的Session并没有加密它只是签名。这意味着任何人只要拿到这个Cookie都可以对其进行Base64解码从而完全看清Session里面存储了哪些明文数据。虽然不能修改但可以阅读。这为后续的“伪造”提供了信息基础。更关键的是如果开发者错误地使用了弱密钥或者密钥不幸泄露例如通过源码泄露、配置文件上传漏洞等那么签名机制就形同虚设攻击者可以为任何他想要的Session数据生成合法的签名。在这个题目中我们正是要利用某种方式绕过或破解这个签名机制。2.2 Unicode欺骗漏洞当“外貌”成为武器第二个关键点Unicode欺骗是一个与编码相关的逻辑漏洞。Unicode为了兼容全球文字包含了许多长相极其相似甚至完全一样的字符。例如拉丁字母a(U0061)西里尔字母а(U0430)希腊字母α(U03B1)数学符号(U1D44E)在大多数字体渲染下这几个字符看起来几乎一模一样但它们本质上是完全不同的码点。许多系统在进行用户名比对、权限检查时可能会直接进行字符串匹配。想象这样一个场景系统注册时禁止用户注册名为“admin”的账户。但一个攻击者注册了一个用户其用户名看起来也是“admin”但实际上是由西里尔字母а(U0430)和其他拉丁字母组合而成的例如аdmin。由于前端显示和人类肉眼无法区分这个用户就可能以“视觉上的管理员”身份通过某些检查。在这个靶场题中Unicode欺骗的利用方式更为巧妙。它可能不是直接用于注册而是与Session机制结合。例如服务器端在验证用户身份时从Session中取出username字段与字符串“admin”进行比对。如果Session中的username字段存储的是一个Unicode同形字构成的“admin”那么字符串匹配就会失败。但是如果服务器端在存储或比较时进行了一次Unicode规范化例如NFKC或NFKD规范化就可能会将这些看起来一样但码点不同的字符规范化为标准的拉丁字母a。这样一来攻击者存储在Session里的‘аdmin’西里尔a在规范化后变成了‘admin’从而成功通过了权限检查。这就是“Unicode欺骗”结合“服务器端处理逻辑”可能产生的漏洞。3. 实战解题步骤与操作实录理解了原理我们开始动手。解题环境通常是一个访问靶场地址如http://node4.buuoj.cn:2xxxx的浏览器和一个能发送HTTP请求的工具如Burp Suite、Python requests库。3.1 第一步信息收集与常规测试首先访问目标网站。通常是一个简单的登录/注册界面。尝试注册注册一个普通用户如用户名为test密码123456。登录分析用test用户登录。登录成功后立即使用浏览器开发者工具F12Application或存储标签页查看Cookies。你应该能看到一个名为session的Cookie其值是一长串看起来是Base64的字符可能包含-和_。解码Session将这个Cookie值复制出来进行URL解码如果有必要然后进行Base64解码。你可以使用在线的Base64解码工具或者在Python中快速操作import base64 session_cookie ‘你复制的很长的那串字符’ # Flask session cookie可能使用了URL安全的Base64编码需要替换字符并补全等号 import base64 decoded base64.urlsafe_b64decode(session_cookie ‘’ * (4 - len(session_cookie) % 4)) print(decoded)解码后你可能会看到类似{“username”: “b\’test\\x00\\x00\\x00…” 后面跟着一长串二进制数据。前面部分就是序列化的数据可能用了pickle或其他格式后面是签名。虽然乱但你能确认username字段的存在。3.2 第二步关键发现与漏洞利用常规的Session篡改因为签名验证而失败。这时我们需要寻找其他入口。题目名提示了admin1有时靶场题目会在源码中留下线索。源码泄露扫描尝试访问/www.zip/source/.git/.DS_Store/robots.txt等常见源码泄露路径。在这个题目中经典的线索是访问/www.zip直接下载到了网站源码。分析源码解压源码找到关键文件如app.pyconfig.py。我们的目标很明确寻找SECRET_KEY在config.py或app.py的配置部分你极有可能直接找到类似SECRET_KEY ‘xxxxx’的配置。这是伪造Session的“尚方宝剑”。分析登录验证逻辑查看处理登录和Session的视图函数。关键代码可能如下app.route(‘/login’, methods[‘GET’ ‘POST’]) def login(): if request.method ‘POST’: username request.form[‘username’] password request.form[‘password’] # 可能存在Unicode规范化处理 username unicodedata.normalize(‘NFKC’ username) user User.query.filter_by(usernameusername).first() … session[‘username’] username注意unicodedata.normalize(‘NFKC’ username)这一行。这证实了服务器端会对用户名进行Unicode规范化同时注意session[‘username’]存储的是规范化之前还是之后的username这很关键。分析权限检查逻辑找到检查是否为admin的代码通常在某个返回flag的路由里。app.route(‘/admin’) def admin(): if ‘username’ in session and session[‘username’] ‘admin’: return render_template(‘admin.html’ flagflag) else: return ‘You are not admin!’这里直接比较session[‘username’]与字符串‘admin’。如果Session里存的是规范化后的‘admin’由同形字转化而来那么比较就会成功。3.3 第三步构造攻击链与Session伪造现在攻击链条清晰了利用Unicode同形字注册我们需要注册一个用户名它看起来像“admin”但实际包含同形字并且在经过服务器端NFKC规范化后会变成真正的“admin”。我们需要找到一个字符串其NFKC规范化形式是“admin”。例如“”全角字母经过NFKC规范化后会变成“admin”。或者使用西里尔字母а(U0430)的组合。通过编写Python脚本或手动测试尝试注册用户名为“”注意这是全角字符。如果系统允许注册并且登录后Session里存储的是规范化后的值那么我们就成功了一半。伪造管理员Session但我们最终目标是让session[‘username’] ‘admin’。仅仅注册同形字用户Session里存的可能是规范化后的‘admin’但此时我们只是普通用户‘admin’由同形字变来未必有管理员权限。真正的管理员是那个在数据库创建之初就存在的、用户名严格等于‘admin’的账户。更直接的攻击是我们不需要知道管理员密码而是直接伪造一个Session其中username字段为‘admin’并用窃取或破解的SECRET_KEY为其签名。从源码中我们已获知SECRET_KEY。使用Flask内置的itsdangerous库我们可以本地生成一个合法的、带有管理员身份的Session Cookie。from flask import Flask, session import requests from itsdangerous import URLSafeTimedSerializer app Flask(__name__) app.config[‘SECRET_KEY’] ‘从源码中找到的密钥’ # 方法一使用Flask上下文更规范 with app.test_request_context(): session[‘username’] ‘admin’ # 直接设置为admin session_cookie session._get_current_object().encode(app.secret_key) print(“伪造的Session Cookie:” session_cookie.decode(‘utf-8’)) # 方法二直接使用itsdangerous更底层 # serializer URLSafeTimedSerializer(app.config[‘SECRET_KEY’]) # cookie serializer.dumps({‘username’: ‘admin’}) # print(“伪造的Cookie:” cookie)运行这段代码你将得到一个全新的、合法的sessionCookie值。替换Cookie完成攻击将浏览器中当前的sessionCookie值替换成我们刚刚伪造生成的值。然后刷新页面或直接访问/admin路由。系统验证Session签名有效且从中读取的username为‘admin’权限检查通过于是我们成功看到了只有管理员才能看到的页面拿到了Flag。3.4 第四步另一种可能的利用路径——直接修改与重签名如果无法直接获得SECRET_KEY但题目存在其他漏洞导致密钥泄露比如通过报错信息、配置文件读取等或者存在一个已知的弱密钥攻击路径则略有不同解码现有Cookie用Base64解码你作为普通用户登录后的Session Cookie。修改数据部分在解码后的数据中找到代表username的部分将其从test的序列化值修改为admin的序列化值。这需要了解Flask默认的Session序列化格式通常是itsdangerous的特定格式直接修改二进制数据非常困难。重签名由于你有SECRET_KEY你可以用正确的算法和密钥为修改后的数据生成新的签名并组装成新的Cookie。 然而在实践中由于Flask Session的序列化结构直接修改明文并重签名远比使用itsdangerous库重新生成一个全新的Session数据字典要复杂和容易出错。因此拿到SECRET_KEY后最稳妥的方法永远是使用Flask或itsdangerous库重新生成一个全新的、内容任意的合法Session。4. 漏洞挖掘与防御的深层思考这个题目虽然解决了但留给我们的思考远不止于此。它暴露了Web开发中几个层次的安全问题。4.1 开发者常见误区与安全硬伤将SECRET_KEY视为儿戏很多开发者在开发测试时使用简单的字符串如‘dev’‘123456’作为SECRET_KEY并且将其直接硬编码在源码中提交到公开的代码仓库。这是致命错误。SECRET_KEY应该像数据库密码一样被严格保护必须使用强随机字符串并通过环境变量注入绝对不应出现在版本控制系统里。混淆“签名”与“加密”Flask Session默认只签名不加密意味着会话数据对客户端是透明的。开发者绝不能将任何敏感信息如用户ID、密码哈希、权限等级存入默认的Session中。如果需要存储必须使用扩展如Flask-Session配置为服务器端存储或自行加密。对用户输入缺乏规范化与过滤Unicode同形字攻击属于“视觉欺骗”。防御方法是在关键逻辑点如注册、登录、权限比对对用户名这类标识符进行Unicode规范化如NFKC并确保在整个应用生命周期内使用规范化后的值进行比较和存储。同时可以禁止注册包含非ASCII字符或特定Unicode区块字符的用户名。权限检查逻辑不严谨本题中权限检查仅仅依赖于Session中的一个用户名字符串。更安全的做法是在Session中存储一个不可预测的用户唯一ID如数据库主键每次权限检查时用这个ID去数据库查询用户的真实角色和权限。这样即使Session被伪造攻击者也无法得知合法管理员的用户ID。4.2 针对CTF赛题的进阶利用思路在更复杂的CTF场景中漏洞利用可能不会这么直接。条件竞争与时间窗口如果SECRET_KEY是通过某个临时文件生成或在一定条件下可被读取可能需要结合条件竞争漏洞。Python反序列化漏洞Flask早期版本默认使用pickle序列化Session数据。如果SECRET_KEY已知或为空攻击者可以构造恶意的pickle数据在Session反序列化时触发RCE。这就是著名的Flask Session Pickle反序列化漏洞。防御方法是更换为更安全的序列化器如json。组合漏洞本题是Session伪造Unicode欺骗的组合。在实际挖掘中可能需要先通过其他漏洞如SSTI、文件读取获取SECRET_KEY然后再进行Session伪造。4.3 企业级防御方案建议对于生产环境仅仅修复单个漏洞是不够的需要体系化的防御会话管理使用Flask-Session扩展将Session数据存储到服务器端的Redis或数据库中仅向客户端发送一个无意义的Session ID。定期轮换SECRET_KEY并确保其足够长且随机可使用os.urandom(24)生成。设置Session过期时间PERMANENT_SESSION_LIFETIME。输入处理建立统一的输入验证和清洗层对所有用户提供的字符串数据根据其用途进行规范化、过滤和转义。对于用户名、邮箱等标识符强制使用白名单策略如只允许字母、数字、特定符号并在存储和比较前进行规范化。权限系统实现基于角色的访问控制RBAC权限判断不依赖于客户端可控的数据而是基于服务器端会话中存储的用户ID查询的实时结果。关键操作如管理员后台登录增加二次认证2FA。安全开发流程将SECRET_KEY、数据库凭证等所有敏感信息纳入配置管理使用环境变量或安全的配置中心。代码审计中将Session处理、密码比较、权限验证作为重点审查部分。使用依赖扫描工具确保Flask及其依赖库保持最新避免已知漏洞。5. 从靶场到实战经验总结与避坑指南通过这个靶场题我深刻体会到安全漏洞往往诞生于“便利性”与“安全性”的权衡之间以及开发者对底层机制的无意识信任。我踩过的坑与心得不要忽视任何错误信息在早期测试时我尝试篡改Cookie后服务器返回了500错误。查看错误日志如果开放或仔细分析响应体有时会泄露SECRET_KEY或关键的路径信息。在这个题目中www.zip的泄露就是最直接的“错误配置”。工具链要熟练但思维更重要Burp Suite的Decoder、Repeater功能很强大Python的requests、flask、itsdangerous库是自动化利用的利器。但比工具更重要的是分析源码的逻辑链条。拿到源码后不要急着跑先静下心画出数据流图用户输入从哪里进经过哪些处理存到了哪里最后在哪里做判断。Unicode问题防不胜防不仅仅是用户名任何用于显示、比较的字符串都可能存在此问题比如文件名、验证码、重定向URL。在处理时心里要有一根弦。一个简单的防御测试在注册页面尝试用各种同形字注册“admin”看系统是否拦截。Session伪造的延伸这个漏洞不局限于Flask。任何使用客户端签名式Session的框架如Django的signed_cookie后端都存在类似风险。原理相通只是签名算法和格式不同。关键在于密钥的保密性是生命线。CTF中的“非预期解”有时题目可能存在多种解法。例如如果网站存在一个修改密码的功能且仅验证Session中的用户名那么通过Unicode欺骗登录一个“视觉管理员”账户后可能可以利用这个功能去修改真正管理员admin的密码。这就要求我们不仅关注目标漏洞还要通盘考虑整个应用的功能逻辑。这个[HCTF 2018]admin1题目像一把精巧的钥匙打开了理解Web会话安全与编码安全的大门。它告诉我们安全是一个整体任何一个环节的疏忽无论是配置管理、逻辑处理还是对标准的理解偏差都可能被组合利用造成严重的后果。对于开发者这意味着要时刻保持警惕深入理解所用工具的特性对于安全研究者这意味着需要拥有穿透表面功能洞察底层机制与数据流转的洞察力。每一次这样的实战分析都是对我们安全思维的一次有效训练。

相关新闻

关于网站建设的图片:那些被低估的视觉灵魂,如何决定你的流量生死

关于网站建设的图片:那些被低估的视觉灵魂,如何决定你的流量生死

咱们今天不聊那些虚头巴脑的技术参数,也不谈什么晦涩难懂的后端架构,咱们就坐下来,泡杯茶,聊聊那个在网站建设里最容易被人忽视,却又能一眼定生死的东西。对,就是图片。你可能听过那句话:“颜值即正义。”在互联网时代,这句话简直就是真理。当用户第一次点进你的网站,…

2026/8/6 7:08:11 阅读更多 →
为什么我不再让一个 Agent 做所有事情?Hermes 多 Profile 实战

为什么我不再让一个 Agent 做所有事情?Hermes 多 Profile 实战

前两篇,我们分别解决了两个问题。第一篇,把 Hermes 从一个聊天机器人,改造成了一个可以 24 小时持续工作的 AI 工作台。第二篇,把多个 Agent 之间的协作,从"群聊接话"变成了基于 Kanban 的任务管理&#xff…

2026/8/6 7:08:11 阅读更多 →
虚拟机CPU超配问题解析:从超量分配到性能调优的实战指南

虚拟机CPU超配问题解析:从超量分配到性能调优的实战指南

1. 项目概述:当虚拟机CPU配置“超标”时,我们到底在解决什么?在虚拟化运维和开发测试的日常工作中,我猜不少朋友都遇到过这个让人心头一紧的弹窗或提示:你试图为虚拟机分配的虚拟处理器(vCPU)数…

2026/8/6 7:07:11 阅读更多 →

最新新闻

2024 Excel函数公式实战指南:从核心函数到动态数组,告别重复劳动

2024 Excel函数公式实战指南:从核心函数到动态数组,告别重复劳动

1. 项目概述:为什么你需要一份2024年的Excel函数与公式指南?如果你还在用“复制粘贴”和“手动计算”来对付Excel里那些密密麻麻的数据,那这份指南就是为你准备的。我干了十多年数据分析,见过太多同事和学员,面对一个简…

2026/8/6 7:55:40 阅读更多 →
扣子事件触发器安全加固手册:防止恶意payload注入、重放攻击与越权触发(含OWASP合规检查清单)

扣子事件触发器安全加固手册:防止恶意payload注入、重放攻击与越权触发(含OWASP合规检查清单)

更多请点击: https://intelliparadigm.com 第一章:扣子事件触发器安全加固手册:防止恶意payload注入、重放攻击与越权触发(含OWASP合规检查清单) 扣子(Coze)平台的事件触发器(Event…

2026/8/6 7:55:40 阅读更多 →
2026年GEO优化深度解读:郑州企业如何抓住AI搜索新流量?

2026年GEO优化深度解读:郑州企业如何抓住AI搜索新流量?

2026年GEO优化深度解读:郑州企业如何抓住AI搜索新流量?导读:当用户不再打开搜索引擎,而是直接问AI"郑州哪家工厂做盾构机配件靠谱",你的企业还能被找到吗?这就是GEO(生成式引擎优化&a…

2026/8/6 7:55:40 阅读更多 →
小程序定制开发公司怎么选?源码、买断、页面设计和长期维护对比

小程序定制开发公司怎么选?源码、买断、页面设计和长期维护对比

小程序定制开发公司怎么选?源码、买断、页面设计和长期维护对比小程序定制开发公司怎么选,已经不能只问“能不能按需求做”。企业更需要确认的是源码、买断、页面设计、后台功能、接口、验收和长期维护之间的边界。很多项目预算失控,是因为把…

2026/8/6 7:55:40 阅读更多 →
基于规则匹配与模板填充的智能回复生成器实战指南

基于规则匹配与模板填充的智能回复生成器实战指南

最近在开发中遇到一个很有意思的需求:需要根据用户输入的文本,自动生成一个既酷炫又带点调侃意味的“金句”作为回应。比如用户说“今天好累”,系统能回一句“man!what can i say”。这种需求在社交应用、智能客服或者游戏对话系统…

2026/8/6 7:55:40 阅读更多 →
揭秘建设网站用的软件:从小白到专家的完整攻略与避坑指南

揭秘建设网站用的软件:从小白到专家的完整攻略与避坑指南

说实话,以前我觉得搞网站那是程序员的事,跟我这种普通小老板或者自媒体人有什么关系?那时候我觉得网站这东西,要么花钱找外面公司做,要么自己啃那些像天书一样的代码,想想都头大。但是,随着这两年互联网环境的变迁,尤其是现在大家越来越重视个人IP,越来越重视私域流量…

2026/8/6 7:54:39 阅读更多 →

日新闻

深入解析LimboAI C++内核:架构设计与性能优化实战

深入解析LimboAI C++内核:架构设计与性能优化实战

1. 项目概述:为什么我们需要深入LimboAI的C内核?如果你是一名使用Godot引擎的游戏开发者,尤其是对AI行为逻辑有较高要求的项目,那么LimboAI这个名字你大概率不会陌生。它作为Godot 4生态中一个备受瞩目的行为树与状态机插件&#…

2026/8/6 0:00:06 阅读更多 →
Unity 2D游戏敌人AI系统:基于PlayMaker状态机与2D Toolkit的实战开发

Unity 2D游戏敌人AI系统:基于PlayMaker状态机与2D Toolkit的实战开发

1. 项目概述与核心思路大家好,我是老张,一个在游戏开发一线摸爬滚打了十多年的老码农。今天咱们接着聊《空洞骑士》风格2D动作游戏的Demo制作。上一期我们搭好了基础框架,处理了角色移动和碰撞,这一期,我们要让游戏世界…

2026/8/6 0:00:06 阅读更多 →
被动防火门市场前景发展趋势

被动防火门市场前景发展趋势

被动防火门依靠材质结构、密闭构造阻隔烟火蔓延,无需电控启动,是建筑被动消防系统核心构件,行业依托新规管控、城市更新、工业安全升级迎来稳定扩容,整体朝着合规化、专项化、低碳化、智能化方向发展。现阶段 GB12955‑2024 新版国…

2026/8/6 0:00:06 阅读更多 →

周新闻

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

1. 从水管网络到最大流:一个核心问题的诞生想象一下,你是一个城市供水系统的总工程师。你的城市有多个水源(水库),需要通过一个复杂的地下管道网络,将水输送到各个居民区。每条管道都有其最大通水能力&…

2026/8/5 15:00:43 阅读更多 →
基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/5 13:13:56 阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/5 10:20:36 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/5 23:28:39 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/5 21:00:14 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/5 23:46:51 阅读更多 →