forked from vulncheck-oss/go-exploit
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbasic.go
More file actions
84 lines (75 loc) · 1.99 KB
/
basic.go
File metadata and controls
84 lines (75 loc) · 1.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package cli
import (
"bufio"
"net"
"os"
"strings"
"sync"
"time"
"github.com/vulncheck-oss/go-exploit/output"
"github.com/vulncheck-oss/go-exploit/protocol"
)
// A very basic reverse/bind shell handler.
func Basic(conn net.Conn) {
// Create channels for communication between goroutines.
responseCh := make(chan string)
quit := make(chan struct{})
// Use a WaitGroup to wait for goroutines to finish.
var wg sync.WaitGroup
// Goroutine to read responses from the server.
wg.Add(1)
go func() {
defer wg.Done()
responseBuffer := make([]byte, 1024)
for {
select {
case <-quit:
return
default:
_ = conn.SetReadDeadline(time.Now().Add(1 * time.Second))
bytesRead, err := conn.Read(responseBuffer)
if err != nil && !strings.Contains(err.Error(), "i/o timeout") {
// things have gone sideways, but the command line won't know that
// until they attempt to execute a command and the socket fails.
// i think that's largely okay.
return
}
if bytesRead > 0 {
// I think there is technically a race condition here where the socket
// could have move data to write, but the user has already called exit
// below. I that that's tolerable for now.
responseCh <- string(responseBuffer[:bytesRead])
}
}
}
}()
// Goroutine to handle responses and print them.
wg.Add(1)
go func() {
defer wg.Done()
for response := range responseCh {
select {
case <-quit:
return
default:
output.PrintShell(response)
}
}
}()
for {
// read user input until they type 'exit\n' or the socket breaks
// note that ReadString is blocking, so they won't know the socket
// is broken until they attempt to write something
reader := bufio.NewReader(os.Stdin)
command, _ := reader.ReadString('\n')
ok := protocol.TCPWrite(conn, []byte(command))
if !ok || command == "exit\n" {
break
}
}
// signal for everyone to shutdown
quit <- struct{}{}
close(responseCh)
// wait until the go routines are clean up
wg.Wait()
}