IoT診断メモ

# **[+]はじめに**

IoT診断のメモです。
[IoTSecJP公式ページ](http://ruffnex.net/iotsecjp/)からスライドを合計4つダウンロードしておいてください。
左から順に

- tutorial01_vuln.pdf
- tutorial02_app.pdf
- tutorial03_jtag.pdf
- tutorial04_spi.pdf

とします。

# **[+]tutorial01_vuln.pdf**

## まずはnmap

```
nmap -A -p- ${IP_addr}
```

## RTSP

Real Time Streaming Protocol（リアルタイム・ストリーミング・プロトコル 以下:RTSP)。
IETFにおいて標準化されたリアルタイム性のあるデータの配布 (ストリーミング) を制御するためのプロトコルであり、ストリーミングデータ自体の配信を行うためのプロトコルではない。
ネットワークカメラの画像などは、このポート経由で配信するようです。

## ONVIF

アクシス、ボッシュ、ソニーが立ち上げたネットワークカメラ製品のインターフェースの規格標準化フォーラムである。
ネットワークカメラの機能を Web サービスとして公開するのが特徴で、クライアントはカメラから WSDLを取得してそのカメラが持つ機能の利用方法を動的に入手します。
カメラの動的な発見、カメラ情報の設定および取得、カメラの光学制御および PTZ (Pan, Tilt, Zoom) 制御、イベントハンドリング、Video Analytics, ストリーミング、セキュリティといったネットワークカメラの利用に必要な一通りのインターフェイスを定義しています。

## HTTP

HTTP。
これを見つけたらWebからアクセスしてみよう。

# **[+]tutorial02_app.pdf**

# **[+]tutorial03_jtag.pdf**

## マイクロプロセッサ

いわゆるCPU。

## MCU

組み込み用マイクロプロセッサ。
一般的なマイクロプロセッサとは異なり、ROMやRAMなどのメモリ、I/O関連など多くの周辺機能をMCU自体に搭載している。

## ステートマシン

switch文のような制御フローのこと。

> よく知られているステート・マシンとして、ジュースの自動販売機があります。 自動販売機に硬貨を入れると、目的のジュースとともに正確なお釣りが出てきます。ステート・マシンは、投入された硬貨と返却しなければならない硬貨の金額を機械的に計算します。

## TAPコントローラ (TAP: テストアクセスポート(後述))

TCK信号(後述)とTMS信号(後述)の組み合わせによって変化するステートマシン。

## バウンダリスキャンテスト

