Manipulação de Dados


Cyberguard: Linux Luminarium.

Você já aprendeu a conectar dados via pipes, redirecionar entradas e saídas e utilizar variáveis. Agora vamos começar a combinar tudo isso! Neste módulo, você aprenderá uma série de comandos essenciais para manipulação e transformação de fluxos de dados, permitindo que você realize operações complexas de processamento de texto diretamente na linha de comando.


Existem inúmeros utilitários que mestres da shell usam para manipular fluxos de dados. Cada utilitário realiza tarefas bastante específicas, normalmente seguindo a Filosofia Unix de fazer apenas uma coisa e fazê-la muito bem. Você pode encadear esses comandos para montar lógicas incrivelmente poderosas. Alguns exemplos notáveis que recomendamos explorar quando concluir o Linux Luminarium:

  • awk para processamento avançado de texto
  • cut para extrair colunas e partes de linhas
  • less para leitura interativa de arquivos no terminal
  • more para ler arquivos por páginas
  • paste para mesclar arquivos lado a lado
  • sed para substituições e edições dinâmicas de texto
  • sort para ordenar dados alfabeticamente ou numericamente
  • tail para exibir as últimas linhas (o inverso do head)
  • uniq para filtrar linhas duplicadas consecutivas em um fluxo

Um dos principais objetivos de conectar dados com pipes é modificá-los. Muitos comandos no Linux permitem transformar e tratar dados de formas extremamente práticas. Um deles é o tr, que traduz (translates) ou substitui caracteres recebidos pela entrada padrão e os imprime na saída padrão.

Em seu uso mais elementar, o tr substitui o caractere informado no primeiro argumento pelo caractere correspondente informado no segundo argumento:

hacker@dojo:~$ echo OWN | tr O P
PWN
hacker@dojo:~$

Ele também processa múltiplos caracteres simultaneamente: os caracteres nas posições do primeiro conjunto são substituídos pelos caracteres das posições equivalentes do segundo conjunto:

hacker@dojo:~$ echo PWM.COLLAGE | tr MA NE
PWN.COLLEGE
hacker@dojo:~$

Agora é a sua vez! Neste nível, o binário /challenge/run imprimirá a flag, mas com as letras maiúsculas e minúsculas invertidas (por exemplo, A virará a, e vice-versa). Você consegue desfazer essa inversão usando tr e resgatar a flag?

O comando tr também pode traduzir caracteres para nada (ou seja, deletá-los do fluxo). Isso é feito com a opção -d (delete) acompanhada dos caracteres que devem ser eliminados:

hacker@dojo:~$ echo PAWN | tr -d A
PWN
hacker@dojo:~$

Muito direto e simples! Agora experimente você mesmo. Na saída do binário /challenge/run, colocamos alguns caracteres intrusos de ruído (especificamente: ^ e %) intercalados entre os caracteres da flag. Utilize o tr -d para eliminá-los!

Um tipo muito comum de caractere que precisamos remover são as quebras de linha (line separators). Isso ocorre quando temos um fluxo distribuído em várias linhas e queremos uni-lo em uma única linha contínua para processamento posterior. Você pode representar quebras de linha quase como qualquer outro caractere, usando o caractere de escape:

hacker@dojo:~$ echo "hello_world!" | tr _ "\n"
hello
world!
hacker@dojo:~$

Aqui, a barra invertida (\) indica que o caractere que a segue representa um caractere especial que não é fácil de digitar diretamente no terminal. Afinal, a quebra de linha é difícil de digitar diretamente porque pressionar a tecla Enter normalmente dispara a execução do comando. A sequência \n é a representação dessa nova linha, e ela deve estar entre aspas para que a shell não a interprete de maneira antecipada e a repasse intacta ao tr.

Agora, vamos combinar isso com a exclusão de caracteres. Neste desafio, injetamos uma série de quebras de linha no meio da flag. Remova todas elas utilizando a opção -d do tr junto com a especificação da quebra de linha escapada!


