Files
god-eye/internal/http/tls_analyzer.go
Vyntral b1bf119c82 v0.1.1: Major AI improvements, new security modules, and documentation fixes
## AI & CVE Improvements
- Fix AI report to display actual subdomain names instead of generic placeholders
- Add 10-year CVE filter to reduce false positives from outdated vulnerabilities
- Integrate CISA KEV (Known Exploited Vulnerabilities) database support
- Improve AI analysis prompt for more accurate security findings

## New Security Modules
- Add wildcard DNS detection with multi-phase validation (DNS + HTTP)
- Add TLS certificate analyzer for certificate chain inspection
- Add comprehensive rate limiting module for API requests
- Add retry mechanism with exponential backoff
- Add stealth mode for reduced detection during scans
- Add progress tracking module for better UX

## Code Refactoring
- Extract scanner output logic to dedicated module
- Add base source interface for consistent passive source implementation
- Reduce admin panel paths to common generic patterns only
- Improve HTTP client with connection pooling
- Add JSON output formatter

## Documentation Updates
- Correct passive source count to 20 (was incorrectly stated as 34)
- Fix AI model names: deepseek-r1:1.5b (fast) + qwen2.5-coder:7b (deep)
- Update all markdown files for consistency
- Relocate demo GIFs to assets/ directory
- Add benchmark disclaimer for test variability

## Files Changed
- 4 documentation files updated (README, AI_SETUP, BENCHMARK, EXAMPLES)
- 11 new source files added
- 12 existing files modified
2025-11-21 12:00:58 +01:00

488 lines
12 KiB
Go

