From 278b3a8a5582e1e3c298dc55a6f4230730cebcd6 Mon Sep 17 00:00:00 2001 From: wh1te909 Date: Sat, 13 Feb 2021 19:08:12 -0800 Subject: [PATCH] switch back to http requests --- agent/agent_windows.go | 17 +++++------ agent/choco_windows.go | 25 ++++++--------- agent/install_windows.go | 2 +- agent/patches_windows.go | 44 ++++++++++----------------- agent/rpc_windows.go | 10 +++--- agent/winagentsvc_windows.go | 59 ++++++++++++++++++------------------ 6 files changed, 69 insertions(+), 88 deletions(-) diff --git a/agent/agent_windows.go b/agent/agent_windows.go index e3e4c28..b80b2ac 100644 --- a/agent/agent_windows.go +++ b/agent/agent_windows.go @@ -25,7 +25,6 @@ import ( "github.com/shirou/gopsutil/v3/cpu" "github.com/shirou/gopsutil/v3/disk" "github.com/sirupsen/logrus" - "github.com/ugorji/go/codec" wapf "github.com/wh1te909/go-win64api" rmm "github.com/wh1te909/rmmagent/shared" "golang.org/x/sys/windows" @@ -540,10 +539,7 @@ func (a *WindowsAgent) RecoverSalt() { a.Logger.Debugln("Salt recovery completed on", a.Hostname) } -func (a *WindowsAgent) SyncMeshNodeID(nc *nats.Conn) { - var resp []byte - ret := codec.NewEncoderBytes(&resp, new(codec.MsgpackHandle)) - +func (a *WindowsAgent) SyncMeshNodeID() { out, err := CMD(a.MeshSystemEXE, []string{"-nodeid"}, 10, false) if err != nil { a.Logger.Debugln(err) @@ -568,18 +564,21 @@ func (a *WindowsAgent) SyncMeshNodeID(nc *nats.Conn) { Agentid: a.AgentID, NodeID: StripAll(stdout), } - ret.Encode(payload) - nc.PublishRequest(a.AgentID, "syncmesh", resp) + + _, err = a.rClient.R().SetBody(payload).Post("/api/v3/syncmesh/") + if err != nil { + a.Logger.Debugln("SyncMesh:", err) + } } //RecoverMesh recovers mesh agent -func (a *WindowsAgent) RecoverMesh(nc *nats.Conn) { +func (a *WindowsAgent) RecoverMesh() { a.Logger.Debugln("Attempting mesh recovery on", a.Hostname) defer CMD("net", []string{"start", a.MeshSVC}, 60, false) _, _ = CMD("net", []string{"stop", a.MeshSVC}, 60, false) a.ForceKillMesh() - a.SyncMeshNodeID(nc) + a.SyncMeshNodeID() } //RecoverRPC recovers nats rpc service diff --git a/agent/choco_windows.go b/agent/choco_windows.go index acafcf4..7c11f84 100644 --- a/agent/choco_windows.go +++ b/agent/choco_windows.go @@ -4,49 +4,44 @@ import ( "time" "github.com/go-resty/resty/v2" - nats "github.com/nats-io/nats.go" - "github.com/ugorji/go/codec" rmm "github.com/wh1te909/rmmagent/shared" ) -func (a *WindowsAgent) InstallChoco(nc *nats.Conn) { - var resp []byte +func (a *WindowsAgent) InstallChoco() { + var result rmm.ChocoInstalled result.AgentID = a.AgentID result.Installed = false - ret := codec.NewEncoderBytes(&resp, new(codec.MsgpackHandle)) rClient := resty.New() rClient.SetTimeout(30 * time.Second) + url := "/api/v3/choco/" r, err := rClient.R().Get("https://chocolatey.org/install.ps1") if err != nil { - ret.Encode(result) - nc.PublishRequest(a.AgentID, "chocoinstall", resp) + a.Logger.Debugln(err) + a.rClient.R().SetBody(result).Post(url) return } if r.IsError() { - ret.Encode(result) - nc.PublishRequest(a.AgentID, "chocoinstall", resp) + a.rClient.R().SetBody(result).Post(url) return } _, _, exitcode, err := a.RunScript(string(r.Body()), "powershell", []string{}, 900) if err != nil { - ret.Encode(result) - nc.PublishRequest(a.AgentID, "chocoinstall", resp) + a.Logger.Debugln(err) + a.rClient.R().SetBody(result).Post(url) return } if exitcode != 0 { - ret.Encode(result) - nc.PublishRequest(a.AgentID, "chocoinstall", resp) + a.rClient.R().SetBody(result).Post(url) return } result.Installed = true - ret.Encode(result) - nc.PublishRequest(a.AgentID, "chocoinstall", resp) + a.rClient.R().SetBody(result).Post(url) } func (a *WindowsAgent) InstallWithChoco(name, version string) (string, error) { diff --git a/agent/install_windows.go b/agent/install_windows.go index d3a4510..9ecd690 100644 --- a/agent/install_windows.go +++ b/agent/install_windows.go @@ -271,7 +271,7 @@ func (a *WindowsAgent) Install(i *Installer) { } else { startup := []string{"hello", "osinfo", "winservices", "disks", "publicip", "software", "loggedonuser"} for _, s := range startup { - a.CheckIn(nc, s) + a.CheckIn(s) time.Sleep(200 * time.Millisecond) } nc.Close() diff --git a/agent/patches_windows.go b/agent/patches_windows.go index e02cb19..c8c7d04 100644 --- a/agent/patches_windows.go +++ b/agent/patches_windows.go @@ -4,12 +4,10 @@ import ( "fmt" "time" - nats "github.com/nats-io/nats.go" - "github.com/ugorji/go/codec" rmm "github.com/wh1te909/rmmagent/shared" ) -func (a *WindowsAgent) GetWinUpdates(nc *nats.Conn) { +func (a *WindowsAgent) GetWinUpdates() { updates, err := WUAUpdates("IsInstalled=1 or IsInstalled=0 and Type='Software' and IsHidden=0") if err != nil { a.Logger.Errorln(err) @@ -25,13 +23,13 @@ func (a *WindowsAgent) GetWinUpdates(nc *nats.Conn) { } payload := rmm.WinUpdateResult{AgentID: a.AgentID, Updates: updates} - var resp []byte - ret := codec.NewEncoderBytes(&resp, new(codec.MsgpackHandle)) - ret.Encode(payload) - nc.PublishRequest(a.AgentID, "getwinupdates", resp) + _, err = a.rClient.R().SetBody(payload).Post("/api/v3/winupdates/") + if err != nil { + a.Logger.Debugln(err) + } } -func (a *WindowsAgent) InstallUpdates(nc *nats.Conn, guids []string) { +func (a *WindowsAgent) InstallUpdates(guids []string) { session, err := NewUpdateSession() if err != nil { a.Logger.Errorln(err) @@ -40,9 +38,6 @@ func (a *WindowsAgent) InstallUpdates(nc *nats.Conn, guids []string) { defer session.Close() for _, id := range guids { - var resp []byte - ret := codec.NewEncoderBytes(&resp, new(codec.MsgpackHandle)) - var result rmm.WinUpdateInstallResult result.AgentID = a.AgentID result.UpdateID = id @@ -53,8 +48,7 @@ func (a *WindowsAgent) InstallUpdates(nc *nats.Conn, guids []string) { if err != nil { a.Logger.Errorln(err) result.Success = false - ret.Encode(result) - nc.PublishRequest(a.AgentID, "winupdateresult", resp) + a.rClient.R().SetBody(result).Patch("/api/v3/winupdates/") continue } defer updts.Release() @@ -63,16 +57,14 @@ func (a *WindowsAgent) InstallUpdates(nc *nats.Conn, guids []string) { if err != nil { a.Logger.Errorln(err) result.Success = false - ret.Encode(result) - nc.PublishRequest(a.AgentID, "winupdateresult", resp) + a.rClient.R().SetBody(result).Patch("/api/v3/winupdates/") continue } a.Logger.Debugln("updtCnt:", updtCnt) if updtCnt == 0 { superseded := rmm.SupersededUpdate{AgentID: a.AgentID, UpdateID: id} - ret.Encode(superseded) - nc.PublishRequest(a.AgentID, "superseded", resp) + a.rClient.R().SetBody(superseded).Post("/api/v3/superseded/") continue } @@ -81,8 +73,7 @@ func (a *WindowsAgent) InstallUpdates(nc *nats.Conn, guids []string) { if err != nil { a.Logger.Errorln(err) result.Success = false - ret.Encode(result) - nc.PublishRequest(a.AgentID, "winupdateresult", resp) + a.rClient.R().SetBody(result).Patch("/api/v3/winupdates/") continue } a.Logger.Debugln("u:", u) @@ -90,13 +81,11 @@ func (a *WindowsAgent) InstallUpdates(nc *nats.Conn, guids []string) { if err != nil { a.Logger.Errorln(err) result.Success = false - ret.Encode(result) - nc.PublishRequest(a.AgentID, "winupdateresult", resp) + a.rClient.R().SetBody(result).Patch("/api/v3/winupdates/") continue } result.Success = true - ret.Encode(result) - nc.PublishRequest(a.AgentID, "winupdateresult", resp) + a.rClient.R().SetBody(result).Patch("/api/v3/winupdates/") a.Logger.Debugln("Installed windows update with guid", id) } } @@ -106,10 +95,9 @@ func (a *WindowsAgent) InstallUpdates(nc *nats.Conn, guids []string) { if err != nil { a.Logger.Errorln(err) } - - var resp2 []byte - ret2 := codec.NewEncoderBytes(&resp2, new(codec.MsgpackHandle)) rebootPayload := rmm.AgentNeedsReboot{AgentID: a.AgentID, NeedsReboot: needsReboot} - ret2.Encode(rebootPayload) - nc.PublishRequest(a.AgentID, "needsreboot", resp2) + _, err = a.rClient.R().SetBody(rebootPayload).Put("/api/v3/winupdates/") + if err != nil { + a.Logger.Debugln("NeedsReboot:", err) + } } diff --git a/agent/rpc_windows.go b/agent/rpc_windows.go index db0706e..b759715 100644 --- a/agent/rpc_windows.go +++ b/agent/rpc_windows.go @@ -249,7 +249,7 @@ func (a *WindowsAgent) RunRPC() { switch p.Data["mode"] { case "mesh": a.Logger.Debugln("Recovering mesh") - a.RecoverMesh(nc) + a.RecoverMesh() case "salt": a.Logger.Debugln("Recovering salt") a.RecoverSalt() @@ -312,7 +312,7 @@ func (a *WindowsAgent) RunRPC() { a.Logger.Debugln("Getting sysinfo with WMI") modes := []string{"osinfo", "publicip", "disks"} for _, m := range modes { - a.CheckIn(nc, m) + a.CheckIn(m) time.Sleep(200 * time.Millisecond) } a.GetWMI() @@ -385,7 +385,7 @@ func (a *WindowsAgent) RunRPC() { msg.Respond(resp) }() case "installchoco": - go a.InstallChoco(nc) + go a.InstallChoco() case "installwithchoco": go func(p *NatsMsg) { var resp []byte @@ -402,7 +402,7 @@ func (a *WindowsAgent) RunRPC() { } else { a.Logger.Debugln("Checking for windows updates") defer atomic.StoreUint32(&getWinUpdateLocker, 0) - a.GetWinUpdates(nc) + a.GetWinUpdates() } }() case "installwinupdates": @@ -412,7 +412,7 @@ func (a *WindowsAgent) RunRPC() { } else { a.Logger.Debugln("Installing windows updates", p.UpdateGUIDs) defer atomic.StoreUint32(&installWinUpdateLocker, 0) - a.InstallUpdates(nc, p.UpdateGUIDs) + a.InstallUpdates(p.UpdateGUIDs) } }(payload) case "agentupdate": diff --git a/agent/winagentsvc_windows.go b/agent/winagentsvc_windows.go index 6a8e7a7..f2c24ad 100644 --- a/agent/winagentsvc_windows.go +++ b/agent/winagentsvc_windows.go @@ -1,35 +1,23 @@ package agent import ( - "fmt" "math/rand" - "os" "sync" "time" - nats "github.com/nats-io/nats.go" - "github.com/ugorji/go/codec" rmm "github.com/wh1te909/rmmagent/shared" ) func (a *WindowsAgent) RunAsService() { var wg sync.WaitGroup - opts := a.setupNatsOptions() - server := fmt.Sprintf("tls://%s:4222", a.ApiURL) - - nc, err := nats.Connect(server, opts...) - if err != nil { - a.Logger.Errorln(err) - os.Exit(1) - } wg.Add(1) - go a.WinAgentSvc(nc) + go a.WinAgentSvc() go a.CheckRunner() wg.Wait() } // WinAgentSvc tacticalagent windows nssm service -func (a *WindowsAgent) WinAgentSvc(nc *nats.Conn) { +func (a *WindowsAgent) WinAgentSvc() { a.Logger.Infoln("Agent service started") go a.GetPython(false) sleepDelay := randRange(14, 22) @@ -41,13 +29,13 @@ func (a *WindowsAgent) WinAgentSvc(nc *nats.Conn) { startup := []string{"hello", "osinfo", "winservices", "disks", "publicip", "software", "loggedonuser"} for _, s := range startup { - a.CheckIn(nc, s) + a.CheckIn(s) time.Sleep(time.Duration(randRange(300, 900)) * time.Millisecond) } - a.SyncMeshNodeID(nc) + a.SyncMeshNodeID() time.Sleep(time.Duration(randRange(2, 7)) * time.Second) - a.CheckIn(nc, "startup") + a.CheckIn("startup") checkInTicker := time.NewTicker(time.Duration(randRange(40, 110)) * time.Second) checkInOSTicker := time.NewTicker(time.Duration(randRange(250, 450)) * time.Second) @@ -61,29 +49,28 @@ func (a *WindowsAgent) WinAgentSvc(nc *nats.Conn) { for { select { case <-checkInTicker.C: - a.CheckIn(nc, "hello") + a.CheckIn("hello") case <-checkInOSTicker.C: - a.CheckIn(nc, "osinfo") + a.CheckIn("osinfo") case <-checkInWinSvcTicker.C: - a.CheckIn(nc, "winservices") + a.CheckIn("winservices") case <-checkInPubIPTicker.C: - a.CheckIn(nc, "publicip") + a.CheckIn("publicip") case <-checkInDisksTicker.C: - a.CheckIn(nc, "disks") + a.CheckIn("disks") case <-checkInLoggedUserTicker.C: - a.CheckIn(nc, "loggedonuser") + a.CheckIn("loggedonuser") case <-checkInSWTicker.C: - a.CheckIn(nc, "software") + a.CheckIn("software") case <-syncMeshTicker.C: - a.SyncMeshNodeID(nc) + a.SyncMeshNodeID() } } } -func (a *WindowsAgent) CheckIn(nc *nats.Conn, mode string) { +func (a *WindowsAgent) CheckIn(mode string) { + var rerr error var payload interface{} - var resp []byte - ret := codec.NewEncoderBytes(&resp, new(codec.MsgpackHandle)) switch mode { case "hello": @@ -163,8 +150,20 @@ func (a *WindowsAgent) CheckIn(nc *nats.Conn, mode string) { InstalledSW: a.GetInstalledSoftware(), } } - ret.Encode(payload) - nc.PublishRequest(a.AgentID, mode, resp) + + url := "/api/v3/checkin/" + + if mode == "hello" { + _, rerr = a.rClient.R().SetBody(payload).Patch(url) + } else if mode == "startup" { + _, rerr = a.rClient.R().SetBody(payload).Post(url) + } else { + _, rerr = a.rClient.R().SetBody(payload).Put(url) + } + + if rerr != nil { + a.Logger.Debugln("Checkin:", rerr) + } } func randRange(min, max int) int {