Comment ce «&» à la fin de ma commande a-t-il rendu le script si rapide?

18

Tout en résolvant certains défis CTF en ligne, je suis tombé sur une situation où j'avais besoin de forcer un serveur. Voici le code que j'ai écrit:

#!/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

C'était incroyablement, douloureusement lent . J'avais besoin d'essayer des combinaisons de 1000 à 9999 et cela prenait environ 5 secondes pour 10 essais. Puis, suite à un conseil, j'ai mis un '&' à la fin de cette ligne:

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

Et, il a essayé des centaines de combinaisons en quelques secondes. J'étais très surpris. Quelqu'un pourrait-il m'expliquer la logique? Qu'est-ce que le «&» a fait?

LearnerX
la source
3
Je vous suggère de lire le manuel de votre shell. &fait exécuter la commande en arrière-plan, c'est tout. Cela ne l'a pas rendu plus rapide ou quoi que ce soit. Lisez le manuel du shell que vous utilisez (je suppose bash).
polemon
Il l'a fait fonctionner en arrière-plan, vous devriez le regarder, c'est en fait terminé.
DisplayName
7
Vous ne voulez pas tester en dessous de 1000? Veuillez utiliserfor i in {1000..9999}
Walter A
2
Il est possible que le script s'exécute plus rapidement car les ports expirent maintenant en parallèle. Vous devez cependant inclure un waità la fin.
Bratchley
Avez-vous regardé nc -z localhost 1000-2000?
Walter A

Réponses:

30

L'ajout &génère un processus d'arrière-plan.

Si vous écrivez a; b, il exécutera la commande a, attendez qu'il se termine, puis exécutez la commande b, dans l'ordre.

Si vous écrivez a & b, il apparaîtra acomme un processus d'arrière-plan. Il n'attendra pas sa fin et démarrera bimmédiatement. Il fonctionnera les deux à la fois.

Vous pouvez voir ce qu'il fait en expérimentant dans le shell. Si vous avez Xinstallé, xtermest un bon moyen de voir ce qui se passe: taper

$ xterm

entraînera l'ouverture d'une autre fenêtre de terminal et la première attendra que vous la fermiez. Ce n'est que lorsque vous le fermerez que vous récupérerez votre coque. Si vous tapez

$ xterm &

il l'exécutera en arrière-plan et vous récupérerez immédiatement votre shell, tandis que la xtermfenêtre restera également ouverte.

Donc, si vous écrivez

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

il fait la connexion, envoie la chaîne, les magasins ce qui sort dans le fichier, et ne puis passe à côté puis un.

Ajouter le &fait attendre. Il finira par fonctionner tous les dix mille plus ou moins simultanément.

Votre script semble "se terminer" plus rapidement, car il ne s'est probablement pas terminé à ce moment-là. Il vient de créer dix mille emplois d'arrière-plan, puis a mis fin à celui de premier plan.

Cela signifie également que, dans votre cas, il tentera d'ouvrir plus ou moins dix mille connexions à la fois. Selon ce que l'autre extrémité peut gérer, certains d'entre eux pourraient bien échouer. Non seulement cela, mais il n'y a aucune garantie qu'ils fonctionneront dans l'ordre, en fait, ils ne le seront certainement pas, alors ce qui finira par /tmp/me/dump.txtêtre le cas de tous.

Avez-vous vérifié si la sortie était correcte?

marinus
la source
2
Oui, j'ai résolu le défi. Le serveur devait répondre avec le mot de passe si le bon code lui était fourni. J'ai exécuté cette commande pour vérifier 'dump.txt': .. et $ cat dump.txt | sort | uniq -u la ligne contenant le mot de passe correct m'a été révélée.
LearnerX
16
@intellikid: Je ne veux pas être impoli, mais cela a fonctionné par pure chance. Non seulement l'ordre n'avait pas d'importance, mais les réponses du serveur étaient plus petites que ncle tampon d'écriture de. Si cela n'avait pas été le cas, les réponses du serveur auraient très probablement été entrelacées. C'est-à-dire, si vous aviez eu un tampon d'écriture de 1 octet, et les réponses étaient 1111et 2222, vous auriez probablement vu quelque chose comme 11221212plutôt qu'une séparation nette 1111 2222.
marinus
Oui, je m'en suis rendu compte. C'est pourquoi je joue à ces wargames. J'apprends à chaque niveau. Merci d'avoir aidé cet apprentissage.
LearnerX
2

La commande nc (netcat) est coûteuse, en termes de temps. Il doit se connecter au serveur distant, envoyer les données, attendre une réponse et la renvoyer.

En utilisant &, vous bifurquez essentiellement cette commande dans un processus d'arrière-plan (cela s'appelle un "travail"). En soi, cela ne le fait pas fonctionner plus rapidement. Mais cela signifie que votre boucle n'est plus bloquée et peut déjà faire la prochaine itération (avec le prochain nc).

Donc, fondamentalement, votre accélération est causée par la création de toutes ces connexions à distance en parallèle, sinon elles devraient attendre la fin de la précédente.

De plus, selon votre terminal, les commandes d'écho peuvent également ralentir votre boucle (elles doivent parfois attendre qu'il y ait de la place dans le tampon d'écriture).

Léon
la source