Skip to content

Commit

Permalink
fix #714, Add process Architecture to the ps command
Browse files Browse the repository at this point in the history
  • Loading branch information
timwr committed Jul 18, 2022
1 parent e6277fb commit a13d338
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 34 deletions.
10 changes: 7 additions & 3 deletions client/command/processes/ps.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,13 @@ func PrintPS(os string, ps *sliverpb.Ps, interactive bool, ctx *grumble.Context,

switch os {
case "windows":
tw.AppendHeader(table.Row{"pid", "ppid", "owner", "executable", "session"})
tw.AppendHeader(table.Row{"pid", "ppid", "owner", "arch", "executable", "session"})
case "darwin":
fallthrough
case "linux":
tw.AppendHeader(table.Row{"pid", "ppid", "owner", "executable"})
fallthrough
default:
tw.AppendHeader(table.Row{"pid", "ppid", "owner", "executable"})
tw.AppendHeader(table.Row{"pid", "ppid", "owner", "arch", "executable"})
}

cmdLine := ctx.Flags.Bool("print-cmdline")
Expand Down Expand Up @@ -182,6 +182,7 @@ func procRow(tw table.Writer, proc *commonpb.Process, cmdLine bool, con *console
fmt.Sprintf(color+"%d"+console.Normal, proc.Pid),
fmt.Sprintf(color+"%d"+console.Normal, proc.Ppid),
fmt.Sprintf(color+"%s"+console.Normal, proc.Owner),
fmt.Sprintf(color+"%s"+console.Normal, proc.Architecture),
fmt.Sprintf(color+"%s"+console.Normal, args),
fmt.Sprintf(color+"%d"+console.Normal, proc.SessionID),
}
Expand All @@ -190,6 +191,7 @@ func procRow(tw table.Writer, proc *commonpb.Process, cmdLine bool, con *console
fmt.Sprintf(color+"%d"+console.Normal, proc.Pid),
fmt.Sprintf(color+"%d"+console.Normal, proc.Ppid),
fmt.Sprintf(color+"%s"+console.Normal, proc.Owner),
fmt.Sprintf(color+"%s"+console.Normal, proc.Architecture),
fmt.Sprintf(color+"%s"+console.Normal, proc.Executable),
fmt.Sprintf(color+"%d"+console.Normal, proc.SessionID),
}
Expand All @@ -210,13 +212,15 @@ func procRow(tw table.Writer, proc *commonpb.Process, cmdLine bool, con *console
fmt.Sprintf(color+"%d"+console.Normal, proc.Pid),
fmt.Sprintf(color+"%d"+console.Normal, proc.Ppid),
fmt.Sprintf(color+"%s"+console.Normal, proc.Owner),
fmt.Sprintf(color+"%s"+console.Normal, proc.Architecture),
fmt.Sprintf(color+"%s"+console.Normal, args),
}
} else {
row = table.Row{
fmt.Sprintf(color+"%d"+console.Normal, proc.Pid),
fmt.Sprintf(color+"%d"+console.Normal, proc.Ppid),
fmt.Sprintf(color+"%s"+console.Normal, proc.Owner),
fmt.Sprintf(color+"%s"+console.Normal, proc.Architecture),
fmt.Sprintf(color+"%s"+console.Normal, proc.Executable),
}
}
Expand Down
1 change: 1 addition & 0 deletions implant/sliver/handlers/rpc-handlers_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ func psHandler(data []byte, resp RPCResponse) {
Ppid: int32(proc.PPid()),
Executable: proc.Executable(),
Owner: proc.Owner(),
Architecture: proc.Architecture(),
}
p.CmdLine = proc.(*ps.DarwinProcess).CmdLine()
psList.Processes = append(psList.Processes, p)
Expand Down
1 change: 1 addition & 0 deletions implant/sliver/handlers/rpc-handlers_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ func psHandler(data []byte, resp RPCResponse) {
Ppid: int32(proc.PPid()),
Executable: proc.Executable(),
Owner: proc.Owner(),
Architecture: proc.Architecture(),
}
p.CmdLine = proc.(*ps.UnixProcess).CmdLine()
psList.Processes = append(psList.Processes, p)
Expand Down
3 changes: 3 additions & 0 deletions implant/sliver/ps/ps.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ type Process interface {

// Owner is the account name of the process owner.
Owner() string

// Architecture is the architecture of the process.
Architecture() string
}

