vegeta_ssj@saiyajinz:~/posty/bash_vs_pwsh/$

bash vs. powershell

5 minut czytania opublikowano: 27.05.2021

lubię basha, ale...
Czuję, że tym postem spuszczę na siebie plagę egipską lub klątwe flanelowej
koszuli, ale co tam... Kocham linuxa, latam z nim na codzień, na desktopie, 
na serwerach, wszędzie, ale uwielbiam też powershella ❤ i żyć bez niego nie 
mogę.

en.wikipedia.org/wiki/Bash_(Unix_shell)
en.wikipedia.org/wiki/PowerShell

Nie czuje się na siłach prowadzić równą dyskusję na temat wyższości jednego
wiersza poleceń nad drugim, zostawiam to znudzonym purystom, panom z forum
elektroda i innym piewcom prowokacji. Brak mi po prostu do tego wiedzy i 
doświadczenia. 

W monitorowanym środowisku nieraz ciężko pobierać narzędzia z internetu,
czasem po prostu szybciej je napisać, załadować do pamięci operacyjnej a po 
skończonym zadaniu zapomnieć, że istniały. No i ostatnio musiałem sobie na 
szybciutko zmotać toola pod windowsa który przemieli hash md5 słowniczkiem.
Oczywiście zrobiłem to w powershellu. Na użytek tego posta dodałem do kodu
stopwatch, ale o tym później. Wygląda to tak:

#main.ps1
$hash = Read-Host -Prompt 'podaj hash:' # 5f4dcc3b5aa765d61d8327deb882cf99
$hity = Get-Content .\slownik.txt       # password ^
Write-Host  $hity.Count "strzalow"
$czas = [system.diagnostics.stopwatch]::StartNew()
$md5  = [Security.Cryptography.MD5CryptoServiceProvider]::new()
$utf8 = [Text.UTF8Encoding]::UTF8
foreach($line in Get-Content .\slownik.txt) {
        $bytes= $md5.ComputeHash($utf8.GetBytes($line))
        $proba = [string]::Concat($bytes.foreach{$_.ToString("x2")}) 
        if($proba -match $hash){
        	echo "$proba -> $line"
            	$czas
                break
        }
}

Skrypt co ma robić robi. Tempo nie powala, ale jest znośne. Może to można 
jakoś optymalizować, ale ja się na tym nie znam. 

Jak już wróciłem z pracy do domu, czyli wybiła 16 a ja zmieniłem fotel w 
salonie i biurko na mój tarasik to napisałem to samo w bashu. Po co? Ja
wiem, że hash można sobie pobrać do siebie i lokalnie przemłócić jakimś
hashcatem czy innym, ale jakoś mnie wzięło na eksperymenty i porównania.

#main.sh
echo podaj hash: # 5f4dcc3b5aa765d61d8327deb882cf99
read hash	 # password ^	
hity=$(wc -l ./slownik.txt | awk '{print $1}')
echo $hity strzalow
start=`date +%s` 
while read -r line
do
	proba=$(echo -n $line | md5sum | awk '{print $1}')
	if [ "$proba" = "$hash" ]; then
		echo "$hash -> $line"
		koniec=`date +%s`
		czas=$((koniec-start))
		echo polamalem to w $czas sek
		break
	fi
done < slownik.txt

Gołym okiem widać, że skrypt bashowy wygląda jakby przyjaźniej, ale wynika to
z tego, że polecenia systemu linux są po prostu odzielnymi programami a w 
bashu jest nawet operator porównania który odwołuje się do pliku binarnego.

Pozatym:

bash operuje na bajtach, powershell na obiektach!
- cokolwiek to znaczy ;p

To teraz mały test. Stworzyłem sobie taki prosty słowniczek który zawiera 10
tysięcy prób i jako ostatnią zawiera prawidłowy hit co by skrót odwrócić:

i=1
while [ $i -le 9999 ]
do echo "proba $i"
i=$((i+1))
done >b.txt
echo "password" >> b.txt

Puściłem słownik przez jeden i drugi skrypt. Wynik?



Powershell poradził sobie z hashem w ~2,5 sekundy, bash robił to samo prawie 
10 razy dłużej. Nie wiem, nie znam się, pewnie jakaś mądra głowa potrafiłaby
zoptymalizować ten skrypt by np. nie wywoływać w pętli co strzał awk'a ale 
ja osobiście lubię powershella i nie stronię od niego pod linuxem.

Ps. Uważam, że prawdziwy saijanin powninien poruszać się swobodnie 
w jak największej ilości technologii odrzucając niepotrzebne uprzedzenia 
tudzież przesadnie pursytyczne stwardznienie głowy. Tylko to może Cię 
uczynić prawdziwym saijańskim wojownikiem. Zbędne dyskusje zostawmy ziemianom.

mały apdejt

Zagaiłem do mojego ircowego mentora, wyroczni w sprawach najważniejszych.
Mówię- weź coś zrób, żeby tego awk'a nie było. Ja nie umniem. Zobaczymy co 
będzie, bo bash narazie przegrywa i to srogo. To nieprzyjaciel jest produktów
z Redmont. Podszedł ambicjonalnie, a że to mądra głowa to zajęło mu to dwie
minuty ;p.

Awk był mi potrzebny, bo jak się rurkuje w | md5sum to md5sum do wyjścia 
dodaje myśliczek, o taki o -. Jeszcze po dwóch spacjach. Na ui nie wiem, 
ale robi tak:

vegeta_ssj@saiyajinz:~/md5brute$ echo "yolo" | md5sum
06f5086772e0cd0b8f4e2381fa610d36  -   # na ui to? "*6  -" ???!!!

Więc jak robiłem drugą rurkę do awka to grało:

vegeta_ssj@saiyajinz:~/md5brute$ echo "yolo" | md5sum | awk '{print $1}')
06f5086772e0cd0b8f4e2381fa610d36

Teraz mój ircowy master joda wymyślil na biegu takiego lajfhaka, żeby 
zamiast awkować to co odda md5 lepiej dodać do $hash "  -" i już nie musieć 
awkować w każdej pętli. Diable święty jakie to było genialne...

hash="$hash  -"

Tak- najpierw pobierasz wejścia do zmiennej $hash a potem dorzucasz do niej
"  -" i dopiero porównujesz do $proba. Jejku jak mu to fajnie wyszło ;p

#main.sh
echo podaj hash: # 5f4dcc3b5aa765d61d8327deb882cf99
read hash	 # password ^	
hity=$(wc -l ./slownik.txt | awk '{print $1}')
hash="$hash  -"
echo $hity strzalow
start=`date +%s` 
while read -r line
do
	proba=$(echo -n $line | md5sum 
	if [ "$proba" = "$hash" ]; then
		echo "$hash -> $line"
		koniec=`date +%s`
		czas=$((koniec-start))
		echo polamalem to w $czas sek
		break
	fi
done < slownik.txt

Najważniejsze: czas przelotu basha spadł do 10 sekund, ale to dalej 4x
wolniej niż powershell. Ała, nie po głowie!