O Bash é um shell compatível com sh (outro shell antigo) que nos permite executar comandos complexos e executar diferentes tarefas a partir de uma janela de terminal. Ele incorpora recursos úteis tanto do Korn Shell (ksh) quanto do C shell (csh). Existem muitos shells disponíveis, e você pode visualizar o qual está utilizando lendo a variável de ambiente SHELL:
echo $SHELL
Ah, e para ver os shells disponíveis , pode se ler o arquivo /etc/shells.
cat /etc/shells
E para trocar de shell:
chsh -s /bin/sh
Sai do terminal e entre de novo, terá sido alterado.
Ao abrir uma janela de terminal, um novo processo Bash, que tem suas próprias variáveis de ambiente,
é inicializado. Essas variáveis são uma forma de armazenamento global para várias configurações herdadas por quaisquer aplicativos que são executados durante essa sessão de terminal. Uma das variáveis de ambiente mais comumente referenciadas é PATH, que é uma lista separada por dois pontos de caminhos de diretório que o Bash irá pesquisar sempre que um comando for executado sem um caminho completo.
Podemos visualizar o conteúdo de uma determinada variável de ambiente com o comando echo seguido pelo caractere $ e o nome da variável. Por exemplo, vamos dar uma olhada no conteúdo da variável de ambiente PATH:
echo $PATH
Um problema, é que ele mostra tudo em uma linha, utilizando o : como separador de campo.
Vamos fazer uma magia para melhorar a visualização:
echo $PATH | tr : '\n'
Melhorou a visualização. Para verificar outras variáveis de ambiente como USER, HOME e PWD:
Já precisei instalar o JDK várias vezes em sistemas Linux, e para garantir que o executável estava no local certo e dentro da variável PATH.
Outro detalhe interessante é visualizar com o comando env as variáveis de ambiente disponíveis:
Tem uma variável interessante chamada LOGNAME. Dá para começar a pensar em scripts. Por exemplo, pegar o nome do usuário que está conectado:
echo "Bem vindo $LOGNAME"
O shell trabalha com o conceito de instâncias. De repente uma variável de ambiente disponível em uma instância pode não estar em outras. Vou criar uma variável chamada ANDRE com o conteúdo Linux:
ANDRE=Linux
echo $ANDRE
bash
echo $ANDRE
Perceba que quando digitamos o comando bash ele abre um subprocesso e essa variável ANDRE não existe lá.
Temos que usar o comando export para tornar ela disponível em processos subjacentes.
Agora sim. Ah, podemos criar a variável já exportando.. assim:
export JEDI=Luke
Como explicado, o comando export torna a variável acessível a quaisquer subprocessos que possamos gerar de nossa instância Bash atual. Se definirmos uma variável de ambiente sem export, ela estará disponível apenas no shell atual.
Olha que legal! Vou pegar o IP do meu router:
ip route
Vou criar uma variável com o IP do router:
export IP=192.168.1.254
E agora:
ping -c3 $IP
PING 192.168.1.254 (192.168.1.254) 56(84) bytes of data.
64 bytes from 192.168.1.254: icmp_seq=1 ttl=64 time=1.69 ms
64 bytes from 192.168.1.254: icmp_seq=2 ttl=64 time=1.61 ms
64 bytes from 192.168.1.254: icmp_seq=3 ttl=64 time=3.60 ms
--- 192.168.1.254 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2011ms
rtt min/avg/max/mdev = 1.608/2.300/3.601/0.920 ms
Usaremos a variável $$ para exibir o ID do processo da instância shell atual para garantir que estamos realmente emitindo comandos em dois shells diferentes:
echo $$
teste1="Olá"
echo $teste1
bash
echo $$
echo $teste1
exit
echo $teste1
export teste2="Mundo"
echo $teste2
bash
echo $teste2
exit
A função de autocompletar do shell Bash nos permite completar nomes de arquivos e caminhos de diretório com a tecla TAB. Esse recurso acelera tanto o uso do shell que faz muita falta em outros shells. Vamos dar uma olhada em como isso funciona . Começaremos digitando o seguinte comando:
ls /etc/C[TAB]
Um alias é uma string que podemos definir que substitui um nome de comando. Aliases são úteis para substituir comandos e comumente usados por um comando mais curto, ou alias, que definimos. Em outras palavras, um alias é um comando que definimos nós mesmos, construído a partir de outros comandos. Um exemplo disso é o comando que uso para verificar o IP que meu servidor está usando, faço isso com o comando ip -4 -br a.
Pode-se criar um alias de comandos, apelidos curtos para chamar um comando. Exemplo: Vou criar um alias chamado meuip para executar esse comando:
vim /home/sysadmin/.bashrc
alias meuip="ip -4 -br a"
Salvei o arquivo e em seguida pedi para reler esse arquivo com o comando source.
source /home/sysadmin/.bashrc
Agora basta chamar esse alias:
meuip
Posso fazer em linha de comando, em tempo de execução, contudo quando reiniciar o sistema irá perder. Exemplos:
- Criar um alias para reiniciar o servidor web apache2. Ao invés de digitar systemctl restart apache2:
alias apache='systemctl restart apache2'
Agora basta digitar apache.
Você pode visualizar os alias do sistema, digitando em linha de comando alias:
Para remover um alias , basta digitar o comando unalias.
Ao trabalhar em um teste de penetração, é importante manter um registro dos comandos que foram inseridos no shell. Felizmente, o Bash mantém um histórico dos comandos que foram inseridos, que podem ser exibidos com o comando history.
De forma maliciosa também, um atacante pode após invadir uma máquina, limpar o histórico de comandos:
history -c
Eu agora digitei alguns comandos e digitei o comando history:
history
1 history
2 clear
3 systemctl status ssh
4 clear
5 history
Por exemplo, se eu quiser executar o comando número 3 systemctl status ssh basta fazer:
!3
Outra dica é executar o último comando usando !!
!!
Vai executar o comando 3 do histórico.
Por padrão, o histórico de comandos é salvo no arquivo .bash_history no diretório home do usuário. Duas variáveis de ambiente controlam o tamanho do histórico: HISTSIZE e HISTFILESIZE.
HISTSIZE controla o número de comandos armazenados na memória para a sessão atual e HISTFILESIZE configura quantos comandos são mantidos no arquivo de histórico. Essas variáveis podem ser editadas de acordo com nossas necessidades e salvas no arquivo de configuração do Bash (.bashrc).
Por último, mas não menos importante, manter pressionado CTRL e pressionar r invocará o recurso reverse-i-search. Digite uma letra, por exemplo, s, e você obterá uma correspondência para o comando mais recente em seu histórico que contém a letra "s". Continue digitando para trazer mais informações sobre o comando que você quer executar.
O comportamento de shells interativos, no caso do Bash é realizado no arquivo localizado em /etc/bash.bashrc. As configurações do Bash do usuário pode ser feita no diretório inicial de qualquer usuário.
Por exemplo, estamos trabalhando com o usuário sysadmin e logo ele tem um diretório pessoal em /home/sysadmin . O script .bashrc é executado sempre que o usuário faz login. Como este arquivo é um shell script , podemos inserir qualquer comando que possa ser executado a partir do prompt de comando.
Podemos customizar a quantidade de comandos armazenados no histórico , usando as variáveis citadas acima.
Veja o arquivo /home/sysadmin/.bashrc :
Ali pode ser configurado as variáveis de ambiente que configuram a quantidade de comandos que ficarão no histórico.
Anteriormente neste módulo, discutimos variáveis de ambiente e o comando history. Podemos usar várias variáveis de ambiente para alterar como o comando history opera e retorna dados, as mais comuns incluem HISTCONTROL, HISTIGNORE e HISTTIMEFORMAT.
A variável HISTCONTROL define se deve ou não remover comandos duplicados, comandos que começam com espaços do histórico ou ambos. Por padrão, ambos são removidos, mas você pode achar mais útil omitir apenas duplicatas. Faça:
export HISTCONTROL=ignoredups
A variável HISTIGNORE é particularmente útil para filtrar comandos básicos que são executados com frequência, como ls, exit, history, bg, etc. Exemplo:
export HISTIGNORE="ls*:[bf]g:exit:history:pwd:clear:man"
Faça o teste digitando alguns destes comandos.
Por fim, HISTTIMEFORMAT controla carimbos de data e/ou hora na saída do comando history.
export HISTTIMEFORMAT='%F %T '
Explicando:
- %F %T
Essa string de formatação utiliza códigos reconhecidos pelo comando strftime:
- %F: Exibe a data no formato ISO 8601 (YYYY-MM-DD).
- %T: Exibe o horário no formato de 24 horas (HH:MM:SS).
O espaço final após %T garante a separação visual entre o timestamp e o comando.