diff --git a/Plugins/WMIExec.go b/Plugins/WMIExec.go index a55f1f7..262c1fd 100644 --- a/Plugins/WMIExec.go +++ b/Plugins/WMIExec.go @@ -1,28 +1,24 @@ package Plugins import ( - "errors" "fmt" + "github.com/go-ole/go-ole" + "github.com/go-ole/go-ole/oleutil" "github.com/shadow1ng/fscan/Common" "os" "strings" "time" - - "github.com/C-Sto/goWMIExec/pkg/wmiexec" ) -// 全局变量 var ( - ClientHost string // 客户端主机名 - flag bool // 初始化标志 + ClientHost string + flag bool ) -// init 初始化函数 func init() { if flag { return } - // 获取主机名 clientHost, err := os.Hostname() if err != nil { fmt.Println(err) @@ -31,33 +27,25 @@ func init() { flag = true } -// WmiExec 执行WMI远程命令 func WmiExec(info *Common.HostInfo) (tmperr error) { - // 如果是暴力破解模式则跳过 if Common.DisableBrute { return nil } starttime := time.Now().Unix() - // 遍历用户字典 for _, user := range Common.Userdict["smb"] { PASS: - // 遍历密码字典 for _, pass := range Common.Passwords { - // 替换密码模板中的用户名 pass = strings.Replace(pass, "{user}", user, -1) - // 尝试WMI连接 flag, err := Wmiexec(info, user, pass, Common.HashValue) - // 记录错误日志 errlog := fmt.Sprintf("[-] WmiExec %v:%v %v %v %v", info.Host, 445, user, pass, err) errlog = strings.Replace(errlog, "\n", "", -1) Common.LogError(errlog) if flag { - // 成功连接,记录结果 var result string if Common.Domain != "" { result = fmt.Sprintf("[+] WmiExec %v:%v:%v\\%v ", info.Host, info.Ports, Common.Domain, user) @@ -65,7 +53,6 @@ func WmiExec(info *Common.HostInfo) (tmperr error) { result = fmt.Sprintf("[+] WmiExec %v:%v:%v ", info.Host, info.Ports, user) } - // 添加认证信息到结果 if Common.HashValue != "" { result += "hash: " + Common.HashValue } else { @@ -75,17 +62,14 @@ func WmiExec(info *Common.HostInfo) (tmperr error) { return err } else { tmperr = err - // 检查错误是否需要终止 if Common.CheckErrs(err) { return err } - // 检查是否超时 if time.Now().Unix()-starttime > (int64(len(Common.Userdict["smb"])*len(Common.Passwords)) * Common.Timeout) { return err } } - // 如果使用NTLM HashValue,则跳过密码循环 if len(Common.HashValue) == 32 { break PASS } @@ -94,63 +78,68 @@ func WmiExec(info *Common.HostInfo) (tmperr error) { return tmperr } -// Wmiexec 包装WMI执行函数 func Wmiexec(info *Common.HostInfo, user string, pass string, hash string) (flag bool, err error) { target := fmt.Sprintf("%s:%v", info.Host, info.Ports) - wmiexec.Timeout = int(Common.Timeout) - return WMIExec(target, user, pass, hash, Common.Domain, Common.Command, ClientHost, "", nil) + return WMIExec(target, user, pass, hash, Common.Domain, Common.Command) } -// WMIExec 执行WMI远程命令 -func WMIExec(target, username, password, hash, domain, command, clientHostname, binding string, cfgIn *wmiexec.WmiExecConfig) (flag bool, err error) { - // 初始化WMI配置 - if cfgIn == nil { - cfg, err1 := wmiexec.NewExecConfig(username, password, hash, domain, target, clientHostname, true, nil, nil) - if err1 != nil { - err = err1 - return - } - cfgIn = &cfg - } - - // 创建WMI执行器 - execer := wmiexec.NewExecer(cfgIn) - - // 设置目标绑定 - err = execer.SetTargetBinding(binding) +func WMIExec(target, username, password, hash, domain, command string) (flag bool, err error) { + err = ole.CoInitialize(0) if err != nil { - return + return false, err + } + defer ole.CoUninitialize() + + // 构建认证字符串 + var auth string + if domain != "" { + auth = fmt.Sprintf("%s\\%s:%s", domain, username, password) + } else { + auth = fmt.Sprintf("%s:%s", username, password) } - // 进行认证 - err = execer.Auth() + // 构建WMI连接字符串 + connectStr := fmt.Sprintf("winmgmts://%s@%s/root/cimv2", auth, target) + + unknown, err := oleutil.CreateObject("WbemScripting.SWbemLocator") if err != nil { - return + return false, err } + defer unknown.Release() + + wmi, err := unknown.QueryInterface(ole.IID_IDispatch) + if err != nil { + return false, err + } + defer wmi.Release() + + // 使用connectStr来建立连接 + service, err := oleutil.CallMethod(wmi, "ConnectServer", "", connectStr) + if err != nil { + return false, err + } + defer service.Clear() + + // 连接成功 flag = true // 如果有命令则执行 if command != "" { - // 使用cmd.exe执行命令 command = "C:\\Windows\\system32\\cmd.exe /c " + command - // 检查RPC端口 - if execer.TargetRPCPort == 0 { - err = errors.New("RPC端口为0,无法连接") - return - } - - // 建立RPC连接 - err = execer.RPCConnect() + // 创建Win32_Process对象来执行命令 + process, err := oleutil.CallMethod(service.ToIDispatch(), "Get", "Win32_Process") if err != nil { - return + return flag, err } + defer process.Clear() // 执行命令 - err = execer.Exec(command) + _, err = oleutil.CallMethod(process.ToIDispatch(), "Create", command) if err != nil { - return + return flag, err } } - return + + return flag, nil } diff --git a/go.mod b/go.mod index 5950d64..ea331d4 100644 --- a/go.mod +++ b/go.mod @@ -40,6 +40,7 @@ require ( filippo.io/edwards25519 v1.1.0 // indirect github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect github.com/BurntSushi/toml v0.3.1 // indirect + github.com/StackExchange/wmi v1.2.1 // indirect github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa // indirect github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 // indirect github.com/davecgh/go-spew v1.1.1 // indirect @@ -48,6 +49,7 @@ require ( github.com/eapache/queue v1.1.0 // indirect github.com/geoffgarside/ber v1.1.0 // indirect github.com/go-asn1-ber/asn1-ber v1.5.7 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe // indirect github.com/golang-sql/sqlexp v0.1.0 // indirect github.com/golang/snappy v0.0.4 // indirect diff --git a/go.sum b/go.sum index 788d656..5e2bb0e 100644 --- a/go.sum +++ b/go.sum @@ -24,6 +24,8 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym github.com/IBM/sarama v1.43.3 h1:Yj6L2IaNvb2mRBop39N7mmJAHBVY3dTPncr3qGVkxPA= github.com/IBM/sarama v1.43.3/go.mod h1:FVIRaLrhK3Cla/9FfRF5X9Zua2KpS3SYIXxhac1H+FQ= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= +github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= github.com/Ullaakut/nmap v2.0.2+incompatible h1:edw45QpSQBQ2B/Hqfg86Bt5rrK79tp/fAcqIHyNSdQs= github.com/Ullaakut/nmap v2.0.2+incompatible/go.mod h1:fkC066hwfcoKwlI7DS2ARTggSVtBTZYCjVH1TzuTMaQ= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -87,6 +89,9 @@ github.com/go-ldap/ldap/v3 v3.4.9 h1:KxX9eO44/MpqPXVVMPJDB+k/35GEePHE/Jfvl7oRMUo github.com/go-ldap/ldap/v3 v3.4.9/go.mod h1:+CE/4PPOOdEPGTi2B7qXKQOq+pNBvXZtlBNcVZY0AWI= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-resty/resty/v2 v2.16.2 h1:CpRqTjIzq/rweXUt9+GxzzQdlkqMdt8Lm/fuK/CAbAg= github.com/go-resty/resty/v2 v2.16.2/go.mod h1:0fHAoK7JoBy/Ch36N8VFeMsK7xQOHhvWaC3iOktwmIU= github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= @@ -480,6 +485,7 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -494,6 +500,7 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=