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

Kill Tracee incase of a leak #81

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
15 changes: 15 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@
"time"
"unsafe"

"github.com/hlandau/dexlogconfig"

Check failure on line 49 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L49

import 'github.com/hlandau/dexlogconfig' is not allowed from list 'Main' (depguard)

Check failure on line 49 in main.go

View check run for this annotation

Cirrus CI / Go Lint Mandatory

main.go#L49

import 'github.com/hlandau/dexlogconfig' is not allowed from list 'Main' (depguard)
"github.com/hlandau/xlog"

Check failure on line 50 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L50

import 'github.com/hlandau/xlog' is not allowed from list 'Main' (depguard)

Check failure on line 50 in main.go

View check run for this annotation

Cirrus CI / Go Lint Mandatory

main.go#L50

import 'github.com/hlandau/xlog' is not allowed from list 'Main' (depguard)
"github.com/oraoto/go-pidfd"

Check failure on line 51 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L51

import 'github.com/oraoto/go-pidfd' is not allowed from list 'Main' (depguard)

Check failure on line 51 in main.go

View check run for this annotation

Cirrus CI / Go Lint Mandatory

main.go#L51

import 'github.com/oraoto/go-pidfd' is not allowed from list 'Main' (depguard)
"github.com/robertmin1/heteronculous-horklump/httpproxy"

Check failure on line 52 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L52

import 'github.com/robertmin1/heteronculous-horklump/httpproxy' is not allowed from list 'Main' (depguard)

Check failure on line 52 in main.go

View check run for this annotation

Cirrus CI / Go Lint Mandatory

main.go#L52

import 'github.com/robertmin1/heteronculous-horklump/httpproxy' is not allowed from list 'Main' (depguard)
"github.com/robertmin1/socks5/v4"

Check failure on line 53 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L53

import 'github.com/robertmin1/socks5/v4' is not allowed from list 'Main' (depguard)

Check failure on line 53 in main.go

View check run for this annotation

Cirrus CI / Go Lint Mandatory

main.go#L53

import 'github.com/robertmin1/socks5/v4' is not allowed from list 'Main' (depguard)
"github.com/u-root/u-root/pkg/strace"

Check failure on line 54 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L54

import 'github.com/u-root/u-root/pkg/strace' is not allowed from list 'Main' (depguard)

Check failure on line 54 in main.go

View check run for this annotation

Cirrus CI / Go Lint Mandatory

main.go#L54

import 'github.com/u-root/u-root/pkg/strace' is not allowed from list 'Main' (depguard)
"golang.org/x/sys/unix"
"gopkg.in/hlandau/easyconfig.v1"
)
Expand All @@ -70,18 +70,19 @@
var exitAddr sync.Map

