スープの上で

雑多なメモ

IoTSecJP Vol.1 訂正情報

2018年4月22日(日)に技術書典4で頒布予定の「IoTSecJP Vol.1」について訂正情報がある場合はこちらに記載いたします。

初版訂正情報

2018/04/01:現在訂正情報はありません。

サーバのパケットキャプチャを取って、Mirai亜種からのスキャン活動をELKで視化して、田舎のジャスコで都会との流行時差を調査する人みたいな気持ちになる

 こんにちは、にほんももんがです。昨年植えたハニーポット(Cowrie)ですが、今日も今日とてインターネットの片隅で細々と活動しております。可愛らしいなぁと最近始めた水耕栽培のサラダ菜の芽を見つめるような目でログを眺めている日々です。

 ところで、Cowrieはssh/telnetの低対話型ハニーポットなので、最近流行しているマルウェアが引っかかることはあまりない*1ようなのですが、IIJ Security Diary: 日本国内における Mirai 亜種の感染状況 (2017年12月)の脚注1に記載があるように、パケットキャプチャをして「初期シーケンスNo=サーバ(ハニポ)のIPアドレスのSYNパケット」を抽出すれば、インターネットの片隅にあるサーバでも世の中のビッグウェーブに乗れるのかもしれないなあと思い立ちやってみました。

 気分は完全に田舎のジャスコでは都会から流行が何週間遅れてやってくるのか調査する人って感じです*2

 それでは結論だけ知りたい方は結論に飛んでください。実際に何をしたか知りたい方は引き続きお読みいただければ幸いです。

目次

環境

ソフトウェア バージョン
OS macOS Higth Sierra 10.13.3
tshark(Wireshark) 2.4.3
Elasticsearch 6.1.3
Logstash 6.1.3
Kibana 6.1.3
Kibana 6.1.3

tsharkでパケットキャプチャを取る

 まず、サーバのパケットをキャプチャします。今回パケットキャプチャをするのに使ったのはtsharkです。ポイントはtcp.relative_sequence_numbersというオプションをFASLEにすることです。該当パケットの抽出の際に設定すればいいオプションかと思いきや、取得の際に設定する必要があるようです(自信はないのでキャプチャするサーバと同様に分析PCのWiresharkでもこのオプションをFALSEにしておいてください…GUIの設定からでもFALSEにできます)。

キャプチャコマンド例)

$tshark -i ens4 -o tcp.relative_sequence_numbers:FALSE -b filesize:200000 -w ens4-capture -q &

※指定インターフェースやファイルサイズなどは適宜読み替えてください。

 キャプチャを始めたら適当にお好みの日数熟成させます。満足行くまでキャプチャ出来たら、キャプチャしたファイルをなんらかの手段で分析用のPCへ移します。

 ちなみに私はscpコマンドで雑に手元のPCにダウンロードしてきました。当たり前ですが、この時にまだtsharkを動かしたままだとこのダウンロード作業もキャプチャされるので注意してください

tsharkで該当パケットを抽出する

 次に、ダウンロードしてきたpcapから、tsharkを使って必要な情報だけ抽出します。今回は時間とソースIPくらいでスキャン行為の可視化は十分できるのですが、後ほど利用したい情報はそれ以外にもここで抽出しておいてください。ここでのポイントは、時間として抽出する列をframe.time_epochで指定することです。

 frame.timeと指定してもFeb 4, 2018 16:53:46.464606074 JSTといったような表記で時間を得られるのでこれでいいかと思いがちなのですが、logstashのdateフィルターが最後の「JST」というタイムゾーン表記に対応していないため*3非常に面倒なことになります。

tsharkを用いた抽出例)

# 時間とソースIP以外も、ソースポートとディスティネーションポートを抽出しておくことにしました
$tshark -r <pcapのファイルパス> -Y "tcp.seq == <サーバのIPを10進数で指定>" -T fields -e "frame.time_epoch" -e "ip.src" -e "tcp.srcport" -e "tcp.dstport" > <適当なファイル名.csv>

 出力されるcsvのセパレータはデフォルトでタブです。

logstashでelasticsearchに放り込む

 抽出したcsv用にlogstashのコンフィグファイルを書いてlogstashを起動し、elasticsearchへデータを放り込みます*4

 ここでのポイントは、csvフィルタのセパレータに\tでなく (ハードタブ)を指定することです\t指定だとタブ指定になりません*5。まあそもそもtsharkでcsv出力する時点でセパレータをカンマにすればよかった話なんですけど…。

