Skip to content

Commit 6d505eb

Browse files
author
Code Express
committed
Merge branch 'addcomputername'
2 parents e29a0b7 + ddda376 commit 6d505eb

File tree

3 files changed

+79
-25
lines changed

3 files changed

+79
-25
lines changed

Makefile

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
all:
2-
GOOS=windows GOARCH=386 go build -o binaries/respounder-x86.exe respounder.go
3-
GOOS=windows GOARCH=amd64 go build -o binaries/respounder-x64.exe respounder.go
4-
GOOS=linux GOARCH=386 go build -o binaries/respounder-x86 respounder.go
5-
GOOS=linux GOARCH=amd64 go build -o binaries/respounder-x64 respounder.go
6-
GOOS=darwin GOARCH=386 go build -o binaries/respounder-osx respounder.go
2+
GOOS=windows GOARCH=386 go build -o binaries/respounder-win32.exe respounder.go
3+
GOOS=windows GOARCH=amd64 go build -o binaries/respounder-win64.exe respounder.go
4+
GOOS=linux GOARCH=386 go build -o binaries/respounder-linux32 respounder.go
5+
GOOS=linux GOARCH=amd64 go build -o binaries/respounder-linux64 respounder.go
6+
GOOS=darwin GOARCH=386 go build -o binaries/respounder-osx32 respounder.go
77
GOOS=darwin GOARCH=amd64 go build -o binaries/respounder-osx64 respounder.go
8+

README.md

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,16 @@
2525

2626
### Latest Releases
2727
Respounder is available for 32/64 bit linux, OS X and Windows systems.
28-
Latest versions can be downloaded from the [Release](https://github.com/codeexpress/respounder/releases) tab above.
28+
Latest versions can be downloaded from the
29+
[Release](https://github.com/codeexpress/respounder/releases) tab above.
2930

3031
### Build from source
3132
This is a golang project with no dependencies. Assuming you have golang compiler installed,
3233
the following will build the binary from scratch
3334
```
3435
$ git clone https://github.com/codeexpress/respounder
3536
$ cd respounder
36-
$ go build respounder
37+
$ go build -o respounder respounder.go
3738
```
3839

3940
## Usage
@@ -58,24 +59,26 @@ $ ./respounder
5859
### Flags
5960
6061
```
61-
$ ./respounder [-json] [-debug]
62+
$ ./respounder [-json] [-debug] [-hostname testhostname | -rhostname]
6263

6364
Flags:
6465
-json
6566
Prints a JSON to STDOUT if a responder is detected on
66-
network. Other text is sent to STDERR
67+
the network. Other text is sent to STDERR
6768
-debug
6869
Creates a debug.log file with a trace of the program
69-
-help
70-
Displays this help
70+
-hostname string
71+
Hostname to search for (default "aweirdcomputername")
72+
-rhostname
73+
Searches for a hostname comprised of random string instead
74+
of the default hostname ("aweirdcomputername")
7175
```
7276
73-
7477
### Typical usage scenario
7578
7679
#### Personal
7780
Detect rogue hosts running responder on public Wi-Fi networks
78-
e.g. like Airports, Cafés and avoid joining such networks
81+
e.g. like airports, cafés and avoid joining such networks
7982
(especially if you are running windows OS)
8083
8184
#### Corporate

respounder.go

Lines changed: 62 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import (
4+
"crypto/sha1"
45
"encoding/hex"
56
"encoding/json"
67
"flag"
@@ -24,10 +25,17 @@ const (
2425
'-'
2526
`
2627

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
3139
)
3240

3341
var (
@@ -40,14 +48,35 @@ var (
4048
// argument flags
4149
jsonPtr = flag.Bool("json", false,
4250
`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`)
4452

4553
debugPtr = flag.Bool("debug", false,
4654
`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
4763
)
4864

65+
func init() {
66+
rand.Seed(time.Now().UnixNano())
67+
}
68+
4969
func main() {
5070
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+
}
5180

5281
fmt.Fprintln(os.Stderr, Banner)
5382

@@ -105,16 +134,23 @@ func checkResponderOnInterface(inf net.Interface) map[string]string {
105134

106135
// Creates and sends a LLMNR request to the UDP multicast address.
107136
func sendLLMNRProbe(ip net.IP) string {
137+
var cName string
108138
responderIP := ""
109139
// 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))
112141

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))
113151
// 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"
118154
n, _ := hex.DecodeString(llmnrRequest)
119155

120156
remoteAddr := net.UDPAddr{IP: net.ParseIP(BcastAddr), Port: LLMNRPort}
@@ -124,6 +160,7 @@ func sendLLMNRProbe(ip net.IP) string {
124160
fmt.Println("Couldn't bind to a UDP interface. Bailing out!")
125161
logger.Printf("Bind error: %+v\nSource IP: %v\n", err, ip)
126162
fmt.Println(err)
163+
logger.Printf("LLMNR request payload was: %x\n", llmnrRequest)
127164
}
128165

129166
defer conn.Close()
@@ -134,6 +171,7 @@ func sendLLMNRProbe(ip net.IP) string {
134171
bytes, clientIP, err := conn.ReadFromUDP(buffer)
135172
if err == nil { // no timeout (or any other) error
136173
responderIP = strings.Split(clientIP.String(), ":")[0]
174+
logger.Printf("LLMNR request payload was: %x\n", n)
137175
logger.Printf("Data received on %s from responder IP %s: %x\n",
138176
ip, clientIP, buffer[:bytes])
139177
} else {
@@ -142,6 +180,18 @@ func sendLLMNRProbe(ip net.IP) string {
142180
return responderIP
143181
}
144182

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+
145195
// From all the IP addresses of this interface,
146196
// extract the IPv4 address where we'll bind to
147197
func getValidIPv4Addr(addrs []net.Addr) net.IP {
@@ -159,7 +209,7 @@ func getValidIPv4Addr(addrs []net.Addr) net.IP {
159209
func initFlags() {
160210
flag.Usage = func() {
161211
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]")
163213
fmt.Fprintf(os.Stderr, "\n\nFlags:\n")
164214
flag.PrintDefaults()
165215
}

0 commit comments

Comments
 (0)