// Config is a struct to store the program's configuration values.
type Config struct { //nolint

Check failure on line 73 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L73

directive `//nolint` is unused (nolintlint)

Check failure on line 73 in main.go

View check run for this annotation

Cirrus CI / Go Lint Mandatory

main.go#L73

directive `//nolint` is unused (nolintlint)
Program string `usage:"Program Name"`
SocksTCP string `default:"127.0.0.1:9050"`
Args []string `usage:"Program Arguments"`
KillProg bool `default:"false" usage:"Kill the Program in case of a Proxy Leak (bool)"`

Check failure on line 77 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L77

tag is not aligned, should be: default:"false" usage:"Kill the Program in case of a Proxy Leak (bool)" (tagalign)

Check failure on line 77 in main.go

View check run for this annotation

Cirrus CI / Go Lint Mandatory

main.go#L77

tag is not aligned, should be: default:"false" usage:"Kill the Program in case of a Proxy Leak (bool)" (tagalign)
KillTracee bool `default:"false" usage:"Kill only the specific tracee causing the leak (bool)"`

Check failure on line 78 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L78

tag is not aligned, should be: default:"false" usage:"Kill only the specific tracee causing the leak (bool)" (tagalign)

Check failure on line 78 in main.go

View check run for this annotation

Cirrus CI / Go Lint Mandatory

main.go#L78

tag is not aligned, should be: default:"false" usage:"Kill only the specific tracee causing the leak (bool)" (tagalign)
LogLeaks bool `default:"false" usage:"Allow Proxy Leaks but Log any that Occur (bool)"`

Check failure on line 79 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L79

tag is not aligned, should be: default:"false" usage:"Allow Proxy Leaks but Log any that Occur (bool)" (tagalign)

Check failure on line 79 in main.go

View check run for this annotation

Cirrus CI / Go Lint Mandatory

main.go#L79

tag is not aligned, should be: default:"false" usage:"Allow Proxy Leaks but Log any that Occur (bool)" (tagalign)
EnvVar bool `default:"true" usage:"Use the Environment Vars TOR_SOCKS_HOST and TOR_SOCKS_PORT (bool)"`

Check failure on line 80 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L80

tag is not aligned, should be: default:"true" usage:"Use the Environment Vars TOR_SOCKS_HOST and TOR_SOCKS_PORT (bool)" (tagalign)

Check failure on line 80 in main.go

View check run for this annotation

Cirrus CI / Go Lint Mandatory

main.go#L80

tag is not aligned, should be: default:"true" usage:"Use the Environment Vars TOR_SOCKS_HOST and TOR_SOCKS_PORT (bool)" (tagalign)
Redirect string `default:"socks5" usage:"Incase of leak redirect to the desired proxy(socks5,http,trans)"`

Check failure on line 81 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L81

tag is not aligned, should be: default:"socks5" usage:"Incase of leak redirect to the desired proxy(socks5,http,trans)" (tagalign)

Check failure on line 81 in main.go

View check run for this annotation

Cirrus CI / Go Lint Mandatory

main.go#L81

tag is not aligned, should be: default:"socks5" usage:"Incase of leak redirect to the desired proxy(socks5,http,trans)" (tagalign)
Proxyuser string `default:"" usage:"Proxy username in case of proxy redirection"`

Check failure on line 82 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L82

tag is not aligned, should be: default:"" usage:"Proxy username in case of proxy redirection" (tagalign)

Check failure on line 82 in main.go

View check run for this annotation

Cirrus CI / Go Lint Mandatory

main.go#L82

tag is not aligned, should be: default:"" usage:"Proxy username in case of proxy redirection" (tagalign)
Proxypass string `default:"" usage:"Proxy password in case of proxy redirection"`

Check failure on line 83 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L83

tag is not aligned, should be: default:"" usage:"Proxy password in case of proxy redirection" (tagalign)

Check failure on line 83 in main.go

View check run for this annotation

Cirrus CI / Go Lint Mandatory

main.go#L83

tag is not aligned, should be: default:"" usage:"Proxy password in case of proxy redirection" (tagalign)
OneCircuit bool `default:"false" usage:"Disable random SOCKS behavior"`

Check failure on line 84 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L84

tag is not aligned, should be: default:"false" usage:"Disable random SOCKS behavior" (tagalign)

Check failure on line 84 in main.go

View check run for this annotation

Cirrus CI / Go Lint Mandatory

main.go#L84

tag is not aligned, should be: default:"false" usage:"Disable random SOCKS behavior" (tagalign)
WhitelistLoopback bool `default:"false" usage:"Whitelist outgoing IP connections to loopback addresses (e.g. 127.0.0.1)"` //nolint:lll

Check failure on line 85 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L85

tag is not aligned, should be: default:"false" usage:"Whitelist outgoing IP connections to loopback addresses (e.g. 127.0.0.1)" (tagalign)

Check failure on line 85 in main.go

View check run for this annotation

Cirrus CI / Go Lint Mandatory

main.go#L85

tag is not aligned, should be: default:"false" usage:"Whitelist outgoing IP connections to loopback addresses (e.g. 127.0.0.1)" (tagalign)
}

// FullAddress is the network address and port
Expand All @@ -103,7 +104,7 @@
Port uint16
}

