Pular para o conteúdo
ryancamargoRyan Camargo — home
Todos os posts
labs~12min de leituraRyan Camargo

OverTheWire Bandit: Anotações dos Níveis 0–12

Um walkthrough amigável do OverTheWire Bandit, níveis 0–12 — SSH, arquivos ocultos, find, stderr, codificações e um hexdump que não acaba. Senhas omitidas, conforme as regras.

#ctf#overthewire#bandit#linux#writeup

Aviso de spoiler: Este post percorre os níveis 0–12 do OverTheWire Bandit. Se você está jogando, tente cada nível antes de ler. Seguindo as regras da OverTheWire para criadores de conteúdo, nenhuma senha é publicada aqui — toda credencial foi omitida. O Bandit é gratuito; se ele ajudar você, considere doar para a OverTheWire.

O Bandit é o wargame para iniciantes da OverTheWire e o primeiro que recomendo para quem quer ficar confortável na linha de comando do Linux. Não tem interface gráfica, não tem framework de exploração e não tem adivinhação: você se conecta por SSH, resolve um pequeno quebra-cabeça no sistema de arquivos e usa a senha encontrada para entrar no próximo nível.

Passei pelos níveis 0–12 ao longo de algumas noites. Estas são minhas anotações — organizadas, sem os becos sem saída e com os comandos que realmente usei. O objetivo não é decorar uma lista de respostas. É mostrar o ritmo: olhe para o que você tem, pergunte o que aquilo é e escolha a menor ferramenta que responde à pergunta.

Antes de Começar

Algumas notas práticas:

  • O host do jogo é bandit.labs.overthewire.org e a porta SSH é 2220, não a padrão 22.
  • Suas credenciais iniciais estão na página do nível 0 do Bandit. Não vou repetir a senha aqui.
  • A senha de cada nível serve para entrar no próximo. O nome de usuário muda: bandit0, bandit1, bandit2, e assim por diante.
  • Um terminal Linux/macOS é suficiente. No Windows, use o WSL.
  • Leia as mensagens de erro. Normalmente elas dizem exatamente o que deu errado.

O comando de login é assim:

ssh [email protected] -p 2220

Na primeira conexão, o SSH pergunta se você confia na impressão digital do host:

The authenticity of host '[bandit.labs.overthewire.org]:2220' can't be established.
ED25519 key fingerprint is SHA256:...
Are you sure you want to continue connecting (yes/no/[fingerprint])?

Digite yes se a impressão digital corresponder ao que você espera (ou se aceitar o risco para um host de jogo) e cole a senha da página do nível. A senha não aparece na tela — isso é normal.

Quando terminar, exit fecha a sessão. Depois entre como o próximo usuário com a senha que você encontrou.

Nível 0 — Entre e Leia o README

Depois de entrar, olhe ao redor:

ls

Há um único arquivo chamado readme. Leia:

cat readme

O arquivo explica as regras e termina com a senha do bandit1. Omiti a senha aqui:

The password you are looking for is: [redacted]

Esse é o ciclo inteiro. Saia e entre novamente como bandit1 com essa senha.

Nível 1 — Um Arquivo Chamado -

O próximo nível diz que a senha está em um arquivo chamado -. Se você tentar o óbvio, o shell parece travar:

cat -

Isso acontece porque muitas ferramentas Unix tratam um - sozinho como "leia da entrada padrão", não como "leia um arquivo chamado -". Você precisa deixar isso inequívoco passando um caminho:

ls -l
cat ./-

O prefixo ./ diz "a entrada chamada - no diretório atual". $PWD/- também funciona. Eu também verifiquei o que era o arquivo antes de lê-lo:

du ./-
file ./-

file informa que é texto ASCII, o que é um bom sinal. O cat então imprime a próxima senha, novamente omitida.

Nível 2 — Espaços no Nome do Arquivo

Desta vez o arquivo tem espaços no nome, além de hífens no começo:

ls
cat ./"--spaces in this filename--"

As aspas mantêm o nome inteiro como um único argumento. Sem elas, o shell divide o nome em vários argumentos e o cat reclama. O autocompletar com Tab ajuda muito aqui: digite cat ./--sp e pressione Tab; o shell completa o nome e escapa os espaços para você.

Nível 3 — Arquivos Ocultos

ls mostra um diretório inhere, mas dentro dele parece não haver nada:

cd inhere
ls

Nada. O arquivo está oculto, o que no Unix significa simplesmente que o nome começa com um ponto. Peça ao ls para incluir entradas ocultas:

ls -a

Agora você vê ...Hiding-From-You junto com os habituais . e ... A forma longa confirma que é um arquivo regular:

ls -la
cat ...Hiding-From-You

Os pontos iniciais fazem parte do nome; eles não significam "subir um diretório" a menos que o nome seja exatamente . ou ...

Nível 4 — O Arquivo Legível por Humanos

