¿Cómo este '&' al final de mi comando hizo que el script fuera TAN rápido?

18

Mientras resolvía algunos desafíos de CTF en línea, me encontré con una situación en la que necesitaba forzar un servidor. Este es el código que escribí:

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

Esto fue increíblemente, dolorosamente lento . Necesitaba probar combinaciones de 1000 a 9999 y esto tomó alrededor de 5 segundos por cada 10 intentos. Luego, siguiendo un consejo, pongo un '&' al final de esta línea:

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

Y, probó cientos de combinaciones en segundos. Estaba muy sorprendido. ¿Alguien podría explicarme la lógica? ¿Qué hizo el '&'?

alumno X
fuente
3
Le sugiero que lea su manual de shell. &hace que el comando se ejecute en segundo plano, eso es todo. No lo hizo más rápido ni nada. Lea el manual de shell que esté utilizando (supongo que bash).
polemon
Hizo que se ejecutara en segundo plano, deberías ver que está realmente terminado.
DisplayName
77
¿No quieres probar por debajo de 1000? Por favor, usefor i in {1000..9999}
Walter A
2
Es posible que haya hecho que el script se ejecute más rápido ya que los puertos ahora están agotando el tiempo de espera en paralelo. Sin waitembargo, debe incluir un al final.
Bratchley
¿Lo miraste nc -z localhost 1000-2000?
Walter A

Respuestas:

30

Agregar &genera un proceso en segundo plano.

Si escribe a; b, ejecutará el comando a, esperará a que termine, luego ejecutará el comando b, en secuencia.

Si escribe a & b, se generará acomo un proceso en segundo plano. No esperará a que termine y comenzará a ejecutarse de binmediato. Funcionará ambos a la vez.

Puedes ver lo que hace experimentando en el shell. Si lo ha Xinstalado, xtermes una buena forma de ver qué sucede: escribiendo

$ xterm

hará que se abra otra ventana de terminal, y la primera esperará hasta que la cierre. Solo cuando lo cierres recuperarás tu caparazón. Si escribes

$ xterm &

luego lo ejecutará en segundo plano y obtendrá su shell de inmediato, mientras que la xtermventana también permanecerá abierta.

Entonces si escribes

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

realiza la conexión, envía la cadena, almacena lo que sale en el archivo y solo luego pasa al siguiente.

Agregar el &hace que no espere. Terminará ejecutando los diez mil de ellos más o menos simultáneamente.

Su secuencia de comandos parece "terminar" más rápidamente, porque probablemente en realidad no terminó en ese momento. Simplemente realizó diez mil trabajos en segundo plano, y luego terminó el primero.

Esto también significa que, en su caso, intentará abrir diez mil conexiones más o menos a la vez. Dependiendo de lo que pueda manejar el otro extremo, algunos de ellos podrían fallar. No solo eso, sino que no hay garantía de que se ejecutarán en orden, de hecho, es casi seguro que no, así que lo que realmente terminará /tmp/me/dump.txtes una incógnita.

¿Verificaste si la salida era correcta?

marinus
fuente
2
Sí, resolví el desafío. El servidor debía responder con la contraseña si se le proporcionaba el código correcto. Ejecuté este comando para verificar 'dump.txt': ... $ cat dump.txt | sort | uniq -u y se me reveló la línea que contenía la contraseña correcta.
learnerX
16
@intellikid: No quiero ser grosero, pero funcionó por pura suerte. No solo el orden no importó, las respuestas del servidor fueron más pequeñas que ncel búfer de escritura. Si este no hubiera sido el caso, las respuestas del servidor probablemente se habrían intercalado. Es decir, si hubiera tenido un búfer de escritura de 1 byte, y las respuestas fueran 1111y 2222, probablemente habría visto algo así como 11221212algo bien separado 1111 2222.
marinus
Sí, me di cuenta de eso. Por eso estoy jugando estos juegos de guerra. Aprendo en cada nivel. Gracias por ayudar a ese aprendizaje.
LearnerX
2

El comando nc (netcat) es costoso, en cuanto al tiempo. Necesita conectarse al servidor remoto, enviar los datos, esperar una respuesta y devolverla.

Al usar & básicamente está bifurcando ese comando en un proceso en segundo plano (se llama "trabajo"). Por sí solo eso no lo hace correr más rápido. Pero sí significa que su ciclo ya no está bloqueado, y ya puede hacer la siguiente iteración (con el siguiente nc).

Básicamente, su aceleración es causada por hacer todas estas conexiones remotas en paralelo, de lo contrario tendrían que esperar a que se complete la anterior.

Por cierto, dependiendo de su terminal, los comandos de eco también pueden ralentizar su ciclo (a veces necesitan esperar hasta que haya espacio en el búfer de escritura).

León
fuente