Como isso '&' no final do meu comando, fazer o script tão rápido?

18

Enquanto resolvia alguns desafios de CTF on-line, me deparei com uma situação em que precisei forçar a força de um servidor. Este é o código que eu escrevi:

#!/bin/bash

for i in {0..9}{0..9}{0..9}{0..9} 
    do
    echo "Now trying code.."
    echo $i
    echo "a fixed string" $i | nc localhost *port here* >> /tmp/me/dump.txt
    done

Isso foi incrivelmente, dolorosamente lento . Eu precisava tentar combinações de 1000 a 9999 e isso levou cerca de 5 segundos para cada 10 tentativas. Então, seguindo um conselho, eu coloquei um '&' no final desta linha:

   echo "a fixed string" $i | nc localhost *port here* >> /tmp/me/dump.txt &

E tentou 100s de combinações em segundos. Eu fiquei muito surpreso. Alguém poderia explicar a lógica para mim? O que o '&' fazer?

    
por learnerX 04.04.2015 / 14:25

2 respostas

30

Adicionar & gera um processo em segundo plano.

Se você escrever a; b , ele executará o comando a , aguardará o término e, em seguida, executará o comando b .

Se você escrever a & b , ele gerará a como um processo em segundo plano. Ele não irá esperar pela sua conclusão e começará a executar b imediatamente. Ele irá rodar ambos de uma vez.

Você pode ver o que faz experimentando no shell. Se você tem X instalado, xterm é uma boa maneira de ver o que acontece: digitando

$ xterm

fará com que outra janela de terminal seja aberta, e a primeira esperará até você fechar a janela. Somente quando você fechar você pegará sua concha de volta. Se você digitar

$ xterm &

então ele será executado em segundo plano, e você recuperará seu shell imediatamente, enquanto a janela xterm também permanecerá aberta.

Então, se você escreve

echo "a fixed string" $i | nc localhost *port here* >> /tmp/me/dump.txt

faz a conexão, envia a string, armazena o que sai no arquivo e somente então passa para o próximo.

Adicionar o & faz com que não espere. Ele acabará executando todos os dez mil deles mais ou menos simultaneamente.

Seu script parece "terminar" mais rapidamente, porque provavelmente ele não terminou naquele tempo. Acabou de fazer dez mil empregos em segundo plano e depois terminou o primeiro plano.

Isso também significa que, no seu caso, ele tentará abrir dez mil conexões mais ou menos ao mesmo tempo. Dependendo do que a outra extremidade pode manipular, alguns deles podem falhar. Não só isso, mas não há garantia de que eles serão executados em ordem, na verdade eles quase certamente não, então o que realmente vai acabar em /tmp/me/dump.txt é palpite de ninguém.

Você verificou se a saída estava correta?

    
por 04.04.2015 / 14:45
2

O comando nc (netcat) é caro, no que diz respeito ao tempo. Ele precisa se conectar ao servidor remoto, enviar os dados, aguardar uma resposta e devolvê-los.

Ao usar & você basicamente bifurca esse comando em um processo de segundo plano (ele é chamado de "job"). Por si só, isso não faz com que ele corra mais rápido. Mas isso significa que seu loop não está mais bloqueado e pode fazer a próxima iteração (com o próximo nc) já.

Então, basicamente, o aumento de velocidade é causado por fazer todas essas conexões remotas em paralelo, onde, caso contrário, elas teriam que esperar pela conclusão da anterior.

Btw, dependendo do seu terminal, os comandos de eco também podem retardar seu loop (eles às vezes precisam aguardar até que haja espaço no buffer de gravação).

    
por 05.04.2015 / 11:05