O diretório inhere contém dez arquivos chamados -file00 até -file09. O nível diz que apenas um é legível por humanos. Antes de despejar todos no terminal, pergunte ao sistema o que eles são:

file ./-file*

file identifica o tipo de cada um. Exatamente um é reportado como texto ASCII; os outros são dados. Leia esse:

cat ./-file07

(A resposta usual é -file07; use o arquivo que o file reportar como texto ASCII.)

Se você fizer o que eu fiz primeiro e rodar cat ./-file*, vai receber uma tela cheia de lixo binário e talvez um terminal quebrado. A correção é reset, ou simplesmente fechar a sessão e conectar de novo. file é a primeira jogada mais inteligente.

Nível 5 — Encontrar por Tamanho

Agora a senha está em algum lugar dentro de inhere, em um arquivo legível por humanos, com exatamente 1033 bytes e sem permissão de execução. Há vinte diretórios maybehereNN, então ficar entrando em todos é perda de tempo.

O find consegue filtrar por tudo isso:

find . -type f -size 1033c ! -executable

Uma decodificação rápida:

  • -type f significa apenas arquivos regulares.
  • -size 1033c significa exatamente 1033 bytes; o sufixo c é de bytes.
  • ! -executable exclui arquivos com qualquer bit de execução ligado.

Minha primeira tentativa usou apenas find . -size 1033c, que encontrou um único resultado — mas adicionar as outras propriedades faz o comando dizer exatamente o que você quer. Quando tiver o caminho, confirme e leia:

file ./maybehere07/.file2
cat ./maybehere07/.file2

Nível 6 — O Sistema de Arquivos Inteiro e uma Enxurrada de Erros

Agora o arquivo pode estar em qualquer lugar do servidor. O nível dá três propriedades: pertence ao usuário bandit7, pertence ao grupo bandit6 e tem 33 bytes. Busque a partir da raiz:

find / -type f -size 33c -user bandit7 -group bandit6

O resultado é uma parede de mensagens Permission denied. Isso é esperado: como bandit6, você não pode ler todos os diretórios do sistema. O importante é para onde vão essas mensagens. Elas são escritas na saída de erro padrão (descritor de arquivo 2), enquanto o resultado útil vai para a saída padrão (descritor de arquivo 1).

Você pode jogar os erros fora:

find / -type f -size 33c -user bandit7 -group bandit6 2>/dev/null

Entendendo a linha:

  • 2> redireciona o descritor de arquivo 2 (stderr).
  • /dev/null é um dispositivo especial que descarta tudo o que recebe.
  • O resultado agora fica legível: ./var/lib/dpkg/info/bandit7.password.

Se quiser manter outros erros visíveis e esconder apenas os de permissão, junte o stderr ao stdout e filtre:

find / -type f -size 33c -user bandit7 -group bandit6 2>&1 | grep -v 'Permission denied'

2>&1 significa "mande o stderr para o mesmo lugar que o stdout", então o grep consegue ver os dois fluxos. grep -v inverte a correspondência e descarta as linhas que você não quer. Leia o arquivo:

cat ./var/lib/dpkg/info/bandit7.password

Nível 7 — Grep na Milionésima Palavra

data.txt tem cerca de 4 MB, com uma palavra por linha seguida de um valor. A senha está ao lado da palavra millionth. Não há motivo para ler o arquivo inteiro:

grep "millionth" data.txt

grep imprime a linha correspondente, e o valor depois da tabulação é a próxima senha. Nas minhas anotações eu usei cat data.txt | grep "millionth"; funciona, mas inicia um processo extra sem motivo. O grep consegue ler o arquivo diretamente.

Nível 8 — A Linha que Aparece Uma Única Vez

data.txt está cheio de strings aleatórias repetidas. A senha é a única linha que ocorre exatamente uma vez. O comando uniq consegue encontrar linhas únicas:

sort data.txt | uniq -u

O sort não é opcional. O uniq só compara linhas adjacentes, então duplicatas distantes são invisíveis para ele. Ordenar aproxima as linhas idênticas, e uniq -u imprime apenas as linhas que aparecem uma vez.

Uma distinção útil: sort -u remove duplicatas e imprime cada linha restante uma vez. sort | uniq -u imprime apenas as linhas que não tinham duplicata nenhuma. São perguntas diferentes.

Nível 9 — Strings em um Arquivo Binário

file data.txt diz que isto é data, não texto. cat despejaria ruído binário. O comando strings extrai sequências de caracteres imprimíveis de um arquivo binário, e o nível diz que a senha é uma das poucas strings legíveis, precedida por vários caracteres =:

strings data.txt | grep "="

A saída inclui linhas como ========== password e a própria linha da senha. grep "=" é suficiente para reduzir a busca; os sinais de igual fazem parte da dica, não são decoração.

Nível 10 — Base64

data.txt é texto ASCII, mas está codificado. O file não diz qual é a codificação; o nível diz. Base64 é uma forma comum de representar dados binários como texto, e é codificação, não criptografia:

