feat: 16 funciones cybersecurity — análisis, crypto e IO de seguridad
12 funciones puras con implementación real: HashSHA256, HashMD5, EntropyShannon, IsBase64, IsHex, ExtractURLs, ParseIPCIDR, IPInRange, NormalizeURL, DetectSQLInjection, LevenshteinDistance, JaccardSimilarity 4 funciones impuras con implementación real (stdlib): LookupWhois, ResolveDNS, FetchHTTPHeaders, ScanPortTCP Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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, ""
|
||||
}
|
||||
@@ -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"
|
||||
---
|
||||
@@ -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
|
||||
}
|
||||
@@ -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"
|
||||
---
|
||||
@@ -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
|
||||
}
|
||||
@@ -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"
|
||||
---
|
||||
@@ -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
|
||||
}
|
||||
@@ -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"
|
||||
---
|
||||
@@ -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[:])
|
||||
}
|
||||
@@ -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"
|
||||
---
|
||||
@@ -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[:])
|
||||
}
|
||||
@@ -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"
|
||||
---
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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"
|
||||
---
|
||||
@@ -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
|
||||
}
|
||||
@@ -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"
|
||||
---
|
||||
@@ -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
|
||||
}
|
||||
@@ -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"
|
||||
---
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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"
|
||||
---
|
||||
@@ -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]
|
||||
}
|
||||
@@ -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"
|
||||
---
|
||||
@@ -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
|
||||
}
|
||||
@@ -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"
|
||||
---
|
||||
@@ -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()
|
||||
}
|
||||
@@ -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"
|
||||
---
|
||||
@@ -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
|
||||
}
|
||||
@@ -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"
|
||||
---
|
||||
@@ -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
|
||||
}
|
||||
@@ -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"
|
||||
---
|
||||
@@ -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
|
||||
}
|
||||
@@ -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"
|
||||
---
|
||||
Reference in New Issue
Block a user