Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Ofuscação de código em arquivos ELF utilizando relocação

Repositório com os materiais da palestra apresentada na Cryptorave 2026, em 09 de maio de 2026.

Sobre

Este trabalho explora uma técnica de ofuscação de código em binários ELF x86-64 que abusa do mecanismo de relocação dinâmica do runtime linker (ld.so).

A ideia central é simples: usar as entradas da seção SHT_RELA para sobrescrever trechos de código .text em tempo de execução, antes que o controle seja passado para o programa principal. O resultado é um executável cujo comportamento real só se revela em execução, dificultando tanto a análise estática quanto a dinâmica.

Destaques da técnica

  • O código ofuscado nunca aparece como estático no binário final
  • Breakpoints de depuradores (como o GDB) são sobrescritos em tempo de carga
  • A desofuscação acontece antes mesmo da primeira instrução do programa

Arquivos do repositório

code.s                     # Código original, payload: write("Hello, world!\n", 14)
evil.s                     # Código que será encodado na relocação, payload: execve("/bin/sh", 0, 0)
Makefile
README.md
relocation.asm             # Gerador de ELFs em ASM
relocation.c               # Gerador de ELFs em C, com geração dinâmica das sessões SHT_RELA
slide.pdf                  # Slides da palestra

Uso

Pré-requisitos

  • Ambiente Linux x86-64 com glibc
  • Vim (pelo programa xxd)
  • NASM (para compilar os arquivos code.s, evil.s e relocation.asm)
  • GDB (para observar o efeito nos breakpoints)

Gerando exemplos ofuscados

make

Observando o efeito da técnica

asm.out

# Abra o binário asm.out no GDB
# Inicie a execução
gdb ./asm.out
(gdb) run                             # Iniciar o programa

# O programa sera interrompido na primeira instrução
# Os oito primeiros bytes do código original (um hello world simples) foram sobrescritos
# O payload é um int3 (0xcc)

c.out

# Abra o binário c.out no GDB
# Inicie a execução, tentando colocar um breakpoint na primeira instrução
gdb ./c.out
(gdb) set disassembly-flavor intel    # Opcional: Utilizar sintaxe Intel para o disassembly
(gdb) starti                          # Iniciar o programa e parar na primeira instrução
(gdb) info proc mappings              # Pegar o endereço virtual inicial (vaddr) do nosso executável
(gdb) info files                      # Pegar o offset do Entry Point (entry)
(gdb) print <vaddr> + <entry>         # Salvar o endereco do entry point em $1
(gdb) x/10i $1                        # Verificar se o código original (code.s) se encontra no endereço
(gdb) break *$1                       # Colocar um breakpoint na primeira instrução
(gdb) continue

# O breakpoint será sobrescrito pela relocação
# O programa continua executando sem parar
# O payload é um execve("/bin/sh", 0, 0) simples

Como funciona (resumo rápido)

  1. ELF mínimo: Criamos um binário ELF apenas com as seções realmente necessárias para o ld.so processar
  2. Código malicioso escondido: O código "verdadeiro" fica armazenado como dados em SHT_RELA (no campo r_addend)
  3. Relocação: Entradas de relocação do tipo R_X86_64_SIZE64 são usadas para armazenar esses bytes e copiar em tempo de execução
  4. Ordem de execução: A relocação substitui as instruções originais no entry point antes de passar a execução para o programa
ANTES da carga (estático)          DEPOIS da carga (dinâmico)
+----------------------+           +----------------------+
| .text com lixo       |           | .text reescrito      |
| (código original)    |   ld.so   | (código malicioso)   |
+----------------------+ --------> +----------------------+
| SHT_RELA             |           | SHT_RELA consumida   |
| (esconde o payload)  |           | (ainda legível)      |
+----------------------+           +----------------------+

Referências e trabalhos relacionados

Contributors

Languages