-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from tomsteele/multi-addr
Multi addr
- Loading branch information
Showing
10 changed files
with
378 additions
and
202 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
cookiescan | ||
*.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"net" | ||
"time" | ||
|
||
"github.com/gosuri/uiprogress" | ||
"github.com/miekg/pcap" | ||
"github.com/tomsteele/cookiescan" | ||
) | ||
|
||
type empty struct{} | ||
type task struct { | ||
ip string | ||
port int | ||
} | ||
|
||
func main() { | ||
var ( | ||
options = parse() | ||
filter = "tcp[13] == 0x11 or tcp[13] == 0x10 or tcp[13] == 0x18" | ||
) | ||
|
||
h, err := pcap.OpenLive(options.device, int32(320), true, 500) | ||
if err != nil { | ||
log.Fatal(err.Error()) | ||
} | ||
if err = h.SetFilter(filter); err != nil { | ||
log.Fatal(err.Error()) | ||
} | ||
db := cookiescan.NewStore(options.ips) | ||
|
||
var ( | ||
track = make(chan empty) | ||
tasks = make(chan task, options.minconcurrency) | ||
) | ||
|
||
go func() { | ||
for pkt, r := h.NextEx(); r >= 0; pkt, r = h.NextEx() { | ||
select { | ||
case <-track: | ||
break | ||
default: | ||
if r == 0 { | ||
continue | ||
} | ||
pkt.Decode() | ||
if len(pkt.Headers) < 2 { | ||
continue | ||
} | ||
iphdr, ok := pkt.Headers[0].(*pcap.Iphdr) | ||
if !ok { | ||
continue | ||
} | ||
if len(iphdr.SrcIp) < 4 { | ||
continue | ||
} | ||
ip := fmt.Sprintf("%v.%v.%v.%v", iphdr.SrcIp[0], iphdr.SrcIp[1], iphdr.SrcIp[2], iphdr.SrcIp[3]) | ||
tcphdr, ok := pkt.Headers[1].(*pcap.Tcphdr) | ||
if !ok { | ||
continue | ||
} | ||
db.Add(ip, int(tcphdr.SrcPort), tcphdr.FlagsString()) | ||
} | ||
} | ||
h.Close() | ||
}() | ||
|
||
for i := 0; i < options.minconcurrency; i++ { | ||
go func() { | ||
for tsk := range tasks { | ||
c, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", tsk.ip, tsk.port), options.timeout) | ||
if err != nil { | ||
continue | ||
} | ||
c.Close() | ||
} | ||
}() | ||
} | ||
|
||
uiprogress.Start() | ||
bar := uiprogress.AddBar(len(options.ips) * len(options.services)) | ||
bar.AppendCompleted() | ||
bar.PrependElapsed() | ||
|
||
for _, ip := range options.ips { | ||
for _, p := range options.services { | ||
tasks <- task{ip, p} | ||
bar.Incr() | ||
} | ||
} | ||
|
||
close(tasks) | ||
time.Sleep(time.Duration(2 * time.Second)) | ||
track <- empty{} | ||
close(track) | ||
uiprogress.Stop() | ||
|
||
if options.jsonfile != "" { | ||
db.JSON(options.minconfidence, options.jsonfile) | ||
} | ||
db.Tabbed(options.minconfidence) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
package main | ||
|
||
import ( | ||
"bufio" | ||
"fmt" | ||
"log" | ||
"net" | ||
"os" | ||
"strconv" | ||
"time" | ||
|
||
"github.com/docopt/docopt-go" | ||
"github.com/miekg/pcap" | ||
) | ||
|
||
const usage = ` | ||
Usage: | ||
cookiescan [options] <target> | ||
cookiescan -h | --help | ||
cookiescan -v | --version | ||
Required Arguments: | ||
target: IP Address, Hostname, or CIDR network. May also be a a newline separated | ||
file containing targets. | ||
Options: | ||
-h --help Show this message. | ||
-v --version Show version. | ||
-p <port ranges> Ex: -p 22; -p 1-65535, -p 80,443. [default: 1-1024] | ||
-g <int> Amount of goroutines to spread connection attempts across. [default: 1000] | ||
-c <int> Minimum confidence level to flag port as open. [default: 1] | ||
-i <interface> Network interface to listen on. | ||
-t <timeout> Timeout in Milliseconds to wait for a connection. [default: 400] | ||
-j <file> Output JSON to file. | ||
` | ||
|
||
type O struct { | ||
services []int | ||
minconfidence int | ||
minconcurrency int | ||
timeout time.Duration | ||
device string | ||
ips []string | ||
jsonfile string | ||
} | ||
|
||
func parse() *O { | ||
args, err := docopt.Parse(usage, nil, true, "cookiescan 2.0.0", false) | ||
if err != nil { | ||
log.Fatalf("Error parsing usage. Error: %s\n", err.Error()) | ||
} | ||
if err != nil { | ||
log.Fatalf("Error parsing usage. Error: %s\n", err.Error()) | ||
} | ||
o := &O{ | ||
jsonfile: args["-j"].(string), | ||
} | ||
|
||
var lines []string | ||
hostorfile := args["<target>"].(string) | ||
if ok, err := os.Stat(hostorfile); err == nil && ok != nil { | ||
if lines, err = readFileLines(hostorfile); err != nil { | ||
log.Fatalf("Error parsing input file. Error: %s\n", err.Error()) | ||
} | ||
} else { | ||
lines = append(lines, hostorfile) | ||
} | ||
|
||
if o.ips, err = linesToIPList(lines); err != nil { | ||
log.Fatalf("Error parsing targets. Error: %s\n", err.Error()) | ||
} | ||
|
||
if o.services, err = explode(args["-p"].(string)); err != nil { | ||
log.Fatalf("Error parsing port string. Error %s\n", err.Error()) | ||
} | ||
|
||
if o.minconfidence, err = strconv.Atoi(args["-c"].(string)); err != nil { | ||
log.Fatal("Invalid argument for -c.") | ||
} | ||
if o.minconcurrency, err = strconv.Atoi(args["-g"].(string)); err != nil { | ||
log.Fatal("Invalid argument for -g.") | ||
} | ||
|
||
ti, err := strconv.Atoi(args["-t"].(string)) | ||
if err != nil { | ||
log.Fatal("Invalid argument for -t.") | ||
} | ||
o.timeout = time.Duration(ti) * time.Millisecond | ||
|
||
if args["-i"] != nil { | ||
o.device = args["-i"].(string) | ||
} | ||
if o.device == "" { | ||
devs, err := pcap.FindAllDevs() | ||
if err != nil { | ||
log.Fatal("Error finding interfaces. Error: ", err) | ||
} | ||
if len(devs) == 0 { | ||
log.Fatal("No interfaces found. Are you not running as root?") | ||
} | ||
o.device = devs[0].Name | ||
} | ||
|
||
return o | ||
} | ||
|
||
// linesToIPList processes a list of IP addresses or networks in CIDR format. | ||
// Returning a list of all possible IP addresses. | ||
func linesToIPList(lines []string) ([]string, error) { | ||
ipList := []string{} | ||
for _, line := range lines { | ||
if net.ParseIP(line) != nil { | ||
ipList = append(ipList, line) | ||
} else if ip, network, err := net.ParseCIDR(line); err == nil { | ||
for ip := ip.Mask(network.Mask); network.Contains(ip); increaseIP(ip) { | ||
ipList = append(ipList, ip.String()) | ||
} | ||
} else { | ||
return ipList, fmt.Errorf("%s is not an IP Address or CIDR Network", line) | ||
ips, err := net.LookupIP(line) | ||
if err != nil { | ||
return ipList, fmt.Errorf("%s is not a valid hostname", line) | ||
} | ||
ipList = append(ipList, ips[0].String()) | ||
} | ||
} | ||
return ipList, nil | ||
} | ||
|
||
// increases an IP by a single address. | ||
func increaseIP(ip net.IP) { | ||
for j := len(ip) - 1; j >= 0; j-- { | ||
ip[j]++ | ||
if ip[j] > 0 { | ||
break | ||
} | ||
} | ||
} | ||
|
||
// readFileLines returns all the lines in a file. | ||
func readFileLines(path string) ([]string, error) { | ||
file, err := os.Open(path) | ||
if err != nil { | ||
return nil, err | ||
} | ||
defer file.Close() | ||
lines := []string{} | ||
scanner := bufio.NewScanner(file) | ||
for scanner.Scan() { | ||
if scanner.Text() == "" { | ||
continue | ||
} | ||
lines = append(lines, scanner.Text()) | ||
} | ||
return lines, scanner.Err() | ||
} |
Oops, something went wrong.