1
1
package main
2
2
3
3
import (
4
+ "crypto/sha1"
4
5
"encoding/hex"
5
6
"encoding/json"
6
7
"flag"
@@ -24,10 +25,17 @@ const (
24
25
'-'
25
26
`
26
27
27
- Version = 1.0
28
- TimeoutSec = 3
29
- BcastAddr = "224.0.0.252"
30
- LLMNRPort = 5355
28
+ Version = 1.1
29
+ TimeoutSec = 3
30
+ BcastAddr = "224.0.0.252"
31
+ LLMNRPort = 5355
32
+ DefaultHostname = "aweirdcomputername"
33
+ )
34
+
35
+ const (
36
+ def = 0x00
37
+ newHostname = 0x01
38
+ randHostname = 0x02
31
39
)
32
40
33
41
var (
@@ -40,14 +48,35 @@ var (
40
48
// argument flags
41
49
jsonPtr = flag .Bool ("json" , false ,
42
50
`Prints a JSON to STDOUT if a responder is detected on
43
- network. Other text is sent to STDERR` )
51
+ the network. Other text is sent to STDERR` )
44
52
45
53
debugPtr = flag .Bool ("debug" , false ,
46
54
`Creates a debug.log file with a trace of the program` )
55
+
56
+ hostnamePtr = flag .String ("hostname" , DefaultHostname ,
57
+ `Hostname to search for` )
58
+ randHostnamePtr = flag .Bool ("rhostname" , false ,
59
+ `Searches for a hostname comprised of random string instead
60
+ of the default hostname ("` + DefaultHostname + `")` )
61
+
62
+ hostnameType byte
47
63
)
48
64
65
+ func init () {
66
+ rand .Seed (time .Now ().UnixNano ())
67
+ }
68
+
49
69
func main () {
50
70
initFlags ()
71
+ flag .Parse ()
72
+
73
+ if * hostnamePtr != "aweirdcomputername" {
74
+ hostnameType = newHostname
75
+ } else if * randHostnamePtr {
76
+ hostnameType = randHostname
77
+ } else {
78
+ hostnameType = def
79
+ }
51
80
52
81
fmt .Fprintln (os .Stderr , Banner )
53
82
@@ -105,16 +134,23 @@ func checkResponderOnInterface(inf net.Interface) map[string]string {
105
134
106
135
// Creates and sends a LLMNR request to the UDP multicast address.
107
136
func sendLLMNRProbe (ip net.IP ) string {
137
+ var cName string
108
138
responderIP := ""
109
139
// 2 byte random transaction id eg. 0x8e53
110
- rand .Seed (time .Now ().UnixNano ())
111
- randomTransactionId := fmt .Sprintf ("%04x" , rand .Intn (65535 ))
140
+ randomTransactionID := fmt .Sprintf ("%04x" , rand .Intn (65535 ))
112
141
142
+ switch hostnameType {
143
+ case def , newHostname :
144
+ cName = string (* hostnamePtr )
145
+ case randHostname :
146
+ cName = randomHostname ()
147
+ }
148
+
149
+ cNameLen := fmt .Sprintf ("%02x" , len (cName ))
150
+ encCName := hex .EncodeToString ([]byte (cName ))
113
151
// LLMNR request in raw bytes
114
- // TODO: generate a new computer name evertime instead of the
115
- // hardcoded value 'awierdcomputername'
116
- llmnrRequest := randomTransactionId +
117
- "0000000100000000000012617769657264636f6d70757465726e616d650000010001"
152
+ llmnrRequest := randomTransactionID +
153
+ "00000001000000000000" + cNameLen + encCName + "0000010001"
118
154
n , _ := hex .DecodeString (llmnrRequest )
119
155
120
156
remoteAddr := net.UDPAddr {IP : net .ParseIP (BcastAddr ), Port : LLMNRPort }
@@ -124,6 +160,7 @@ func sendLLMNRProbe(ip net.IP) string {
124
160
fmt .Println ("Couldn't bind to a UDP interface. Bailing out!" )
125
161
logger .Printf ("Bind error: %+v\n Source IP: %v\n " , err , ip )
126
162
fmt .Println (err )
163
+ logger .Printf ("LLMNR request payload was: %x\n " , llmnrRequest )
127
164
}
128
165
129
166
defer conn .Close ()
@@ -134,6 +171,7 @@ func sendLLMNRProbe(ip net.IP) string {
134
171
bytes , clientIP , err := conn .ReadFromUDP (buffer )
135
172
if err == nil { // no timeout (or any other) error
136
173
responderIP = strings .Split (clientIP .String (), ":" )[0 ]
174
+ logger .Printf ("LLMNR request payload was: %x\n " , n )
137
175
logger .Printf ("Data received on %s from responder IP %s: %x\n " ,
138
176
ip , clientIP , buffer [:bytes ])
139
177
} else {
@@ -142,6 +180,18 @@ func sendLLMNRProbe(ip net.IP) string {
142
180
return responderIP
143
181
}
144
182
183
+ // Calculate random hostname by taking random lenght
184
+ // of the SHA1 of current time.
185
+ func randomHostname () string {
186
+ currentTime := time .Now ().Format ("2006-01-02 15:04:05" )
187
+ h := sha1 .New ()
188
+ h .Write ([]byte (currentTime ))
189
+ bs := h .Sum (nil )
190
+ randomSlice := bs [:(rand .Intn (len (bs )- 3 ) + 3 )]
191
+ randomName := fmt .Sprintf ("%x\n " , randomSlice )
192
+ return randomName
193
+ }
194
+
145
195
// From all the IP addresses of this interface,
146
196
// extract the IPv4 address where we'll bind to
147
197
func getValidIPv4Addr (addrs []net.Addr ) net.IP {
@@ -159,7 +209,7 @@ func getValidIPv4Addr(addrs []net.Addr) net.IP {
159
209
func initFlags () {
160
210
flag .Usage = func () {
161
211
fmt .Fprintf (os .Stderr , "Respounder version %1.1f\n " , Version )
162
- fmt .Fprintf (os .Stderr , "Usage: $ respounder [-json] [-debug]" )
212
+ fmt .Fprintf (os .Stderr , "Usage: $ respounder [-json] [-debug] [-hostname testhostname | -rhostname] " )
163
213
fmt .Fprintf (os .Stderr , "\n \n Flags:\n " )
164
214
flag .PrintDefaults ()
165
215
}
0 commit comments