SECCON2016のIoT CTF Challengeに参加してきました
かなり遅いレポートですが、1月末に開催されたSECCON2016決勝大会(のワークショップの方)に行ってきました。
私が参加したのは土曜日だけでしたが、「王様達のヴァイキング」がつくられた裏話などが聞けてとても面白かったです。 そして公演の後はワークショップ、「IoT CTF Challenge」に参加してきました。 環境は手元にはないので、内容の全てを詳細にレポートできませんが、参加していない方でも雰囲気を味わっていただけるかと思います。 また、配線図は公開可能か不明だったので、ネットに落ちている配線図を引っ張ってきましたが、もし不明点や補足点などあれば、ご連絡いただければと思います。
今回開催されたIoT CTF Challengeは、
- 前半:九州大会予選で使用されたIoT CTF Challengeに関するハンズオン・解説
- 後半:IoT CTF(実践)
という構成で行われました。
## 前半
Lチカ〜EEPROMをRaspberry piから読み書き
写真は撮っていないのですが、テーブルにはRaspberry Piが既にセッティングされており(ローカルネットワークに接続されている状態)、sshやVNC ViewerでRAspberry Piに接続するところからワークショップが始まりました。
今回使わせていただいたRaspberry PiはRaspberry Pi 2 Model B。Amazonでは5000円くらいで買えるようです。
Raspberry Piに接続できると、定番のLチカを行った後、以下の練習問題とともにIC「24LC256」が手渡されました。 これは実際に九州大会予選で使用された問題だそうです(ICの内容自体は違った様子です)。
特務機関JN○Aのミッションを遂行せよ あなたは特務機関JN○Aに属しているエージェン トである.当局からとあるミッションを8ピンの ICを受け取るかたちで受けた.ミッションを果た せ!
データシートを確認するとI2C通信するICだということがわかるので、Raspberry PiでI2C通信ができるようにします。
Rasberry Pi I2C EEPROM Program - richud.com
書き込みソフトウェア
GitHub - tat/eeprog: eeprog is a Linux C program that allows you to read and write to 24Cxx EEPROMs.
ワークショップで利用したRaspberry Piには既に準備されていたので上記手順は行わずに問題に着手することができました。 ブレッドボード上にICを置き、配線をし、試しに書き込み・読み出しをしてみます。 ※回路図は公開可能か不明だったので記載しませんが、こちらなどを参考に配線すれば大丈夫かと思います。
Raspberry pi and i2c. Connecting a 24Cxx eeprom.
pi@raspi03:~/work/eeprom/eeprog $ date | ./eeprog -f -16 -w 0 -t 5 /dev/i2c-1 0x50 // ←dateコマンドの結果を書き込み eeprog 0.7.7-tear12, a 24Cxx EEPROM reader/writer Copyright (c) 2003-2004 by Stefano Barbato - All rights reserved. Copyright (c) 2011 by Kris Rusocki - All rights reserved. Bus: /dev/i2c-1, Address: 0x50, Mode: 16bit Operation: write at offset 0, Input file: <stdin> Write cycle time: 5 milliseconds Writing <stdin> starting at address 0x0 ............................. pi@raspi03:~/work/eeprom/eeprog $ ./eeprog -16 -r 0:29 -f /dev/i2c-1 0x50 eeprog 0.7.7-tear12, a 24Cxx EEPROM reader/writer Copyright (c) 2003-2004 by Stefano Barbato - All rights reserved. Copyright (c) 2011 by Kris Rusocki - All rights reserved. Bus: /dev/i2c-1, Address: 0x50, Mode: 16bit Operation: read 29 bytes from offset 0, Output file: <stdout> Reading 29 bytes from 0x0 Sat 21 Jan 17:41:58 UTC 2017 // ←先ほど書き込んだdateコマンドの結果
うまく読み書きできました。 実際に出題された問題は、同様にこのICからデータを読み出すと、以下のようにファイルが取り出せるという問題だったようです。
pi@raspberrypi:~/work/eeprom/eeprog $ ./eeprog -f -16 -r 0:0x8000 /dev/i2c-1 0x50 > image eeprog 0.7.7-tear12, a 24Cxx EEPROM reader/writer Copyright (c) 2003-2004 by Stefano Barbato - All rights reserved. Copyright (c) 2011 by Kris Rusocki - All rights reserved. Bus: /dev/i2c-1, Address: 0x50, Mode: 16bit Operation: read 32768 bytes from offset 0, Output file: <stdout> Reading 32768 bytes from 0x0 pi@raspberrypi:~/work/eeprom/eeprog $ file image image: gzip compressed data, last modified: Tue Jan 17 06:07:30 2017, from Unix pi@raspberrypi:~/work/eeprom/eeprog $ mv image image.gz ; gzip -d image.gz gzip: image.gz: decompressing OK, trailing garbage ignored pi@raspberrypi:~/work/eeprom/eeprog $ file image image: POSIX tar archive (GNU) pi@raspberrypi:~/work/eeprom/eeprog $ mv image image.tar ; tar xvd image.tar flag xxx.jpg xxx.py
flagの中身はSECCON{assemble this circuit}
で、取り出したxxx.jpgに記載された回路図を組み、Raspberry Piでxxx.pyを実行すれば解けるものだったようです。
ArduinoをAVRライタとして使う準備
次に、Raspberry PiからArduinoにプログラムを書き込んでArduinoをAVRマイコンライタにして、AVRにプログラムを(Arduinoを介して)書き込みました。 入れ子のようでややこしいですが、Raspberry Pi上でArduino IDEを起動させ、そこからArduinoを介してAVRにプログラムを書き込みます。
今回利用したArduinoはArduino nanoなので、Raspberry Pi-Arduino間はUSBで接続します。
- File->Preferencesの「Additional Board Manager URLs」にhttp://drazzy.com/package_drazzy.com_index.jsonを追加してOKを押す
- Tools->Board->BoardManagerからATTinyCore by Spence Kondeをインストールする
- Tools->Bard:“xxx(今の設定)”->Arduino Nanoを選択
- Tools->Processor:“xxx(今の設定)”->ATmega328を選択
- File->Examples->ArduinoISP->ArduinoISPを選択
- Uploadボタンを押し、Arduinoに(ArduinoSIPプログラムを)書き込む
以上でArduinoをAVRライタとして動かす準備ができました。
今回利用するAVRは、ATTniy85なので、Arduino-AVR間は以下のような感じで配線します。
ATtiny85にArduinoで書き込んでみた - Qiita
※上記に加えてRST-GND間にコンデンサを入れるとエラーを連発させず書き込めるらしい…プルアップ抵抗つけとけということなのだろうか…(内臓されてるとか書いてありますがライタがあんまりそのへんを考慮してない作りなのでしょうか?)
そして以下でArduinoからAVRに書き込みます
- Tools->Bard:“xxx(今の設定)”->ATtiny25/45/85を選択
- Tools->Chip:“xxx(今の設定)”->ATtiny85を選択
- Tools->Programmer: “xxx(今の設定)”->“Arduino as ISP"を選択
- Uploadボタンを押し、AVRにプログラムを書き込む
これでAVRにプログラムを書き込む準備ができました。
後編
ここで前半のハンズオンが終わり、IoT CTFに
出題された問題は、IC一つのみ(問題文なし)。前半でも利用された24LC256が手渡されました。 ここまででやってきたことで回答できるということなので、先ほどと同じ手順でICからデータを読み出します。
pi@raspi03:~/work/eeprom/eeprog $ ./eeprog -f -16 -r 0:0x8000 /dev/i2c-1 0x50 > image eeprog 0.7.7-tear12, a 24Cxx EEPROM reader/writer Copyright (c) 2003-2004 by Stefano Barbato - All rights reserved. Copyright (c) 2011 by Kris Rusocki - All rights reserved. Bus: /dev/i2c-1, Address: 0x50, Mode: 16bit Operation: read 32768 bytes from offset 0, Output file: <stdout> Reading 32768 bytes from 0x0 pi@raspi03:~/work/eeprom/eeprog $ ls 24cXX.c 24cXX.o dist eeprog.c i2c-dev.h Makefile WARNING 24cXX.h ChangeLog eeprog eeprog.o image README pi@raspi03:~/work/eeprom/eeprog $ file image image: gzip compressed data, last modified: Thu Jan 19 11:35:52 2017, from Unix pi@raspi03:~/work/eeprom/eeprog $ mv image image.gz pi@raspi03:~/work/eeprom/eeprog $ gzip -d image.gs gzip: image.gs.gz: No such file or directory pi@raspi03:~/work/eeprom/eeprog $ gzip -d image.gz gzip: image.gz: decompression OK, trailing garbage ignored pi@raspi03:~/work/eeprom/eeprog $ file image image: POSIX tar archive (GNU) pi@raspi03:~/work/eeprom/eeprog $ mv image image.tar; tar xvf image.tar flag xxx.ico xxx.py pi@raspi03:~/work/eeprom/eeprog $ cat flag SECCON{Assemble this circuit, and execute this code on ATtiny85.}
第一段階のフラグはSECCON{Assemble this circuit, and execute this code on ATtiny85.}
「This」はどれを指しているのでしょうか?「コードを実行しろ」と言っているので、xxx.icoが回路図なのでしょうか?
pi@raspi03:~/work/eeprom/eeprog $ file xxx.ico xxx.ico: ASCII text pi@raspi03:~/work/eeprom/eeprog $ cat xxx.ico int clk = 3; int q7 = 4; int oe = 0; int d[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; int prevClock = LOW; int flag = HIGH; void setup() { pinMode(clk, INPUT); pinMode(q7, OUTPUT); pinMode(oe, INPUT); } void loop() { if (flag == HIGH && digitalRead(clk) == LOW) { if (digitalRead(oe)==HIGH) { d[7]=d[6]=d[5]=d[4]=d[3]=d[2]=d[1]=d[0]=0; return; } int tmp = !(d[6] ^ d[5]) & 1; d[7] = d[6]; d[6] = d[5]; d[5] = d[4]; d[4] = d[3]; d[3] = d[2]; d[2] = d[1]; d[1] = d[0]; d[0] = tmp; if (d[7] != 0) { digitalWrite(q7, HIGH); } else { digitalWrite(q7, LOW); } flag = LOW; } if (flag == LOW && digitalRead(clk) == HIGH) { flag = HIGH; } } pi@raspi03:~/work/eeprom/eeprog $ cat xxx.py #!/usr/bin/env python import RPi.GPIO as GPIO import time import sys CLOCK = 36 Q7 = 38 OE = 40 COUNT = 127 def init() : GPIO.setwarnings(False) GPIO.setmode(GPIO.BOARD) GPIO.setup(CLOCK, GPIO.OUT) GPIO.setup(Q7, GPIO.IN) GPIO.setup(OE, GPIO.OUT) GPIO.output(CLOCK, GPIO.LOW) GPIO.output(OE, GPIO.HIGH) clock() GPIO.output(OE, GPIO.LOW) def clock() : GPIO.output(CLOCK, GPIO.HIGH) time.sleep(0.001) GPIO.output(CLOCK, GPIO.LOW) time.sleep(0.001) def main() : init() for _ in xrange(COUNT) : data = GPIO.input(Q7) sys.stdout.write(str(data)) sys.stdout.flush() clock() sys.stdout.write("\n") GPIO.cleanup() main()
xxx.pyもxxx.icoもプログラムですが、xxx.pyはpythonの(おそらくRaspberry pi用の)プログラム、xxx.icoはマイコン向けのプログラムのようなので、ATtiny85にこのxxx.icoを書き込んだ上でRaspberry Piの上でxxx.pyを実行すればよいのかな?と思ったのですが、ここでブレッドボード上に回路を組んでいる間にタイムアップ。最後のフラグは取得できませんでした。
まとめ
久しぶりにマイコンやブレッドボードに触れられて、とても楽しいワークショップでした。 実際にIoT CTFで出題された問題も解説していただき、IoT CTFの雰囲気を感じることができ参考になりました。
また機会があればセキュリティ系だけではなくIoT系のワークショップに参加したいです( ´ ▽ ` )ノ