Skip to content

Commit

Permalink
services: Moving strings from implant to client, renaming StartExisti…
Browse files Browse the repository at this point in the history
…ngService to StartServiceByName, removing unnecessary test
  • Loading branch information
RafBishopFox committed Jan 15, 2024
1 parent 8ff7d4e commit f50a1ed
Show file tree
Hide file tree
Showing 10 changed files with 389 additions and 359 deletions.
71 changes: 65 additions & 6 deletions client/command/processes/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,21 @@ import (
"golang.org/x/term"
)

const (
serviceStopped = 1
serviceStartPending = 2
serviceStopPending = 3
serviceRunning = 4
serviceContinuePending = 5
servicePausePending = 6
servicePaused = 7
serviceBootStart = 0
serviceSystemStart = 1
serviceAutoStart = 2
serviceDemandStart = 3
serviceDisabled = 4
)

func ServicesCmd(cmd *cobra.Command, con *console.SliverClient, args []string) {
session, beacon := con.ActiveTarget.GetInteractive()
if session == nil && beacon == nil {
Expand Down Expand Up @@ -181,7 +196,7 @@ func ServiceStartCmd(cmd *cobra.Command, con *console.SliverClient, args []strin
return
}

startService, err := con.Rpc.StartExistingService(context.Background(), &sliverpb.StartExistingServiceReq{
startService, err := con.Rpc.StartServiceByName(context.Background(), &sliverpb.StartServiceByNameReq{
ServiceInfo: &sliverpb.ServiceInfoReq{Hostname: hostname, ServiceName: serviceName},
Request: con.ActiveTarget.Request(cmd),
})
Expand Down Expand Up @@ -223,6 +238,44 @@ func ServiceStartCmd(cmd *cobra.Command, con *console.SliverClient, args []strin
}
}

func translateServiceStatus(status uint32) string {
switch status {
case serviceStopped:
return "Stopped"
case serviceStartPending:
return "Start Pending"
case serviceStopPending:
return "Stop Pending"
case serviceRunning:
return "Running"
case serviceContinuePending:
return "Continue Pending"
case servicePausePending:
return "Pause Pending"
case servicePaused:
return "Paused"
default:
return fmt.Sprintf("Unknown (status type: %d)", status)
}
}

func translateServiceStartup(startup uint32) string {
switch startup {
case serviceBootStart:
return "Device (System Loader; Boot)"
case serviceSystemStart:
return "Device (IOInitSystem; System)"
case serviceAutoStart:
return "Automatic"
case serviceDemandStart:
return "Manual"
case serviceDisabled:
return "Disabled"
default:
return fmt.Sprintf("Unknown (Type %d)", startup)
}
}

func PrintServices(serviceInfo *sliverpb.Services, con *console.SliverClient) {
// Get terminal width
width, _, err := term.GetSize(0)
Expand Down Expand Up @@ -263,21 +316,23 @@ func PrintServices(serviceInfo *sliverpb.Services, con *console.SliverClient) {
})

for _, service := range serviceInfo.Details {
status := translateServiceStatus(service.Status)
var row table.Row
if wideTermWidth {
startupType := translateServiceStartup(service.StartupType)
row = table.Row{
service.Name,
service.DisplayName,
service.Status,
service.StartupType,
status,
startupType,
service.BinPath,
service.Account,
}
} else {
row = table.Row{
service.Name,
service.DisplayName,
service.Status,
status,
}
}
tw.AppendRow(row)
Expand Down Expand Up @@ -310,6 +365,10 @@ func PrintServiceDetail(serviceDetail *sliverpb.ServiceDetail, con *console.Sliv
con.Println("Description: ", detail.Description)
con.Println("Account the service runs under: ", detail.Account)
con.Println("Binary Path: ", detail.BinPath)
con.Println("Startup type: ", detail.StartupType)
con.Println("Status: ", detail.Status)
con.Println("Startup type: ", translateServiceStartup(detail.StartupType))
if serviceDetail.Message != "" {
con.Println("Status: ", serviceDetail.Message)
} else {
con.Println("Status: ", translateServiceStatus(detail.Status))
}
}
45 changes: 25 additions & 20 deletions implant/sliver/handlers/handlers_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,22 +75,22 @@ var (
sliverpb.MsgCurrentTokenOwnerReq: currentTokenOwnerHandler,

// Platform specific
sliverpb.MsgIfconfigReq: ifconfigHandler,
sliverpb.MsgScreenshotReq: screenshotHandler,
sliverpb.MsgSideloadReq: sideloadHandler,
sliverpb.MsgNetstatReq: netstatHandler,
sliverpb.MsgMakeTokenReq: makeTokenHandler,
sliverpb.MsgPsReq: psHandler,
sliverpb.MsgTerminateReq: terminateHandler,
sliverpb.MsgRegistryReadReq: regReadHandler,
sliverpb.MsgRegistryWriteReq: regWriteHandler,
sliverpb.MsgRegistryCreateKeyReq: regCreateKeyHandler,
sliverpb.MsgRegistryDeleteKeyReq: regDeleteKeyHandler,
sliverpb.MsgRegistrySubKeysListReq: regSubKeysListHandler,
sliverpb.MsgRegistryListValuesReq: regValuesListHandler,
sliverpb.MsgServicesReq: servicesListHandler,
sliverpb.MsgServiceDetailReq: serviceDetailHandler,
sliverpb.MsgStartExistingServiceReq: startExistingServiceHandler,
sliverpb.MsgIfconfigReq: ifconfigHandler,
sliverpb.MsgScreenshotReq: screenshotHandler,
sliverpb.MsgSideloadReq: sideloadHandler,
sliverpb.MsgNetstatReq: netstatHandler,
sliverpb.MsgMakeTokenReq: makeTokenHandler,
sliverpb.MsgPsReq: psHandler,
sliverpb.MsgTerminateReq: terminateHandler,
sliverpb.MsgRegistryReadReq: regReadHandler,
sliverpb.MsgRegistryWriteReq: regWriteHandler,
sliverpb.MsgRegistryCreateKeyReq: regCreateKeyHandler,
sliverpb.MsgRegistryDeleteKeyReq: regDeleteKeyHandler,
sliverpb.MsgRegistrySubKeysListReq: regSubKeysListHandler,
sliverpb.MsgRegistryListValuesReq: regValuesListHandler,
sliverpb.MsgServicesReq: servicesListHandler,
sliverpb.MsgServiceDetailReq: serviceDetailHandler,
sliverpb.MsgStartServiceByNameReq: startServiceByNameHandler,

// Generic
sliverpb.MsgPing: pingHandler,
Expand Down Expand Up @@ -598,14 +598,14 @@ func stopService(data []byte, resp RPCResponse) {
resp(data, err)
}

func startExistingServiceHandler(data []byte, resp RPCResponse) {
startServiceReq := &sliverpb.StartExistingServiceReq{}
func startServiceByNameHandler(data []byte, resp RPCResponse) {
startServiceReq := &sliverpb.StartServiceByNameReq{}
err := proto.Unmarshal(data, startServiceReq)
if err != nil {
return
}

err = service.StartExistingService(startServiceReq.ServiceInfo.Hostname, startServiceReq.ServiceInfo.ServiceName)
err = service.StartServiceByName(startServiceReq.ServiceInfo.Hostname, startServiceReq.ServiceInfo.ServiceName)
svcInfo := &sliverpb.ServiceInfo{}
if err != nil {
svcInfo.Response = &commonpb.Response{
Expand Down Expand Up @@ -837,7 +837,12 @@ func serviceDetailHandler(data []byte, resp RPCResponse) {
Response: &commonpb.Response{},
}
if err != nil {
serviceDetailResp.Response.Err = err.Error()
if serviceDetail != nil {
// Then we had a non-fatal error
serviceDetailResp.Message = err.Error()
} else {
serviceDetailResp.Response.Err = err.Error()
}
}

data, err = proto.Marshal(serviceDetailResp)
Expand Down
71 changes: 13 additions & 58 deletions implant/sliver/service/service_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,18 +116,12 @@ func RemoveService(hostname string, serviceName string) error {
*/

func connectToServiceManager(hostname string, permissions uint32) (*mgr.Mgr, error) {
var connectHost *uint16

if hostname == "localhost" {
/*
According to Win32 API docs, if the machine name passed to OpenSCManager
is NULL or empty, a connection will be opened to the local machine
https://learn.microsoft.com/en-us/windows/win32/api/winsvc/nf-winsvc-openscmanagera
*/
connectHost = nil
} else {
connectHost = windows.StringToUTF16Ptr(hostname)
}
/*
According to Win32 API docs, if the machine name passed to OpenSCManager
is NULL or empty, a connection will be opened to the local machine
https://learn.microsoft.com/en-us/windows/win32/api/winsvc/nf-winsvc-openscmanagera
*/
connectHost := windows.StringToUTF16Ptr(hostname)
handle, err := windows.OpenSCManager(connectHost, nil, permissions)
if err != nil {
return nil, err
Expand All @@ -148,18 +142,11 @@ func buildServiceDetail(serviceName string, config mgr.Config) *sliverpb.Service

detail.DisplayName = config.DisplayName
detail.Description = config.Description
switch config.StartType {
case mgr.StartManual:
detail.StartupType = "Manual"
case mgr.StartAutomatic:
detail.StartupType = "Automatic"
case mgr.StartDisabled:
detail.StartupType = "Disabled"
}
detail.StartupType = config.StartType
detail.BinPath = config.BinaryPathName
detail.Account = config.ServiceStartName
// Will hopefully be filled in later
detail.Status = "Unknown"
detail.Status = 0

return detail
}
Expand Down Expand Up @@ -197,22 +184,7 @@ func ListServices(hostName string) ([]*sliverpb.ServiceDetails, error) {
servicesList = append(servicesList, serviceInfo)
continue
}
switch serviceStatus.State {
case svc.Stopped:
serviceInfo.Status = "Stopped"
case svc.StartPending:
serviceInfo.Status = "Start Pending"
case svc.StopPending:
serviceInfo.Status = "Stop Pending"
case svc.Running:
serviceInfo.Status = "Running"
case svc.ContinuePending:
serviceInfo.Status = "Continue Pending"
case svc.PausePending:
serviceInfo.Status = "Pause Pending"
case svc.Paused:
serviceInfo.Status = "Paused"
}
serviceInfo.Status = uint32(serviceStatus.State)
servicesList = append(servicesList, serviceInfo)
}

Expand Down Expand Up @@ -242,32 +214,15 @@ func GetServiceDetail(hostName string, serviceName string) (*sliverpb.ServiceDet
serviceDetail := buildServiceDetail(serviceName, serviceConfig)
serviceStatus, err := serviceHandle.Query()
if err != nil {
serviceDetail.Status = fmt.Sprintf("Unknown (could not retrieve: %s)", err.Error())
serviceDetail.Status = 0
// Even though we encountered an error, it was not fatal (we still got some information about the service)
return serviceDetail, nil
return serviceDetail, fmt.Errorf("Unknown (could not retrieve: %s)", err.Error())
}

switch serviceStatus.State {
case svc.Stopped:
serviceDetail.Status = "Stopped"
case svc.StartPending:
serviceDetail.Status = "Start Pending"
case svc.StopPending:
serviceDetail.Status = "Stop Pending"
case svc.Running:
serviceDetail.Status = "Running"
case svc.ContinuePending:
serviceDetail.Status = "Continue Pending"
case svc.PausePending:
serviceDetail.Status = "Pause Pending"
case svc.Paused:
serviceDetail.Status = "Paused"
}

serviceDetail.Status = uint32(serviceStatus.State)
return serviceDetail, nil
}

func StartExistingService(hostName string, serviceName string) error {
func StartServiceByName(hostName string, serviceName string) error {
manager, err := connectToServiceManager(hostName, ConnectServiceManagerPermissions)
if err != nil {
return err
Expand Down
Loading

0 comments on commit f50a1ed

Please sign in to comment.