base64 -d data.txt

A flag -d decodifica. A saída é uma frase legível terminando na próxima senha. Se você ver uma string que termina em = ou == e usa apenas letras, números, + e /, base64 é uma boa aposta.

Nível 11 — ROT13

Todas as letras deste arquivo foram rotacionadas em 13 posições. ROT13 é o inverso dele mesmo: aplicar duas vezes devolve o original. O comando tr mapeia um conjunto de caracteres para outro:

tr 'A-Za-z' 'N-ZA-Mn-za-m' < data.txt

O mapeamento é A → N, B → O, e assim por diante, dando a volta no Z; minúsculas funcionam do mesmo jeito. Eu originalmente escrevi cat data.txt | tr ..., que também funciona. O redirecionamento de entrada (<) é mais limpo porque o tr não precisa de um argumento de arquivo.

Nível 12 — O Hexdump que Continua se Desdobrando

Este é o nível que parece intimidador e é, na maior parte, paciência. data.txt é um hexdump de um arquivo que foi comprimido várias vezes. Seu trabalho é reverter o hexdump e depois ficar perguntando ao file o que é o resultado, descomprimindo com a ferramenta correspondente.

Primeiro, crie um diretório de trabalho em /tmp com um nome difícil de adivinhar e copie os dados para lá:

WORK=$(mktemp -d)
cp ~/data.txt "$WORK/"
cd "$WORK"

mktemp -d cria um diretório único e imprime o nome. A variável WORK guarda esse nome para você limpar tudo depois. Agora reverta o hexdump:

xxd -r data.txt data1
file data1

xxd -r transforma o hexdump de volta em binário. file diz que são dados gzip, então renomeie para a extensão .gz e descomprima:

mv data1 data.gz
gunzip data.gz
file data

gunzip remove o arquivo .gz e escreve data. O file agora diz bzip2. Repita o mesmo padrão: combine a ferramenta com o tipo.

mv data data.bz2
bzip2 -d data.bz2
file data

Agora é gzip de novo:

mv data data.gz
gunzip data.gz
file data

Desta vez é um arquivo tar POSIX:

mv data data.tar
tar xf data.tar
file *

tar xf extrai o arquivo; file * mostra o que saiu. É data5.bin, e é outro arquivo tar:

mv data5.bin data5.tar
tar xf data5.tar
file *

Agora data6.bin é bzip2:

mv data6.bin data6.bz2
bzip2 -d data6.bz2
file data6.bin

Ele volta como um arquivo tar, então extraia:

mv data6.bin data6.tar
tar xf data6.tar
file *

data8.bin é gzip. Mais uma rodada:

mv data8.bin data8.gz
gunzip data8.gz
file data8.bin
cat data8.bin

Desta vez file diz texto ASCII, e cat imprime a frase com a senha. Omiti o valor:

The password is [redacted]

Os nomes exatos dos arquivos podem variar um pouco entre execuções, mas o ritmo não muda: file → escolha gunzip, bzip2 -d ou tar xf → renomeie se a ferramenta exigir uma extensão → repita. O comando file é o mapa; as extensões são apenas pistas.

Duas notas práticas:

  • O gzip se recusa a descomprimir um arquivo sem o sufixo .gz, a menos que você diga o contrário. Renomear é a correção mais simples. gunzip é apenas outro nome para gzip -d.
  • Quando terminar, limpe o que você criou, como as regras da OverTheWire pedem: cd ~ && rm -r "$WORK".

Nível 13 — Continua...

O nível 13 muda o padrão. Em vez de entregar uma senha, ele dá uma chave SSH privada que pode entrar como bandit14, e a próxima senha fica em um arquivo que só o bandit14 consegue ler. Isso significa permissões de chave, ssh -i e ler as mensagens de erro com atenção — o arquivo de dica do nível existe por um motivo.

Ainda não escrevi essa parte. Sim, este post termina em um cliffhanger. O próximo começa no nível 13.

O Que Eu Levo Disso

Nenhum desses níveis exigiu um exploit sofisticado. Eles exigiram saber qual pequena ferramenta responde à pergunta:

  • ls -a para nomes ocultos.
  • file antes de cat, especialmente quando o "arquivo" pode não ser texto.
  • find por propriedades, não só por nomes.
  • 2> e 2>&1 para separar a saída útil do ruído.
  • grep, sort, uniq, strings, base64 e tr para filtrar e decodificar.
  • xxd -r mais file para descascar camadas de compressão.

A meta-habilidade é a mesma que importa no trabalho de segurança: observe, formule uma pequena hipótese, teste e leia o erro quando falhar. O Bandit é um lugar seguro para praticar esse ciclo.

Obrigado à comunidade OverTheWire por manter o Bandit gratuito e aberto. Se você está jogando, leia as regras e as páginas dos níveis, e não publique credenciais — é por isso que toda senha acima está omitida.

Bons estudos. Nível 13 na próxima.

Nesta página