Como esse '&' no final do meu comando tornou o script tão rápido?

18

Ao resolver alguns desafios do CTF on-line, deparei-me com uma situação em que precisava forçar força bruta em um servidor. Este é o código que 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, coloquei um '&' no final desta linha:

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

E, tentou centenas de combinações em segundos. Fiquei muito surpreso. Alguém poderia me explicar a lógica? O que o '&' fez?

aprendizX
fonte
3
Eu sugiro que você leia o manual do shell. &faz com que o comando seja executado em segundo plano, isso é tudo. Não tornou mais rápido nem nada. Leia o manual do shell que você estiver usando (presumo que o bash).
Polemon
Ele foi executado em segundo plano, você deve ver que está realmente concluído.
DisplayName
7
Você não quer testar abaixo de 1000? Por favor, usefor i in {1000..9999}
Walter A
2
É possível que o script tenha sido executado mais rapidamente, pois as portas agora estão atingindo o tempo limite em paralelo. Você deve incluir um waitno final, no entanto.
Bratchley 04/04
Você olhou nc -z localhost 1000-2000?
Walter A

Respostas:

30

Adicionar &gera um processo em segundo plano.

Se você escrever a; b, ele executará o comando a, aguarde o término e execute o comando b, em sequência.

Se você escrever a & b, ele aparecerá acomo um processo em segundo plano. Não esperará que termine e começará a funcionar bimediatamente. Ele executará os dois ao mesmo tempo.

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

$ xterm

fará com que outra janela do terminal seja aberta e a primeira aguardará até você fechá-la. Somente quando você o fechar, você recuperará sua concha. Se você digitar

$ xterm &

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

Então se você escreve

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

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

Adicionando o &faz não esperar. Terminará executando todos os dez mil deles mais ou menos simultaneamente.

Seu script parece "terminar" mais rapidamente, porque provavelmente não terminou realmente nesse período. Acabou de fazer dez mil trabalhos em segundo plano e depois encerrou o primeiro.

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 suportar, algumas delas podem falhar. Não apenas isso, mas não há garantia de que eles irão funcionar em ordem, na verdade eles quase certamente não, então o que realmente vai acabar /tmp/me/dump.txté o palpite de alguém.

Você verificou se a saída estava correta?

marinus
fonte
2
Sim, eu resolvi o desafio. O servidor responderia com a senha se o código correto fosse fornecido. Eu executei este comando para verificar 'dump.txt': $ cat dump.txt | sort | uniq -u ..e a ​​linha que contém a senha correta foi revelada para mim.
LearnerX
16
@intellikid: Não quero ser rude, mas funcionou com pura sorte. Não apenas o pedido não importava, as respostas do servidor eram menores que nco buffer de gravação do servidor . Se não fosse esse o caso, as respostas do servidor provavelmente teriam sido intercaladas. Ou seja, se você tivesse um buffer de gravação de 1 byte e as respostas fossem 1111e 2222, provavelmente teria visto algo como, em 11221212vez de um, ordenadamente separado 1111 2222.
marinus
Sim, eu percebi isso. É por isso que estou jogando esses jogos de guerra. Eu aprendo em cada nível. Obrigado por ajudar nesse aprendizado.
LearnerX
2

O comando nc (netcat) é oneroso, em termos de tempo. Ele precisa se conectar ao servidor remoto, enviar os dados, aguardar uma resposta e devolvê-los.

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

Então, basicamente, sua aceleração é causada por fazer todas essas conexões remotas em paralelo, caso contrário, elas teriam que esperar a conclusão da anterior.

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

Leon
fonte