Desvendando o PATH


Cyberguard: Linux Luminarium.

Até agora, você invocou comandos de várias maneiras:

  • Por meio de um caminho absoluto (ex.: /challenge/run).
  • Por meio de um caminho relativo (ex.: ./run).
  • Por meio apenas do nome do comando (ex.: ls).

Os dois primeiros casos — caminhos absolutos e relativos — são diretos: o arquivo run reside no diretório /challenge e ambos os casos apontam para ele (desde que, claro, o caminho relativo seja executado tendo /challenge como diretório de trabalho atual). Mas e quanto ao último caso? Onde o programa ls está localizado no sistema? Como a shell sabe onde procurá-lo?

Neste módulo, vamos desvendar os bastidores e responder a essa pergunta! Venha conosco.


Acontece que a resposta para "Como a shell encontra o ls?" é bastante simples. Existe uma variável especial de shell, chamada PATH, que armazena uma lista de diretórios nos quais a shell procurará pelos programas correspondentes aos comandos digitados. Se você esvaziar essa variável, as coisas começam a falhar:

hacker@dojo:~$ ls
Desktop    Downloads  Pictures  Templates
Documents  Music      Public    Videos
hacker@dojo:~$ PATH=""
hacker@dojo:~$ ls
bash: ls: No such file or directory
hacker@dojo:~$

Sem a variável PATH, o bash não consegue encontrar o comando ls.

Neste nível, você irá interferir no funcionamento do programa /challenge/run. Esse programa tentará EXCLUIR o arquivo da flag usando o comando rm. No entanto, se ele não conseguir encontrar o comando rm, a flag não será excluída e o desafio a entregará para você! Portanto, você deve fazer com que o /challenge/run também não consiga encontrar o comando rm!

Lembre-se: se você não conseguir e a flag for apagada, será necessário reiniciar o desafio para tentar novamente!

Certo, as coisas quebram quando você esvazia a variável PATH. Mas que tal fazermos algo útil com o PATH?

Vamos explorar como poderíamos, por exemplo, adicionar um novo diretório de programas ao nosso repertório de comandos. Lembre-se de que o PATH armazena uma lista de diretórios onde os comandos são procurados. Para comandos que estão em locais não padronizados, geralmente precisamos executá-los informando seus caminhos completos:

hacker@dojo:~$ ls /home/hacker/scripts
goodscript	badscript	okayscript
hacker@dojo:~$ goodscript
bash: goodscript: command not found
hacker@dojo:~$ /home/hacker/scripts/goodscript
YEAH! This is the best script!
hacker@dojo:~$

Se você mantém scripts úteis que gostaria de executar digitando apenas seus nomes, ter que digitar o caminho inteiro é incômodo. No entanto, ao adicionar ou substituir diretórios nessa lista, você pode disponibilizar esses programas para serem chamados apenas pelo nome! Por exemplo:

hacker@dojo:~$ PATH=/home/hacker/scripts
hacker@dojo:~$ goodscript
YEAH! This is the best script!
hacker@dojo:~$

Vamos praticar. Neste nível, /challenge/run tentará executar o comando win apenas pelo nome, mas esse comando reside no diretório /challenge/more_commands/, que inicialmente não está no PATH. O comando win é a única coisa de que /challenge/run precisa, então você pode simplesmente sobrescrever o PATH com esse diretório específico. Boa sorte!

Quando você digita o nome de um comando, algo dentro de um dos vários diretórios listados na sua variável $PATH é o que realmente é executado (a menos, é claro, que o comando seja um comando embutido (builtin) da shell!). Mas qual arquivo exatamente? Você pode descobrir isso com o apropriadamente chamado comando which:

hacker@dojo:~$ which cat
/bin/cat
hacker@dojo:~$ /bin/cat /flag
YEAH
hacker@dojo:~$

Espelhando exatamente o que a shell faz ao procurar comandos, o which examina cada diretório do $PATH em ordem e imprime o primeiro arquivo encontrado cujo nome corresponda ao argumento fornecido.

Neste desafio, adicionamos um comando win em algum lugar do seu $PATH, mas executá-lo não lhe dará a flag diretamente. Em vez disso, ele está localizado no mesmo diretório de um arquivo flag com permissão de leitura para você! Você deve encontrar o win (usando o comando which) e usar cat para ler a flag daquele diretório!

Relembre o exemplo do nível anterior:

hacker@dojo:~$ ls /home/hacker/scripts
goodscript	badscript	okayscript
hacker@dojo:~$ PATH=/home/hacker/scripts
hacker@dojo:~$ goodscript
YEAH! This is the best script!
hacker@dojo:~$

O que vemos aqui, é claro, é o hacker tornando a shell mais útil para si mesmo ao trazer seus próprios comandos para o jogo. Com o tempo, você construirá seu próprio conjunto de ferramentas elegantes. Vamos começar com o win!

Anteriormente, o comando win executado por /challenge/run estava armazenado em /challenge/more_commands. Desta vez, o comando win simplesmente não existe! Relembre o último nível de Encadeando Comandos, crie um shell script chamado win, adicione a localização dele ao PATH e permita que /challenge/run o encontre!


Dica: /challenge/run roda como root e chamará win. Logo, o seu script win pode simplesmente ler o arquivo da flag com cat. Mais uma vez, o comando win é a única coisa necessária para o /challenge/run, então você pode apenas sobrescrever o PATH com esse diretório. Mas lembre-se: se fizer isso, o seu comando win não conseguirá encontrar o cat pelo nome.

Você tem três opções para contornar isso:

  1. Descobrir onde o programa cat está no sistema de arquivos. Ele obrigatoriamente está em um dos diretórios presentes na variável PATH, então você pode exibir o conteúdo dessa variável (consulte Variáveis de Shell para relembrar como!), examinar os diretórios listados (lembre-se de que as entradas são separadas por :), encontrar qual deles contém o cat e chamar cat por seu caminho absoluto.
  2. Definir um PATH contendo os diretórios originais mais uma nova entrada apontando para onde você criou o win.
  3. Usar read (novamente, consulte Variáveis de Shell) para ler /flag. Como read é um recurso embutido (builtin) do bash, ele não é afetado por alterações no PATH.

Agora vá em frente e alcance o win!

Munido do seu conhecimento, você agora pode realizar alguns truques engenhosos. Este desafio é quase idêntico ao primeiro desafio deste módulo. Novamente, ele tentará apagar a flag usando o comando rm. Mas, ao contrário de antes, ele não imprimirá nada automaticamente para você.

Como resolver isso? Você sabe que o rm é procurado nos diretórios listados na variável PATH. Você já tem experiência em criar o comando win no desafio anterior. O que mais você pode criar?


30-Day Scoreboard:

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

Rank Hacker Badges Score