yellow~ opinionated web scanning pipeline for pentesters in a hurry |
| git clone https://github.com/djnnvx/yellow.git |
| log | files | refs | archive | README | LICENSE |
asn_test.go (3911B)
1 package osint 2 3 import ( 4 "errors" 5 "net" 6 "testing" 7 ) 8 9 func TestParseCymruOrigin(t *testing.T) { 10 got, ok := parseCymruOrigin("15169 | 8.8.8.0/24 | US | arin | 1992-12-01") 11 if !ok { 12 t.Fatal("real cymru record failed to parse") 13 } 14 want := asnOrigin{ASN: "15169", Prefix: "8.8.8.0/24", Country: "US", Registry: "arin"} 15 if got != want { 16 t.Errorf("got %+v, want %+v", got, want) 17 } 18 } 19 20 func TestParseCymruOriginMultiOrigin(t *testing.T) { 21 got, ok := parseCymruOrigin("1234 5678 | 194.204.0.0/18 | EE | ripencc | 1995-12-04") 22 if !ok || got.ASN != "1234" { 23 t.Errorf("multiply-originated prefix: got ASN %q, want 1234", got.ASN) 24 } 25 } 26 27 func TestParseCymruOriginRejectsJunk(t *testing.T) { 28 for _, txt := range []string{"", " ", "no pipes here", " | 1.2.3.0/24"} { 29 if _, ok := parseCymruOrigin(txt); ok { 30 t.Errorf("parsed junk %q as a record", txt) 31 } 32 } 33 } 34 35 func TestParseShadowserverOriginFieldOrder(t *testing.T) { 36 got, ok := parseShadowserverOrigin("15169 | 8.8.8.0/24 | AS15169 | US | Google LLC") 37 if !ok { 38 t.Fatal("real shadowserver record failed to parse") 39 } 40 // field order differs from cymru: org is index 4, country index 3 41 want := asnOrigin{ASN: "15169", Prefix: "8.8.8.0/24", Country: "US", Org: "Google LLC"} 42 if got != want { 43 t.Errorf("got %+v, want %+v", got, want) 44 } 45 } 46 47 func TestParseCymruASName(t *testing.T) { 48 // AS name itself contains hyphens and commas 49 got := parseCymruASName("20473 | US | arin | 2001-05-11 | AS-VULTR - The Constant Company, LLC, US") 50 if got != "AS-VULTR - The Constant Company, LLC, US" { 51 t.Errorf("got %q", got) 52 } 53 if parseCymruASName("20473 | US | arin") != "" { 54 t.Error("short record should yield no name") 55 } 56 } 57 58 func TestReverseIPv4(t *testing.T) { 59 if got := reverseIPv4("1.2.3.4"); got != "4.3.2.1" { 60 t.Errorf("got %q, want 4.3.2.1", got) 61 } 62 if got := reverseIPv4("2001:4860::1"); got != "" { 63 t.Errorf("ipv6 should yield empty, got %q", got) 64 } 65 } 66 67 func TestIsHostingProviderCatchesVultr(t *testing.T) { 68 // RFC 5737 documentation range: cdncheck does not match it, so only the 69 // AS-name keyword can flag this. Same situation as Vultr in the wild. 70 doc := net.ParseIP("192.0.2.1") 71 if LookupCDNMatches(doc) { 72 t.Skip("cdncheck now covers the documentation range; keyword path untestable here") 73 } 74 if !isHostingProvider("AS-VULTR - The Constant Company, LLC, US", doc) { 75 t.Error("Vultr not flagged as hosting provider") 76 } 77 if isHostingProvider("EXAMPLE-CORP - Example Bank Inc", doc) { 78 t.Error("a self-hosted org was wrongly flagged as a provider") 79 } 80 } 81 82 func TestOriginFailsOverToSecondProvider(t *testing.T) { 83 calls := []string{} 84 a := &ASN{ 85 lookupTXT: func(name string) ([]string, error) { 86 calls = append(calls, name) 87 if name == "4.3.2.1.origin.asn.cymru.com" { 88 return nil, errors.New("primary down") 89 } 90 return []string{"15169 | 8.8.8.0/24 | AS15169 | US | Google LLC"}, nil 91 }, 92 providers: asnProviders, 93 } 94 95 origin, source, ok := a.origin("1.2.3.4") 96 if !ok { 97 t.Fatalf("failover produced no record; queried %v", calls) 98 } 99 if source != "shadowserver" { 100 t.Errorf("source = %q, want shadowserver", source) 101 } 102 if origin.ASN != "15169" || origin.Prefix != "8.8.8.0/24" || origin.Org != "Google LLC" { 103 t.Errorf("bad failover record: %+v", origin) 104 } 105 } 106 107 func TestOriginAllProvidersDown(t *testing.T) { 108 a := &ASN{ 109 lookupTXT: func(string) ([]string, error) { return nil, errors.New("down") }, 110 providers: asnProviders, 111 } 112 if _, _, ok := a.origin("1.2.3.4"); ok { 113 t.Error("all providers down must yield no record, not a bogus one") 114 } 115 } 116 117 func TestOriginEmptyAnswerIsNotARecord(t *testing.T) { 118 a := &ASN{ 119 lookupTXT: func(string) ([]string, error) { return []string{""}, nil }, 120 providers: asnProviders, 121 } 122 if _, _, ok := a.origin("192.168.1.1"); ok { 123 t.Error("private IP with empty TXT must yield no record") 124 } 125 } 126 127 func LookupCDNMatches(ip net.IP) bool { 128 return isHostingProvider("", ip) 129 }