Как это '&' в конце моей команды сделало скрипт таким быстрым?

18

Решая некоторые проблемы CTF онлайн, я столкнулся с ситуацией, когда мне нужно было перебить сервер. Это код, который я написал:

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

Это было невероятно, мучительно медленно . Мне нужно было попробовать комбинации от 1000 до 9999, и это заняло около 5 секунд на каждые 10 попыток. Затем, следуя совету, я ставлю '&' в конце этой строки:

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

И он попробовал сотни комбинаций в течение нескольких секунд. Я был очень удивлен. Может ли кто-нибудь объяснить мне логику? Что сделал «&»?

learnerX
источник
3
Я предлагаю вам прочитать руководство по вашей оболочке. &заставляет команду работать в фоновом режиме, вот и все. Это не сделало это быстрее или что-нибудь. Прочитайте любую оболочку, которую вы используете (я полагаю, Bash) руководство.
Полемон
Это заставило его работать в фоновом режиме, вы должны посмотреть, что оно действительно закончено.
DisplayName
7
Вы не хотите тестировать ниже 1000? Пожалуйста, используйтеfor i in {1000..9999}
Уолтер
2
Возможно, это заставило скрипт работать быстрее, поскольку порты теперь синхронизируются параллельно. Вы должны включить waitв конце, хотя.
Братчли
Вы смотрели nc -z localhost 1000-2000?
Уолтер

Ответы:

30

Добавление &порождает фоновый процесс.

Если вы напишите a; b, он запустит команду a, дождется ее завершения, а затем запустит команду bпо порядку.

Если вы напишите a & b, он появится aкак фоновый процесс. Он не будет ждать его завершения и bсразу же начнет работать . Он будет работать одновременно.

Вы можете увидеть, что он делает, экспериментируя в оболочке. Если вы Xустановили, xtermэто хороший способ увидеть, что происходит: набрав

$ xterm

вызовет открытие другого окна терминала, а первое будет ждать, пока вы его не закроете. Только когда вы закроете его, вы вернете свою оболочку. Если вы печатаете

$ xterm &

затем он запустит его в фоновом режиме, и вы немедленно вернете свою оболочку, в то время как xtermокно также останется открытым.

Так что если вы напишите

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

он устанавливает соединение, отправляет строку, сохраняет то, что выходит в файл, и только затем переходит к следующему.

Добавление &делает это не ждать. В итоге все десять тысяч из них будут работать более или менее одновременно.

Ваш сценарий, кажется, «заканчивается» быстрее, потому что он, вероятно, не закончился в то время. Он только что сделал десять тысяч фоновых заданий, а затем закончил первый.

Это также означает, что в вашем случае он попытается открыть более десяти тысяч соединений более или менее одновременно. В зависимости от того, что другой конец может обработать, некоторые из них вполне могут потерпеть неудачу. Мало того, но нет никакой гарантии, что они будут работать по порядку, на самом деле они почти наверняка не будут работать, так что на самом деле все останется /tmp/me/dump.txtв догадках.

Вы проверили, был ли вывод правильным?

Мэринус
источник
2
Да, я решил проблему. Сервер должен был ответить паролем, если ему был предоставлен правильный код. Я выполнил эту команду, чтобы проверить «dump.txt»: ... и мне открылась $ cat dump.txt | sort | uniq -u строка, содержащая правильный пароль.
LearnerX
16
@intellikid: Я не хочу быть грубым, но это сработало благодаря чистой удаче. Мало того, что порядок не имеет значения, ответы сервера были меньше, чем ncбуфер записи. Если бы это было не так, ответы сервера, скорее всего, были бы чередованы. Т.е., если бы у вас был буфер записи в 1 байт, а ответы были 1111и 2222, вы, скорее всего, видели бы что-то похожее, 11221212а не аккуратно разделенное 1111 2222.
марин
Да, я понял это. Вот почему я играю в эти варгеймы. Я учусь на каждом уровне. Спасибо за помощь в этом обучении.
учащийся
2

Команда nc (netcat) является дорогостоящей с точки зрения времени. Необходимо подключиться к удаленному серверу, отправить данные, дождаться ответа и вернуть его.

Используя & вы в основном разветвляете эту команду в фоновом процессе (это называется «заданием»). Само по себе это не заставляет его работать быстрее. Но это означает, что ваш цикл больше не блокируется и уже может выполнять следующую итерацию (со следующим nc).

Таким образом, в основном ваше ускорение вызвано выполнением всех этих удаленных подключений параллельно, в противном случае им пришлось бы ждать завершения предыдущего соединения.

Кстати, в зависимости от вашего терминала, команды echo также могут замедлять ваш цикл (иногда им нужно подождать, пока в буфере записи не будет места).

Леон
источник