Skip to content

Instantly share code, notes, and snippets.

@leoloobeek
Last active September 14, 2021 02:57
Show Gist options
  • Save leoloobeek/d86aba34605eb0b46073e20e4cfb4381 to your computer and use it in GitHub Desktop.
Save leoloobeek/d86aba34605eb0b46073e20e4cfb4381 to your computer and use it in GitHub Desktop.
Quick 'n dirty script to match Amass results with in-scope networks
package main
// go run main.go -amass amass.json -scope scope.txt
import (
"bufio"
"encoding/json"
"flag"
"fmt"
"net"
"os"
"strings"
)
type AmassResult struct {
Name string `json:"name"`
Domain string `json:"domain"`
Addresses []AmassAddress `json:"addresses"`
Tag string `json:"tag"`
Sources []string `json:"sources"`
}
type AmassAddress struct {
IP string `json:"ip"`
CIDR string `json:"cidr"`
ASN int `json:"asn"`
Description string `json:"desc"`
}
type InScopeRecord struct {
Hostname string `json:"hostname"`
IP string `json:"ip"`
Network string `json:"network"`
}
func main() {
amassFile := flag.String("amass", "", "Path to amass JSON output file")
scopeFile := flag.String("scope", "", "Path to text file containing each network in scope, one per line")
flag.Parse()
if *amassFile == "" || *scopeFile == "" {
fmt.Printf("[!] %s\n", flag.Usage)
}
networks, err := parseScopeFile(*scopeFile)
if err != nil {
fmt.Printf("[!] Error: %s\n", err)
}
var records []InScopeRecord
amass, err := os.Open(*amassFile)
if err != nil {
panic(err)
}
scanner := bufio.NewScanner(amass)
for scanner.Scan() {
line := strings.TrimSuffix(scanner.Text(), "\n")
newRecord, err := checkAmassResult(line, networks)
if err != nil {
fmt.Printf("[!] Error unmarshalling data: %s\n", err)
continue
}
if newRecord.Empty() {
continue
}
records = append(records, newRecord)
}
if err := scanner.Err(); err != nil {
panic(err)
}
fmt.Println("Hostname,IP,Network")
for _, record := range records {
fmt.Printf("%s,%s,%s\n", record.Hostname, record.IP, record.Network)
}
}
func checkAmassResult(result string, scope []net.IPNet) (InScopeRecord, error) {
var ar AmassResult
err := json.Unmarshal([]byte(result), &ar)
if err != nil {
return InScopeRecord{}, err
}
var addresses []string
var networks []string
for _, ara := range ar.Addresses {
ip := net.ParseIP(ara.IP)
if ip == nil {
fmt.Printf("could not parse '%s' as IP\n", ara.IP)
continue
}
for _, network := range scope {
if network.Contains(ip) {
addresses = append(addresses, ara.IP)
networks = append(networks, network.String())
}
}
}
if len(addresses) == 0 {
return InScopeRecord{}, nil
}
return InScopeRecord{
Hostname: ar.Name,
IP: strings.Join(addresses, " "),
Network: strings.Join(networks, " "),
}, nil
}
func (i InScopeRecord) Empty() bool {
if i.IP == "" {
return true
}
return false
}
func parseScopeFile(scopeFile string) ([]net.IPNet, error) {
var networks []net.IPNet
amass, err := os.Open(scopeFile)
if err != nil {
panic(err)
}
scanner := bufio.NewScanner(amass)
for scanner.Scan() {
line := strings.TrimSuffix(scanner.Text(), "\n")
_, net, err := net.ParseCIDR(line)
if err != nil {
fmt.Printf("failed parsing network %s: %s\n", line, err)
continue
}
networks = append(networks, *net)
}
if err := scanner.Err(); err != nil {
return networks, err
}
return networks, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment