One place for hosting & domains

      Serviços

      Como usar Systemctl para gerenciar serviços e unidades do systemd


      Introdução

      Systemd é um sistema init e gerenciador de sistema que se tornou o novo padrão para distribuições Linux. Devido à sua forte adoção, familiarizar-se com o systemd vale muito a pena, pois irá tornar a administração de servidores consideravelmente mais fácil. Aprender sobre as ferramentas e daemons que compõem o systemd e como usá-los irá ajudar a entender melhor o poder, flexibilidade e capacidades que ele oferece ou, pelo menos, facilitará o seu trabalho.

      Neste guia, vamos discutir o comando systemctl, que é a ferramenta de gerenciamento central para controlar o sistema init. Vamos abordar como gerenciar serviços, verificar status, alterar estados de sistema e trabalhar com os arquivos de configuração.

      Observe que embora o systemd tenha se tornado o sistema init padrão para muitas distribuições Linux, ele não é implementado universalmente em todas as distros. À medida que você percorrer este tutorial, se o seu terminal exibir o erro bash: systemctl is not installed, então é provável que sua máquina tenha um sistema init diferente instalado.

      Gerenciamento de serviços

      O objetivo fundamental de um sistema init é inicializar os componentes que devem ser iniciados após o kernel do Linux ser inicializado (tradicionalmente conhecido como componentes “userland”). O sistema init também é usado para gerenciar serviços e daemons para o servidor em qualquer momento enquanto o sistema está em execução. Com isso em mente, vamos começar com algumas operações básicas de gerenciamento de serviços.

      No systemd, o alvo da maioria das ações são “unidades”, que são os recursos que o systemd sabe gerenciar. As unidades são categorizadas pelo tipo de recurso que representam e são definidas com arquivos conhecidos como arquivos unit. O tipo de cada unidade pode ser inferido a partir do sufixo no final do arquivo.

      Para tarefas de gerenciamento de serviços, a unidade de destino serão unidades de serviço, que possuem arquivos de unidade com um sufixo .service. No entanto, para a maioria dos comandos de gerenciamento de serviços, é possível deixar o sufixo .service, pois o systemd é inteligente o suficiente para saber que você provavelmente deseja operar em um serviço ao usar comandos de gerenciamento de serviços.

      Iniciando e interrompendo os serviços

      Para iniciar um serviço systemd, executando instruções no arquivo de unidade do serviço, use o comando start. Caso esteja usando um usuário não root, você terá que usar o sudo, pois isso afetará o estado do sistema operacional:

      • sudo systemctl start application.service

      Como mencionamos acima, o systemd sabe procurar por arquivos *.service para comandos de gerenciamento de serviços, de forma que o comando poderia ser também digitado desta forma:

      • sudo systemctl start application

      Embora você possa usar o formato acima para a administração geral, para maior clareza, vamos usar o sufixo .service para o resto dos comandos, para sermos explícitos sobre o alvo em que estamos operando.

      Para parar um serviço que esteja atualmente em execução, use o comando stop:

      • sudo systemctl stop application.service

      Reiniciando e recarregando

      Para reiniciar um serviço em execução, use o comando restart:

      • sudo systemctl restart application.service

      Se o aplicativo em questão for capaz de recarregar seus arquivos de configuração (sem reiniciar), você pode emitir o comando reload para iniciar esse processo:

      • sudo systemctl reload application.service

      Se não tiver certeza se o serviço possui a funcionalidade para recarregar sua configuração, emita o comando reload-or-restart. Isso irá recarregar a configuração em vigor, se disponível. Caso contrário, o serviço será reiniciado para que a nova configuração seja ativada:

      • sudo systemctl reload-or-restart application.service

      Habilitando e desabilitando serviços

      Os comandos acima são úteis para iniciar ou interromper serviços durante a sessão atual. Para dizer ao systemd para iniciar serviços automaticamente na inicialização do sistema, é necessário habilitá-los.

      Para iniciar um serviço na inicialização, use o comando enable:

      • sudo systemctl enable application.service

      Isso irá criar um link simbólico a partir da cópia do arquivo de serviço do sistema (geralmente em /lib/systemd/system ou /etc/systemd/system) para a localização em disco onde o systemd procura por arquivos de inicialização automática (geralmente etc/systemd/system/some_target.target.wants. Vamos abordar o que é um alvo mais adiante neste guia).

      Para impedir que o serviço seja iniciado automaticamente, digite:

      • sudo systemctl disable application.service

      Isso irá remover o link simbólico que indica que o serviço deve ser iniciado automaticamente.

      Esteja ciente de que habilitar um serviço não o inicia na sessão atual. Se quiser iniciar o serviço e também habilitá-lo na inicialização, será necessário emitir ambos os comandos start e enable.

      Verificando o status de serviços

      Para verificar o status de um serviço em seu sistema, use o comando status:

      • systemctl status application.service

      Isso irá mostrar-lhe o estado do serviço, a hierarquia de cgroup e as primeiras linhas de registro.

      Por exemplo, ao verificar o status de um servidor Nginx, pode ser que você veja um resultado como este:

      Output

      ● nginx.service - A high performance web server and a reverse proxy server Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled) Active: active (running) since Tue 2015-01-27 19:41:23 EST; 22h ago Main PID: 495 (nginx) CGroup: /system.slice/nginx.service ├─495 nginx: master process /usr/bin/nginx -g pid /run/nginx.pid; error_log stderr; └─496 nginx: worker process Jan 27 19:41:23 desktop systemd[1]: Starting A high performance web server and a reverse proxy server... Jan 27 19:41:23 desktop systemd[1]: Started A high performance web server and a reverse proxy server.

      Isso oferece uma visão geral interessante do status atual do aplicativo, notificando você acerca de qualquer problema ou ação que possa ser necessária.

      Há também métodos para verificar por estados específicos. Por exemplo, para verifciar se uma unidade está ativa (em execução), use o comando is-active:

      • systemctl is-active application.service

      Isso irá retornar o estado da unidade atual, que geralmente é active ou inactive. O código de saída será “0” se for ativo, tornando o resultado mais simples de se analisar em scripts do shell.

      Para ver se uma unidade está habilitada, use o comando is-enabled:

      • systemctl is-enabled application.service

      Isso irá mostrar se o serviço está enabled ou disabled e irá definir novamente o código de saída como “0” ou “1”, dependendo da resposta para a pergunta do comando.

      Uma terceira verificação é se a unidade está em um estado de falha. Ele indica se houve um problema ao iniciar a unidade em questão:

      • systemctl is-failed application.service

      Isso irá retornar active se a unidade estiver executando corretamente ou failed caso um erro tenha ocorrido. Se a unidade tiver sido intencionalmente interrompida, ela pode retornar unknown ou inactive. Um status de saída de “0” indica que uma falha ocorreu, enquanto um status de saída de “1” indica qualquer outro status.

      Visão geral do estado do sistema

      Os comandos mostrados até agora têm sido úteis para o gerenciamento de serviços únicos, mas não são muito úteis para explorar o estado atual do sistema. Existem diversos comandos do systemctl que fornecem essa informação.

      Listando as unidades atuais

      Para ver uma lista com todas as unidades ativas das quais o systemd sabe, podemos usar o comando list-units:

      Isso irá mostrar-lhe uma lista de todas as unidades que o systemd possui como ativa atualmente no sistema. O resultado se parecerá com este:

      Output

      UNIT LOAD ACTIVE SUB DESCRIPTION atd.service loaded active running ATD daemon avahi-daemon.service loaded active running Avahi mDNS/DNS-SD Stack dbus.service loaded active running D-Bus System Message Bus dcron.service loaded active running Periodic Command Scheduler dkms.service loaded active exited Dynamic Kernel Modules System getty@tty1.service loaded active running Getty on tty1 . . .

      O resultado possui as seguintes colunas:

      • UNIT: o nome da unidade de systemd
      • LOAD: se a configuração da unidade foi analisada pelo systemd. A configuração de unidades carregadas é mantida na memória.
      • ACTIVE: um estado resumido que diz se a unidade está ativa. Essa é geralmente uma maneira bastante simples de dizer se a unidade foi iniciada com sucesso ou não.
      • SUB: esse é um estado de nível mais baixo que indica informações mais detalhadas sobre a unidade. Isso muitas vezes varia dependendo do tipo de unidade, estado e do método em si com o qual a unidade é executada.
      • DESCRIPTION: uma breve descrição textual do que a unidade é/faz.

      Como o comando list-units mostra apenas unidades ativas por padrão, todas as entradas acima exibirão loaded na coluna LOAD e active na coluna ACTIVE. Essa exibição é na verdade o comportamento padrão do systemctl quando chamado sem comandos adicionais. Sendo assim, você irá ver a mesma coisa se chamar systemctl sem argumentos:

      Podemos dizer ao systemctl para mostrar outras informações adicionando sinalizadores adicionais. Por exemplo, para ver todas as unidades que o systemd carregou (ou tentou carregar), independentemente se estão ou não ativas, use o sinalizador --all, desta forma:

      • systemctl list-units --all

      Isso irá mostrar qualquer unidade que o systemd carregou ou tentou carregar, independentemente do seu estado atual no sistema. Algumas unidades tornam-se inativas após serem executadas, e algumas unidades que o systemd tentou carregar podem não ter sido encontradas em disco.

      Use outros sinalizadores para filtrar esses resultados. Por exemplo, é possível usar o sinalizador --state= para indicar os estados LOAD, ACTIVE ou SUB que desejamos ver. Será necessário manter o sinalizador --all para que o systemctl permita que unidades não ativas sejam exibidas:

      • systemctl list-units --all --state=inactive

      Outro filtro comum é o filtro --type=. Podemos dizer ao systemctl para exibir apenas unidades do tipo em que estamos interessados. Por exemplo, para ver apenas unidades de serviço ativas, podemos usar:

      • systemctl list-units --type=service

      Listando todos os arquivos de unidade

      O comando list-units exibe apenas unidades que o systemd tentou analisar e carregar na memória. Como o systemd irá ler apenas unidades as quais ele acha necessário, isso não incluirá necessariamente todas as unidades disponíveis no sistema. Para ver todos os arquivos de unidade disponíveis nos caminhos do systemd, incluindo aquelas que o systemd não tentou carregar, use o comando list-unit-files:

      • systemctl list-unit-files

      As unidades são representações de recursos sobre os quais o systemd sabe. Como o systemd não leu necessariamente todas as definições de unidade nesta visão, ele apresenta apenas informações sobre os arquivos em si. O resultado possui duas colunas: o arquivo de unidade e o estado.

      Output

      UNIT FILE STATE proc-sys-fs-binfmt_misc.automount static dev-hugepages.mount static dev-mqueue.mount static proc-fs-nfsd.mount static proc-sys-fs-binfmt_misc.mount static sys-fs-fuse-connections.mount static sys-kernel-config.mount static sys-kernel-debug.mount static tmp.mount static var-lib-nfs-rpc_pipefs.mount static org.cups.cupsd.path enabled . . .

      O estado normalmente será enabled, disabled, static ou masked. Neste contexto, estático significa que o arquivo de unidade não contém uma seção install, que é usada para habilitar uma unidade. Dessa forma, essas unidades não podem ser ativadas. Geralmente, isso significa que a unidade executa uma ação única ou é usada apenas como uma dependência de outra unidade e não deve ser executada sozinha.

      Vamos abordar o que masked significa daqui a pouco.

      Gerenciamento de unidades

      Até aqui, estivemos trabalhando com serviços e exibindo informações sobre a unidade e arquivos de unidade sobre os quais o systemd sabe. No entanto, é possível descobrir mais informações específicas sobre unidades usando alguns comandos adicionais.

      Exibindo um arquivo de unidade

      Para exibir o arquivo de unidade que o systemd carregou em seu sistema, use o comando cat (adicionado na versão 209 do systemd). Por exemplo, para ver o arquivo de unidade do daemon de planejamento atd, poderíamos digitar:

      • systemctl cat atd.service

      Output

      [Unit] Description=ATD daemon [Service] Type=forking ExecStart=/usr/bin/atd [Install] WantedBy=multi-user.target

      O resultado é o arquivo de unidade, da forma como é conhecido pelo processo do systemd atualmente em execução. Isso pode ser importante se você tiver arquivos de unidade modificados recentemente ou se estiver sobrepondo certas opções em um fragmento de arquivo de unidade (vamos falar disso mais tarde).

      Exibindo dependências

      Para ver a árvore de dependências de uma unidade, use o comando list-dependencies:

      • systemctl list-dependencies sshd.service

      Isso irá exibir uma hierarquia mapeando as dependências que devem ser tratadas para iniciar a unidade em questão. Dependências, neste contexto, incluem aquelas unidades que são exigidas ou procuradas pelas unidades acima dela.

      Output

      sshd.service ├─system.slice └─basic.target ├─microcode.service ├─rhel-autorelabel-mark.service ├─rhel-autorelabel.service ├─rhel-configure.service ├─rhel-dmesg.service ├─rhel-loadmodules.service ├─paths.target ├─slices.target . . .

      As dependências recursivas são exibidas apenas para unidades .target, que indicam estados do sistema. Para listar recursivamente todas as dependências, inclua o sinalizador --all.

      Para mostrar dependências reversas (unidades que dependem da unidade especificada), adicione o sinalizador --reverse ao comando. Outros sinalizadoras que são úteis são os sinalizadoras --before e --after, que podem ser usados para mostrar unidades que dependem da unidade especificada iniciando antes e depois de si mesmos, respectivamente.

      Verificando propriedades da unidade

      Para ver as propriedades de baixo nível de uma unidade, use o comando show. Ele irá exibir uma lista de propriedades que são definidas para a unidade especificada usando um formato key=value:

      • systemctl show sshd.service

      Output

      Id=sshd.service Names=sshd.service Requires=basic.target Wants=system.slice WantedBy=multi-user.target Conflicts=shutdown.target Before=shutdown.target multi-user.target After=syslog.target network.target auditd.service systemd-journald.socket basic.target system.slice Description=OpenSSH server daemon . . .

      Se quiser exibir uma única propriedade, passe o sinalizador -p com o nome da propriedade. Por exemplo, para ver os conflitos que a unidade sshd.service possui, digite:

      • systemctl show sshd.service -p Conflicts

      Output

      Conflicts=shutdown.target

      Mascarando e desmascarando unidades

      Vimos na seção de gerenciamento de serviços como parar ou desativar um serviço. No entanto, o systemd também possui a capacidade de marcar uma unidade como absolutamente não iniciável, de modo automático ou manual, ligando-a ao /dev/null. Isso é chamado de mascarar a unidade, e é possível com o comando mask:

      • sudo systemctl mask nginx.service

      Isso irá impedir que o serviço Nginx seja iniciado, automaticamente ou manualmente, enquanto estiver mascarado.

      Se verificar o list-unit-files, verá que o serviço está agora listado como mascarado:

      • systemctl list-unit-files

      Output

      . . . kmod-static-nodes.service static ldconfig.service static mandb.service static messagebus.service static nginx.service masked quotaon.service static rc-local.service static rdisc.service disabled rescue.service static . . .

      Se você tentar iniciar o serviço, verá uma mensagem como esta:

      • sudo systemctl start nginx.service

      Output

      Failed to start nginx.service: Unit nginx.service is masked.

      Para desmascarar uma unidade, tornando-a disponível para uso novamente, use o comando unmask:

      • sudo systemctl unmask nginx.service

      Isso irá retornar a unidade ao seu estado anterior, permitindo que seja iniciada ou habilitada.

      Editando arquivos de unidade

      Embora o formato específico para arquivos de unidade esteja fora do âmbito deste tutorial, o systemctl fornece mecanismos integrados para editar e modificar arquivos de unidade, se for necessário fazer ajustes. Essa funcionalidade foi adicionada na versão 218do systemd.

      O comando edit, por padrão, irá abrir um trecho de código do arquivo de unidade para a unidade em questão:

      • sudo systemctl edit nginx.service

      Esse será um arquivo em branco que pode ser usado para substituir ou adicionar diretivas à definição da unidade. Um diretório será criado dentro do diretório /etc/systemd/system, que contém o nome da unidade com o .d anexado. Por exemplo, para o nginx.service, um diretório chamado nginx.service.d será criado.

      Dentro deste diretório, um trecho de código chamado override.conf será criado. Quando a unidade for carregada, o systemd irá mesclar, na memória, o trecho sobrescrito com o arquivo de unidade completo. As diretivas do trecho terão precedência sobre aquelas encontradas no arquivo de unidade original.

      Se quiser editar o arquivo de unidade completo ao invés de criar um fragmento, passe o sinalizador --full:

      • sudo systemctl edit --full nginx.service

      Isso irá carregar o arquivo de unidade atual no editor, onde pode ser modificado. Quando o editor for fechado, o arquivo alterado será escrito em /etc/systemd/system e terá precedência sobre a definição de unidade do sistema (geralmente encontrada em algum lugar em /lib/systemd/system).

      Para remover qualquer adição que tenha sido feita, exclua o diretório de configuração .d da unidade ou o arquivo de serviço modificado de /etc/systemd/system. Por exemplo, para remover um fragmento, podemos digitar:

      • sudo rm -r /etc/systemd/system/nginx.service.d

      Para remover um arquivo de unidade modificado completo, digitamos:

      • sudo rm /etc/systemd/system/nginx.service

      Depois de excluir o arquivo ou diretório, recarregue o processo do systemd para que ele não tente mais fazer referência a esses arquivos e volte a usar as cópias do sistema. Faça isso digitando:

      • sudo systemctl daemon-reload

      Os alvos são arquivos de unidade especiais que descrevem um estado do sistema ou um ponto de sincronização. Assim como outras unidades, os arquivos que definem alvos podem ser identificados por seu sufixo, que neste caso é .target. Os alvos não fazem muito por conta própria, mas são usados para agrupar outras unidades.

      Isso pode ser usado para trazer o sistema para determinados estados, da mesma forma que outros sistemas init usam os níveis de execução. Eles são usados como referência para quando certas funções estão disponíveis, permitindo especificar o estado desejado em vez das unidades individuais necessárias para produzir esse estado.

      Por exemplo, existe um swap.target que é usado para indicar que o swap está pronto para ser usado. Unidades que fazem parte deste processo podem sincronizar-se com esse alvo indicando em sua configuração que elas são WantedBy= ou RequiredBy= pelo swap.target. Unidades que exigem o swap para ficarem disponíveis podem especificar essa condição usando as especificações Wants=, Requires= e After= para indicar a natureza do seu relacionamento.

      Obtendo e definindo o alvo padrão

      O processo do systemd possui um alvo padrão usado por ele ao inicializar o sistema. Satisfazer a cascata de dependências a partir desse único alvo irá trazer o sistema para o estado desejado. Para encontrar o alvo padrão para o seu sistema, digite:

      Output

      multi-user.target

      Se quiser definir um alvo padrão diferente, use o set-default. Por exemplo, se você possui um desktop gráfico instalado e quer que o sistema seja inicializado nele por padrão, altere seu alvo padrão de acordo:

      • sudo systemctl set-default graphical.target

      Listando alvos disponíveis

      É possível obter uma lista dos alvos disponíveis em seu sistema digitando:

      • systemctl list-unit-files --type=target

      Ao contrário dos níveis de execução, vários alvos podem estar ativos ao mesmo tempo. Um alvo ativo indica que o systemd tentou iniciar todas as unidades ligadas ao alvo e não tentou destruí-las novamente. Para ver todos os alvos ativos, digite:

      • systemctl list-units --type=target

      Isolando alvos

      É possível iniciar todas as unidades associadas a um alvo e parar todas as unidades que não fazem parte da árvore de dependência. O comando que precisamos emitir para isso chama-se, apropriadamente, isolate. Isso é parecido com alterar o nível de execução em outros sistemas init.

      Por exemplo, se estiver operando em um ambiente gráfico com o graphical.target ativo, você pode desligar o sistema gráfico e colocar o sistema em um estado de linha de comando multiusuário isolando o multi-user.target. Como o graphical.target depende do multi-user.target, mas o contrário não é válido, todas as unidades gráficas serão interrompidas.

      Pode ser interessante dar uma olhada nas dependências do alvo que você está isolando antes de executar este procedimento, de forma a garantir que não estará impedindo serviços vitais:

      • systemctl list-dependencies multi-user.target

      Quando estiver satisfeito com as unidades que serão mantidas vivas, isole o alvo digitando:

      • sudo systemctl isolate multi-user.target

      Usando atalhos para eventos importantes

      Existem alvos definidos para eventos importantes, como desligar ou reinicializar o sistema. No entanto, o systemctl também possui alguns atalhos que adicionam outras funcionalidades adicionais.

      Por exemplo, para colocar o sistema em modo de resgate (único usuário), simplesmente use o comando rescue ao invés de isolate rescue.target:

      Isso irá fornecer a funcionalidade adicional de alertar todos os usuários conectados sobre o evento.

      Para parar o sistema, use o comando halt:

      Para iniciar um desligamento completo, use o comando poweroff:

      Uma reinicialização pode ser feita com o comando reboot:

      Todos esses comandos alertam usuários conectados que o evento está ocorrendo, o que não acontece ao apenas executar ou isolar o alvo. Observe que a maioria das máquinas irão vincular os comandos mais curtos e convencionais para essas operações de modo que funcionem corretamente com o systemd.

      Por exemplo, para reiniciar o sistema, costuma-se digitar:

      Conclusão

      A partir agora, você deve estar familiarizado com algumas das capacidades básicas do comando systemctl que permitem interagir e controlar sua instância do systemd. O utilitário systemctl será o seu ponto principal de interação para o gerenciamento do serviço e do estado do sistema.

      Embora o systemctl opere principalmente com o processo principal do systemd, existem outros componentes do ecossistema do systemd que são controlados por outros utilitários. Outras capacidades, como o gerenciamento de registro e sessões de usuário são controladas por daemons e utilitários de gerenciamento separados (journald/journalctl e logind/loginctl respectivamente). Gastar algum tempo para se familiarizar com essas outras ferramentas e daemons irá tornar o gerenciamento uma tarefa mais fácil.



      Source link

      Como instalar e utilizar a ferramenta Radamsa para fazer teste de fuzzing em programas e serviços de rede no Ubuntu 18.04


      O autor selecionou a Electronic Frontier Foundation, Inc para receber uma doação como parte do programa Write for DOnations.

      Introdução

      As ameaças de segurança estão se tornando cada vez mais sofisticadas, de modo que os desenvolvedores e administradores de sistemas precisam adotar uma abordagem proativa na defesa e teste da segurança de seus aplicativos.

      Um método comum para testar a segurança dos aplicativos cliente ou serviços de rede é o fuzzing, que envolve a transmissão de dados inválidos ou malformados repetidamente para o aplicativo e analisando sua resposta. Isso é útil para ajudar a testar a resiliência e a robustez do aplicativo a entradas inesperadas, que podem incluir dados corrompidos ou ataques reais.

      A Radamsa é uma ferramenta de fuzzing de código aberto que pode gerar casos de teste baseados em dados de entrada específicos do usuário. A Radamsa é totalmente passível de script e, até agora, tem sido bem-sucedida em encontrar vulnerabilidades em aplicativos reais, como o Gzip.

      Neste tutorial, você instalará e usará a Radamsa para fazer o teste de fuzzing da linha de comando e dos aplicativos baseados em rede, usando seus próprios casos de teste.

      Aviso: a Radamsa é uma ferramenta de teste de penetração que pode permitir que você identifique as vulnerabilidades ou pontos fracos em certos sistemas ou aplicativos. Você não deve usar as vulnerabilidades encontradas com a Radamsa para qualquer forma de comportamento inconsequente, exploração prejudicial ou mal-intencionada. As vulnerabilidades devem ser relatadas para o mantenedor do aplicativo afetado, de maneira ética e não ser divulgadas publicamente, sem permissão expressa.

      Pré-requisitos

      Antes de iniciar este guia, será necessário o seguinte:

      • Um servidor Ubuntu 18.04 configurado de acordo com o tutorial de Configuração Inicial do servidor com o Ubuntu 18.04, incluindo um usuário não raiz com privilégios sudo e firewall habilitado para bloquear portas não essenciais.
      • Um aplicativo de linha de comando ou baseado em rede que deseja testar, como o Gzip, Tcpdumb, Bind, Apache, jq ou qualquer outro aplicativo de sua escolha. A título de exemplo para este tutorial,usaremos o jq.

      Aviso: a Radamsa pode provocar a instabilidade ou a falha dos aplicativos ou sistemas em execução. Assim, somente execute a Radamsa em um ambiente em que você esteja preparado para essa situação, como num servidor dedicado, por exemplo. Além disso, assegure-se de que possui a devida permissão escrita do proprietário de um sistema, antes de realizar o teste de fuzzing em tal sistema.

      Assim que tiver tudo pronto, logue no seu servidor como usuário não raiz para começar.

      Passo 1 — Instalando a Radamsa

      Primeiro, você irá baixar e compilar a Radamsa para começar a usá-la no seu sistema. O código fonte da Radamsa está disponível no repositório oficial no GitLab.

      Comece atualizando o índice de pacotes local para refletir quaisquer novas alterações dos autores do código:

      Em seguida, instale os pacotes gcc, git, make e wget. Eles são necessários para compilar o código fonte em um binário executável:

      • sudo apt install gcc git make wget

      Após confirmar a instalação, a ferramenta apt irá baixar e instalar os pacotes especificados e todas as dependências necessárias.

      Em seguida, você irá baixar uma cópia do código fonte da Radamsa, clonando-o a partir do repositório hospedado no GitLab:

      • git clone https://gitlab.com/akihe/radamsa.git

      Isso criará um diretório chamado radamsa, que contém o código fonte do aplicativo. Vá para o diretório para começar a compilar o código:

      Em seguida, inicie o processo de compilação usando o make:

      Por fim, instale o binário da Radamsa compilado para o seu $PATH:

      Assim que terminar, verifique a versão instalada para garantir que tudo está funcionando:

      Sua saída será semelhante à seguinte:

      Output

      Radamsa 0.6

      Caso veja um erro radamsa: command not found (comando não encontrado), verifique novamente se todas as dependências necessárias foram instaladas e se não houve erros durante a compilação.

      Agora que instalou a Radamsa, comece a gerar alguns exemplos de casos para teste, a fim de entender como a Radamsa funciona e para o que ela pode ser usada.

      Passo 2 — Gerando casos para o teste de fuzzing

      Agora que a Radamsa foi instalada, utilize-a para gerar alguns casos para o teste de fuzzing.

      Um caso de teste é uma fração de dados que será usada como entrada para o programa que você estiver testando. Por exemplo, se estiver fazendo o teste de fuzzing em um programa de arquivamento como o Gzip. Como caso para teste, você pode usar um arquivo morto que estiver tentando descompactar.

      Nota: a Radamsa manipulará os dados de entrada de diversas formas inesperadas, inclusive através de repetição extrema, bit flips [manipulação de bits], controle de injeção de caractere e assim por diante. Isso pode provocar a interrupção ou a instabilidade de sua sessão no terminal; portanto, esteja ciente disso, antes de continuar.

      Primeiro, envie uma mensagem de texto simples para a Radamsa para ver o que acontece:

      • echo "Hello, world!" | radamsa

      Isso manipulará (ou confundirá) os dados inseridos e dará como resultado um caso de teste, por exemplo:

      Output

      Hello,, world!

      Neste caso, a Radamsa adicionou uma vírgula extra entre o Hello e o world. Pode não parecer uma alteração significativa, mas, em alguns aplicativos, pode levar à interpretação incorreta dos dados.

      Vamos tentar novamente, executando o mesmo comando. Você verá um outro resultado:

      Output

      Hello, '''''''wor'd!

      Dessa vez, várias aspas (') foram inseridas na string, incluindo uma que sobrescreveu-e à letra l da palavra world. Esse caso de teste em particular traz maior probabilidade de gerar problemas para um aplicativo, uma vez que as aspas simples/duplas são usadas com frequência para separar diferentes frações de dados em uma lista.

      Vamos testar mais uma vez:

      Output

      Hello, $+$PATHu0000`xcalc`world!

      Nesse caso, a Radamsa inseriu uma string de injeção do shell, o que será útil para testar as vulnerabilidades da injeção de comandos no aplicativo que você está testando.

      Você usou a Radamsa para fazer fuzz com uma string de entrada e produzir uma série de casos de teste. Em seguida, você usará a Radamsa para fazer o fuzz em um aplicativo de linha de comando.

      Passo 3 — Fazendo o fuzzing em um aplicativo de linha de comando

      Neste passo, você utilizará o Radamsa para fazer o fuzz em um aplicativo de linha de comando e informará sobre quaisquer falhas que ocorrerem.

      A técnica exata para o fuzzing em cada programa varia significativamente e métodos distintos serão mais eficazes para programas distintos. No entanto, neste tutorial utilizaremos o exemplo do jq, que é um programa de linha de comando para o processamento de dados JSON.

      Você pode usar qualquer outro programa similar, desde que ele siga o princípio geral de tomar alguma forma de dados estruturados ou não estruturados, fazendo algo com eles e em seguida, exibindo um resultado. Por exemplo, esse exemplo também funcionaria com o Gzip, Grep, bc, tr e assim por diante.

      Se ainda não tiver o jq instalado, instale-o usando a apt:

      O jq será instalado agora.

      Para começar o fuzzing, crie um arquivo de exemplo que você usará como a entrada para a Radamsa:

      Então, adicione os seguintes dados de exemplo em JSON ao arquivo:

      test.json

      {
        "test": "test",
        "array": [
          "item1: foo",
          "item2: bar"
        ]
      }
      

      Você pode analisar esse arquivo usando o jq caso queria verificar se a sintaxe JSON é válida:

      Se o JSON for válido, o jq exibirá o arquivo. Caso contrário, ele exibirá um erro, que você pode usar para corrigir a sintaxe, onde for necessário.

      Em seguida, faça o fuzz no arquivo de teste em JSON usando a Radamsa e, em seguida, envie-o para o jq. Isso fará com que o jq leia o caso de teste de fuzzing/para manipulação, em vez de dados originais JSON válidos:

      Se a Radamsa fizer o fuzzing dos dados JSON, de modo que ainda fiquem válidos – do ponto de vista sintático, o jq exibirá os dados, mas com as alterações que a Radamsa tiver feito neles.

      Como alternativa, se a Radamsa fizer com que os dados JSON se tornem inválidos, o jq exibirá um erro relevante. Por exemplo:

      Output

      parse error: Expected separator between values at line 5, column 16

      O resultado alternativo seria que o jq não conseguiria lidar corretamente com os dados que passaram por fuzzing, fazendo com que ele falhe ou que se comporte indevidamente. É precisamente isso o que você estará buscando alcançar com o fuzzing, uma vez que isso pode ser indicação de uma vulnerabilidade de segurança, tais como um estouro de buffer ou uma injeção de comando.

      Para testar as vulnerabilidades de maneira mais eficaz dessa maneira, um script Bash pode ser usado para automatizar o processo de fuzzing, incluindo a geração de casos de teste, passando-os para o programa alvo e capturando qualquer resultado relevante.

      Crie um arquivo chamado jq-fuzz.sh:

      O conteúdo exato do script irá variar, dependendo do tipo de programa em que você estiver fazendo o fuzzing e os dados de entrada. No caso do jq e de outros programas semelhantes, porém, o script a seguir será o suficiente.

      Copie o script em seu arquivo jq-fuzz.sh:

      jq-fuzz.sh

      #!/bin/bash
      while true; do
        radamsa test.json > input.txt
        jq . input.txt > /dev/null 2>&1
        if [ $? -gt 127 ]; then
          cp input.txt crash-`date +s%.%N`.txt
          echo "Crash found!"
        fi
      done
      

      Esse script contém um while para fazer o conteúdo entrar em um loop, repetidas vezes. A cada vez que o script entrar em loop, a Radamsa gerará um caso de teste, com base no test.json e o salvará no arquivo input.txt.

      Na sequência, o caso de teste, input.txt, será executado com o programa jq e todo o resultado – padrão e de erros – será redirecionado para o diretório /dev/null, a fim de evitar que a tela do terminal fique cheia.

      Por fim, o valor de saída do jq é verificado. Se o valor de saída for maior que 127, isso indica que houve um encerramento fatal (uma falha); em seguida, os dados de entrada são salvos – para revisão posterior – em um arquivo chamado crash-, seguido de carimbo de data do Unix, com a data atual em segundos e nanossegundos.

      Marque o script como executável e o coloque em funcionamento, de modo a iniciar o teste de fuzzing do jq, automaticamente:

      • chmod +x jq-fuzz.sh
      • ./jq-fuzz.sh

      Você pode teclar o CTRL+C a qualquer momento para terminar o script. Então, você pode verificar se foram encontradas falhas com o ls, a fim de exibir uma listagem de diretório, contendo quaisquer arquivos de falha que tiverem sido criados.

      Você pode querer melhorar seus dados de entrada JSON, uma vez que o uso de um arquivo de entrada mais complexo provavelmente melhoraria a qualidade de seus resultados de fuzzing. Evite utilizar um arquivo grande ou que contenha muitos dados repetidos—um arquivo pequeno seria a entrada ideal, mas que contenha o máximo de elementos ‘complexos’ possível. Por exemplo, um bom arquivo de entrada conterá amostras de dados armazenados em todos formatos, que incluem strings, números inteiros, booleanos, listas e objetos, bem como dados aninhados, sempre que possível.

      Você usou a Radamsa para fazer o fuzzing em um aplicativo de linha de comando. Em seguida, você usará a Radamsa para fazer o fuzz em serviços de rede.

      Passo 4 — Pedidos de fuzzing em serviços de rede

      A Radamsa também pode ser usada para fazer o fuzzing em serviços de rede, seja atuando como um cliente ou servidor de rede. Neste passo, você usará a Radamsa para fazer o fuzzing em um serviço de rede, com a Radamsa atuando como cliente.

      O objetivo do fuzzing em serviços de rede é testar o quão resiliente um determinado serviço de rede é para os clientes, enviando-lhe dados malformados ou mal-intencionados. Muitos serviços de rede – como servidores Web ou DNS – são geralmente expostos à Internet, o que significa que eles são um alvo comum para invasores. Um serviço de rede que não seja resistente o suficiente para receber dados malformados pode falhar ou, pior ainda, falhar em um estado aberto, o que permite que invasores leiam dados confidenciais, como chaves de criptografia ou dados do usuário.

      A técnica específica para o fuzzing em serviços de rede varia bastante, dependendo do serviço de rede em questão. No entanto, neste exemplo usaremos a Radamsa para fazer o fuzz em um servidor Web básico, servindo conteúdo de HTML estático.

      Primeiro, você precisa configurar o servidor Web para testes. Você pode fazer isso usando o servidor de desenvolvimento integrado que vem com o pacote php-cli. Você também precisará do curl para testar seu servidor Web.

      Se não tiver o php-cli e/ou o curl instalados, instale-os usando a ferramenta apt:

      • sudo apt install php-cli curl

      Em seguida, crie um diretório para armazenar seus arquivos do servidor Web e vá até ele:

      Então, crie um arquivo HTML que contenha uma amostra de texto:

      Adicione o que vem a seguir ao arquivo:

      index.html

      <h1>Hello, world!</h1>
      

      Agora, você pode executar seu servidor Web do PHP. Você precisará ser capaz de visualizar o registro do servidor Web, ao mesmo tempo que ainda continuará a usar outra sessão de terminal. Dessa maneira, abra outra sessão de terminal e de SSH para o seu servidor para este fim:

      • cd ~/www
      • php -S localhost:8080

      Isso irá gerar algo parecido com o seguinte:

      Output

      PHP 7.2.24-0ubuntu0.18.04.1 Development Server started at Wed Jan 1 16:06:41 2020 Listening on http://localhost:8080 Document root is /home/user/www Press Ctrl-C to quit.

      Agora, você pode retornar para a sessão de terminal original e testar se o servidor Web está funcionando, usando o curl:

      Isso exibirá o arquivo de exemplo index.html que você criou anteriormente:

      Output

      <h1>Hello, world!</h1>

      Seu servidor Web precisa estar acessível apenas localmente. Assim, você não deve abrir quaisquer portas no seu firewall para ele.

      Agora que você configurou seu servidor Web de teste, você pode iniciar o teste de fuzzing nele, usando a Radamsa.

      Primeiro, será necessário criar um exemplo de pedido de HTTP para usar como dados de entrada para a Radamsa. Crie um novo arquivo para armazenar isso em:

      Então, copie a seguinte amostra de pedido HTTP para o arquivo:

      http-request.txt

      GET / HTTP/1.1
      Host: localhost:8080
      User-Agent: test
      Accept: */*
      

      Em seguida, utilize a Radamsa para enviar esse pedido HTTP para o seu servidor Web local. Para fazer isso, você terá que usar a Radamsa como cliente TCP, o que pode ser feito especificando-se um endereço IP e porta à qual se conectar:

      • radamsa -o 127.0.0.1:8080 http-request.txt

      Nota: esteja ciente que usar a Radamsa como um cliente TCP possivelmente fará com que dados malformados/mal-intencionados sejam transmitidos pela rede. Isso pode interromper as coisas. Assim, tenha o cuidado de acessar somente as redes que você está autorizado a testar ou, de preferência, continue usando o endereço do localhost (127.0.0.1).

      Por fim, caso visualize os registros produzidos em relação ao seu servidor Web local, verá que ele recebeu os pedidos, mas provavelmente não os processou, já que eles eram inválidos/malformados.

      Os registros produzidos estarão visíveis em sua segunda janela de terminal:

      Output

      [Wed Jan 1 16:26:49 2020] 127.0.0.1:49334 Invalid request (Unexpected EOF) [Wed Jan 1 16:28:04 2020] 127.0.0.1:49336 Invalid request (Malformed HTTP request) [Wed Jan 1 16:28:05 2020] 127.0.0.1:49338 Invalid request (Malformed HTTP request) [Wed Jan 1 16:28:07 2020] 127.0.0.1:49340 Invalid request (Unexpected EOF) [Wed Jan 1 16:28:08 2020] 127.0.0.1:49342 Invalid request (Malformed HTTP request)

      Para obter resultados ideais e garantir que as falhas fiquem registradas, talvez você queira escrever um script de automação semelhante ao usado no Passo 3. Você deve considerar, ainda, o uso de um arquivo de entrada mais complexo, que possa conter adições, como a função de cabeçalhos HTTP extras.

      Você fez o fuzzing em um serviço de rede usando a Radamsa, que agiu como um cliente TCP. Em seguida você fará o fuzzing em um cliente de rede com a Radamsa atuando como um servidor.

      Passo 5 — Fazendo o fuzzing em aplicativos clientes de rede

      Neste passo, você usará a Radamsa para fazer o teste de fuzzing em um aplicativo cliente de rede. Isso pode ser feito através da interceptação das respostas de um serviço de rede e do fuzzing delas, antes de serem recebidas pelo cliente.

      O objetivo deste tipo de fuzzing é testar o quão resilientes os aplicativos cliente de rede são para receberem dados malformados ou mal-intencionados, vindos de serviços de rede. Por exemplo, testar um navegador Web (cliente) recebendo um HTML malformado de um servidor Web (serviço de rede), ou testar um cliente DNS recebendo respostas de DNS malformadas de um servidor DNS.

      Tal como aconteceu com o fuzzing de aplicativos de linha de comando ou de serviços de rede, a técnica exata para o fuzzing em cada aplicativo cliente de rede varia consideravelmente. No entanto, neste exemplo, você usará o whois, que é um aplicativo de envio/recebimento, baseado no protocolo TCP.

      O aplicativo whois é utilizado para fazer pedidos aos servidores WHOIS e receber registros WHOIS como resposta. O WHOIS opera pela porta TCP 43 em texto não criptografado, o que o torna um bom candidato para testes de fuzzing baseados em rede.

      Se ainda não tiver o whois instalado, instale-o usando a ferramenta apt:

      Primeiro, você precisará adquirir uma amostra de resposta do whois para usar como dados de entrada. Para tanto, você pode fazer um pedido whois e salvar o resultado em um arquivo. Aqui, você pode usar qualquer domínio que quiser, uma vez que estará testando o programa whois localmente, usando dados de amostra:

      • whois example.com > whois.txt

      Em seguida, você precisará configurar a Radamsa como um servidor que atenda versões dessa resposta do whois que já passaram pelo fuzzing. Uma vez que a Radamsa está executando em modo de servidor, você terá que conseguir continuar usando o seu terminal. Assim, é recomendável abrir outra sessão de terminal e outra conexão via protocolo SSH com o seu servidor para esse fim:

      • radamsa -o :4343 whois.txt -n inf

      Agora, a Radamsa estará executando em modo de servidor TCP e atenderá uma versão de whois.txt – que já passou por fuzzing – toda vez que uma conexão for feita no servidor, independentemente de quais dados da solicitação forem recebidos.

      Agora, você já pode prosseguir com o teste do aplicativo cliente whois. Você vai precisar fazer uma solicitação whois normal para um domínio de sua escolha (não precisa ser o mesmo para os quais os dados da amostra se destinam), mas com o whois apontado para o seu servidor local da Radamsa:

      • whois -h localhost:4343 example.com

      A resposta consistirá nos dados da sua amostra, mas que já passaram pelo processo de fuzzing da Radamsa. Desde que a Radamsa esteja em execução, você pode continuar a fazer pedidos para o servidor local, pois toda vez ele irá fornecer uma resposta diferente que já passou pelo fuzzing.

      Assim como ocorre no fuzzing em serviços de rede, para melhorar a eficiência esse teste de fuzzing do cliente de rede e assegurar que eventuais falhas sejam capturadas, talvez você queira escrever um script de automação semelhante ao usado no Passo 3.

      Neste passo final, você usou a Radamsa para realizar o teste de fuzzing de um aplicativo cliente de rede.

      Conclusão

      Neste artigo, você configurou a Radamsa e a usou para fazer o fuzzing em um aplicativo de linha de comando, um serviço de rede e um cliente de rede. Portanto, você já tem o conhecimento básico necessário para fazer o teste de fuzzing em seus próprios aplicativos, com a expectativa de aprimorar a robustez e a resistência deles a ataques.

      Se quiser explorar a Radamsa ainda mais, faça uma revisão detalhada do arquivo README da Radamsa, pois ele traz outras informações técnicas e exemplos de como a ferramenta pode ser usada:

      Confira também algumas outras ferramentas de fuzzing, como a American Fuzzy Lop (AFL), que é uma ferramenta de fuzzing avançada, desenvolvida para testar aplicativos binários em velocidade e com precisão extremamente elevadas.



      Source link