package http
import (
"crypto/x509"
"regexp"
"strings"
"god-eye/internal/config"
)
// AppliancePattern defines a pattern to match vendor/product from certificate fields
type AppliancePattern struct {
Vendor string
Product string
ApplianceType string // firewall, vpn, loadbalancer, proxy, waf, appliance
// Match patterns (any match triggers detection)
SubjectCNPatterns []string
SubjectOrgPatterns []string
SubjectOUPatterns []string
IssuerCNPatterns []string
IssuerOrgPatterns []string
// Version extraction regex (optional)
VersionRegex string
}
// appliancePatterns contains known signatures for security appliances
var appliancePatterns = []AppliancePattern{
// Fortinet FortiGate
{
Vendor: "Fortinet",
Product: "FortiGate",
ApplianceType: "firewall",
SubjectCNPatterns: []string{
"FortiGate", "FGT", "fortinet", "FGVM",
},
SubjectOrgPatterns: []string{"Fortinet"},
IssuerCNPatterns: []string{"FortiGate", "Fortinet"},
IssuerOrgPatterns: []string{"Fortinet"},
VersionRegex: `(?i)(?:FortiGate|FGT|FGVM)[_-]?(\d+[A-Z]?)`,
},
// Palo Alto Networks
{
Vendor: "Palo Alto Networks",
Product: "PAN-OS",
ApplianceType: "firewall",
SubjectCNPatterns: []string{
"PA-", "Palo Alto", "PAN-OS", "paloaltonetworks",
},
SubjectOrgPatterns: []string{"Palo Alto Networks", "paloaltonetworks"},
IssuerOrgPatterns: []string{"Palo Alto Networks"},
VersionRegex: `(?i)PA-(\d+)`,
},
// Cisco ASA
{
Vendor: "Cisco",
Product: "ASA",
ApplianceType: "firewall",
SubjectCNPatterns: []string{
"ASA", "Cisco ASA", "adaptive security",
},
SubjectOrgPatterns: []string{"Cisco"},
IssuerOrgPatterns: []string{"Cisco"},
VersionRegex: `(?i)ASA[_-]?(\d+)`,
},
// Cisco Firepower
{
Vendor: "Cisco",
Product: "Firepower",
ApplianceType: "firewall",
SubjectCNPatterns: []string{
"Firepower", "FTD", "FMC",
},
SubjectOrgPatterns: []string{"Cisco"},
},
// SonicWall
{
Vendor: "SonicWall",
Product: "SonicWall",
ApplianceType: "firewall",
SubjectCNPatterns: []string{
"SonicWall", "sonicwall", "SonicOS", "NSA", "TZ",
},
SubjectOrgPatterns: []string{"SonicWall", "SonicWALL"},
IssuerOrgPatterns: []string{"SonicWall", "SonicWALL"},
VersionRegex: `(?i)(?:NSA|TZ)[\s-]?(\d+)`,
},
// Check Point
{
Vendor: "Check Point",
Product: "Gaia",
ApplianceType: "firewall",
SubjectCNPatterns: []string{
"Check Point", "checkpoint", "Gaia", "SmartCenter",
},
SubjectOrgPatterns: []string{"Check Point"},
IssuerOrgPatterns: []string{"Check Point"},
},
// F5 BIG-IP
{
Vendor: "F5",
Product: "BIG-IP",
ApplianceType: "loadbalancer",
SubjectCNPatterns: []string{
"BIG-IP", "BIGIP", "F5 Networks", "f5.com",
},
SubjectOrgPatterns: []string{"F5 Networks", "F5, Inc"},
IssuerOrgPatterns: []string{"F5 Networks", "F5, Inc"},
VersionRegex: `(?i)BIG-IP\s+(\d+\.\d+)`,
},
// Citrix NetScaler / ADC
{
Vendor: "Citrix",
Product: "NetScaler",
ApplianceType: "loadbalancer",
SubjectCNPatterns: []string{
"NetScaler", "Citrix ADC", "ns.citrix", "citrix.com",
},
SubjectOrgPatterns: []string{"Citrix"},
IssuerOrgPatterns: []string{"Citrix"},
},
// Juniper
{
Vendor: "Juniper",
Product: "Junos",
ApplianceType: "firewall",
SubjectCNPatterns: []string{
"Juniper", "JunOS", "SRX", "juniper.net",
},
SubjectOrgPatterns: []string{"Juniper Networks"},
IssuerOrgPatterns: []string{"Juniper Networks"},
VersionRegex: `(?i)SRX[_-]?(\d+)`,
},
// Barracuda
{
Vendor: "Barracuda",
Product: "Barracuda",
ApplianceType: "waf",
SubjectCNPatterns: []string{
"Barracuda", "barracuda", "cudatel",
},
SubjectOrgPatterns: []string{"Barracuda Networks"},
IssuerOrgPatterns: []string{"Barracuda Networks"},
},
// pfSense
{
Vendor: "Netgate",
Product: "pfSense",
ApplianceType: "firewall",
SubjectCNPatterns: []string{
"pfSense", "pfsense", "Netgate",
},
SubjectOrgPatterns: []string{"pfSense", "Netgate"},
},
// OPNsense
{
Vendor: "Deciso",
Product: "OPNsense",
ApplianceType: "firewall",
SubjectCNPatterns: []string{
"OPNsense", "opnsense",
},
},
// WatchGuard
{
Vendor: "WatchGuard",
Product: "Firebox",
ApplianceType: "firewall",
SubjectCNPatterns: []string{
"WatchGuard", "Firebox", "watchguard",
},
SubjectOrgPatterns: []string{"WatchGuard"},
},
// Sophos
{
Vendor: "Sophos",
Product: "XG Firewall",
ApplianceType: "firewall",
SubjectCNPatterns: []string{
"Sophos", "sophos", "XG Firewall", "Cyberoam",
},
SubjectOrgPatterns: []string{"Sophos"},
},
// Ubiquiti
{
Vendor: "Ubiquiti",
Product: "UniFi",
ApplianceType: "appliance",
SubjectCNPatterns: []string{
"Ubiquiti", "UniFi", "UBNT", "ubnt.com",
},
SubjectOrgPatterns: []string{"Ubiquiti"},
},
// MikroTik
{
Vendor: "MikroTik",
Product: "RouterOS",
ApplianceType: "router",
SubjectCNPatterns: []string{
"MikroTik", "mikrotik", "RouterOS",
},
SubjectOrgPatterns: []string{"MikroTik"},
},
// OpenVPN
{
Vendor: "OpenVPN",
Product: "OpenVPN AS",
ApplianceType: "vpn",
SubjectCNPatterns: []string{
"OpenVPN", "openvpn",
},
SubjectOrgPatterns: []string{"OpenVPN"},
},
// Pulse Secure / Ivanti
{
Vendor: "Pulse Secure",
Product: "Pulse Connect Secure",
ApplianceType: "vpn",
SubjectCNPatterns: []string{
"Pulse Secure", "pulse", "Ivanti",
},
SubjectOrgPatterns: []string{"Pulse Secure", "Ivanti"},
},
// GlobalProtect (Palo Alto VPN)
{
Vendor: "Palo Alto Networks",
Product: "GlobalProtect",
ApplianceType: "vpn",
SubjectCNPatterns: []string{
"GlobalProtect", "globalprotect",
},
},
// Cisco AnyConnect
{
Vendor: "Cisco",
Product: "AnyConnect",
ApplianceType: "vpn",
SubjectCNPatterns: []string{
"AnyConnect", "anyconnect",
},
SubjectOrgPatterns: []string{"Cisco"},
},
// VMware NSX / vSphere
{
Vendor: "VMware",
Product: "NSX",
ApplianceType: "appliance",
SubjectCNPatterns: []string{
"NSX", "vSphere", "VMware", "vcenter",
},
SubjectOrgPatterns: []string{"VMware"},
},
// Imperva / Incapsula
{
Vendor: "Imperva",
Product: "WAF",
ApplianceType: "waf",
SubjectCNPatterns: []string{
"Imperva", "Incapsula",
},
SubjectOrgPatterns: []string{"Imperva", "Incapsula"},
},
// HAProxy
{
Vendor: "HAProxy",
Product: "HAProxy",
ApplianceType: "loadbalancer",
SubjectCNPatterns: []string{
"HAProxy", "haproxy",
},
},
// NGINX Plus
{
Vendor: "NGINX",
Product: "NGINX Plus",
ApplianceType: "loadbalancer",
SubjectCNPatterns: []string{
"NGINX", "nginx.com",
},
SubjectOrgPatterns: []string{"NGINX", "F5 NGINX"},
},
// Kemp LoadMaster
{
Vendor: "Kemp",
Product: "LoadMaster",
ApplianceType: "loadbalancer",
SubjectCNPatterns: []string{
"Kemp", "LoadMaster",
},
SubjectOrgPatterns: []string{"Kemp Technologies"},
},
// Zyxel
{
Vendor: "Zyxel",
Product: "USG",
ApplianceType: "firewall",
SubjectCNPatterns: []string{
"Zyxel", "zyxel", "USG",
},
SubjectOrgPatterns: []string{"Zyxel"},
},
// DrayTek
{
Vendor: "DrayTek",
Product: "Vigor",
ApplianceType: "router",
SubjectCNPatterns: []string{
"DrayTek", "Vigor", "draytek",
},
SubjectOrgPatterns: []string{"DrayTek"},
},
}
// AnalyzeTLSCertificate analyzes a TLS certificate for appliance fingerprinting
func AnalyzeTLSCertificate(cert *x509.Certificate) *config.TLSFingerprint {
if cert == nil {
return nil
}
fp := &config.TLSFingerprint{
SubjectCN: cert.Subject.CommonName,
SerialNumber: cert.SerialNumber.String(),
}
// Extract organization info
if len(cert.Subject.Organization) > 0 {
fp.SubjectOrg = strings.Join(cert.Subject.Organization, ", ")
}
if len(cert.Subject.OrganizationalUnit) > 0 {
fp.SubjectOU = strings.Join(cert.Subject.OrganizationalUnit, ", ")
}
if len(cert.Issuer.CommonName) > 0 {
fp.IssuerCN = cert.Issuer.CommonName
}
if len(cert.Issuer.Organization) > 0 {
fp.IssuerOrg = strings.Join(cert.Issuer.Organization, ", ")
}
// Extract internal hostnames from DNS names
for _, name := range cert.DNSNames {
if isInternalHostname(name) {
fp.InternalHosts = append(fp.InternalHosts, name)
}
}
// Try to match against known appliance patterns
matchAppliance(fp, cert)
// Only return if we found something interesting
if fp.Vendor != "" || len(fp.InternalHosts) > 0 || fp.SubjectOrg != "" {
return fp
}
return nil
}
// matchAppliance tries to identify the appliance vendor/product
func matchAppliance(fp *config.TLSFingerprint, cert *x509.Certificate) {
subjectCN := strings.ToLower(cert.Subject.CommonName)
subjectOrg := strings.ToLower(strings.Join(cert.Subject.Organization, " "))
subjectOU := strings.ToLower(strings.Join(cert.Subject.OrganizationalUnit, " "))
issuerCN := strings.ToLower(cert.Issuer.CommonName)
issuerOrg := strings.ToLower(strings.Join(cert.Issuer.Organization, " "))
for _, pattern := range appliancePatterns {
matched := false
// Check Subject CN
for _, p := range pattern.SubjectCNPatterns {
if strings.Contains(subjectCN, strings.ToLower(p)) {
matched = true
break
}
}
// Check Subject Organization
if !matched {
for _, p := range pattern.SubjectOrgPatterns {
if strings.Contains(subjectOrg, strings.ToLower(p)) {
matched = true
break
}
}
}
// Check Subject OU
if !matched {
for _, p := range pattern.SubjectOUPatterns {
if strings.Contains(subjectOU, strings.ToLower(p)) {
matched = true
break
}
}
}
// Check Issuer CN
if !matched {
for _, p := range pattern.IssuerCNPatterns {
if strings.Contains(issuerCN, strings.ToLower(p)) {
matched = true
break
}
}
}
// Check Issuer Organization
if !matched {
for _, p := range pattern.IssuerOrgPatterns {
if strings.Contains(issuerOrg, strings.ToLower(p)) {
matched = true
break
}
}
}
if matched {
fp.Vendor = pattern.Vendor
fp.Product = pattern.Product
fp.ApplianceType = pattern.ApplianceType
// Try to extract version
if pattern.VersionRegex != "" {
re := regexp.MustCompile(pattern.VersionRegex)
// Check all relevant fields
for _, field := range []string{cert.Subject.CommonName, cert.Issuer.CommonName} {
if matches := re.FindStringSubmatch(field); len(matches) > 1 {
fp.Version = matches[1]
break
}
}
}
return
}
}
}
// isInternalHostname checks if a hostname looks like an internal name
func isInternalHostname(name string) bool {
name = strings.ToLower(name)
// Common internal TLDs
internalTLDs := []string{
".local", ".internal", ".lan", ".corp", ".home",
".intranet", ".private", ".localdomain",
}
for _, tld := range internalTLDs {
if strings.HasSuffix(name, tld) {
return true
}
}
// Internal hostname patterns
internalPatterns := []string{
"localhost", "fw-", "firewall", "vpn-", "gw-", "gateway",
"proxy-", "lb-", "router", "switch", "core-", "dc-",
"srv-", "server-", "host-", "node-", "mgmt", "management",
"admin-", "internal-", "private-", "corp-", "office-",
}
for _, pattern := range internalPatterns {
if strings.Contains(name, pattern) {
return true
}
}
// IP-like patterns in hostname
ipPattern := regexp.MustCompile(`\d{1,3}[.-]\d{1,3}[.-]\d{1,3}[.-]\d{1,3}`)
if ipPattern.MatchString(name) {
return true
}
return false
}
// IsSelfSigned checks if a certificate is self-signed
func IsSelfSigned(cert *x509.Certificate) bool {
if cert == nil {
return false
}
// Check if issuer equals subject
if cert.Issuer.String() == cert.Subject.String() {
return true
}
// Check if it's self-signed by verifying against its own public key
err := cert.CheckSignatureFrom(cert)
return err == nil
}