コンフィグ例)

Kibanaで可視化してダッシュボードを作る

ワールドマップ

 それではここからは画像のオンパレードです。まずKibanaにアクセスして、メニューの「Management」をクリックし、先ほどLogstashでElasticsearchに放り込んだデータをインデックスパターンに設定して「Next Step」をクリックします。

f:id:haruna_nishiwaki:20180211043000p:plain

 @timestampを選択して「Create Index Patterns」をクリック。

f:id:haruna_nishiwaki:20180211043331p:plain

 これでインデックスパターンが作成できました。ここで、「geoip_location」のtypeが「geo_point」になっていることを確認します。これがgeo_pointタイプになっていない場合はデータの取り込みに失敗しているので地図にマッピングはできません。

f:id:haruna_nishiwaki:20180211043334p:plain

 次に、メニューの「Visualize」を選択し、「+」マークか「Create a visualization」をクリックします。

f:id:haruna_nishiwaki:20180211043339p:plain

 とりあえずみんな大好きな世界地図へのマッピングがしたいので、「Cordinate Map」を選択します(以前はTile Mapと呼称されていたようですが変更されました)。

f:id:haruna_nishiwaki:20180211043341p:plain

 先ほど取り込んだデータで作成したインデックスを選択します。

f:id:haruna_nishiwaki:20180211043344p:plain

 まず、Metrics>Agrregationで「Count」を選択します。次に、Buckets>Aggregationでは「Geohash」を選択します。すると、Fieldの項目が選択できるようになるので、「geoip.location」を選択します。そして最後に右上の「▶︎」マークをクリックします。

f:id:haruna_nishiwaki:20180211043351p:plain

 マッピングできました。

f:id:haruna_nishiwaki:20180211043354p:plain

 Option>Map Typeを変更することでヒートマップにもできます。

f:id:haruna_nishiwaki:20180211044538p:plain

 右上のSaveをクリックして、名前をつけて保存しておきます。あとでダッシュボードを作る時に利用します。

f:id:haruna_nishiwaki:20180211043356p:plain

ヒストグラム

 スキャン活動を時系列で観測するため、データのヒストグラムを作ります。メニューの「Visualize」を選択し「+」マークから新規作成し、Vertival Barを選択します。

f:id:haruna_nishiwaki:20180211051241p:plain

 Y-Axis(Y軸)のAggregationはCountのまま、X-Axis(X軸)を追加します。Aggregationを「Date Histogram」にし、Fieldを「@timestamp」にして「▶︎」マークをクリックして反映すると、図のようにヒストグラムができますので、こちらも保存しておきます。もし何も表示されないといったような場合は、データを表示する期間などを調整してみてください。

f:id:haruna_nishiwaki:20180211051255p:plain

スキャン元都市ランキング

 次は、スキャンのログの数を都市別にカウントし、スキャン活動が多い≒感染端末が多い都市ランキングを作ります。メニューの「Visualize」を選択し、「+」マークから新規作成し、Data Tableを選択します。

f:id:haruna_nishiwaki:20180211051307p:plain

 MetricsのAggregationはCountのまま、Bucketsで「Split Rows」を選択し、Aggregationを「Term」に、Fieldを「geoip.city_name.keyword」に、Sizeに抽出する数を入力して「▶︎」マークで反映すると、どの都市から何回スキャンが来ているかのランキングを出すことができます。Fieldを「geoip.county_name.keyword」などにすることで国ごとのランキングにすることもできますし、「source_ip.keyword」にすることにより同じホストが何度スキャンして来ているのかのランキングを作ることもできます。

f:id:haruna_nishiwaki:20180211051310p:plain

ダッシュボード作成

 それでは今まで作成してきたグラフをまとめたダッシュボードを作成します。メニューの「Dashboard」を選択してダッシュボードの新規作成を選びます。

f:id:haruna_nishiwaki:20180211052926p:plain

 次に右上の「Add」を選択します。

f:id:haruna_nishiwaki:20180211052930p:plain

 すると下図のように今まで保存して来たグラフが(名前だけで)一覧として出てくるので、それを選択してゆくと下の方にグラフが追加されてゆきます。レイアウトはドラッグ&ドロップなどで自由に変更することができます。

f:id:haruna_nishiwaki:20180211052937p:plain

 じゃーん!これでダッシュボードが完成しました。ダッシュボードも忘れず 保存しておきましょう。

f:id:haruna_nishiwaki:20180211052952p:plain

