Jak to „&” na końcu mojej komendy sprawiło, że skrypt jest tak szybki?

18

Podczas rozwiązywania niektórych problemów CTF w Internecie natknąłem się na sytuację, w której musiałem brutalnie zmusić serwer. Oto kod, który napisałem:

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

To było niesamowicie, boleśnie powolne . Musiałem wypróbować kombinacje od 1000 do 9999 i zajęło to około 5 sekund na każde 10 prób. Następnie, zgodnie z radą, umieszczam znak „&” na końcu tego wiersza:

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

I wypróbował setki kombinacji w ciągu kilku sekund. Byłem bardzo zaskoczony. Czy ktoś mógłby mi wyjaśnić logikę? Co zrobiły „&”?

learnerX
źródło
3
Sugeruję przeczytanie instrukcji powłoki. &sprawia, że ​​polecenie działa w tle, to wszystko. Nie przyspieszyło to ani nic. Przeczytaj, jakiej powłoki używasz (zakładam bash) manual.
polemon
Sprawiło, że działał w tle, powinieneś wyglądać, że jest naprawdę skończony.
DisplayName
7
Nie chcesz testować poniżej 1000? Proszę używaćfor i in {1000..9999}
Walter A
2
Możliwe, że przyspieszyło to działanie skryptu, ponieważ porty wygasają równolegle. Powinieneś jednak dodać waitna końcu.
Bratchley,
Czy obejrzysz nc -z localhost 1000-2000?
Walter A

Odpowiedzi:

30

Dodanie &powoduje odrodzenie się w tle.

Jeśli napiszesz a; b, uruchomi polecenie a, zaczeka na jego zakończenie, a następnie uruchom polecenie bpo kolei.

Jeśli napiszesz a & b, odrodzi się ajako proces w tle. Nie będzie czekać na zakończenie i zacznie działać bnatychmiast. Będzie działać jednocześnie.

Możesz zobaczyć, co robi, eksperymentując w powłoce. Jeśli masz Xzainstalowany, xtermto dobry sposób, aby zobaczyć, co się dzieje: pisanie

$ xterm

spowoduje otwarcie innego okna terminala, a pierwsze zaczeka na jego zamknięcie. Dopiero po zamknięciu odzyskasz swoją skorupę. Jeśli wpiszesz

$ xterm &

wtedy uruchomi go w tle i natychmiast otrzymasz powłokę, a xtermokno pozostanie otwarte.

Więc jeśli napiszesz

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

nawiązuje połączenie, wysyła ciąg znaków, przechowuje to, co wychodzi z pliku, a dopiero potem przechodzi do następnego.

Dodanie &sprawia, że ​​nie trzeba czekać. W efekcie wszystkie dziesięć tysięcy z nich będzie mniej więcej jednocześnie.

Twój skrypt wydaje się „kończyć” szybciej, ponieważ prawdopodobnie nie zakończył się w tym czasie. Właśnie wykonał dziesięć tysięcy prac w tle, a następnie zakończył pracę na pierwszym planie.

Oznacza to również, że w twoim przypadku spróbuje otworzyć mniej więcej dziesięć tysięcy połączeń naraz. W zależności od tego, co może poradzić sobie drugi koniec, niektóre z nich mogą się nie powieść. Nie tylko, ale nie ma gwarancji, że będą działać w porządku, w rzeczywistości prawie na pewno nie zrobią tego, więc to, co ostatecznie się skończy, /tmp/me/dump.txtjest przypuszczeniem.

Czy sprawdziłeś, czy dane wyjściowe są prawidłowe?

marinus
źródło
2
Tak, rozwiązałem wyzwanie. Serwer miał odpowiedzieć hasłem, jeśli podano mu poprawny kod. Wykonałem to polecenie, aby sprawdzić „dump.txt”: $ cat dump.txt | sort | uniq -u .. i ukazał mi się wiersz zawierający prawidłowe hasło.
uczeń X
16
@intellikid: Nie chcę być niegrzeczny, ale działało przez zwykłe szczęście. Kolejność nie tylko nie miała znaczenia, odpowiedzi serwera były mniejsze niż ncbufor zapisu. Gdyby tak nie było, odpowiedzi serwera byłyby prawdopodobnie przeplatane. To znaczy, gdybyś miał bufor zapisu 1 bajt, a odpowiedzi były 1111i 2222, prawdopodobnie zobaczyłbyś coś w rodzaju 11221212raczej niż starannie oddzielonego 1111 2222.
marinus
Tak, zdałem sobie z tego sprawę. Dlatego gram w te gry wojenne. Uczę się na każdym poziomie. Dziękujemy za pomoc w nauce.
uczący się X
2

Komenda nc (netcat) jest kosztowna, jeśli chodzi o czas. Musi połączyć się ze zdalnym serwerem, wysłać dane, poczekać na odpowiedź i zwrócić ją.

Korzystając z &, po prostu rozwidlasz to polecenie w procesie w tle (nazywa się to „zadaniem”). Samo to nie przyspiesza działania. Ale to znaczy, że twoja pętla nie jest już blokowana i może już wykonać następną iterację (z następnym nc).

Zasadniczo twoje przyspieszenie jest spowodowane równoległym wykonywaniem wszystkich tych zdalnych połączeń, w przeciwnym razie musieliby czekać na zakończenie poprzedniego.

Btw, w zależności od terminala, polecenia echa mogą również spowolnić pętlę (czasami muszą czekać, aż w buforze zapisu będzie miejsce).

Leon
źródło