func main() {

Check failure on line 107 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L107

calculated cyclomatic complexity for function main is 14, max is 10 (cyclop)
// Create a Config and initialize it with default values.
cfg := Config{}
config := easyconfig.Configurator{
Expand Down Expand Up @@ -138,7 +139,7 @@
}

// Start the program with tracing and handle the CONNECT system call events.
if err := strace.Trace(program, func(t strace.Task, record *strace.TraceRecord) error {

Check failure on line 142 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L142

parameter name 't' is too short for the scope of its usage (varnamelen)
if record.Event == strace.SyscallEnter && record.Syscall.Sysno == unix.SYS_CONNECT {
if err := HandleConnect(t, record, program, cfg); err != nil {
return err
Expand Down Expand Up @@ -204,6 +205,11 @@

return nil
}
if cfg.KillTracee {
KillTracee(record.PID)

Check failure on line 209 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L209

Error return value is not checked (errcheck)

Check failure on line 209 in main.go

View check run for this annotation

Cirrus CI / Go Lint Mandatory

main.go#L209

Error return value is not checked (errcheck)

return nil
}
if cfg.KillProg {
KillApp(program, IPPort)

Expand All @@ -218,7 +224,7 @@
}

return nil
// TODO: handle invalid flag

Check failure on line 227 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L227

main.go:227: Line contains TODO/BUG/FIXME: "TODO: handle invalid flag" (godox)
// Incase trans proxy will require a different implementation a switch will be used.
}

Expand All @@ -233,7 +239,7 @@

// eventName returns an event name. There should never be an event name
// we do not known and, if we encounter one, we panic.
func eventName(r *strace.TraceRecord) (string, error) { //nolint

Check failure on line 242 in main.go

View check run for this annotation

Cirrus CI / Go Lint Mandatory

main.go#L242

directive `//nolint` is unused (nolintlint)
// form up a reasonable name for a system call.
// If there is no name, then it will be Exxxx or Xxxxx, where x
// is the system call number as %04x.
Expand All @@ -254,16 +260,16 @@
case strace.SyscallExit:
return sysName, nil
case strace.SignalExit:
return fmt.Sprintf("SignalExit"), nil

Check failure on line 263 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L263

S1039: unnecessary use of fmt.Sprintf (gosimple)

Check failure on line 263 in main.go

View check run for this annotation

Cirrus CI / Go Lint Mandatory

main.go#L263

fmt.Sprintf can be replaced with just using the string (perfsprint)
case strace.Exit:
return fmt.Sprintf("Exit"), nil

Check failure on line 265 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L265

S1039: unnecessary use of fmt.Sprintf (gosimple)

Check failure on line 265 in main.go

View check run for this annotation

Cirrus CI / Go Lint Mandatory

main.go#L265

fmt.Sprintf can be replaced with just using the string (perfsprint)
case strace.SignalStop:
return fmt.Sprintf("SignalStop"), nil

Check failure on line 267 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L267

S1039: unnecessary use of fmt.Sprintf (gosimple)

Check failure on line 267 in main.go

View check run for this annotation

Cirrus CI / Go Lint Mandatory

main.go#L267

fmt.Sprintf can be replaced with just using the string (perfsprint)
case strace.NewChild:
return fmt.Sprintf("NewChild"), nil
}

return "", fmt.Errorf("unknown event %#x from record %v", r.Event, r)

Check failure on line 272 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L272

do not define dynamic errors, use wrapped static errors instead: "fmt.Errorf(\"unknown event %#x from record %v\", r.Event, r)" (err113)
}

// ParseAddress reads an sockaddr struct from the given address and converts it
Expand Down Expand Up @@ -347,7 +353,7 @@
// out.NIC = NICID(a.Scope_id)
//}

if out.Addr == strings.Repeat(nullByte, 16) {

Check failure on line 356 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L356

Magic number: 16, in <argument> detected (gomnd)

Check failure on line 356 in main.go

View check run for this annotation

Cirrus CI / Go Lint Mandatory

main.go#L356

Magic number: 16, in <argument> detected (mnd)
out.Addr = ""
}

Expand All @@ -371,6 +377,15 @@
log.Warnf("Proxy Leak Detected : %v. Killing the Application.", iPPort)
}

// KillTracee kills the specific tracee process causing the leak.
func KillTracee(traceePID int) error {
if err := syscall.Kill(traceePID, syscall.SIGKILL); err != nil {
return fmt.Errorf("failed to kill tracee PID %d: %w", traceePID, err)
}
log.Infof("Killed tracee PID: %d due to a proxy leak.", traceePID)
return nil

Check failure on line 386 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L386

return with no blank line before (nlreturn)

Check failure on line 386 in main.go

View check run for this annotation

Cirrus CI / Go Lint Mandatory

main.go#L386

return with no blank line before (nlreturn)
}

// Setting environment variables.
func SetEnv(cfg Config) string {
host, port := os.Getenv("TOR_SOCKS_HOST"), os.Getenv("TOR_SOCKS_PORT")
Expand Down Expand Up @@ -462,7 +477,7 @@
case parsedhost.To4()[0] == UDPProtolNum:
log.Error("Support for UDP will be implemented")
default:
return errors.New("invalid ip address")

Check failure on line 480 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L480

do not define dynamic errors, use wrapped static errors instead: "errors.New(\"invalid ip address\")" (err113)
}

// Poking our proxy IP/Port to the address containing the original address
Expand All @@ -475,7 +490,7 @@
return nil
}