結論

 今まで作って来たダッシュボード上でフィルタgeoip.country_name == Japanを適用してみた結果が以下です。

f:id:haruna_nishiwaki:20180211052955p:plain

 5日間パケットキャプチャしているだけでも、自分が思っていたよりも日本国内ホストからのMirai亜種(と思しき)スキャン活動があるなあということがわかりました。インターネットの片隅での細々とした観測(つまりグローバルIPは一つしか保持してないってことです)でもこれだけスキャンされるので、いろんな場所にあるサーバで観測していれば、感染端末の規模感をそれなりの精度で予測できそうです。

 ちなみにMiraiからのスキャンをマッピングしていたサービス、Mirai Trackerを公開していた(今は公開されていない)@MalwareTechBlog氏は500台くらいセンサー(観測するサーバ)を用意したと発言している*6ので、そのくらいあると本格的に規模感を把握できるのかもしれません。

宣伝

一連の話をデモを交えて「第3回 ハニーポッター技術交流会」で話す予定です。インフルエンザなどにかからなければ、3度目の正直で今回こそ参加できる予定です。

hanipo-tech.connpass.com

他の発表者が若者なので緊張しますがよろしくお願いいたします。

*1:ハニポ検出技術によって、丁寧な職人仕事(?)の施されたマルウェアはあまり捕獲できないような印象を受けます。印象でしかないので本当かどうかは保証し兼ねますが…。IoT狙いのコインマイナーとか雑な感じのマルウェアはわりとあっさり捕獲できたりしています。もちろん、最近流行のMirai亜種はスキャン活動をしているボットとは別にマルウェアをダウンロードしてくるサーバがあるので、おそらくボットよりもかなり数が少ないであろうそいつがイソイソとやってこないとマルウェアが設置されないからという理由もあるのでなんとも主張し兼ねますが…とにかく、アンチハニポ検出技術をご存知の方は教えてくださいということでよろしくお願いいたします。

*2:決して田舎のジャスコをdisっているわけではありません。随分お世話になっております。私はイトーヨーカドー派ですがジャスコもサイコーですよね。

*3:対応しているタイムゾーン表記はこちらです:Joda-Time - Java date and time API - Time Zones。JapanはOKなのに何故JSTがダメなのか納得いかない。

*4:Logstashをよく使われている方はご存知かもしれませんが、Windowsの場合ファイルのパスのセパレータに「¥」ではなくて「/」を利用してください。

*5:elasticsearch - logstash tab separator not escaping - Stack Overflow

*6:Mapping Mirai: A Botnet Case Study | MalwareTech

技術書典にサークル参加して得た知見(というか反省)

にほんももんがです。 台風が近づいておりますが、本日無事に技術書典3に参加し、本を頒布することができました。

onthesoup.hatenablog.com

サークル参加した中で得た知見がいくつかありましたので、今後はじめてサークル参加する方に向けて知見(というほどでもないかもしれないですが…)を共有します。

準備編

まず、今回(10月22日開催)の技術書典の締め切りは3ヶ月前の7月下旬に締め切りがありました。 私は締め切りギリギリ(7月23日)に申し込み、8月ごろから準備を始めました。

  • テーマ決め
  • 目次決め
  • (悪名高きエクセル方眼紙を使って)スケジュール決め

くらいまでを8月中には行っていました。 この時点では、「9月一杯の土日とシルバーウィークを使って執筆し、10月上旬には入稿する」という予定でした。 とにかく、誰がなんと言おうと当初はそういう予定だったんです。

ネタ収集編

9月初旬、ネタ集めのためいくつかハニーポットを構築・運用し始めます。 以前にも以下の通り運用していたことはありましたが、運用費が家計を直撃していたので(AWSでT-pot運用は月7千円くらいはかかりました。年間8万4千円、帰郷費3回分だなと思うとでかすぎます、ていうかそのお金を学資保険に回したい…)、今回は家計を圧迫しない運用を目指そうといろいろな方法やサービスを比較していました(が、結局大手クラウドサービスが安いし利便性が良いというおもしろくもなんともない結果に…)。

onthesoup.hatenablog.com

ここまでは順調でした。ここまでは。

頒布物制作編

それまではほぼスケジュール通りだったものの、ハニーポット構築後、土日はほぼ寝込む(というか平日も寝込む)という体調不良に10月中旬まで見舞われてしまい、頒布物は絶望的だ…と思いながら布団の中でうんうん唸っていました。

