Arduinoを USB/HIDデバイス(仮想キーボード)として活用する


本記事について

 Arduino はPCやスマフォとUSB接続したとき,自身をUSB/HIDデバイスとして認識させる機能が標準で備わっています。HID(ヒューマン・インターフェイス・デバイス)とはUSB接続のキーボードやマウス,ゲームパッドのような入出力装置のことです。この記事から一連の連載では、Arduinoを仮想キーボードとして動作させ、その活用方法をさぐってみようと思います。

第一弾)「BadUSB(仮想キーボード)紹介」

Arduinoを仮想キーボードとして活用する事例を調べているうちに、 BadUSBなる言葉があることを知りました。アマゾンなどでは、それを実現する製品も販売されています。BadUSB製品の多くは、 ATmega32U4というマイコンを使っていることがわかったため、BadUSBとはいかなるものかを知るためにも、まず、「ATmega32U4」マイコンを搭載した製品を使用し、どんな使い方ができるか検討しました。

説明

アプリケーション

マイコンをPCやスマートフォンと接続して動かすアプリケーションを考えたとき、機種依存ではなく、Web技術を利用したクラウド連携システムが注目されています。これをWOT(※)と呼び、広く普及することが期待できます。今後のWOTの流れが見逃せないと考えます。
※Web of Things (WoT)とは、「モノの Web」という意味で、普及しているHTMLやJavaScriptなどのWeb技術を使ってIoTを利用したサービスやアプリケーションの提供を行うことを目指している。

ブラウザーとUSBデバイスの接続

ブラウザーとデバイスの接続に関して、主な接続の仕方には以下のようなものがあります。

(1) http / WebSocket:
CloudのWebServerを介在してBrowserとデバイスを接続する。
(2) Sound(Mic-in, Speaker-out):
音を媒体として入出力を行う。
(3) HID(USB / Bluetooth):
キーボードやマウスといったHIDデバイスとして接続する。BadUSBと呼ばれているものもこれに属する。ブラウザー上のボタンを押すことで処理を駆動するイベントの発生ができ、マイコン主導で自動処理や定時処理を実行することが容易である。
(4) WebUSB:
JavaScriptを使用してブラウザーからUSB機器を扱うことができる。
(5) MIDI(USB / Serial):
電子音楽の接続規格を使って接続する。音を扱うアプリには適する。反面、利用は限定的である。

 現時点では、(4)(5)はOSやブラウザーの種類によっては対応していないものもあります。http / WebSocketを使った接続が近年WOTの本命視されていますが、上記のうち唯一マイコン主導でイベントを発生できることから、自動化が進めやすくUSB/HIDの魅力は高いと考えます。弱点として、USBホストからUSBデバイスへの下り通信を扱うことができないことがあげられます。

BadUSBとGoodUSB

 マイコンによるUSB/HIDデバイスを作成する場合、 BadUSBという言葉を考慮する必要があります。BadUSBとは、USBデバイス内のファームウエアを更新する仕組みを悪用できてしまうという、USBの規格に存在する脆弱性です。私は言葉の意味を広く捉え、UBSデバイスを悪用することを、BadUSBと捉えています。
この脆弱性を悪用することで、セキュリティー問題を引き起こす仕組みを簡単に作ることができてしまいます。そんな危険性もありますが、USBデバイスは、以下の様なメリットがあり潜在能力は高いと思われます。
・キーストロークを自動化できる
・個人に配布すれば、個人特定などセキュリティーの高い使い方ができる
・プログラムが簡単。キーボードという汎用性の高いデバイスを作ることができる
 もちろん、USBデバイスの悪用はいいことではないので、Arduinoを使ったUSBデバイスを、GoodUSBとして、自分の手の届く範囲(自作のデバイスを意味します。得体のしれないUSBをPC等にさしてはいけません)で処理の自動化のために便利なツールとして使うことを目指します。
 GoodUSBとしての使い方の例として、パスワードをUSB内に保存する、セキュリティー的な使い方を実験しました。

準備するもの

 PC (Windows10)
 Beetle BadUSB ATMEGA32U4開発ボード仮想キーボードArduino用
 開発環境は Windows版のArduino IDE v1.8.9

ハード構成

ソフトウエア

ソースコード
/*
 *起動後、一度だけ文字列を出力するサンプル。WindowsPC接続用。
 *32U4のKBD
 */
#include "Keyboard.h"
//
void setup() {
  Keyboard.begin();
  delay(3000);
  Keyboard.print("testid"); //ID
  Keyboard.write(KEY_TAB);
  delay(100);
  Keyboard.print("test"); //password
  Keyboard.write(KEY_TAB);
  Keyboard.write(KEY_RETURN);
}
//
void loop() {
}
HTML
<!DOCTYPE html><html>
<script type="text/javascript">
<!--
function t3220() {
 if (document.getElementById("IM1").value=='testid'){
  document.F1.IM1.value='OK';
  document.F1.IM1.focus();
 } else {
  document.F1.IM1.value='NG';
  document.F1.IM1.focus();
 }
 return false;
}
// -->
</script><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<title>HID sample</title>
<meta name="Generator" content="Cocoa HTML Writer">
<meta name="CocoaVersion" content="1404.47">
<style type="text/css"> body {background-color: #ffffdf} </style>
<style type="text/css"> .center {text-align: center;} </style>
</head><body>
<form method="POST" name="F1">
<div class="center">
<tr>exsampleログイン画面</tr><br>
<tr>ID<input type="text" name="IM1" id="IM1" size=8>
<tr> パスワード<input type="text" name="IM2" id="IM2" size=8></tr><br><br>
<tr><input type="button" value="ログイン" onclick="return t3220()"></tr><br>
<br></div>
<p id="commandx"></p></form></body></html>

実行

 準備として、WindowsPCでブラウザーを起動し、テスト用パスワード入力画面を表示しておく。
Arduino互換製品をUSBに接続すると、IDとパスワード文字列が一度だけ入力されます。

まとめ

 USBデバイスを悪用する BadUSBと呼ばれる言葉を理解した上で、BadUSBの潜在的な能力を節度をもって利用すれば、GoodUSBとして使えることを学んだ。また、Arduinoを USB/HIDデバイスとしてPCとつなぐことが確認できました。次回は本格的なアプリケーションを検討する予定です。