├── demo1.gif ├── demo2.gif ├── .gitignore ├── README.md ├── LICENSE ├── renamepid.go └── renameeverything.go /demo1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benjojo/upsetsysadmins/HEAD/demo1.gif -------------------------------------------------------------------------------- /demo2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benjojo/upsetsysadmins/HEAD/demo2.gif -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.test 24 | *.prof 25 | 26 | renameeverything 27 | renamepid 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # upsetsysadmins 2 | A tool that will really upset your sysadmin 3 | 4 | This is a tool that can rename a process so that it appears to be something else when you look in "ps" than it really is. 5 | 6 | ## Disclaimer 7 | 8 | Don't run this on things you don't want to get totally broken. This tool 9 | performs process memory modifications and may not get it right, corrupting 10 | the process. Thus the `renameeverything.go` really is as bad of a idea as 11 | it sounds. 12 | 13 | ## Demos 14 | 15 | ![demo1](demo1.gif) 16 | 17 | ![demo2](demo2.gif) 18 | 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Ben Cox 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of upsetsysadmins nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | -------------------------------------------------------------------------------- /renamepid.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "io/ioutil" 7 | "log" 8 | "os" 9 | "strconv" 10 | "strings" 11 | "syscall" 12 | ) 13 | 14 | func main() { 15 | tpid := flag.Int("pid", 0, "the pid you want to fuck with") 16 | tname := flag.String("rename", "", "the name you want it to be called") 17 | flag.Parse() 18 | 19 | if *tpid == 0 || *tname == "" { 20 | flag.Usage() // RTFM 21 | os.Exit(1) 22 | } 23 | 24 | StackLocation := FindStack(*tpid) 25 | 26 | if StackLocation == "" { 27 | log.Fatal("Unable to find stack. this shouldnt happen.") 28 | } 29 | 30 | log.Printf("Found stack at %s", StackLocation) 31 | 32 | cmdline := GetCmdLine(*tpid) 33 | offset := GetRamOffset(*tpid, StackLocation, cmdline) 34 | 35 | data := []byte(fmt.Sprint(*tname)) 36 | data = append(data, 0x00) 37 | 38 | eh, _ := os.FindProcess(*tpid) 39 | 40 | err := syscall.PtraceAttach(eh.Pid) 41 | 42 | if err != nil { 43 | log.Fatalf("Could not attach to the PID. Why? %s", err) 44 | } 45 | 46 | _, err = syscall.PtracePokeData(eh.Pid, uintptr(offset), data) 47 | 48 | if err != nil { 49 | log.Fatalf("now I've fucked up! %s is the error", err) 50 | } 51 | 52 | // fmt.Printf("No idea what it means, but here is 'c' : %d", c) 53 | 54 | err = syscall.PtraceDetach(eh.Pid) 55 | 56 | if err != nil { 57 | log.Fatalf("Unable to detach?? Why? %s", err) 58 | } 59 | 60 | err = syscall.Kill(eh.Pid, syscall.SIGCONT) 61 | 62 | if err != nil { 63 | log.Fatalf("Unable to detach?? Why? %s", err) 64 | } 65 | 66 | } 67 | 68 | func GetOffsets(stackrange string) (start uint64, end uint64) { 69 | bits := strings.Split(stackrange, "-") 70 | start, err := strconv.ParseUint(bits[0], 16, 64) 71 | if err != nil { 72 | log.Fatalf("failed to decode hex info on map, this should not happen") 73 | } 74 | 75 | end, err = strconv.ParseUint(bits[1], 16, 64) 76 | if err != nil { 77 | log.Fatalf("failed to decode hex info on map, this should not happen") 78 | } 79 | 80 | return start, end 81 | } 82 | 83 | func GetRamOffset(pid int, stackrange, cmdline string) int { 84 | file, err := os.Open(fmt.Sprintf("/proc/%d/mem", pid)) 85 | 86 | if err != nil { 87 | log.Fatalf("Unable to access the memory of that PID, possibly due to permissions? '%s'", err) 88 | } 89 | 90 | start, end := GetOffsets(stackrange) 91 | 92 | log.Printf("Reading from %d to %d bytes", start, end) 93 | 94 | stack := make([]byte, end-start) 95 | 96 | file.Seek(int64(start), 0) 97 | 98 | n, err := file.Read(stack) 99 | 100 | if err != nil { 101 | log.Printf("uwot %d", n) 102 | } 103 | 104 | ptr := strings.LastIndex(string(stack), cmdline) 105 | 106 | file.Close() 107 | 108 | return ptr + int(start) 109 | } 110 | 111 | func GetCmdLine(pid int) string { 112 | cmdline, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cmdline", pid)) 113 | 114 | if err != nil { 115 | log.Fatalf("Unable to access the memory map of that PID, possibly due to permissions? '%s'", err) 116 | } 117 | 118 | return string(cmdline) 119 | } 120 | 121 | func FindStack(pid int) string { 122 | mapdata, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/maps", pid)) 123 | 124 | if err != nil { 125 | log.Fatalf("Unable to access the memory map of that PID, possibly due to permissions? '%s'", err) 126 | } 127 | 128 | lines := strings.Split(string(mapdata), "\n") 129 | 130 | for _, v := range lines { 131 | if strings.Contains(v, "[stack]") { 132 | bits := strings.Split(v, " ") 133 | return bits[0] 134 | } 135 | } 136 | 137 | return "" 138 | } 139 | -------------------------------------------------------------------------------- /renameeverything.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "fmt" 6 | "io/ioutil" 7 | "log" 8 | "os" 9 | "strconv" 10 | "strings" 11 | "syscall" 12 | ) 13 | 14 | func main() { 15 | tname := flag.String("rename", "", "the name you want everything to be called") 16 | spareinit := flag.Bool("spareinit", false, "Enable for systems that do not allow init to be touched") 17 | flag.Parse() 18 | 19 | if *tname == "" { 20 | flag.Usage() // RTFM 21 | os.Exit(1) 22 | } 23 | 24 | pids := GetPids(*spareinit) 25 | 26 | for _, pid := range pids { 27 | AggressiveRename(pid, *tname) 28 | } 29 | } 30 | 31 | func AggressiveRename(pid int, tname string) { 32 | attempts := 0 33 | for { 34 | RenamePid(pid, tname) 35 | if strings.HasPrefix(GetCmdLine(pid), tname) { 36 | break 37 | } 38 | attempts++ 39 | if attempts == 10 { 40 | break 41 | } 42 | } 43 | } 44 | 45 | func GetPids(avoidinit bool) []int { 46 | 47 | files, err := ioutil.ReadDir("/proc") 48 | 49 | if err != nil { 50 | log.Fatalf("Okay something is really fucked if I can't read proc | %s", err) 51 | } 52 | 53 | pids := make([]int, 0) 54 | 55 | for _, v := range files { 56 | if v.IsDir() { 57 | if v.Name() == "1" && avoidinit { 58 | continue 59 | } 60 | 61 | i, err := strconv.ParseInt(v.Name(), 10, 64) 62 | if err == nil { 63 | pids = append(pids, int(i)) 64 | } 65 | } 66 | } 67 | 68 | return pids 69 | } 70 | 71 | func RenamePid(tpid int, tname string) { 72 | log.Printf("Attempting to rename pid %d to %s", tpid, tname) 73 | StackLocation := FindStack(tpid) 74 | 75 | if StackLocation == "" { 76 | log.Printf("Unable to find stack. this shouldnt happen.") 77 | return 78 | } 79 | 80 | cmdline := GetCmdLine(tpid) 81 | offset := GetRamOffset(tpid, StackLocation, cmdline) 82 | 83 | data := []byte(fmt.Sprint(tname)) 84 | data = append(data, 0x00) 85 | 86 | eh, _ := os.FindProcess(tpid) 87 | 88 | err := syscall.PtraceAttach(eh.Pid) 89 | 90 | if err != nil { 91 | log.Printf("Could not attach to the PID. Why? %s", err) 92 | return 93 | } 94 | 95 | _, err = syscall.PtracePokeData(eh.Pid, uintptr(offset), data) 96 | 97 | if err != nil { 98 | log.Printf("now I've fucked up! %s is the error", err) 99 | return 100 | } 101 | 102 | // fmt.Printf("No idea what it means, but here is 'c' : %d", c) 103 | 104 | err = syscall.PtraceDetach(eh.Pid) 105 | 106 | if err != nil { 107 | log.Printf("Unable to detach?? Why? %s", err) 108 | return 109 | } 110 | 111 | err = syscall.Kill(eh.Pid, syscall.SIGCONT) 112 | 113 | if err != nil { 114 | log.Printf("Unable to detach?? Why? %s", err) 115 | return 116 | } 117 | } 118 | 119 | func GetOffsets(stackrange string) (start uint64, end uint64) { 120 | bits := strings.Split(stackrange, "-") 121 | start, err := strconv.ParseUint(bits[0], 16, 64) 122 | if err != nil { 123 | log.Fatalf("failed to decode hex info on map, this should not happen") 124 | return 125 | } 126 | 127 | end, err = strconv.ParseUint(bits[1], 16, 64) 128 | if err != nil { 129 | log.Fatalf("failed to decode hex info on map, this should not happen") 130 | return 131 | } 132 | 133 | return start, end 134 | } 135 | 136 | func GetRamOffset(pid int, stackrange, cmdline string) int { 137 | file, err := os.Open(fmt.Sprintf("/proc/%d/mem", pid)) 138 | 139 | if err != nil { 140 | log.Fatalf("Unable to access the memory of that PID, possibly due to permissions? '%s'", err) 141 | } 142 | 143 | start, end := GetOffsets(stackrange) 144 | 145 | stack := make([]byte, end-start) 146 | 147 | file.Seek(int64(start), 0) 148 | 149 | n, err := file.Read(stack) 150 | 151 | if err != nil { 152 | log.Printf("uwot %d", n) 153 | } 154 | 155 | ptr := strings.LastIndex(string(stack), cmdline) 156 | 157 | file.Close() 158 | 159 | return ptr + int(start) 160 | } 161 | 162 | func GetCmdLine(pid int) string { 163 | cmdline, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cmdline", pid)) 164 | 165 | if err != nil { 166 | log.Fatalf("Unable to access the memory map of that PID, possibly due to permissions? '%s'", err) 167 | } 168 | 169 | return string(cmdline) 170 | } 171 | 172 | func FindStack(pid int) string { 173 | mapdata, err := ioutil.ReadFile(fmt.Sprintf("/proc/%d/maps", pid)) 174 | 175 | if err != nil { 176 | log.Fatalf("Unable to access the memory map of that PID, possibly due to permissions? '%s'", err) 177 | } 178 | 179 | lines := strings.Split(string(mapdata), "\n") 180 | 181 | for _, v := range lines { 182 | if strings.Contains(v, "[stack]") { 183 | bits := strings.Split(v, " ") 184 | return bits[0] 185 | } 186 | } 187 | 188 | return "" 189 | } 190 | --------------------------------------------------------------------------------