Curiosidade: Quer substituir literalmente o próprio caractere de barra invertida (\)? Como a \ é o caractere de escape, você precisa escapar a própria barra! A sequência \\ será interpretada como uma barra invertida literal pelo tr. Isso não é necessário para este desafio em particular, mas é uma dica valiosa para a vida!

Em sua jornada pelo Linux, você passará por inúmeras situações em que precisará capturar apenas as primeiras linhas da saída de programas bastante verbosos. Para isso, você usará o comando head! O head é utilizado para exibir as linhas iniciais de sua entrada:

hacker@dojo:~$ cat /something/very/long | head
this
is
just
the
first
ten
lines
of
the
file
hacker@dojo:~$

Por padrão, ele exibe as 10 primeiras linhas, mas você pode definir a quantidade desejada através da opção -n:

hacker@dojo:~$ cat /something/very/long | head -n 2
this
is
hacker@dojo:~$

Neste desafio, /challenge/pwn gera uma grande quantidade de dados, e você precisará canalizar essa saída com pipe para o head, pegando apenas as 7 primeiras linhas, e em seguida canalizar essas linhas adiante para /challenge/college, que entregará a flag caso o procedimento esteja correto! Sua solução consistirá em um pipeline composto conectando três comandos por meio de dois pipes (|). Boa sorte!

Às vezes, você precisa extrair colunas de dados específicas, como a primeira coluna, a terceira coluna ou a 42ª coluna. Para isso, existe o comando cut.

Por exemplo, imagine que você tenha o seguinte arquivo de dados:

hacker@dojo:~$ cat scores.txt
hacker 78 99 67
root 92 43 89
hacker@dojo:~$

Você pode usar o cut para isolar colunas específicas:

hacker@dojo:~$ cut -d " " -f 1 scores.txt
hacker
root
hacker@dojo:~$ cut -d " " -f 2 scores.txt
78
92
hacker@dojo:~$ cut -d " " -f 3 scores.txt
99
43
hacker@dojo:~$

O parâmetro -d especifica o delimitador das colunas (como os campos são separados entre si). Neste exemplo, é o caractere de espaço em branco. Naturalmente, ele deve estar entre aspas para que a shell compreenda que o espaço é o valor do argumento, e não um separador sintático de argumentos! Já o parâmetro -f especifica o número do campo (field) ou coluna a ser extraída (iniciando em 1).

Neste desafio, o programa /challenge/run fornecerá várias linhas contendo números aleatórios e caracteres individuais (caracteres pertencentes à flag) dispostos em colunas. Use o comando cut para isolar a coluna com os caracteres da flag e, em seguida, canalize a saída para tr -d "\n" (como no nível anterior!) para reuni-los em uma única linha contínua. Sua solução terá a estrutura de /challenge/run | cut ??? | tr ???, substituindo os ??? pelos parâmetros corretos.

Arquivos (ou saídas de comandos) nem sempre aparecem na ordem em que precisamos! O comando sort ajuda a organizar esses fluxos de dados. Ele lê as linhas de uma entrada padrão (ou de arquivos) e as exibe devidamente ordenadas:

hacker@dojo:~$ cat names.txt
  hack
  the
  planet
  with
  pwn
  college
hacker@dojo:~$ sort names.txt
  college
  hack
  planet
  pwn
  the
  with
hacker@dojo:~$

Por padrão, o sort organiza as linhas em ordem alfabética. Várias opções permitem modificar essa ordenação:

  • -r: ordem reversa (de Z a A)
  • -n: ordenação numérica (interpreta valores como números)
  • -u: apenas linhas únicas (unique, descarta duplicatas)
  • -R: ordenação aleatória (random)!

Neste desafio, existe um arquivo em /challenge/flags.txt com 100 flags falsas e a flag verdadeira escondida no meio delas. Ao ordenar o arquivo alfabeticamente, a flag real ficará na última linha (garantimos isso na geração dos despistes). Vá até lá e capture-a!


30-Day Scoreboard:

This scoreboard reflects solves for challenges in this module after the module launched in this dojo.

Rank Hacker Badges Score