diff --git a/hola_mundo.py b/hola_mundo.py new file mode 100644 index 00000000..f552cdf8 --- /dev/null +++ b/hola_mundo.py @@ -0,0 +1,2 @@ +# Simple Hola Mundo program in Python +print("Hola Mundo") diff --git a/port_scanner.go b/port_scanner.go new file mode 100644 index 00000000..d454b204 --- /dev/null +++ b/port_scanner.go @@ -0,0 +1,133 @@ +package main + +import ( + "fmt" + "net" + "sync" + "time" + "sort" + "strings" +) + +// Mapeo básico de puertos a servicios comunes +var commonPorts = map[int]string{ + 20: "FTP-data", 21: "FTP", 22: "SSH", 23: "Telnet", + 25: "SMTP", 53: "DNS", 80: "HTTP", 110: "POP3", + 115: "SFTP", 135: "RPC", 139: "NetBIOS", 143: "IMAP", + 194: "IRC", 443: "HTTPS", 445: "SMB", 989: "FTPS-data", + 990: "FTPS", 1433: "MSSQL", 3306: "MySQL", 3389: "RDP", + 5432: "PostgreSQL", 5900: "VNC", 6379: "Redis", 8080: "HTTP-Proxy", + 8443: "HTTPS-Alt", 27017: "MongoDB", +} + +// Estructura para almacenar resultados +type ScanResult struct { + Port int + State string + Service string + Banner string +} + +func scanPort(ip string, port int, timeout time.Duration) ScanResult { + target := fmt.Sprintf("%s:%d", ip, port) + conn, err := net.DialTimeout("tcp", target, timeout) + + result := ScanResult{Port: port} + + if err != nil { + result.State = "closed" + return result + } + + defer conn.Close() + result.State = "open" + + // Intentar identificar el servicio + if service, exists := commonPorts[port]; exists { + result.Service = service + } else { + result.Service = "unknown" + } + + // Intentar obtener un banner + if conn != nil { + _ = conn.SetReadDeadline(time.Now().Add(1 * time.Second)) + banner := make([]byte, 1024) + _, err := conn.Read(banner) + if err == nil { + result.Banner = strings.TrimSpace(string(banner)) + if len(result.Banner) > 100 { + result.Banner = result.Banner[:100] + "..." + } + } + } + + return result +} + +func main() { + ip := "192.168.1.1" + fmt.Printf("Iniciando escaneo de puertos en %s\n", ip) + fmt.Println("---------------------------------------") + + // Lista de puertos a escanear + portsToScan := []int{} + + // Agregar los puertos comunes + for port := range commonPorts { + portsToScan = append(portsToScan, port) + } + + // Agregar algunos puertos adicionales comunes + additionalPorts := []int{8000, 8008, 8081, 8888, 9000, 9090} + portsToScan = append(portsToScan, additionalPorts...) + + // Ordenar puertos para una salida más legible + sort.Ints(portsToScan) + + // Configurar concurrencia + var wg sync.WaitGroup + var mutex sync.Mutex + results := make(map[int]ScanResult) + timeout := 500 * time.Millisecond + + // Limitar la concurrencia para evitar problemas + semaphore := make(chan struct{}, 100) + + for _, port := range portsToScan { + wg.Add(1) + semaphore <- struct{}{} + + go func(p int) { + defer wg.Done() + defer func() { <-semaphore }() + + result := scanPort(ip, p, timeout) + + mutex.Lock() + results[p] = result + mutex.Unlock() + }(port) + } + + wg.Wait() + + // Mostrar resultados + fmt.Println("PUERTO\tESTADO\tSERVICIO\tBANNER") + fmt.Println("---------------------------------------") + + openPorts := 0 + for _, port := range portsToScan { + if result, exists := results[port]; exists && result.State == "open" { + banner := result.Banner + if banner != "" { + banner = ": " + banner + } + fmt.Printf("%d\t%s\t%s\t%s\n", result.Port, result.State, result.Service, banner) + openPorts++ + } + } + + fmt.Println("---------------------------------------") + fmt.Printf("Escaneo completado: %d puertos abiertos encontrados en %s\n", openPorts, ip) +} diff --git a/port_scanner.py b/port_scanner.py new file mode 100644 index 00000000..aabbe8da --- /dev/null +++ b/port_scanner.py @@ -0,0 +1,52 @@ +import socket +import sys +from datetime import datetime + +# Define target +target = "192.168.1.1" +print(f"\nStarting scan on host: {target}") +print("-" * 50) + +# Get the current time when scan started +t1 = datetime.now() + +try: + # Scan common ports + common_ports = [21, 22, 23, 25, 53, 80, 110, 111, 135, 139, 143, 443, 445, 993, 995, 1723, 3306, 3389, 5900, 8080] + + print(f"Scanning common ports on {target}...") + + for port in common_ports: + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + socket.setdefaulttimeout(1) + + # Returns an error indicator + result = s.connect_ex((target, port)) + + if result == 0: + try: + service = socket.getservbyport(port) + print(f"Port {port}: OPEN - {service}") + except: + print(f"Port {port}: OPEN - Unknown service") + s.close() + + # Get the current time when scan completed + t2 = datetime.now() + + # Calculate the difference of time to know how long the scan took + total = t2 - t1 + + # Print the information to screen + print("-" * 50) + print(f"Scanning completed in: {total}") + +except KeyboardInterrupt: + print("\nExiting program.") + sys.exit() +except socket.gaierror: + print("\nHostname could not be resolved.") + sys.exit() +except socket.error: + print("\nServer not responding.") + sys.exit() diff --git a/portscan.go b/portscan.go new file mode 100644 index 00000000..ee364d55 --- /dev/null +++ b/portscan.go @@ -0,0 +1,152 @@ +package main + +import ( + "fmt" + "net" + "strconv" + "sync" + "time" +) + +// Lista de puertos comunes para escanear +var commonPorts = []int{ + 20, 21, 22, 23, 25, 53, 80, 88, 110, 111, 135, 139, 143, + 443, 445, 465, 587, 993, 995, 1433, 1434, 3306, 3389, 5900, + 5901, 8080, 8443, 8888, +} + +// Información básica sobre servicios comunes por puerto +var serviceMap = map[int]string{ + 20: "FTP (data)", + 21: "FTP (control)", + 22: "SSH", + 23: "Telnet", + 25: "SMTP", + 53: "DNS", + 80: "HTTP", + 88: "Kerberos", + 110: "POP3", + 111: "RPC", + 135: "MSRPC", + 139: "NetBIOS", + 143: "IMAP", + 443: "HTTPS", + 445: "SMB", + 465: "SMTPS", + 587: "SMTP (submission)", + 993: "IMAPS", + 995: "POP3S", + 1433: "MSSQL", + 1434: "MSSQL Browser", + 3306: "MySQL", + 3389: "RDP", + 5900: "VNC", + 5901: "VNC", + 8080: "HTTP (alternate)", + 8443: "HTTPS (alternate)", + 8888: "HTTP (alternate)", +} + +// Estructura para almacenar resultados +type ScanResult struct { + Port int + Status string + Service string +} + +func scanPort(ip string, port int, wg *sync.WaitGroup, results chan<- ScanResult) { + defer wg.Done() + + address := ip + ":" + strconv.Itoa(port) + conn, err := net.DialTimeout("tcp", address, 500*time.Millisecond) + + if err != nil { + // Puerto cerrado o filtrado + return + } + defer conn.Close() + + service := "Unknown" + if serviceName, ok := serviceMap[port]; ok { + service = serviceName + } + + results <- ScanResult{Port: port, Status: "open", Service: service} +} + +func grabBanner(ip string, port int) string { + address := ip + ":" + strconv.Itoa(port) + conn, err := net.DialTimeout("tcp", address, 1*time.Second) + if err != nil { + return "" + } + defer conn.Close() + + // Establecer un timeout para la lectura del banner + conn.SetReadDeadline(time.Now().Add(1 * time.Second)) + + // Buffer para recibir datos + buffer := make([]byte, 1024) + + // Intentar leer el banner + _, err = conn.Read(buffer) + if err != nil { + return "" + } + + return string(buffer) +} + +func main() { + target := "192.168.1.1" + fmt.Printf("Iniciando escaneo de puertos en %s\n", target) + fmt.Println("================================================") + + // Canal para recopilar resultados + results := make(chan ScanResult, len(commonPorts)) + + // WaitGroup para sincronizar goroutines + var wg sync.WaitGroup + + // Escanear puertos comunes + for _, port := range commonPorts { + wg.Add(1) + go scanPort(target, port, &wg, results) + } + + // Crear una goroutine para cerrar el canal cuando todas las goroutines de escaneo terminen + go func() { + wg.Wait() + close(results) + }() + + // Recopilar resultados + var openPorts []ScanResult + for result := range results { + openPorts = append(openPorts, result) + } + + // Mostrar resultados de forma organizada + if len(openPorts) == 0 { + fmt.Println("No se encontraron puertos abiertos.") + } else { + fmt.Printf("Encontrados %d puertos abiertos:\n\n", len(openPorts)) + fmt.Printf("%-10s %-15s %s\n", "PUERTO", "SERVICIO", "DETALLES") + fmt.Println("------------------------------------------") + + for _, r := range openPorts { + banner := grabBanner(target, r.Port) + bannerInfo := "" + if banner != "" { + if len(banner) > 40 { + bannerInfo = banner[:40] + "..." + } else { + bannerInfo = banner + } + } + fmt.Printf("%-10d %-15s %s\n", r.Port, r.Service, bannerInfo) + } + } + + fmt.Println("\nEscaneo finalizado.") +} diff --git a/scan_ip.py b/scan_ip.py new file mode 100644 index 00000000..e40ec954 --- /dev/null +++ b/scan_ip.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 +import socket +import sys +from datetime import datetime +import concurrent.futures + +# Define the target +target = "192.168.1.1" +print(f"Starting scan of {target} at {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") + +# Function to scan a single port +def scan_port(port): + try: + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + s.settimeout(1) + result = s.connect_ex((target, port)) + if result == 0: + try: + service = socket.getservbyport(port) + return f"Port {port}: OPEN - {service}" + except: + return f"Port {port}: OPEN - Unknown service" + s.close() + except: + pass + return None + +# List of common ports to scan +common_ports = [20, 21, 22, 23, 25, 53, 80, 110, 123, 143, 443, 445, 3389, 8080, 8443] + +print(f"Scanning common ports on {target}...") + +# Use a thread pool to scan ports in parallel +with concurrent.futures.ThreadPoolExecutor(max_workers=25) as executor: + results = executor.map(scan_port, common_ports) + + # Print results + for result in results: + if result: + print(result) + +# Now do a scan of the first 1000 ports +print(f"\nScanning ports 1-1000 on {target}...") +open_ports = [] + +with concurrent.futures.ThreadPoolExecutor(max_workers=50) as executor: + results = executor.map(scan_port, range(1, 1001)) + + for result in results: + if result: + print(result) + +print(f"Scan completed at {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") diff --git a/scanner b/scanner new file mode 100755 index 00000000..3a286057 Binary files /dev/null and b/scanner differ diff --git a/simple_scanner.go b/simple_scanner.go new file mode 100644 index 00000000..6a5ca7ed --- /dev/null +++ b/simple_scanner.go @@ -0,0 +1,111 @@ +package main + +import ( + "fmt" + "net" + "sort" + "sync" + "time" +) + +// Mapeo básico de puertos a servicios comunes +var commonPorts = map[int]string{ + 20: "FTP-data", 21: "FTP", 22: "SSH", 23: "Telnet", + 25: "SMTP", 53: "DNS", 80: "HTTP", 110: "POP3", + 143: "IMAP", 443: "HTTPS", 445: "SMB", 3306: "MySQL", + 3389: "RDP", 8080: "HTTP-Proxy", 8443: "HTTPS-Alt", +} + +// Estructura para almacenar resultados +type ScanResult struct { + Port int + State string + Service string +} + +func scanPort(ip string, port int, timeout time.Duration) ScanResult { + target := fmt.Sprintf("%s:%d", ip, port) + conn, err := net.DialTimeout("tcp", target, timeout) + + result := ScanResult{Port: port} + + if err != nil { + result.State = "closed" + return result + } + + defer conn.Close() + result.State = "open" + + // Identificar el servicio + if service, exists := commonPorts[port]; exists { + result.Service = service + } else { + result.Service = "unknown" + } + + return result +} + +func main() { + ip := "192.168.1.1" + fmt.Printf("Iniciando escaneo de puertos en %s\n", ip) + fmt.Println("---------------------------------------") + + // Lista de puertos a escanear + portsToScan := []int{} + + // Agregar los puertos comunes + for port := range commonPorts { + portsToScan = append(portsToScan, port) + } + + // Agregar algunos puertos adicionales + additionalPorts := []int{8000, 8008, 8081, 8888, 9000, 9090} + portsToScan = append(portsToScan, additionalPorts...) + + // Ordenar puertos + sort.Ints(portsToScan) + + // Configurar concurrencia + var wg sync.WaitGroup + var mutex sync.Mutex + results := make(map[int]ScanResult) + timeout := 500 * time.Millisecond + + // Limitar la concurrencia + semaphore := make(chan struct{}, 50) + + for _, port := range portsToScan { + wg.Add(1) + semaphore <- struct{}{} + + go func(p int) { + defer wg.Done() + defer func() { <-semaphore }() + + result := scanPort(ip, p, timeout) + + mutex.Lock() + results[p] = result + mutex.Unlock() + }(port) + } + + wg.Wait() + + // Mostrar resultados + fmt.Println("PUERTO\tESTADO\tSERVICIO") + fmt.Println("---------------------------------------") + + openPorts := 0 + for _, port := range portsToScan { + if result, exists := results[port]; exists && result.State == "open" { + fmt.Printf("%d\t%s\t%s\n", result.Port, result.State, result.Service) + openPorts++ + } + } + + fmt.Println("---------------------------------------") + fmt.Printf("Escaneo completado: %d puertos abiertos encontrados en %s\n", openPorts, ip) +} diff --git a/src/cai/util.py b/src/cai/util.py index f786d7a3..00e4bbd4 100644 --- a/src/cai/util.py +++ b/src/cai/util.py @@ -27,6 +27,7 @@ from rich.panel import Panel from rich.console import Group from rich.box import ROUNDED from rich.table import Table +import re # Global timing variables for tracking active and idle time _active_timer_start = None @@ -1913,62 +1914,105 @@ def _create_tool_panel_content(tool_name, args, output, execution_info=None, tok # Determine if we need specialized content formatting group_content = [header] - # Special handling for execute_code tool if tool_name == "execute_code" and isinstance(args, dict): - command_type = args.get("command") - actual_code = args.get("code") - language = args.get("language", "python") # Default to python - - # For execute command, show code and output panels - if command_type == "execute" and actual_code: - # Ensure language is a string for Syntax - language_str = get_language_from_code_block(str(language)) + command = args.get("command") + code_from_code_key = args.get("code") + language_from_lang_key = args.get("language", "python") + args_str_payload = args.get("args") + + panel1_content_str = None + panel1_language_name = "text" + panel1_title = "Executed Command Details" + panel1_border_style = "cyan" # Default for "executed code" + + if command == "execute" and code_from_code_key: + pass + elif args_str_payload: # Covers 'cat << EOF', 'python3 script.py' + panel1_content_str = args_str_payload + inferred_lang_for_args = "text" # Default + + if command and command.lower() == "cat" and \ + ("<<" in args_str_payload or ">" in args_str_payload): + # For cat with heredoc/redirection, infer from target file + match = re.search(r'(?:>|>>)\s*([\w\./-]+\.\w+)', + args_str_payload) + if match: + filename = match.group(1) + ext = filename.split('.')[-1] if '.' in filename else "" + inferred_lang_for_args = get_language_from_code_block(ext) + else: + inferred_lang_for_args = get_language_from_code_block("bash") + elif re.match(r'^[\w\./-]+\.\w+$', args_str_payload.strip()): + # If args_str_payload is a filename like "script.py" + filename = args_str_payload.strip() + ext = filename.split('.')[-1] if '.' in filename else "" + inferred_lang_for_args = get_language_from_code_block(ext) + else: + # General arguments string, could be JSON, XML, or just text/bash + try: + json.loads(args_str_payload) + inferred_lang_for_args = "json" + except json.JSONDecodeError: + if args_str_payload.strip().startswith("<") and \ + args_str_payload.strip().endswith(">"): + inferred_lang_for_args = "xml" + elif command: # Default to bash if it's for a known command + inferred_lang_for_args = get_language_from_code_block("bash") - code_syntax = Syntax(actual_code, language_str, theme="monokai", - line_numbers=True, background_color="#272822", - indent_guides=True, word_wrap=True) - code_panel = Panel( - code_syntax, - title=f"Code ({language_str})", - border_style="cyan", + panel1_language_name = inferred_lang_for_args + panel1_title = f"Code ({panel1_language_name})" + panel1_border_style = "yellow" + + if panel1_content_str is not None: + syntax_obj_panel1 = Syntax( + panel1_content_str, + panel1_language_name, + theme="monokai", + line_numbers=True, + background_color="#272822", + indent_guides=True, + word_wrap=True + ) + actual_panel1 = Panel( + syntax_obj_panel1, + title=panel1_title, + border_style=panel1_border_style, title_align="left", box=ROUNDED, - padding=(0,1) + padding=(0, 1) ) - group_content.extend([Text("\n"), code_panel]) + group_content.extend([Text("\n"), actual_panel1]) + + if output: + output_lang_name = "text" + try: + json.loads(output) + output_lang_name = "json" + except json.JSONDecodeError: + if output.strip().startswith("<") and \ + output.strip().endswith(">") and \ + "