Skip to content

Commit

Permalink
Merge branch 'addcomputername'
Browse files Browse the repository at this point in the history
  • Loading branch information
Code Express committed Feb 19, 2018
2 parents e29a0b7 + ddda376 commit 6d505eb
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 25 deletions.
11 changes: 6 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
all:
GOOS=windows GOARCH=386 go build -o binaries/respounder-x86.exe respounder.go
GOOS=windows GOARCH=amd64 go build -o binaries/respounder-x64.exe respounder.go
GOOS=linux GOARCH=386 go build -o binaries/respounder-x86 respounder.go
GOOS=linux GOARCH=amd64 go build -o binaries/respounder-x64 respounder.go
GOOS=darwin GOARCH=386 go build -o binaries/respounder-osx respounder.go
GOOS=windows GOARCH=386 go build -o binaries/respounder-win32.exe respounder.go
GOOS=windows GOARCH=amd64 go build -o binaries/respounder-win64.exe respounder.go
GOOS=linux GOARCH=386 go build -o binaries/respounder-linux32 respounder.go
GOOS=linux GOARCH=amd64 go build -o binaries/respounder-linux64 respounder.go
GOOS=darwin GOARCH=386 go build -o binaries/respounder-osx32 respounder.go
GOOS=darwin GOARCH=amd64 go build -o binaries/respounder-osx64 respounder.go

19 changes: 11 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,16 @@

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

### Build from source
This is a golang project with no dependencies. Assuming you have golang compiler installed,
the following will build the binary from scratch
```
$ git clone https://github.com/codeexpress/respounder
$ cd respounder
$ go build respounder
$ go build -o respounder respounder.go
```

## Usage
Expand All @@ -58,24 +59,26 @@ $ ./respounder
### Flags
```
$ ./respounder [-json] [-debug]
$ ./respounder [-json] [-debug] [-hostname testhostname | -rhostname]

Flags:
-json
Prints a JSON to STDOUT if a responder is detected on
network. Other text is sent to STDERR
the network. Other text is sent to STDERR
-debug
Creates a debug.log file with a trace of the program
-help
Displays this help
-hostname string
Hostname to search for (default "aweirdcomputername")
-rhostname
Searches for a hostname comprised of random string instead
of the default hostname ("aweirdcomputername")
```
### Typical usage scenario
#### Personal
Detect rogue hosts running responder on public Wi-Fi networks
e.g. like Airports, Cafés and avoid joining such networks
e.g. like airports, cafés and avoid joining such networks
(especially if you are running windows OS)
#### Corporate
Expand Down
74 changes: 62 additions & 12 deletions respounder.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"crypto/sha1"
"encoding/hex"
"encoding/json"
"flag"
Expand All @@ -24,10 +25,17 @@ const (
'-'
`

Version = 1.0
TimeoutSec = 3
BcastAddr = "224.0.0.252"
LLMNRPort = 5355
Version = 1.1
TimeoutSec = 3
BcastAddr = "224.0.0.252"
LLMNRPort = 5355
DefaultHostname = "aweirdcomputername"
)

const (
def = 0x00
newHostname = 0x01
randHostname = 0x02
)

var (
Expand All @@ -40,14 +48,35 @@ var (
// argument flags
jsonPtr = flag.Bool("json", false,
`Prints a JSON to STDOUT if a responder is detected on
network. Other text is sent to STDERR`)
the network. Other text is sent to STDERR`)

debugPtr = flag.Bool("debug", false,
`Creates a debug.log file with a trace of the program`)

hostnamePtr = flag.String("hostname", DefaultHostname,
`Hostname to search for`)
randHostnamePtr = flag.Bool("rhostname", false,
`Searches for a hostname comprised of random string instead
of the default hostname ("`+DefaultHostname+`")`)

hostnameType byte
)

func init() {
rand.Seed(time.Now().UnixNano())
}

func main() {
initFlags()
flag.Parse()

if *hostnamePtr != "aweirdcomputername" {
hostnameType = newHostname
} else if *randHostnamePtr {
hostnameType = randHostname
} else {
hostnameType = def
}

fmt.Fprintln(os.Stderr, Banner)

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

// Creates and sends a LLMNR request to the UDP multicast address.
func sendLLMNRProbe(ip net.IP) string {
var cName string
responderIP := ""
// 2 byte random transaction id eg. 0x8e53
rand.Seed(time.Now().UnixNano())
randomTransactionId := fmt.Sprintf("%04x", rand.Intn(65535))
randomTransactionID := fmt.Sprintf("%04x", rand.Intn(65535))

switch hostnameType {
case def, newHostname:
cName = string(*hostnamePtr)
case randHostname:
cName = randomHostname()
}

cNameLen := fmt.Sprintf("%02x", len(cName))
encCName := hex.EncodeToString([]byte(cName))
// LLMNR request in raw bytes
// TODO: generate a new computer name evertime instead of the
// hardcoded value 'awierdcomputername'
llmnrRequest := randomTransactionId +
"0000000100000000000012617769657264636f6d70757465726e616d650000010001"
llmnrRequest := randomTransactionID +
"00000001000000000000" + cNameLen + encCName + "0000010001"
n, _ := hex.DecodeString(llmnrRequest)

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

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

// Calculate random hostname by taking random lenght
// of the SHA1 of current time.
func randomHostname() string {
currentTime := time.Now().Format("2006-01-02 15:04:05")
h := sha1.New()
h.Write([]byte(currentTime))
bs := h.Sum(nil)
randomSlice := bs[:(rand.Intn(len(bs)-3) + 3)]
randomName := fmt.Sprintf("%x\n", randomSlice)
return randomName
}

// From all the IP addresses of this interface,
// extract the IPv4 address where we'll bind to
func getValidIPv4Addr(addrs []net.Addr) net.IP {
Expand All @@ -159,7 +209,7 @@ func getValidIPv4Addr(addrs []net.Addr) net.IP {
func initFlags() {
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "Respounder version %1.1f\n", Version)
fmt.Fprintf(os.Stderr, "Usage: $ respounder [-json] [-debug]")
fmt.Fprintf(os.Stderr, "Usage: $ respounder [-json] [-debug] [-hostname testhostname | -rhostname]")
fmt.Fprintf(os.Stderr, "\n\nFlags:\n")
flag.PrintDefaults()
}
Expand Down

0 comments on commit 6d505eb

Please sign in to comment.