// Processes returns all processes.
Expand Down
7 changes: 7 additions & 0 deletions implant/sliver/ps/ps_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type DarwinProcess struct {
ppid int
binary string
owner string
arch string
cmdLine []string
}

Expand All @@ -42,6 +43,10 @@ func (p *DarwinProcess) CmdLine() []string {
return p.cmdLine
}

func (p *DarwinProcess) Architecture() []string {
return p.arch
}

func findProcess(pid int) (Process, error) {
ps, err := processes()
if err != nil {
Expand Down Expand Up @@ -98,13 +103,15 @@ func processes() ([]Process, error) {
if owner == "" {
owner = uid
}
arch := "amd64"

darwinProcs[i] = &DarwinProcess{
pid: int(p.Proc.P_pid),
ppid: int(p.Eproc.Ppid),
binary: binPath,
owner: owner,
cmdLine: cmdLine,
arch: arch,
}
}

Expand Down
34 changes: 34 additions & 0 deletions implant/sliver/ps/ps_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type UnixProcess struct {
state rune
pgrp int
sid int
arch string
cmdLine []string

binary string
Expand Down Expand Up @@ -51,6 +52,10 @@ func (p *UnixProcess) CmdLine() []string {
return p.cmdLine
}

func (p *UnixProcess) Architecture() string {
return p.arch
}

func getProcessOwnerUid(pid int) (uint32, error) {
filename := fmt.Sprintf("/proc/%d/task", pid)
f, err := os.Open(filename)
Expand Down Expand Up @@ -89,6 +94,34 @@ func getProcessCmdLine(pid int) ([]string, error) {
return argv, nil
}

func getProcessArchitecture(pid int) (string, error) {
exePath := fmt.Sprintf("/proc/%d/exe", pid)

f, err := os.Open(exePath)
if err != nil {
return "Unknown", err
}
_, err = f.Seek(0x12, 0)
if err != nil {
return "Unknown", err
}
mach := make([]byte, 2)
_, err = io.ReadAtLeast(f, mach, 2)

f.Close()

if mach[0] == 0xb3 {
return "aarch64", nil
}
if mach[0] == 0x03 {
return "x86", nil
}
if mach[0] == 0x3e {
return "amd64", nil
}
return "Unknown", err
}

// Refresh reloads all the data associated with this process.
func (p *UnixProcess) Refresh() error {
statPath := fmt.Sprintf("/proc/%d/stat", p.pid)
Expand Down Expand Up @@ -176,6 +209,7 @@ func processes() ([]Process, error) {
p.binary = argv[0]
}
}
p.arch, err = getProcessArchitecture(int(pid))
results = append(results, p)
}
}
Expand Down
41 changes: 30 additions & 11 deletions implant/sliver/ps/ps_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type WindowsProcess struct {
ppid int
exe string
owner string
arch string
cmdLine []string
sessionID int
}
Expand All @@ -38,6 +39,10 @@ func (p *WindowsProcess) Owner() string {
return p.owner
}

func (p *WindowsProcess) Architecture() string {
return p.arch
}

func (p *WindowsProcess) CmdLine() []string {
return p.cmdLine
}
Expand All @@ -57,14 +62,15 @@ func newWindowsProcess(e *syscall.ProcessEntry32) *WindowsProcess {
}
account, _ := getProcessOwner(e.ProcessID)
sessionID, _ := getSessionID(e.ProcessID)
cmdLine, _ := getCmdLine(e.ProcessID)
cmdLine, arch, _ := getProcessInfo(e.ProcessID)

return &WindowsProcess{
pid: int(e.ProcessID),
ppid: int(e.ParentProcessID),
exe: syscall.UTF16ToString(e.ExeFile[:end]),
owner: account,
cmdLine: cmdLine,
arch: arch,
sessionID: sessionID,
}
}
Expand Down Expand Up @@ -167,17 +173,17 @@ func main() {
fmt.Println(uintptrToBytes(&u))
}

func getCmdLine(pid uint32) ([]string, error) {
func getProcessInfo(pid uint32) ([]string, string, error) {
handle, err := syscall.CreateToolhelp32Snapshot(syscall.TH32CS_SNAPMODULE, pid)
if err != nil {
return []string{}, err
return []string{}, "", err
}
defer syscall.CloseHandle(handle)

var module syscalls.MODULEENTRY32W
module.DwSize = uint32(unsafe.Sizeof(module))
if err = syscalls.Module32FirstW(windows.Handle(handle), &module); err != nil {
return []string{}, err
return []string{}, "", err
}

proc, err := syscall.OpenProcess(
Expand All @@ -186,7 +192,7 @@ func getCmdLine(pid uint32) ([]string, error) {
pid,
)
if err != nil {
return strings.Fields(syscall.UTF16ToString(module.SzExePath[:])), err
return strings.Fields(syscall.UTF16ToString(module.SzExePath[:])), "", err
}

var info windows.PROCESS_BASIC_INFORMATION
Expand All @@ -198,7 +204,7 @@ func getCmdLine(pid uint32) ([]string, error) {
nil,
)
if err != nil {
return strings.Fields(syscall.UTF16ToString(module.SzExePath[:])), err
return strings.Fields(syscall.UTF16ToString(module.SzExePath[:])), "", err
}

var peb windows.PEB
Expand All @@ -210,7 +216,7 @@ func getCmdLine(pid uint32) ([]string, error) {
nil,
)
if err != nil {
return strings.Fields(syscall.UTF16ToString(module.SzExePath[:])), err
return strings.Fields(syscall.UTF16ToString(module.SzExePath[:])), "", err
}

var params windows.RTL_USER_PROCESS_PARAMETERS
Expand All @@ -222,7 +228,7 @@ func getCmdLine(pid uint32) ([]string, error) {
nil,
)
if err != nil {
return strings.Fields(syscall.UTF16ToString(module.SzExePath[:])), err
return strings.Fields(syscall.UTF16ToString(module.SzExePath[:])), "", err
}

var cmdLine []uint16 = make([]uint16, params.CommandLine.Length)
Expand All @@ -234,15 +240,28 @@ func getCmdLine(pid uint32) ([]string, error) {
nil,
)
if err != nil {
return strings.Fields(syscall.UTF16ToString(module.SzExePath[:])), err
return strings.Fields(syscall.UTF16ToString(module.SzExePath[:])), "", err
}


var arch string
var is64Bit bool
if err := windows.IsWow64Process(proc, &is64Bit); err != nil {
arch = "Unknown"
} else {
if !is64Bit {
arch = "x86"
} else {
arch = "amd64"
}
}

err = syscall.CloseHandle(proc)
if err != nil {
return strings.Fields(syscall.UTF16ToString(module.SzExePath[:])), err
return strings.Fields(syscall.UTF16ToString(module.SzExePath[:])), "", err
}

return strings.Fields(syscall.UTF16ToString(module.SzExePath[:]) + " : " + syscall.UTF16ToString(cmdLine[:])), nil
return strings.Fields(syscall.UTF16ToString(module.SzExePath[:]) + " : " + syscall.UTF16ToString(cmdLine[:])), arch, nil
}

func getSessionID(pid uint32) (int, error) {
Expand Down
46 changes: 28 additions & 18 deletions protobuf/commonpb/common.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions protobuf/commonpb/common.proto
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ message Process {
int32 Ppid = 2;
string Executable = 3;
string Owner = 4;
int32 SessionID = 5;
repeated string CmdLine = 6;
string Architecture = 5;
int32 SessionID = 6;
repeated string CmdLine = 7;
}

// EnvVar - Environment variable K/V
Expand Down

0 comments on commit a13d338

Please sign in to comment.