しかし、そこでお布団で横になりながらスマホでちょくちょく原稿を書くという諦めの悪さを発揮し、割増料金にはなってしまいましたがなんとか入稿することができました(この時点で10月18日、つまりイベント4日前でした)。

印刷所さんにめっちゃ迷惑かけてしまった編

しかしながら、印刷所さんに頼んでの印刷ははじめてだったため、データ不備でめちゃくちゃご迷惑をかけてしまいました。 ちなみに利用したのは日光企画さんのオンデマンド平閉じフルカラーセットです。

画像の濃淡がなさすぎる

GCPのコンソールやビューワーのWebインターフェースなどで使われている灰色のラインなどが薄く、そのままの状態ではすべて白に見えてしまうかもしれない、と指摘がありました。

⬇️濃淡薄すぎ画像 f:id:haruna_nishiwaki:20171022173510p:plain

⬇️最終的に採用した画像 f:id:haruna_nishiwaki:20171022173553p:plain

結局全体的に画像を差し替えさせていただき、ことなきを得ました。

トンボの位置が仕上がりサイズにかぶって入っている(トンボが見えた状態の仕上がりになる)

なぜか「特定のツールでトンボを設定する方法はわかるがどういうトンボが正しい状態か理解していない」という中途半端な理解度でトンボをつけたため(なんちゅう良い加減な)、なんと仕上がり位置から余白(ドブ)を入れずにトンボを入れてしまうというミスを犯していました。

トンボはあくまで仕上がり位置のガイドなので、仕上がり位置+余白3ミリ以上(3ミリよりも多くていい)の外側に入れないといけません。

この「仕上がり位置+3ミリ以上の余白(ドブ)の外側」という指定が最初どういうことかまったくわかっていなかったのですが、これ見てやっと意味を理解しました(遅い)。

Illustrator初期設定(サイズとトリムマーク"トンボ"設定方法)|Illustrator入稿・印刷データ作成方法/注意点|印刷通販の【WAVE】

なぜそんな中途半端な知識でトンボを入れたのか今となってはよくわからないのですが、ツールを使うのもはじめて&トンボを入れるのもはじめて&作業日が締め切り日という切羽詰まり具合だったのでそのせいかと思われます…😫

⬇️ダメなトンボ(仕上がりサイズちょうどに入れたためトンボが重なって表示されている) f:id:haruna_nishiwaki:20171022181428p:plain

⬇️正しいトンボ(ずれて表示される) f:id:haruna_nishiwaki:20171022181455p:plain

トンボの位置を修正したはいいが、余白が少なすぎる

上記の図で「おお、正しい位置に入れられた!」と喜び勇んで差し替え入稿をしたわけですが、実際は余白(ドブ)が3mミリに達しておらず(今回はサイズ計算を間違えるというポカ)、「探したらトンボが見えちゃうかも…」と印刷所の方から連絡がありました。

もう差し替えできる期限を過ぎてしまっているため、そのままでお願いします、とお伝えしましたが、そもそもそれまでに適当すぎる原稿を入稿するなって感じです…反省しています。

印刷所の方にはめちゃくちゃご迷惑をかけてしまいましたが、終始丁寧に応対してくださって救われました…。

当日編

その後なんとか入稿が完了し、イベント当日まで時間があったので、電子版のQRコードが入ったチラシを作っていました。

前日にチラシを印刷しようとしたところ、通院や買い物でバタバタしてしまい、「まあ明日でも印刷できるか…」と思い当日を迎え会場に向かいました。

その油断がよくありませんでした…

USBメモリにチラシを入れてきたはずが入っておらず、急遽QRコードを生成してネットプリントを試したのですが、どうしても上下が切れてプリントされてしまったり、「画像が小さすぎます」と言われプリントできなかったりといった事態に見舞われました…。

頒布数が少なく早々に完売してしまったため、電子版の問い合わせを多数いただいていたようなのですが、QRコードがなく「あとでサークルページからリンクたどってください」という不親切な案内をせざるをえなくなりました…前日までに準備は万端にしておけということですね…悲しい…。

その後携帯にQRコードを表示させて置いておくという手段に出ましたが、やはりチラシがあるのとないのとでは違っただろうなぁと感じました。

コミケとか、なんかみんな当日コピ本印刷&製本とかしてるし大丈夫っしょ」とか思ってましたがあれは全然大丈夫じゃない人たちだったんだなということがわかりました(友人たちに失礼ですが)。

まとめ

