Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix #714, Add process Architecture to the ps command #745

Merged
merged 1 commit into from
Jul 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 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 All @@ -134,8 +134,8 @@ func PrintPS(os string, ps *sliverpb.Ps, interactive bool, ctx *grumble.Context,
tw.AppendRow(row)
}
tw.SortBy([]table.SortBy{
{Name: "pid", Mode: table.Asc},
{Name: "ppid", Mode: table.Asc},
{Name: "pid", Mode: table.AscNumeric},
{Name: "ppid", Mode: table.AscNumeric},
})
if !interactive {
overflow = true
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
1 change: 1 addition & 0 deletions implant/sliver/handlers/rpc-handlers_windows.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.WindowsProcess).CmdLine()
p.SessionID = int32(proc.(*ps.WindowsProcess).SessionID())
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 := ""

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

Expand Down
38 changes: 38 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,38 @@ 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 "", err
}
_, err = f.Seek(0x12, 0)
if err != nil {
return "", err
}
mach := make([]byte, 2)
n, err := io.ReadAtLeast(f, mach, 2)

f.Close()

if err != nil || n < 2 {
return "", nil
}

if mach[0] == 0xb3 {
return "aarch64", nil
}
if mach[0] == 0x03 {
return "x86", nil
}
if mach[0] == 0x3e {
return "x86_64", nil
}
return "", 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 +213,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 isWow64 bool
if err := windows.IsWow64Process(windows.Handle(proc), &isWow64); err != nil {
arch = ""
} else {
if isWow64 {
arch = "x86"
} else {
arch = "x86_64"
}
}

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.

Loading