[参考URL](http://www.tokudenkairo.co.jp/jtag/tech/techbas2.html)

## JTAG

バウンダリスキャンテストをするためのテストアクセスポートの標準。
以下の5ピンが存在する。

- TDI(Test Data In データ入力)
TAPコントローラのスピードを決めるメトロノーム。
単純にリズミカルで安定したビートで上下にパルスする。

- TDO(Test Data Out データ出力)
このピンの電圧を操作することによって、JTAGに何をさせたいかを指示する。

- TCK(Test Clock クロック)
チップにデータを供給するピン。
JTAGにとって、1 と 0 がチップに入るための進入方法になる。

- TMS(Test Mode Select 状態制御)
JTAGを既知の正常な状態にリセットするために使われる。

- TRST(Test Reset リセット信号) 
JTAGハックでは不必要。

## JTAGピン推測ツール: JTAGulator

https://github.com/grandideastudio/jtagulator
あまり信用できない。

## JTAGデバッグツール: OpenOCD

さまざまなチップとインタフェースのための唯一のOSS。
対象デバイス上のJTAGのTAPコントローラを操作してチップに有効なコマンドとして解釈されるビットを送信することができる。

### OpenOCDを利用したファームウェアダンプ

> BUS pirate や Attify badge または Shikra といったデバッグツールたちを使用して、Linux 上で動作するデバッグソフトウェアである OpenOCD を使うために、cfg ファイルに関する説明をしたいと思います。
一般的な OpenOCD のコマンド文は下記のようになっています。

> ```
$ sudo openocd -c "telnet _port 4444" --f interface.cfg target.cfg
```

> この interface.cfg は、BUS pirate などのデバッグツール用の cfg ファイルです。
次にある、target.cfg ファイルは、対象プロセッサごとの cfg ファイルになります。
基本的な cfg ファイルは OpenOCD が下記のように提供してくれています。


> [OpenOCD](https://github.com/arduino/OpenOCD)
[interface](https://github.com/arduino/OpenOCD/tree/master/tcl/interface)
[target](https://github.com/arduino/OpenOCD/tree/master/tcl/target)

## attify badge

シリアル通信をUSBを介して行うことができるツール。

https://github.com/attify/attify-badge

### Usage

1．起動

```
sudo python main.py
```

2．対象のマイクロプロセッサを選択
3．[Start OpenOCD Server] -> [Connect to OpenOCD Server] でJTAGに接続
4．色々いじくる

## OpenOCDのコマンド

```:フラッシュメモリ情報取得
flash banks
```

```:ファームウェアダンプ
dump_image firmware.bin [start] [size]
```
#### その他コマンド一覧

##### サーバーコマンド

```:OpenOCDサーバを閉じて、すべてのクライアント（GDB、telnet、other）を切断
shutdown
```

```:現在のTelnetセッションを終了
exit
```

```:ヘルプ
help [string]
```

```:再開する前に少なくともmsecミリ秒待つ命令
sleep msec [busy]
```

```:ユーザーの優先度でメッセージを記録し、メッセージをstdoutに出力します
echo [-n] message
```

```:ファイル/スクリプト検索パスにディレクトリを追加します。
add_script_search_dir [directory]
```

```:待ち受けるTCP/IP接続を待機するアドレスを名前で指定します。
bindto [name]
```

##### ターゲット状態の処理

```:番号または名前で1つのレジスタにアクセス
reg [(number|name) [(value|'force')]]
```

```:停止
halt [ms]
```

```:ターゲットが停止して（デバッグモードに入る）、パラメータがない場合は最大msミリ秒、または5秒待機
wait_halt [ms]
```

```:ターゲットを現在のコード位置で再開します。
resume [アドレス]
```

```:ターゲットを現在のコード位置でシングルステップするか、オプションのアドレスが提供されている場合はそのアドレスをシングルステップ
step [address
```

```:リセット
reset
```

```:ターゲットを実行させる
reset run
```

```:ターゲットを直ちに停止する
reset halt
```

```:ターゲットをただちに停止し、reset-initスクリプトを実行します
reset init
```

※http://openocd.org/doc/html/Reset-Configuration.html#Reset-Configuration

```:ターゲットの停止を要求し、ソフトリセットを実行
soft_reset_halt
```

##### メモリアクセスコマンド

```:アドレス内容を32ビットワードで表示
mdw [phys] addr [count]
```

```:アドレス内容を16ビットワードで表示
mdh [phys] addr [count]
```

```:アドレス内容を8ビットワードで表示
mdb [phys] addr [count]
```

```:アドレスに指定された32ビットの値を書き込む
mww [phys] addr word
```

```:アドレスに指定された16ビットの値を書き込む
mwh [phys] addr halfword
```

```:アドレスに指定された8ビットの値を書き込む
mwb [phys] addr byte
```

##### イメージの読み込みコマンド

```:バイナリファイルのアドレスから始まるターゲットメモリのダンプ
dump_image filename address size
```

##### その他コマンド

http://openocd.org/doc/html/General-Commands.html

### target.cfgの作成

```cfg
#ボードはチップ名をオーバーライドする可能性があります。
#デフォルトはベンダが使用するものと一致する必要があります

# CHIPNAME(チップセット名)が存在しなければ自分で設定する
if { [info exists CHIPNAME] } {
   set _CHIPNAME $_CHIPNAME
} else {
   set _CHIPNAME ar9331
}

# CPUTAPIDが存在しなければ自分で設定する
# CPUTAPIDはIDCODEのことで、JTAGチェーン内のパーツタイプを一意に識別する32ビットの番号のこと。
# チップセット名でggればでてくる。
if { [info exists CPUTAPID] } {
   set _CPUTAPID $CPUTAPID
} else {
   set _CPUTAPID 0x00000001
}

# 各チップの TAP を JTAG スキャンチェーンに追加
# Usage: jtag newtap [chipname] [tapname] [configparams]
#
# tapname:
#   bs - これが別の TAP である場合、バウンダリスキャンの場合。
#   cpu-チップのメイン CPU、代わり arm と dspARM と DSP の CPU の両方を有するチップ上、 arm1 および
#   arm2 等々二つのアームとを有するチップ上。
#   etb - 組み込みトレースバッファ（例：ARM ETB11）の場合。
#   flash - チップに str912 のようなフラッシュ TAP がある場合、
#   jrc - JTAG ルートコントローラ（例：Beagleboards 上の OMAP3530 のような多くの Texas Instruments チップ
#   上の ICEPick モジュール）。
#   tap - 単一の TAP を持つ FPGA または CPLD のようなデバイスでのみ使用する必要があります。
#   unknownN - TAP が何であるか分からないなら（N は数字です）;
#
# configparams:
#   -irlen: 命令レジスタのビット長（4 ビットまたは 5 ビットなど）
#   -expected-id:ゼロ以外の数値は、スキャンチェーンの検証時に検出されると予想される 32 ビットの IDCODEを表します。
jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID

# CPU に TAP を追加したら、GDB や他のコマンドがそれを使用できるように設定する
# 形式 target create [target_name] [type] [configparams] ...
#
# type:
#     http://openocd.org/doc/html/CPU-Configuration.html の"Command: target types"を参照
#
# configparams:
#     -chain-position dotted.name - このターゲットにアクセスするために使用される TAP を指定します。
#     -endian （大きい|少し） - CPU が大小のエンディアン規則を使用するかどうかを指定します
#     -work-area-backup （0|1） - 作業領域がバックアップされるかどうかを示します。
#     -defer-examine - 最初の JTAG チェインスキャンおよびリセット後のターゲット検査をスキップします。
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME mips_m4k -endian big -chain-position $_TARGETNAME
```

```:その他configparams
disable:
    TRST または JTAG ステートマシンの RESET ステートを使用してリセットした後にスキャンチェーンにリンクされていない TAP にフラグを立てます。
ignore-version:
    オプションの JTAG バージョンフィールドを無視します。
ircapture NUMBER:
    エントリ時に、TAP によって JTAG シフトレジスタにロードされるビットパターン（0x01 など）。
irmask NUMBER:
    命令のスキャンが正しく機能するかどうかを確認するために使用されるマスク。
その他:
    http://openocd.org/doc/html/TAP-Declaration.html#TAP-Declaration
```

GPIOに対応したcfgを書くこともできる。

```cfg
# OpenOCD に telnet で接続する際のポート番号
telnet_port 4444

# JTAG をシミュレートするためのインターフェース
interface sysfsgpio

# TCK/TMS/TDI/TDO の対応するGPIO番号
sysfsgpio_jtag_nums 19 18 7 8

# TRSTの対応するGPIO番号
sysfsgpio_trst_num 6

# SRSTの対応するGPIO番号
# sysfsgpio_srst_num 6

# sysfsgpio_trst_numとsysfsgpio_srst_numは両方もしくはどちらかが必要。

adapter_nsrst_delay 100
jtag_ntrst_delay 100
reset_config trst_and_srst
set CHIPNAME ar9341
jtag newtap $CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id 1
set TARGETNAME $CHIPNAME.cpu
target create $TARGETNAME mips_m4k -endian big -chain-position $TARGETNAME
$TARGETNAME configure -work-area-phys 0xa0600000 -work-area-size 0x20000
```

jtag 接続時に、以下のようなエラーになった場合は、JTAG の配線を最初に疑ってください。
もし、配線が正しければ、起動したターゲットボードでブートローダが JTAG を無効にしている可能性があります。

```
Error: JTAG scan chain interrogation failed: all ones
Error: Check JTAG interface, timings, target power, etc.
Error: Trying to use configured scan chain anyway...
Error: ar934x.m4: IR capture error; saw 0x00 not 0x01
```

# **[+]tutorial04_spi.pdf**

## SPI

シリアル・ペリフェラル・インタフェース(Serial Peripheral Interface, SPI)。
> コンピュータ内部で使われるデバイス同士を接続するバスである。パラレルバスに比べて接続端子数が少なくて済むシリアルバスの一種で、比較的低速なデータ転送を行うデバイスに利用される。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/132486/1caf50a5-15b0-979c-a8c1-d81124edc392.png)

## データシート検索

まずはチップセットのデータシートを検索します。
データシート検索手法は、大きく分けてふたつあります。

- Googleで型番を検索する
- [OCTOPART](https://octopart.com)で型番を検索する
- [chipdb](http://www.msarnoff.org/chipdb/)で型番を検索する
- [findchips](http://www.findchips.com)で型番を検索する

![image.png](https://qiita-image-store.s3.amazonaws.com/0/132486/f7580bee-7de4-0f25-c957-8b4d9d33273c.png)

MX 25L12835FのMXは"Macronix社"の略称なので、MXを抜いた**"25L12835F"**をOCTOPARTで検索します。
その結果、MX 25L12835F MI-10G と MX 25L12835F M2I-10G が一致しました。
今回の型番は、M21-10G なので後者である M21-10G のデータシートをダウンロードすればデータシートの取得は成功です。

## SPIダンプ基礎

### flashrom

> フラッシュチップの識別、読み取り、書き込み、検証、および消去のためのユーティリティで、476 個以上のフラッシュ・チップ、291 個のチップセット、500 個のメインボード、79 個の PCI デバイス、17 個の USB デバイス、さまざまなパラレル/シリアル・ポート・ベースのプログラマをサポートしている優秀なツールです

公式ページ: https://www.flashrom.org/Flashrom
対応チップセット一覧: https://www.flashrom.org/Supported_hardware#Supported_chipsets

### - spiflash.py(libmpsse)

> C と Python を使って SPI や I2C デバイスとインターフェースするために使いやすい API を提供する libftdi の周りの Linux ラッパーライブラリです。

公式ページ: https://github.com/devttys0/libmpsse


# memo

・Retdec
デコンパイラ

### BusPirate

・(0)コマンド
マクロリスト

m
4
3
W
P
A
[0xA0 0x00 0x00]
[0xA1 r:1024]