反省点がありすぎるサークル参加でしたが、非常に勉強になりました。次回以降はこの反省点を生かします!

本日は購入してくださったみなさま、応援&協力してくださったみなさま、本当にありがとうございました。

技術書典3 にて「家計にやさしいハニーポット入門」を出します!

2017年10月22日(日)秋葉原UDXで行われる技術書典3にサークル参加します。場所はお05です。頒布するのは「家計にやさしいハニーポット入門」というハニーポット構築本です。

  • セキュリティには詳しくないけど、興味はある
  • サーバは構築・運用したことがある

といった方(一年前の自分)を想定して書きました。DockerやElasticsearch等々といったリッチなものは一切使わず、メモリ0.6GBのサーバでハニーポットを運用しようという感じの趣旨の本です。

安く上げるためのあれこれTipsではなく、目的に合ったハニーポットを構築することに重きをおいた内容です。後ほどBOOTHにて電子版でも販売します。

当日はよろしくお願いいたします。

f:id:haruna_nishiwaki:20171017232643p:plain

イベント頒布価格:500円

電子版(PDF):450円 - 家計にやさしいハニーポット入門 - にほんももんがの本 - BOOTH(同人誌通販・ダウンロード)

目次

はじめに
第1章 ハニーポットの選定
第2章 サーバ選定
  • 2.1 物理サーバ
  • 2.2 VPSなどの利用
第3章 ハニーポットの構築
  • 3.1 準備
  • 3.2 端末上での構築
  • 3.3 Cowrieのインストール
  • 3.4 ログの可視化
第4章 ログ分析・マルウェアの簡易解析

ハニーポット詰め合わせT-potをAmazon EC2上で10日間運用してかかった費用の話

経緯

突然ですが、ある日唐突にハニーポットを運用してみたくなりました。 以前IoTマルウェアの記事を書かせていただいた経緯もあり、そういったマルウェアからの攻撃を実際に受けてみたいなと思ったのが動機です。

嘘です。

森久和昭さんの「サイバー攻撃の足跡を分析するハニーポット観察記録」が会社に置いてあって、カッコイイ!とミーハーな気持ちで運用し始めました。

全くハニーポットについてなにも知らない状態だったので、調べてみたところ、ハニーポットの選定やインストール方法の記事は発見したのですが、運用にいくら位必要なのか明記しているのはあまりなかったので備忘録的に記しておきます。

あくまでも2017年5月31日時点での情報になりますが、これから運用してみようかなという方の参考になればと思います。

運用期間

運用期間は、2017年5月21日(日)17時ごろ 〜 2017年5月31日(水)10時ごろ の約10日間です。

環境

自宅にRaspberryPiが転がっていたのでそいつをハニーポット化してみようかとも思いましたが、自宅のネットワークに手を加えると同居人に鉄拳制裁を喰らうので今回はEC2を利用しました。

ホスティングサービスを利用してハニーポットを構築する前に留意しておくべきなのはサービスの利用規約ですが、AWSの日本語規約は、現時点ではハニーポット運用は明示的に許可されてもいませんし、明示的に禁止されてもいません。

今回の運用中、事業主から注意されるようなことはありませんでしたが、T-potを立てたサーバ自体が侵害されてしまった場合、事業主の判断でインスタンスを止められたり、規約違反としてサービスが利用できなくなる可能性もあります。規約は各ホスティングサービスによって異なりますので確認の上実施ください。

黒彪さんが以下の記事にて各サービスに問い合わせた結果を載せていらっしゃるので、参考にしてください。

blackle0pard.hateblo.jp

今回EC2上に立てた環境は以下の通りです。

項目 タイプ
ホスティングサービス AWS EC2
リージョン 東京
インスタンスタイプ t2.medium
メモリ 4GB
ディスク SSD64GB(ボリュームタイプgp2)
OS Ubuntu16.04 LTS
ハニーポット T-pot 16-10

T-potの要求スペックが結構高い(ハニーポット+ELKで可視化して見ようと思うとメモリ最低4GB、ボリューム最低64GB)のでこんなことになっております。 別にSSDにする必要はなかったと思うのですが、いい機会なので使ってみました。

T-potのインストールについてはこちらがわかりやすかったので参考にさせていただきました。

qiita.com

上記記事ではElastic IPが割り当てられていますが、Elastic IPは作成すると追加料金がかかったことと(かなり微々たるものではありましたが)、割り当てられるIPが北米のものになってしまったので日本のIP帯にくる攻撃が見たかったため今回は割り当てていません。

