188 lines
4.0 KiB
Go
Executable File
188 lines
4.0 KiB
Go
Executable File
/*
|
|
asnip: ASN target organization IP range attack surface mapping
|
|
by github.com/harleo — MIT Licence
|
|
*/
|
|
|
|
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"flag"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"net"
|
|
"net/http"
|
|
"os"
|
|
"regexp"
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
type sliceVal []string
|
|
|
|
func (s sliceVal) String() string {
|
|
var str string
|
|
for _, i := range s {
|
|
str += fmt.Sprintf("%s\n", i)
|
|
}
|
|
return str
|
|
}
|
|
|
|
func writeLines(lines []string, path string) {
|
|
file, err := os.Create(path)
|
|
if err != nil {
|
|
log.Fatalf("[!] Couldn't create file: %s\n", err.Error())
|
|
}
|
|
defer func(file *os.File) {
|
|
err := file.Close()
|
|
if err != nil {
|
|
log.Fatalf("Failed to write file %s: %s", file.Name(), err)
|
|
}
|
|
}(file)
|
|
|
|
w := bufio.NewWriter(file)
|
|
for _, line := range lines {
|
|
_, err := fmt.Fprintln(w, line)
|
|
if err != nil {
|
|
log.Fatalf("Failed to write '%s' to file %s: %s", line, file.Name(), err)
|
|
}
|
|
}
|
|
flushErr := w.Flush()
|
|
if flushErr != nil {
|
|
log.Fatalf("Couldn't write file %s: %s", file.Name(), flushErr)
|
|
}
|
|
}
|
|
|
|
func httpRequest(URI string) string {
|
|
response, errGet := http.Get(URI)
|
|
if errGet != nil {
|
|
log.Fatalf("[!] Error sending request: %s\n", errGet.Error())
|
|
}
|
|
|
|
responseText, errRead := io.ReadAll(response.Body)
|
|
if errRead != nil {
|
|
log.Fatalf("[!] Error reading response: %s\n", errRead.Error())
|
|
}
|
|
|
|
defer func(Body io.ReadCloser) {
|
|
err := Body.Close()
|
|
if err != nil {
|
|
os.Exit(1)
|
|
}
|
|
}(response.Body)
|
|
return string(responseText)
|
|
}
|
|
|
|
func incrementIP(ip net.IP) {
|
|
for j := len(ip) - 1; j >= 0; j-- {
|
|
ip[j]++
|
|
if ip[j] > 0 {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
func IsIPv6CIDR(cidr string) bool {
|
|
ip, _, _ := net.ParseCIDR(cidr)
|
|
return ip != nil && ip.To4() == nil
|
|
}
|
|
|
|
func CIDRToIP(cidr string) []string {
|
|
ip, ipnet, err := net.ParseCIDR(cidr)
|
|
if err != nil {
|
|
log.Fatalf("[!] Failed to convert CIDR to IP: %s\n", err.Error())
|
|
}
|
|
|
|
var ips []string
|
|
for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); incrementIP(ip) {
|
|
ips = append(ips, ip.String())
|
|
}
|
|
|
|
// Exclude network and broadcast addresses
|
|
if len(ips) >= 3 {
|
|
return ips[1 : len(ips)-1]
|
|
} else {
|
|
return ips
|
|
}
|
|
}
|
|
|
|
func getIP(ipDomain string) []net.IP {
|
|
ip, err := net.LookupIP(ipDomain)
|
|
if err != nil {
|
|
log.Fatalf("[!] Error looking up domain: %s\n", err.Error())
|
|
}
|
|
return ip
|
|
}
|
|
|
|
func parseResponse(response string) []string {
|
|
r := regexp.MustCompile(`[^\s"']+|"([^"]*)"|'([^']*)`)
|
|
arr := r.FindAllString(response, -1)
|
|
return arr
|
|
}
|
|
|
|
func checkAPIRateLimit(response string) {
|
|
if strings.Contains(response, "API") {
|
|
fmt.Println("[!] The HackerTarget API limit was reached, exiting...")
|
|
os.Exit(0)
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
var (
|
|
target = flag.String("t", "", "Domain or IP address (Required)")
|
|
onlyPrint = flag.Bool("p", false, "Only print results to console")
|
|
onlyCidrs = flag.Bool("c", false, "Only download list of CIDRs")
|
|
)
|
|
|
|
flag.Parse()
|
|
|
|
ipAddress := getIP(*target)[0]
|
|
|
|
apiRequest := fmt.Sprintf("https://api.hackertarget.com/aslookup/?q=%s", ipAddress)
|
|
apiResponse := httpRequest(apiRequest)
|
|
apiResponseInfo := parseResponse(apiResponse)
|
|
checkAPIRateLimit(apiResponse)
|
|
|
|
fmt.Printf("[?] ASN: %s ORG: %s\n", apiResponseInfo[2], apiResponseInfo[6])
|
|
|
|
apiASRequest := fmt.Sprintf("https://api.hackertarget.com/aslookup/?q=AS%s", strings.Trim(apiResponseInfo[2], "\""))
|
|
apiASResponse := httpRequest(apiASRequest)
|
|
apiASResponseInfo := parseResponse(apiASResponse)
|
|
checkAPIRateLimit(apiASResponse)
|
|
|
|
var CIDRSv4 []string
|
|
for _, cidrV4 := range apiASResponseInfo[3:] {
|
|
if !IsIPv6CIDR(cidrV4) {
|
|
CIDRSv4 = append(CIDRSv4, cidrV4)
|
|
}
|
|
}
|
|
sort.Strings(CIDRSv4)
|
|
|
|
if *onlyPrint {
|
|
fmt.Print(sliceVal(CIDRSv4))
|
|
} else {
|
|
fmt.Printf("[:] Writing %d CIDRs to file...\n", len(CIDRSv4))
|
|
writeLines(CIDRSv4, "cidrs.txt")
|
|
}
|
|
|
|
if !*onlyCidrs {
|
|
var ips []string
|
|
fmt.Println("[:] Converting to IPs...")
|
|
for _, cidr := range CIDRSv4 {
|
|
ips = append(ips, CIDRToIP(cidr)...)
|
|
}
|
|
|
|
if *onlyPrint {
|
|
for _, ipsValue := range ips {
|
|
fmt.Println(ipsValue)
|
|
}
|
|
} else {
|
|
fmt.Printf("[:] Writing %d IPs to file...\n", len(ips))
|
|
writeLines(ips, "ips.txt")
|
|
}
|
|
}
|
|
|
|
fmt.Println("[!] Done.")
|
|
}
|