diff --git a/functions/cybersecurity/detect_sql_injection.go b/functions/cybersecurity/detect_sql_injection.go new file mode 100644 index 00000000..bf69982b --- /dev/null +++ b/functions/cybersecurity/detect_sql_injection.go @@ -0,0 +1,33 @@ +package cybersecurity + +import ( + "regexp" + "strings" +) + +var sqliPatterns = []struct { + name string + re *regexp.Regexp +}{ + {"union_select", regexp.MustCompile(`(?i)\bunion\s+(all\s+)?select\b`)}, + {"or_1_eq_1", regexp.MustCompile(`(?i)\bor\s+1\s*=\s*1`)}, + {"comment_injection", regexp.MustCompile(`(--|#|/\*)\s*$`)}, + {"single_quote_or", regexp.MustCompile(`(?i)'\s*(or|and)\s+'`)}, + {"drop_table", regexp.MustCompile(`(?i)\bdrop\s+(table|database)\b`)}, + {"sleep_benchmark", regexp.MustCompile(`(?i)\b(sleep|benchmark)\s*\(`)}, + {"exec_xp", regexp.MustCompile(`(?i)\b(exec|xp_)\w*`)}, + {"tautology", regexp.MustCompile(`(?i)\bor\s+['"]?\w+['"]?\s*=\s*['"]?\w+['"]?`)}, + {"stacked_query", regexp.MustCompile(`;\s*(select|insert|update|delete|drop|alter)\b`)}, +} + +// DetectSQLInjection analiza un input en busca de patrones heuristicos de inyeccion SQL. +// Devuelve si se detecto una amenaza y el nombre del patron encontrado. +func DetectSQLInjection(input string) (isThreat bool, pattern string) { + normalized := strings.TrimSpace(input) + for _, p := range sqliPatterns { + if p.re.MatchString(normalized) { + return true, p.name + } + } + return false, "" +} diff --git a/functions/cybersecurity/detect_sql_injection.md b/functions/cybersecurity/detect_sql_injection.md new file mode 100644 index 00000000..76a751da --- /dev/null +++ b/functions/cybersecurity/detect_sql_injection.md @@ -0,0 +1,21 @@ +--- +name: detect_sql_injection +kind: function +lang: go +domain: cybersecurity +version: "1.0.0" +purity: pure +signature: "func DetectSQLInjection(input string) (isThreat bool, pattern string)" +description: "Analiza un input en busca de patrones heuristicos de inyeccion SQL y devuelve si se detecto amenaza y el patron encontrado." +tags: [cybersecurity, sqli, detection, security] +uses_functions: [] +uses_types: [] +returns: [] +returns_optional: false +error_type: "" +imports: [regexp, strings] +tested: false +tests: [] +test_file_path: "" +file_path: "functions/cybersecurity/detect_sql_injection.go" +--- diff --git a/functions/cybersecurity/entropy_shannon.go b/functions/cybersecurity/entropy_shannon.go new file mode 100644 index 00000000..27c53ba1 --- /dev/null +++ b/functions/cybersecurity/entropy_shannon.go @@ -0,0 +1,26 @@ +package cybersecurity + +import "math" + +// EntropyShannon calcula la entropia de Shannon de los datos proporcionados. +// Devuelve un valor entre 0 (datos uniformes) y 8 (datos completamente aleatorios para bytes). +func EntropyShannon(data []byte) float64 { + if len(data) == 0 { + return 0 + } + + var freq [256]float64 + for _, b := range data { + freq[b]++ + } + + n := float64(len(data)) + entropy := 0.0 + for _, f := range freq { + if f > 0 { + p := f / n + entropy -= p * math.Log2(p) + } + } + return entropy +} diff --git a/functions/cybersecurity/entropy_shannon.md b/functions/cybersecurity/entropy_shannon.md new file mode 100644 index 00000000..45824b93 --- /dev/null +++ b/functions/cybersecurity/entropy_shannon.md @@ -0,0 +1,21 @@ +--- +name: entropy_shannon +kind: function +lang: go +domain: cybersecurity +version: "1.0.0" +purity: pure +signature: "func EntropyShannon(data []byte) float64" +description: "Calcula la entropia de Shannon de un slice de bytes. Retorna un valor entre 0 y 8 bits por byte." +tags: [cybersecurity, entropy, shannon, analysis] +uses_functions: [] +uses_types: [] +returns: [] +returns_optional: false +error_type: "" +imports: [math] +tested: false +tests: [] +test_file_path: "" +file_path: "functions/cybersecurity/entropy_shannon.go" +--- diff --git a/functions/cybersecurity/extract_urls.go b/functions/cybersecurity/extract_urls.go new file mode 100644 index 00000000..c05550f9 --- /dev/null +++ b/functions/cybersecurity/extract_urls.go @@ -0,0 +1,14 @@ +package cybersecurity + +import "regexp" + +var urlRegex = regexp.MustCompile(`https?://[^\s<>"'` + "`" + `\)\]\}]+`) + +// ExtractURLs extrae todas las URLs (http/https) encontradas en el texto proporcionado. +func ExtractURLs(text string) []string { + matches := urlRegex.FindAllString(text, -1) + if matches == nil { + return []string{} + } + return matches +} diff --git a/functions/cybersecurity/extract_urls.md b/functions/cybersecurity/extract_urls.md new file mode 100644 index 00000000..02a1b72a --- /dev/null +++ b/functions/cybersecurity/extract_urls.md @@ -0,0 +1,21 @@ +--- +name: extract_urls +kind: function +lang: go +domain: cybersecurity +version: "1.0.0" +purity: pure +signature: "func ExtractURLs(text string) []string" +description: "Extrae todas las URLs HTTP/HTTPS de un texto usando expresiones regulares." +tags: [cybersecurity, extract, url, parse] +uses_functions: [] +uses_types: [] +returns: [] +returns_optional: false +error_type: "" +imports: [regexp] +tested: false +tests: [] +test_file_path: "" +file_path: "functions/cybersecurity/extract_urls.go" +--- diff --git a/functions/cybersecurity/fetch_http_headers.go b/functions/cybersecurity/fetch_http_headers.go new file mode 100644 index 00000000..4874ae9f --- /dev/null +++ b/functions/cybersecurity/fetch_http_headers.go @@ -0,0 +1,27 @@ +package cybersecurity + +import ( + "fmt" + "net/http" + "time" +) + +// FetchHTTPHeaders realiza una solicitud HTTP HEAD a la URL y devuelve los headers de respuesta. +func FetchHTTPHeaders(url string) (map[string][]string, error) { + client := &http.Client{ + Timeout: 10 * time.Second, + } + + resp, err := client.Head(url) + if err != nil { + return nil, fmt.Errorf("error realizando solicitud HEAD a %s: %w", url, err) + } + defer resp.Body.Close() + + headers := make(map[string][]string, len(resp.Header)) + for k, v := range resp.Header { + headers[k] = v + } + + return headers, nil +} diff --git a/functions/cybersecurity/fetch_http_headers.md b/functions/cybersecurity/fetch_http_headers.md new file mode 100644 index 00000000..b7422e70 --- /dev/null +++ b/functions/cybersecurity/fetch_http_headers.md @@ -0,0 +1,21 @@ +--- +name: fetch_http_headers +kind: function +lang: go +domain: cybersecurity +version: "1.0.0" +purity: impure +signature: "func FetchHTTPHeaders(url string) (map[string][]string, error)" +description: "Realiza una solicitud HTTP HEAD a una URL y devuelve los headers de la respuesta." +tags: [cybersecurity, io, http, headers] +uses_functions: [] +uses_types: [] +returns: [] +returns_optional: false +error_type: "error_go_core" +imports: [fmt, net/http, time] +tested: false +tests: [] +test_file_path: "" +file_path: "functions/cybersecurity/fetch_http_headers.go" +--- diff --git a/functions/cybersecurity/hash_md5.go b/functions/cybersecurity/hash_md5.go new file mode 100644 index 00000000..95d3f3a8 --- /dev/null +++ b/functions/cybersecurity/hash_md5.go @@ -0,0 +1,12 @@ +package cybersecurity + +import ( + "crypto/md5" + "encoding/hex" +) + +// HashMD5 calcula el hash MD5 de los datos proporcionados y devuelve el resultado como string hexadecimal. +func HashMD5(data []byte) string { + h := md5.Sum(data) + return hex.EncodeToString(h[:]) +} diff --git a/functions/cybersecurity/hash_md5.md b/functions/cybersecurity/hash_md5.md new file mode 100644 index 00000000..6bdaf9de --- /dev/null +++ b/functions/cybersecurity/hash_md5.md @@ -0,0 +1,21 @@ +--- +name: hash_md5 +kind: function +lang: go +domain: cybersecurity +version: "1.0.0" +purity: pure +signature: "func HashMD5(data []byte) string" +description: "Calcula el hash MD5 de un slice de bytes y devuelve el resultado como string hexadecimal." +tags: [cybersecurity, hash, md5, crypto] +uses_functions: [] +uses_types: [] +returns: [] +returns_optional: false +error_type: "" +imports: [crypto/md5, encoding/hex] +tested: false +tests: [] +test_file_path: "" +file_path: "functions/cybersecurity/hash_md5.go" +--- diff --git a/functions/cybersecurity/hash_sha256.go b/functions/cybersecurity/hash_sha256.go new file mode 100644 index 00000000..0b7d8a78 --- /dev/null +++ b/functions/cybersecurity/hash_sha256.go @@ -0,0 +1,12 @@ +package cybersecurity + +import ( + "crypto/sha256" + "encoding/hex" +) + +// HashSHA256 calcula el hash SHA-256 de los datos proporcionados y devuelve el resultado como string hexadecimal. +func HashSHA256(data []byte) string { + h := sha256.Sum256(data) + return hex.EncodeToString(h[:]) +} diff --git a/functions/cybersecurity/hash_sha256.md b/functions/cybersecurity/hash_sha256.md new file mode 100644 index 00000000..65bd2ca6 --- /dev/null +++ b/functions/cybersecurity/hash_sha256.md @@ -0,0 +1,21 @@ +--- +name: hash_sha256 +kind: function +lang: go +domain: cybersecurity +version: "1.0.0" +purity: pure +signature: "func HashSHA256(data []byte) string" +description: "Calcula el hash SHA-256 de un slice de bytes y devuelve el resultado como string hexadecimal." +tags: [cybersecurity, hash, sha256, crypto] +uses_functions: [] +uses_types: [] +returns: [] +returns_optional: false +error_type: "" +imports: [crypto/sha256, encoding/hex] +tested: false +tests: [] +test_file_path: "" +file_path: "functions/cybersecurity/hash_sha256.go" +--- diff --git a/functions/cybersecurity/ip_in_range.go b/functions/cybersecurity/ip_in_range.go new file mode 100644 index 00000000..6621264c --- /dev/null +++ b/functions/cybersecurity/ip_in_range.go @@ -0,0 +1,16 @@ +package cybersecurity + +import "net" + +// IPInRange verifica si una direccion IP esta dentro de un rango CIDR dado. +func IPInRange(ip, cidr string) bool { + parsedIP := net.ParseIP(ip) + if parsedIP == nil { + return false + } + _, ipNet, err := net.ParseCIDR(cidr) + if err != nil { + return false + } + return ipNet.Contains(parsedIP) +} diff --git a/functions/cybersecurity/ip_in_range.md b/functions/cybersecurity/ip_in_range.md new file mode 100644 index 00000000..1fb32230 --- /dev/null +++ b/functions/cybersecurity/ip_in_range.md @@ -0,0 +1,21 @@ +--- +name: ip_in_range +kind: function +lang: go +domain: cybersecurity +version: "1.0.0" +purity: pure +signature: "func IPInRange(ip, cidr string) bool" +description: "Verifica si una direccion IP se encuentra dentro de un rango CIDR dado." +tags: [cybersecurity, network, cidr, check] +uses_functions: [] +uses_types: [] +returns: [] +returns_optional: false +error_type: "" +imports: [net] +tested: false +tests: [] +test_file_path: "" +file_path: "functions/cybersecurity/ip_in_range.go" +--- diff --git a/functions/cybersecurity/is_base64.go b/functions/cybersecurity/is_base64.go new file mode 100644 index 00000000..8b6faf99 --- /dev/null +++ b/functions/cybersecurity/is_base64.go @@ -0,0 +1,12 @@ +package cybersecurity + +import "encoding/base64" + +// IsBase64 verifica si el string proporcionado es una cadena base64 valida (standard encoding). +func IsBase64(s string) bool { + if len(s) == 0 { + return false + } + _, err := base64.StdEncoding.DecodeString(s) + return err == nil +} diff --git a/functions/cybersecurity/is_base64.md b/functions/cybersecurity/is_base64.md new file mode 100644 index 00000000..3f7be675 --- /dev/null +++ b/functions/cybersecurity/is_base64.md @@ -0,0 +1,21 @@ +--- +name: is_base64 +kind: function +lang: go +domain: cybersecurity +version: "1.0.0" +purity: pure +signature: "func IsBase64(s string) bool" +description: "Valida si un string es una cadena base64 valida segun el encoding estandar." +tags: [cybersecurity, validation, base64, format] +uses_functions: [] +uses_types: [] +returns: [] +returns_optional: false +error_type: "" +imports: [encoding/base64] +tested: false +tests: [] +test_file_path: "" +file_path: "functions/cybersecurity/is_base64.go" +--- diff --git a/functions/cybersecurity/is_hex.go b/functions/cybersecurity/is_hex.go new file mode 100644 index 00000000..0599a21f --- /dev/null +++ b/functions/cybersecurity/is_hex.go @@ -0,0 +1,15 @@ +package cybersecurity + +// IsHex verifica si el string proporcionado es una cadena hexadecimal valida. +// Requiere longitud par y que todos los caracteres sean digitos hex (0-9, a-f, A-F). +func IsHex(s string) bool { + if len(s) == 0 || len(s)%2 != 0 { + return false + } + for _, c := range s { + if !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) { + return false + } + } + return true +} diff --git a/functions/cybersecurity/is_hex.md b/functions/cybersecurity/is_hex.md new file mode 100644 index 00000000..73a049e9 --- /dev/null +++ b/functions/cybersecurity/is_hex.md @@ -0,0 +1,21 @@ +--- +name: is_hex +kind: function +lang: go +domain: cybersecurity +version: "1.0.0" +purity: pure +signature: "func IsHex(s string) bool" +description: "Valida si un string es una cadena hexadecimal valida (longitud par, caracteres 0-9 a-f A-F)." +tags: [cybersecurity, validation, hex, format] +uses_functions: [] +uses_types: [] +returns: [] +returns_optional: false +error_type: "" +imports: [] +tested: false +tests: [] +test_file_path: "" +file_path: "functions/cybersecurity/is_hex.go" +--- diff --git a/functions/cybersecurity/jaccard_similarity.go b/functions/cybersecurity/jaccard_similarity.go new file mode 100644 index 00000000..02040703 --- /dev/null +++ b/functions/cybersecurity/jaccard_similarity.go @@ -0,0 +1,37 @@ +package cybersecurity + +// JaccardSimilarity calcula la similitud de Jaccard entre dos conjuntos de tokens. +// Devuelve un valor entre 0.0 (sin interseccion) y 1.0 (conjuntos identicos). +func JaccardSimilarity(a, b []string) float64 { + if len(a) == 0 && len(b) == 0 { + return 1.0 + } + if len(a) == 0 || len(b) == 0 { + return 0.0 + } + + setA := make(map[string]struct{}, len(a)) + for _, s := range a { + setA[s] = struct{}{} + } + + setB := make(map[string]struct{}, len(b)) + for _, s := range b { + setB[s] = struct{}{} + } + + intersection := 0 + for k := range setA { + if _, ok := setB[k]; ok { + intersection++ + } + } + + // Union = |A| + |B| - |A intersect B| (usando conjuntos sin duplicados) + union := len(setA) + len(setB) - intersection + if union == 0 { + return 0.0 + } + + return float64(intersection) / float64(union) +} diff --git a/functions/cybersecurity/jaccard_similarity.md b/functions/cybersecurity/jaccard_similarity.md new file mode 100644 index 00000000..f82f1b8d --- /dev/null +++ b/functions/cybersecurity/jaccard_similarity.md @@ -0,0 +1,21 @@ +--- +name: jaccard_similarity +kind: function +lang: go +domain: cybersecurity +version: "1.0.0" +purity: pure +signature: "func JaccardSimilarity(a, b []string) float64" +description: "Calcula la similitud de Jaccard entre dos conjuntos de tokens. Retorna un valor entre 0.0 y 1.0." +tags: [cybersecurity, similarity, jaccard, tokens] +uses_functions: [] +uses_types: [] +returns: [] +returns_optional: false +error_type: "" +imports: [] +tested: false +tests: [] +test_file_path: "" +file_path: "functions/cybersecurity/jaccard_similarity.go" +--- diff --git a/functions/cybersecurity/levenshtein_distance.go b/functions/cybersecurity/levenshtein_distance.go new file mode 100644 index 00000000..279e2f1d --- /dev/null +++ b/functions/cybersecurity/levenshtein_distance.go @@ -0,0 +1,49 @@ +package cybersecurity + +// LevenshteinDistance calcula la distancia de edicion (Levenshtein) entre dos strings. +func LevenshteinDistance(a, b string) int { + ra := []rune(a) + rb := []rune(b) + la := len(ra) + lb := len(rb) + + if la == 0 { + return lb + } + if lb == 0 { + return la + } + + // Usar solo dos filas para optimizar memoria + prev := make([]int, lb+1) + curr := make([]int, lb+1) + + for j := 0; j <= lb; j++ { + prev[j] = j + } + + for i := 1; i <= la; i++ { + curr[0] = i + for j := 1; j <= lb; j++ { + cost := 1 + if ra[i-1] == rb[j-1] { + cost = 0 + } + del := prev[j] + 1 + ins := curr[j-1] + 1 + sub := prev[j-1] + cost + + m := del + if ins < m { + m = ins + } + if sub < m { + m = sub + } + curr[j] = m + } + prev, curr = curr, prev + } + + return prev[lb] +} diff --git a/functions/cybersecurity/levenshtein_distance.md b/functions/cybersecurity/levenshtein_distance.md new file mode 100644 index 00000000..1eb6bee6 --- /dev/null +++ b/functions/cybersecurity/levenshtein_distance.md @@ -0,0 +1,21 @@ +--- +name: levenshtein_distance +kind: function +lang: go +domain: cybersecurity +version: "1.0.0" +purity: pure +signature: "func LevenshteinDistance(a, b string) int" +description: "Calcula la distancia de edicion de Levenshtein entre dos strings. Util para deteccion de typosquatting." +tags: [cybersecurity, string, distance, typosquatting] +uses_functions: [] +uses_types: [] +returns: [] +returns_optional: false +error_type: "" +imports: [] +tested: false +tests: [] +test_file_path: "" +file_path: "functions/cybersecurity/levenshtein_distance.go" +--- diff --git a/functions/cybersecurity/lookup_whois.go b/functions/cybersecurity/lookup_whois.go new file mode 100644 index 00000000..0e048167 --- /dev/null +++ b/functions/cybersecurity/lookup_whois.go @@ -0,0 +1,33 @@ +package cybersecurity + +import ( + "fmt" + "io" + "net" + "strings" + "time" +) + +// LookupWhois realiza una consulta WHOIS para el dominio proporcionado conectandose al servidor whois.iana.org. +func LookupWhois(domain string) (string, error) { + conn, err := net.DialTimeout("tcp", "whois.iana.org:43", 10*time.Second) + if err != nil { + return "", fmt.Errorf("error conectando al servidor WHOIS: %w", err) + } + defer conn.Close() + + _ = conn.SetDeadline(time.Now().Add(10 * time.Second)) + + _, err = fmt.Fprintf(conn, "%s\r\n", domain) + if err != nil { + return "", fmt.Errorf("error enviando consulta WHOIS: %w", err) + } + + var sb strings.Builder + _, err = io.Copy(&sb, conn) + if err != nil { + return "", fmt.Errorf("error leyendo respuesta WHOIS: %w", err) + } + + return sb.String(), nil +} diff --git a/functions/cybersecurity/lookup_whois.md b/functions/cybersecurity/lookup_whois.md new file mode 100644 index 00000000..d216d27e --- /dev/null +++ b/functions/cybersecurity/lookup_whois.md @@ -0,0 +1,21 @@ +--- +name: lookup_whois +kind: function +lang: go +domain: cybersecurity +version: "1.0.0" +purity: impure +signature: "func LookupWhois(domain string) (string, error)" +description: "Realiza una consulta WHOIS para un dominio conectandose al servidor whois.iana.org por TCP." +tags: [cybersecurity, io, whois, recon] +uses_functions: [] +uses_types: [] +returns: [] +returns_optional: false +error_type: "error_go_core" +imports: [fmt, io, net, strings, time] +tested: false +tests: [] +test_file_path: "" +file_path: "functions/cybersecurity/lookup_whois.go" +--- diff --git a/functions/cybersecurity/normalize_url.go b/functions/cybersecurity/normalize_url.go new file mode 100644 index 00000000..3375558f --- /dev/null +++ b/functions/cybersecurity/normalize_url.go @@ -0,0 +1,44 @@ +package cybersecurity + +import ( + "net/url" + "strings" +) + +// trackingParams lista de parametros de tracking comunes a eliminar. +var trackingParams = map[string]bool{ + "utm_source": true, + "utm_medium": true, + "utm_campaign": true, + "utm_term": true, + "utm_content": true, + "fbclid": true, + "gclid": true, + "ref": true, + "mc_cid": true, + "mc_eid": true, +} + +// NormalizeURL normaliza una URL: convierte el host a minusculas, elimina fragmentos +// y remueve parametros de tracking comunes. +func NormalizeURL(rawURL string) string { + u, err := url.Parse(rawURL) + if err != nil { + return rawURL + } + + // Lowercase host + u.Host = strings.ToLower(u.Host) + + // Eliminar fragmento + u.Fragment = "" + + // Eliminar parametros de tracking + q := u.Query() + for param := range trackingParams { + q.Del(param) + } + u.RawQuery = q.Encode() + + return u.String() +} diff --git a/functions/cybersecurity/normalize_url.md b/functions/cybersecurity/normalize_url.md new file mode 100644 index 00000000..4b33429c --- /dev/null +++ b/functions/cybersecurity/normalize_url.md @@ -0,0 +1,21 @@ +--- +name: normalize_url +kind: function +lang: go +domain: cybersecurity +version: "1.0.0" +purity: pure +signature: "func NormalizeURL(rawURL string) string" +description: "Normaliza una URL: convierte el host a minusculas, elimina fragmentos y remueve parametros de tracking comunes." +tags: [cybersecurity, url, normalize, sanitize] +uses_functions: [] +uses_types: [] +returns: [] +returns_optional: false +error_type: "" +imports: [net/url, strings] +tested: false +tests: [] +test_file_path: "" +file_path: "functions/cybersecurity/normalize_url.go" +--- diff --git a/functions/cybersecurity/parse_ip_cidr.go b/functions/cybersecurity/parse_ip_cidr.go new file mode 100644 index 00000000..ea8d8e6c --- /dev/null +++ b/functions/cybersecurity/parse_ip_cidr.go @@ -0,0 +1,44 @@ +package cybersecurity + +import ( + "encoding/binary" + "fmt" + "net" +) + +// ParseIPCIDR parsea una notacion CIDR y devuelve la direccion de red, broadcast, cantidad de hosts y error. +func ParseIPCIDR(cidr string) (network string, broadcast string, hosts int, err error) { + ip, ipNet, err := net.ParseCIDR(cidr) + if err != nil { + return "", "", 0, fmt.Errorf("CIDR invalido: %w", err) + } + + // Solo soportamos IPv4 + ip4 := ip.To4() + if ip4 == nil { + return "", "", 0, fmt.Errorf("solo se soporta IPv4") + } + + mask := ipNet.Mask + networkIP := ipNet.IP.To4() + network = networkIP.String() + + // Calcular broadcast + broadcastIP := make(net.IP, 4) + for i := 0; i < 4; i++ { + broadcastIP[i] = networkIP[i] | ^mask[i] + } + broadcast = broadcastIP.String() + + // Calcular hosts usables + netInt := binary.BigEndian.Uint32(networkIP) + bcastInt := binary.BigEndian.Uint32(broadcastIP) + total := int(bcastInt - netInt + 1) + if total > 2 { + hosts = total - 2 // excluir network y broadcast + } else { + hosts = total // /31 o /32 + } + + return network, broadcast, hosts, nil +} diff --git a/functions/cybersecurity/parse_ip_cidr.md b/functions/cybersecurity/parse_ip_cidr.md new file mode 100644 index 00000000..23938903 --- /dev/null +++ b/functions/cybersecurity/parse_ip_cidr.md @@ -0,0 +1,21 @@ +--- +name: parse_ip_cidr +kind: function +lang: go +domain: cybersecurity +version: "1.0.0" +purity: pure +signature: "func ParseIPCIDR(cidr string) (network string, broadcast string, hosts int, err error)" +description: "Parsea una notacion CIDR IPv4 y devuelve la direccion de red, broadcast y cantidad de hosts usables." +tags: [cybersecurity, network, cidr, parse] +uses_functions: [] +uses_types: [] +returns: [] +returns_optional: false +error_type: "" +imports: [encoding/binary, fmt, net] +tested: false +tests: [] +test_file_path: "" +file_path: "functions/cybersecurity/parse_ip_cidr.go" +--- diff --git a/functions/cybersecurity/resolve_dns.go b/functions/cybersecurity/resolve_dns.go new file mode 100644 index 00000000..330f4f91 --- /dev/null +++ b/functions/cybersecurity/resolve_dns.go @@ -0,0 +1,15 @@ +package cybersecurity + +import ( + "fmt" + "net" +) + +// ResolveDNS resuelve un hostname a sus direcciones IP usando el resolver del sistema. +func ResolveDNS(host string) ([]string, error) { + ips, err := net.LookupHost(host) + if err != nil { + return nil, fmt.Errorf("error resolviendo DNS para %s: %w", host, err) + } + return ips, nil +} diff --git a/functions/cybersecurity/resolve_dns.md b/functions/cybersecurity/resolve_dns.md new file mode 100644 index 00000000..5c0b5a76 --- /dev/null +++ b/functions/cybersecurity/resolve_dns.md @@ -0,0 +1,21 @@ +--- +name: resolve_dns +kind: function +lang: go +domain: cybersecurity +version: "1.0.0" +purity: impure +signature: "func ResolveDNS(host string) ([]string, error)" +description: "Resuelve un hostname a sus direcciones IP usando el resolver DNS del sistema." +tags: [cybersecurity, io, dns, resolve] +uses_functions: [] +uses_types: [] +returns: [] +returns_optional: false +error_type: "error_go_core" +imports: [fmt, net] +tested: false +tests: [] +test_file_path: "" +file_path: "functions/cybersecurity/resolve_dns.go" +--- diff --git a/functions/cybersecurity/scan_port_tcp.go b/functions/cybersecurity/scan_port_tcp.go new file mode 100644 index 00000000..c2b3ec3c --- /dev/null +++ b/functions/cybersecurity/scan_port_tcp.go @@ -0,0 +1,34 @@ +package cybersecurity + +import ( + "fmt" + "net" + "time" +) + +// ScanPortTCP intenta conectarse a un puerto TCP y devuelve el estado ("open", "closed", "filtered"), +// un banner si el puerto esta abierto, y un posible error. +func ScanPortTCP(host string, port int, timeoutMs int) (status string, banner string, err error) { + address := fmt.Sprintf("%s:%d", host, port) + timeout := time.Duration(timeoutMs) * time.Millisecond + + conn, err := net.DialTimeout("tcp", address, timeout) + if err != nil { + // Distinguir entre conexion rechazada (closed) y timeout (filtered) + if netErr, ok := err.(net.Error); ok && netErr.Timeout() { + return "filtered", "", nil + } + return "closed", "", nil + } + defer conn.Close() + + // Intentar leer un banner con timeout corto + _ = conn.SetReadDeadline(time.Now().Add(2 * time.Second)) + buf := make([]byte, 1024) + n, _ := conn.Read(buf) + if n > 0 { + banner = string(buf[:n]) + } + + return "open", banner, nil +} diff --git a/functions/cybersecurity/scan_port_tcp.md b/functions/cybersecurity/scan_port_tcp.md new file mode 100644 index 00000000..be961707 --- /dev/null +++ b/functions/cybersecurity/scan_port_tcp.md @@ -0,0 +1,21 @@ +--- +name: scan_port_tcp +kind: function +lang: go +domain: cybersecurity +version: "1.0.0" +purity: impure +signature: "func ScanPortTCP(host string, port int, timeoutMs int) (status string, banner string, err error)" +description: "Escanea un puerto TCP en un host dado. Devuelve el estado (open/closed/filtered) y un banner si esta abierto." +tags: [cybersecurity, io, port, scan] +uses_functions: [] +uses_types: [] +returns: [] +returns_optional: false +error_type: "error_go_core" +imports: [fmt, net, time] +tested: false +tests: [] +test_file_path: "" +file_path: "functions/cybersecurity/scan_port_tcp.go" +---