func Socksify(args strace.SyscallArguments, record *strace.TraceRecord, t strace.Task, cfg Config) error {

Check failure on line 493 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L493

unused-parameter: parameter 'args' seems to be unused, consider removing or renaming it as _ (revive)
username, password := cfg.Proxyuser, cfg.Proxypass

if !cfg.OneCircuit {
Expand All @@ -491,7 +506,7 @@

addr, _ := exitAddr.LoadAndDelete(record.PID)
IPPort := fmt.Sprintf("%v", addr)
fd := record.Syscall.Args[0].Uint()

Check failure on line 509 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L509

variable name 'fd' is too short for the scope of its usage (varnamelen)

p, err := pidfd.Open(record.PID, 0)
if err != nil {
Expand All @@ -512,9 +527,9 @@

switch cfg.Redirect {
case "socks5":
cl, err := socks5.NewClient(IPPort, username, password, 10, 10)

Check failure on line 530 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L530

Magic number: 10, in <argument> detected (gomnd)

Check failure on line 530 in main.go

View check run for this annotation

Cirrus CI / Go Lint Mandatory

main.go#L530

Magic number: 10, in <argument> detected (mnd)
if err != nil {
return err

Check failure on line 532 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L532

error returned from external package is unwrapped: sig: func github.com/robertmin1/socks5/v4.NewClient(addr string, username string, password string, tcpTimeout int, udpTimeout int) (*github.com/robertmin1/socks5/v4.Client, error) (wrapcheck)
}

_, err = cl.Dial("tcp", IPPort, conn)
Expand All @@ -525,12 +540,12 @@
case "http":
cl, err := httpproxy.NewClient(cfg.SocksTCP, username, password)
if err != nil {
return err

Check failure on line 543 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L543

error returned from external package is unwrapped: sig: func github.com/robertmin1/heteronculous-horklump/httpproxy.NewClient(addr string, username string, password string) (*github.com/robertmin1/heteronculous-horklump/httpproxy.HTTPDialer, error) (wrapcheck)
}

_, err = cl.Dial("tcp", IPPort, conn)
if err != nil {
return err

Check failure on line 548 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L548

error returned from external package is unwrapped: sig: func (*github.com/robertmin1/heteronculous-horklump/httpproxy.HTTPDialer).Dial(network string, addr string, httpconn net.Conn) (net.Conn, error) (wrapcheck)
}
}

Expand All @@ -541,7 +556,7 @@
// Create or open the log file in append mode
logFile, err := os.OpenFile("stack_trace.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) //nolint
if err != nil {
return err

Check failure on line 559 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L559

error returned from external package is unwrapped: sig: func os.OpenFile(name string, flag int, perm io/fs.FileMode) (*os.File, error) (wrapcheck)
}

defer logFile.Close()
Expand All @@ -552,7 +567,7 @@

commBytes, err := os.ReadFile(commPath)
if err != nil {
return err

Check failure on line 570 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L570

error returned from external package is unwrapped: sig: func os.ReadFile(name string) ([]byte, error) (wrapcheck)
}
// Split the contents by null byte to separate command and arguments
cmdline := strings.Split(string(commBytes), "\x00")
Expand All @@ -566,7 +581,7 @@
go_log.Printf("Program and Arguments:%v\n", cmdline)

// Get the stack trace
stack := make([]byte, 8192)

Check failure on line 584 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L584

Magic number: 8192, in <argument> detected (gomnd)

Check failure on line 584 in main.go

View check run for this annotation

Cirrus CI / Go Lint Mandatory

main.go#L584

Magic number: 8192, in <argument> detected (mnd)
length := runtime.Stack(stack, true)

// Write the stack trace to the log file
Expand All @@ -589,16 +604,16 @@
}

func GenerateRandomCredentials() (string, error) {
bytes := make([]byte, 48)

Check failure on line 607 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L607

Magic number: 48, in <argument> detected (gomnd)

Check failure on line 607 in main.go

View check run for this annotation

Cirrus CI / Go Lint Mandatory

main.go#L607

Magic number: 48, in <argument> detected (mnd)
if _, err := rand.Read(bytes); err != nil {
return "", err

Check failure on line 609 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L609

error returned from external package is unwrapped: sig: func crypto/rand.Read(b []byte) (n int, err error) (wrapcheck)
}

return hex.EncodeToString(bytes), nil
}

func initializeAuthData() {
for i := 0; i < 10; i++ {

Check failure on line 616 in main.go

View check run for this annotation

Cirrus CI / Go Lint

main.go#L616

for loop can be changed to use an integer range (Go 1.22+) (intrange)

Check failure on line 616 in main.go

View check run for this annotation

Cirrus CI / Go Lint Mandatory

main.go#L616

for loop can be changed to use an integer range (Go 1.22+) (intrange)
username, _ := GenerateRandomCredentials()
password, _ := GenerateRandomCredentials()
authData = append(authData, struct {
Expand Down
Loading