このような感じの構成で10日間、運用してみました。

かかった費用

項目 価格
Data Transfer / Asia Pacific (Tokyo) Region $0.08
Elastic Compute Cloud / Asia Pacific (Tokyo) Region $17.81
消費税(日本) $1.43
合計 $19.32
合計(円) ¥2,168

※レートはあくまでもAmazonが管理しているので為替レートを即時反映しているわけではないと思われる

このスペックならそんなもんか〜と思っていたのですが、方々から「高い」と言われるので、日常的にサーバーを運用している人にとっては多分高いんだと思います。SSDをHDDにすればもう少し抑えられそうです。

ちなみにさくらのVPSとかでも料金を見積もってみましたが、メモリ4GB以上/SSDで64GB以上…とするとこんな感じになってしまい、あまり値段的には変わらない感じでした。

f:id:haruna_nishiwaki:20170531232857p:plain

ConoHaはもう少し安いようなので、移動しようかなあと検討中です。 ConoHaはハニーポット構築は不可とのことでした。

攻撃を観察してみたい人はハニーポットOKなVPSとかでぽこっとサーバを立てて1週間とか運用してみると楽しいと思います。 インストール時にトラブったんですがそれでも一時間半くらいで導入できました。

観測結果

f:id:haruna_nishiwaki:20170531225821p:plain f:id:haruna_nishiwaki:20170531225753p:plain f:id:haruna_nishiwaki:20170531225805p:plain ※ポート22は2222へ、23は2223へ転送されるようになってます

23日に急に観測数が跳ね上がっていますが、これは多分Shodanで見つけられるようになったのがその頃くらいからだからなのではないかと思われます。

同じ期間の辻さんのハニーポット情報と結構違うような気がするなぁと思っていましたが、telnetsshで試行されるユーザー名とパスワードは似た感じ、という印象です。

開けてあるポートもおそらく違うでしょうし(私は全ポート解放はしてません)、どの場所のIP帯かでも違うと思うので、環境差が出てしまった、という感じでしょうか。

その他

T-pot バージョン16-10だと、一部の検体はハニーポット(cowrie)であることを検出していて捕まえられないようです。 まだリリースはされていませんが、17.06ブランチでは修正されているようなので、近々こちらにアップデートする予定です。

github.com

SECCON2016のIoT CTF Challengeに参加してきました

かなり遅いレポートですが、1月末に開催されたSECCON2016決勝大会(のワークショップの方)に行ってきました。

f:id:haruna_nishiwaki:20170202224757j:plain

私が参加したのは土曜日だけでしたが、「王様達のヴァイキング」がつくられた裏話などが聞けてとても面白かったです。 そして公演の後はワークショップ、「IoT CTF Challenge」に参加してきました。 環境は手元にはないので、内容の全てを詳細にレポートできませんが、参加していない方でも雰囲気を味わっていただけるかと思います。 また、配線図は公開可能か不明だったので、ネットに落ちている配線図を引っ張ってきましたが、もし不明点や補足点などあれば、ご連絡いただければと思います。

今回開催されたIoT CTF Challengeは、

  • 前半:九州大会予選で使用されたIoT CTF Challengeに関するハンズオン・解説
  • 後半:IoT CTF(実践)

という構成で行われました。

## 前半

Lチカ〜EEPROMをRaspberry piから読み書き

写真は撮っていないのですが、テーブルにはRaspberry Piが既にセッティングされており(ローカルネットワークに接続されている状態)、sshVNC ViewerRAspberry Piに接続するところからワークショップが始まりました。

今回使わせていただいたRaspberry PiRaspberry Pi 2 Model B。Amazonでは5000円くらいで買えるようです。

Raspberry Piに接続できると、定番のLチカを行った後、以下の練習問題とともにIC「24LC256」が手渡されました。 これは実際に九州大会予選で使用された問題だそうです(ICの内容自体は違った様子です)。

特務機関JN○Aのミッションを遂行せよ

あなたは特務機関JN○Aに属しているエージェン トである.当局からとあるミッションを8ピンの ICを受け取るかたちで受けた.ミッションを果た
せ!

akizukidenshi.com

データシートを確認すると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にプログラムを書き込みます。

今回利用したArduinoArduino nanoなので、Raspberry Pi-Arduino間はUSBで接続します。

まずは、Arduino IDEの設定を整えます。

  • 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系のワークショップに参加したいです( ´ ▽ ` )ノ