ロマンティック・アイロニー

好きなこと・気になったことについて書いていきます!

Ubuntu16.04にDocker入れてさくっとハニーポット構築(cowrie)

以前からハニーポットを立ててみたかったのだがなかなか機会が見つけられずそのままずるずる時間がたってしまった。しかし最近ちょうど時間もあったので勢いで構築してみた。今回はSSHハニーポットのcowrieを使った。cowrieはkippoの上位互換なので。どこが上位互換なんだよ!って人はSSHハニーポットはKippoではなくCowrieを使え - 日々のおべんきょを参考にしてください。

基本的には DockerをLinux(Ubuntu 14.04 LTS)にインストールする方法と解説 | tracpath:Worksに書いてある通りに進めていった。

構築環境

  • さくらのVPS
  • OS : Ubuntu 16.04
  • メモリ : 1GB
  • HDD : 100GB

Dockerインストール

OSの確認

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu  
Description:    Ubuntu 16.04.1 LTS  
Release:        16.04  
Codename:       xenial

カーネルのバージョン確認

Dockerはカーネルのバージョンが3.10以上でないと動作しないらしい

$ uname -a
Linux ubuntu 4.4.0-42-generic

wgetコマンドがあるか確認

$ which wget
/usr/bin/wget

wgetでDockerダウンロード

$ wget -qO- https://get.docker.com/ | sh

Dockerの動作確認

$ sudo docker run hello-world

dockerグループを作成しsudo権限のあるユーザをグループに追加

$ sudo usermod -aG docker [ユーザ名]

ここで一旦ログアウトもしくは再起動

もう一度Docker動作確認(sudoなしで!)

$ docker run hello-world

先ほどと同じようなメッセージが表示されれば成功 このあと先ほどの参考記事ではgrubの設定をいじっていたがVPSで手元に実機がないうえ、実はVPSを友人と共有していてビビったので行わなかった。(おそらく問題はないと思うが...)

ファイアウォールの設定

Ubuntu16.04ではデフォルトでUFW(Uncompaticable FireWall)という複雑なiptablesをラップするツールがありとても便利なのでこれを利用すると良い。

ファイアウォールが動作しているか確認

$ sudo ufw status
Status: active

エディタでufwの設定変更

$ sudo vi /etc/default/ufw

DEFAULT_FORWARD_POLICYをACCEPTへ変更

DEFAULT_FORWARD_POLICY="ACCEPT" 

ポート2375(tcp)を開放(Dockerのデフォルトポート)

$ sudo ufw allow 2375/tcp

もし22番ポートも閉じていたら開けるのを忘れないように(cowrieで使う)

ファイアウォール設定リロード

$ sudo ufw reload
Firewall reloaded

DNS設定

Dockerの設定ファイルを編集

$ sudo vi /etc/default/docker

外部のDNSサーバ(ここではGoogle)を利用するように以下のコメントを消す

#DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4"

Docker再起動

$ sudo /etc/init.d/docker restart

これでDockerのインストールは終了! つづいてcowrieの構築。といってもすぐに終わる。

Docker上にcowrie構築

DockerHubから他の人が保管しているcowrieコンテナイメージを探す

$ docker search cowrie
NAME                               DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
k0st/cowrie                        Cowrie - SSH honeypot based on kippo (mini...   4                    [OK]
dtagdevsec/cowrie                  cowrie                                          2                    [OK]
wonderfall/cowrie                  SSH Honeypot. Based on Alpine Linux.            2                    [OK]
ouspg/cowrie                       Cowrie honeypot based on alpine:latest          1                    [OK]
armbues/netscreen                  SSH honeypot based on Cowrie modified to l...   1                    [OK]
vimagick/cowrie                    A SSH honeypot                                  0                    [OK]
rayson/cowrie                      Cowrie is a medium interaction SSH and Tel...   0                    [OK]
valerianomanassero/cowrie-centos   Docker Image packaging for Cowrie on Centos     0                    [OK]
thechris/cowrie                    A lightly modified version of cowrie            0
viker/cowrie                                                                       0
solson/cowrie                                                                      0
viker/cowrie-kippo                                                                 0

この中から好きなものを選択(今回はk0st/cowrieを使った)

コンテナイメージをローカルにもってくる

$ docker pull k0st/cowrie

コンテナ起動

$ docker run -it -name cowrie -p 22:2222 k0st/cowrie /bin/sh

ここでちょっとdocker runオプションの説明
-it : コンテナ起動後そのままコンテナ内にログイン
-name : コンテナに名前をつける(この名前はコンテナ削除時などコンテナ指定する場合に使用。これを指定していないとデフォルトで付与されるランダムな英数字の文字列で指定しなければいけないためめんどう)
-p : ホストの任意のポートをコンテナの任意のポートへ転送(この場合ホストの22番ポートにきたアクセスをコンテナの2222番ポート(cowrieのデフォルトの待ち受けポート)へ転送)

最後の/bin/shはコンテナ内で使用されているシェル(普通は/bin/bashだがこのk0st/cowrieで設定されているシェルが/bin/shだった)
コンテナから出るときは、

$ exit

ででれる。すでに起動した後にもう一度入りたいときは以下のコマンドで入れる。

$ docker exec -it cowrie /bin/sh

作成したコンテナの確認

$ docker ps -a

cowrieコンテナの削除

$ docker rm cowrie

まとめ

今回はじめてDockerとハニーポットを使用してみてこれはいろいろできそうだなと期待が高まった。(Dockerつよすぎ!!) ハニーポットに関しては侵入してきた攻撃者の動きが動画で再生できるのはとてもおもしろい。今後はkippo-graphなどでデータの可視化にも挑戦したい。

参考

DockerをLinux(Ubuntu 14.04 LTS)にインストールする方法と解説 | tracpath:Works

SSHハニーポットはKippoではなくCowrieを使え - 日々のおべんきょ

Dockerコマンドメモ - Qiita

いまさら聞けないDocker入門(1):アプリ開発者もインフラ管理者も知っておきたいDockerの基礎知識 - @IT

VPSでハニーポット運用はセーフなのか

前々からハニーポットを運用してみたいと思っていたが、金銭的に難しくなかなか機会がなかった。しかし、今回さくらインターネットのクーポン券が手に入ったのでこれを機にはじめよう!...と思った。しかしVPSハニーポット運用は契約的にセーフなのか気になったので調べてみた。(これは個人的な見解なので鵜呑みにしないようにお願いします。)

サービスと規約一覧

>犯罪行為、犯罪行為をそそのかしたり容易にさせる行為、またはそれらのおそれのある行為
→場合によってはアウト?
>当社あるいは第三者の運用するコンピュータ、電気通信設備等に不正にアクセスする行為、クラッキング行為、アタック行為、および当社あるいは第三者の運用するコンピュータ、電気通信設備等に支障を与える方法あるいは態様において本サービスを利用する行為、およびそれらの行為を促進する情報掲載等の行為、あるいはそれに類似する行為
→ビミョーww

まとめ

 結果的にハニーポットを明示的に禁止しているところはなさそう?ただ、運用のミスがありサービスに影響を与えてしまった場合はアウトになりそうなところもあったように思える。(無難にラズパイとかで運用したほうがいいのかな〜)  知見のある方からコメントをいただいたところによると、インバウンド(自鯖にアクセスしてくる悪意のある通信)はセーフだけど、アウトバウンド(自鯖から出て行く悪意のある通信)はアウトみたいです。それと、ハニーポットが見破られて破壊されてももちろんアウト!!  ということなので、運用には十分気をつけましょう。

もしこういう場合はアウトといった情報や経験があればコメントをお願いします。m( )m

セキュリティ・キャンプ全国大会2016に参加した

8/9〜8/13に開催されたセキュリティ・キャンプ全国大会2016に参加してきました。このセキュリティ・キャンプはこれまでに13回開催され約600名もの卒業生を輩出しています。その卒業生の方々は様々な分野で活躍されておられ、私としましては憧れの存在です。そんな先輩方に追いつくべく、耳の穴かっぽじって講義を受けてきました!笑

f:id:n0x2ca:20160815234211j:plain

0日目

私は地方から参戦しましたので、初日の集合時間に間に合わないということで会場兼宿泊施設であるクロスウェーブ幕張に前泊しました。私以外にも数人前泊対象の参加者がおられましたので、一足先に名刺交換させていただきました!この日は明日の準備だけして早めに寝ました。

1日目

 いよいよセキュリティ・キャンプが始まりました!会場へ向かうとさっそく本格的なカメラを向けられ抱負を聞かれました。(テンパって噛みまくったww)既に名刺交換の応酬が始まっていたので 「出遅れた」と思いつつも開講式の時間までひたすら名刺交換していました。(同時に数十人が名刺交換していたので誰と交換したかわからなくなりましたw)
 開講式が終わるとセキュリティ基礎講座や特別講義が行われ、大変興味深いお話を聞くことができました!特に特別講義でのインターポールの福森さんのお話はインターポールという組織の重要性やこれまで自分の中になかった視点の話が聞けてとても面白かったです。講義の後に福森さんと名刺交換させていただき、CDIシャツをいただけることに!!(やったぜ!)
 夕食後は会場に戻りグループワークの説明を受けました。テーマは4つあってその中から私たちのグループは唯一「10年後のIT社会のセキュリティのあるべき姿」を選びました。ちなみにチーム名は『osx』(おーえすえっくす)です。(たまたまグループ全員がMacという奇跡w)読みが「おーえすてん」ではないのはあえて。

2日目

 この日から毎朝8:30に専門講義が始まりました。私が受けた講義は「1-C 公開鍵暗号のハードウェア実装と攻撃〜ICカードが持つ脆弱性とその対策〜」と「2-C 人工知能とセキュリティ」でした。専門講義の後はグループ対抗seccamp CTFが開催されました!!
 1-Cではまず公開鍵暗号の概説があり、そのあと実際に機器を使用してICカードに対してサイドチャネル攻撃をしかけ鍵を取り出すということをしました。これは実際のクレジットカードにも有効だということでなかなか中二心をくすぐられる講義でしたw
 2-CではRやPythonディープラーニングを使ってみるという実習と人工知能を活用していく上での問題点として学習の時点でコンタミがある場合の対策などについてグループでディスカッションしました。

3日目

 この日受けた講義は「3-D The OOM CTF」「4-D 実行ファイルの防御機構を突破せよ」「5-A サーバ運用におけるパスワード管理」盛りだくさんな専門講義の後は特別講義として伊藤忠テクノソリューションの方から普段の仕事のお話をしていただきました。
 3-DではLinuxのメモリ管理機構として備わっているOOM killerについてお話していただきました。序盤はふむふむと余裕ブッこいて聞いていたのですが、OOMの本題に入ったあたりからとても難解になりよくわかりませんでしたw(チューターの方にとっても難しかったらしい) さすがLinuxのメモリ管理の闇というだけあるなと感じました。ただ、Linuxカーネルの闇を理解したいという気持ちが湧いてきたのでよかったと思います。
 4-Dでは事前課題で解いたx86バイナリをさらにグレードアップさせた問題をひたすら解析しました。x86バイナリを読むのはだいぶ慣れてきたのですが、ASLRが有効の状態でシェルを奪取するというのは自分には少し難しかったです…。ただGOT領域のアドレスをリークさせるところまではできたので復習して解けるようにしたいと思います。
 5-Aでは業務でペネトレーションテストをされておられる講師の経験をお話しいただいた上で、パスワードの管理方法についてグループでディスカッションしました。以前からパスワードの管理は煩わしいと思っていて何か有効な解決策はないのかと気になっていたので、いろんな意見が聞くことができとても参考になりました。

4日目

 この日受けた講義は「6・7-E インフラセキュリティ・ブートキャンプ」でした。この後に特別講義でDeNAがスタートアップだった頃からインフラを担当されている方になぜセキュリティの仕事をしているのかというルーツをお話をしていただきました。
 6・7-Eでは主にAWSをterraformというツールを使いチームで構築するというものでした。私はAWSもterraformも今回初めて触ったので、AWSの環境と構築方法の理解とterraformとの関係性などについて調べるとこから始めました。その後手動でAWSと構築し、ある程度理解した後terraformを使ってVPCを構築してみるとその容易さわかりやすさに驚きました。これを機にクラウドでのインフラ構築もやっていきたい。

5日目

 最終日は午前中にグループワークの発表がありました。他のグループはとても面白い発表していてやべーってなってましたw
発表終了後は昼食食べて閉講式して集合写真撮ってという感じでした。集合写真のとき今年のセキュキャンのキーワードでもある「今日も1日がんばるぞい!」を何回言ったかわからないw そして最後になんと!!プレゼントタイム&サイン会!!!様々な技術本や雑誌、Tシャツ、グッズなどをいただきました!(圧倒的感謝!!!!!!)

f:id:n0x2ca:20160815234255j:plainf:id:n0x2ca:20160815234310j:plainf:id:n0x2ca:20160815234317j:plainf:id:n0x2ca:20160815234323j:plain

感想

 参加する前は4泊5日は長いな〜と思っていましたが、終わってみるとまだまだやりたいという思いでいっぱいでした。CTFは時間が短かったのでここからというところで終わってしまいちょっと残念でした。
 私はあまりアニメを見ないのでついていけてないところもあり、会話に入れないことがあったので今後はアニメトラックもがんばりますww そして来年はチューターとして参加したいと思います!!

さいごに

 今回セキュキャンに参加させていただくことで各技術分野のトップの方たちとお話ができたり、SNSで繋がれたり、ともに頑張る仲間できたりと技術や知識以上に得られるものが大きかったです。技術力をあげたいという人や仲間がほしいという人は絶対に参加すべきだと思います。ただセキュキャンに参加することがすべてではないですし、参加して満足するようでは意味がないのでそこをお忘れなきを。

Bluelog README 和訳

気が向いたのでBluelogという近くにあるBluetoothバイスを検知するツールのREADMEを和訳してみた。英語の勉強という面もあるので、訳が間違ってたり表現がよくないところは優しく指摘していただければとても喜びます。

原文 GitHub - MS3FGX/Bluelog: A highly configurable Linux Bluetooth scanner with optional web interface.

Bluelog

Bluelogはwebサイトでの調査やトラフィック監視用に設計され、システムのデーモンかwebフロントエンドを選択して実行させることができるLinuxBluetoothスキャナーである。それは長期間、特定の静的な場所でその範囲にあるできるだけたくさんのBluetoothバイスを発見できることも目標としている。

Bluelogは放置されるように設計されているので、ユーザーインターフェースを持っていないし、一度スタートさせると何の操作も必要はない。その特色としては完全にログファイルのフォーマットが設定可能であり、同様にsyslogへネットワークを超えた中央集積型のログの機能がある。

Bluelogは貧弱で小型であるx86MIPS、ARMプロセッサで動作するよう設計された。BluelogはKali linux(www.kali.org)やPwnie Express(www.pwnieexpress.com)が提供しているPwn Pad やPwn Plugペネトレーションテストバイスに含まれている。また公式のOpenWRTレポジトリーやArch Linux AUR コミュニティーレポジトリからも入手可能である。

Bluelog Live

Bluelog Liveは定期的に発見されたデバイスの更新を提供し、それらの該当する情報は任意のwebブラウザから見ることができる。Liveモードは主に公開情報や、悪名高い”Wall of Sheep”からインスピレーションを受け設計された。(www.wallofsheep.com)

高度なLiveモードはメインのBluelogツールから分割されたソフトウェアであある。それはシンプルな静的なHTMLページやCGIモジュールから構成されBluelogからのログファイルを読み込む。

Bluelogはwebサーバではなく、ただ単にあなたが選択したHTTPデーモン(Apachelighttpd、etc)が提供するHTMLファイルを生成する。したがって、Bluelog Liveをスタートさせてみる前にwebサーバはすでに適切に設定されているか確認がいる。Bluelogは実は起動中Liveページの状態に全く気づかない。それはまさに吐き出すデータがベストな状態であることを望んでいる。

Basic Option

-i
このオプションはBluelogにあなたがスキャンしたいBluetoothバイスを伝える。あなたはHCIデバイス名(hci2のような)かローカルアダプタのMACアドレスを使うことができる。ボーナスとして、もしあなたが存在しないデバイスを与えるなら、Bluelogは稼働しているデバイスを自動検知し戻ってくるだろう。
-o
これはログを書き込むファイルを任意のファイル名にできる。デフォルトのフォーマットは”bluelog-YYYY-MM-DD-HHMM.log”で、カレントディレクトリに作られる。 -v
このオプションを付加すると見つかったデバイスをコンソールに表示する。出力にはくどくどとデバイスクラスの情報やタイムスタンプの記録が含まれている。デフォルトではこのオプションはOFFになっている。
-q
これは重要ではない出力をOFFにする。これが意味するのは、通常ではスキャンの実行開始時間と適切なシャットダウンがされたかのメッセージしか見ることができない。
-d
このオプションはBluelogをバックグラウンドで動作するデーモンとして起動する。まだ定型文やスタートアップメッセージを見ることになるだろう、しかしその後はターミナル内でBluelogから情報は少しも見かけないだろう。
-k
Bluelogプロセスがデーモンモードで実行されているときに、-kオプションはそのプロセスを停止することができる。

Logging Option

-n
このオプションを使うと発見されたデバイスのデバイス名が表示される。デバイス名を見つけることに時間がかかりすぎ時折失敗することがある。したがってデバイス名を解決しないことにより、Bluelogは高速にそして正確にスキャンできる。デフォルトではOFFになっている。
-m
このオプションを利用可能ならMAC OUIを通して稼働しているハードウェアメーカーを特定する。ハードウェアメーカーはBluelog Liveと同様に標準のログファイルに記録されているだろう。この機能を利用するにはいくつかのプラットフォーム(OpenWRTのような)メーカーの法外に大きなデータベースをインストールする必要がある。
-c
このオプションを指定すると生のデバイスクラスをログファイルに書き込むようになる。このオプションをOFFにするには -f を使う。デフォルトではOFFになっている。
-f
このオプションはデバイスクラスを翻訳し多くの人が読みやすい形式にする。それはデバイスのクラスとコア容量を教えてくれるだろう。例えば、クラス”0x7a020c”は”Smart Phone, (Net Capture Obex Audio Phone)”として見える。このオプションをOFFにするには -c を使う。デフォルトではOFFになっている。
-t
このオプションを使うとスキャン開始時間と終了時間、また新しいデバイスが発見された時間がログファイルに記録されるようになる。デフォルトでは OFFになっている。
-x
このオプションを使うとMACアドレスをうやむやにすることができる。このオプションをONにすると、Bluelogは発見されたそれぞれのメーカー部分のMACアドレスを表示するが、デバイスを固有の情報はブロックする。デフォルトではOFFになっている。
-e
このオプションを使うとMACアドレスをCRC32形式へエンコーディングする。このオプションをONにすると、発見されたこれまでディスクに記録されていないMACアドレスはこの形式で記録される。 -a
このオプションは”amnesia mode”を可能にすると与えられた時間が経つとBluelogは一度発見した特定のデバイスを忘れてしまう。このオプションによってBluelogはデバイスと出会ったとき、初めて出会ったものとして再びログに記録し、発見された時間も更新されるだろう。

Output Options

-l
このオプションはBluelogを中継してLiveモードも変更する。コンソールやログファイルよりも自動的に更新されるwebページの結果を表示する。
-b
このオプションは結果のデータがronin’s Bluetoothプロファイリングプロジェクト(BlueProPro)へのアップロードにふさわしいログの形式に設定する。これは他の多くのログオプションを上書きし、Bluelog LiveはOFFになる。このプロジェクトのさらなる情報と、さらなるヒントはあなたのデータを提出してもらう必要がある。www.hackfromacave.com
-s
このオプションを使うとsyslogのみに出力するモードになる。このモードではBluelogは通常のログファイルには記録しない代わりにシステムログファイル(/var/log/syslog)だけに記録される。このモードはネットワークで接続されたsyslogデーモンに気づかない時に特に便利であり、複数のBluelogにより記録されたログを一箇所に集約する際にも使うことができる。

Acknowledgemets

Bluelogの開発当初はAlbert Huangによって執筆された”Bluetooth Essentials for Programmers”という本に含まれているサンプルコードをもとに製作されていました。この本はとても有益な本であり、もしあなたがBlueZプログラミングの入門書を探しているのならとても役立つだろう。それはBlueZプロジェクトのひどいドキュメントを ほとんど補完してくれるだろう。

この本に関するwebサイト:http://www.btessentials.com/

Bluelogのデバイスクラスを解析するコードはMichael John Wensleyによって執筆されGPLv2によって保障されている”Inquisition”を実装している。

“Inquisition"に関するさらなる情報を読みたいのなら彼のサイトへ:http://www.wensley.org.uk/

BluelogはSven Reifegersteによってかかれた”CRC Tester”のCRCハッシュ関数の修正バージョンを実装している。

CRCエンコーディングに関するSvenのページ:http://www.zorc.breitbandkatze.de/crc.html

.roninによる”SpoofTooph”はリテラルコードではないデバイスキャッシュの書き換えという素晴らしい発想をくれた。”SpoofTooph”と.roninの他のプロジェクトは彼のサイトからチェックすることができる:http://www.hackfromacave.com/

BluelogのUDP関数はlan Macdonaldが提出したコードをもとにされている。(ianmac51@googlemail.com)

BluelogもまたMartin Schlzeによってかかれたpidfile.cに含まれる関数にインスパイアされたコードをいくつか使用している。

Bluelog Liveのロゴに使用されているフォントはJakob Fischerによる”Electric Boots”である。彼のフォントコレクションはここでみることができる:http://www.pizzadude.dk/

BluelogのOpenWRTバージョンはGary Bonnerの仕事ぶりやJoshua HurstとDean Nielsonの陰の支えがなければ可能ではなかっただろう。Stephen Walkerもありがとう。彼女はBluelogのためにプラットフォームの貴重な情報である公式のOpenWRTパッケージを保守し続けてくれた

BluelogのためにArch Linuxの組み込みスクリプトを保守してくれてありがとう、Jonas ”onny” Heinrich。彼のプロジェクト:http://www.project-insanity.org/

BluelogようにカスマイズされたPwn Plug上での支援や助力には大変感謝します、Dave Porcello、Jonathan Cran、Punie Express team。

イタリアのボルザノでネットワークトラフィックモニタリングの構造を開発している間にBluelogへパッチを当ててくれた、Paolo ValleriやIntegreenプロジェクトありがとう。プロジェクトサイト:http://www.integreen-life.bz.it/

DEFCON Privacy VillageのテーマにBluelog Liveを組み入れてくれたTeresa Brooksありがとう。

Bluelogについてのコメントや提案をしてくださり正しい方向へと私を進めてくださったすべてのユーザに感謝します。

最後に、調整の目的で私にBluetoothバイスを寄付してくださった方々に感謝いたします。スキャンするデバイスがなしでBluetoothスキャナーをかくことはかなり難しい、そのためハードウェアは私にとって大変貴重である。

License

このプログラムはフリーソフトウェア;あなたはフリーソフトウェア団体によって公開されているGNU GPLv2のライセンスによりこれを再配布または修正して再配布ができる。
このプログラムは便利になるよう望まれて配布されている。しかしなにも保証はない。;暗にほのめかされる市場的な保証や特定の適性な目的のようなものもない。
詳細はソースディレクトリに含まれている”COPYING”ファイルを見て。

C言語の参照外しとダブルポインタ

ふと、「参照外し」の語源というか由来というかそんなものは何かあるのかな〜と思いググってたところ別のある問題に出くわした。 これってみんなパッと答えられるのかなと思い書いてみた。 そのソースコードが以下である。

gistd9a5cbadb0c86a3adb99cb94b95302a5

問題はこれの出力を答えろというもの。

char型の配列とポインタ変数が宣言してある。 そして、ポインタ変数に配列のアドレスが代入され、出力してある。 という簡単なC言語のプログラムである。 慣れてる人ならこんな問題は瞬殺なんだろうけど、自分は少し考えてしまった... ということで、整理も兼ねて解答を書いていく。

解答

まず1つ目の出力から。
char mark_1[][5] = {"zyx", "wv", "utsr", "qpo", "nmlk"};
まずこれは普通にchar型の二次元配列を宣言して初期化しているだけ。
printf("%s¥n", mark_1[1] + 1);
出力ではフォーマットパラメータに%sが指定されている。(文字列を出力) その出力の値としてmark_1[1] + 1が指定されている。
これはまずmark_1[1]で配列の要素"wv"のアドレスを指定し、そのあと"wv"要素の中の先頭から+1個進んだ先の文字列"v"が出力される。

2つ目の出力
printf("%s¥n", pt_1 + 1);
これも1つ目と同様の考え方で理解できる。ただ、今度はmark_1を直接使っているのではなくpt_1にmark_1のアドレスを代入してそれを利用している。この場合pt_1ではすでに*mark_1が代入されているので、配列mark_1の先頭要素であることが確定している。(1つ目と表記をあわせるならpt_1=*mark_1=mark_1[0])そして要素内で+1してあるので、結果出力は"yx"になる。

3つ目
ここはもう1つの配列
char *mark_2[5] = {"cba", "ed", "ihgf", "lkj", "ponm"};
を使っている。そして
pt_2 = mark_2;
で配列mark_2の先頭アドレスをpt_2に代入。
printf("%s¥n", *pt_2 + 2);
ここでは*pt_2で先頭の要素"cba"を指しており、+2で先頭から2つ進んだ先の"a"を出力している。

4つ目
printf("%c¥n", **pt_2 + 2);
ここがちょっと特殊である。といっても難しくはない。フォーマットパラメータは%cとなっている。(1文字を出力)そしてその値として**pt_2+2となっている。この考え方としては、参照外しの演算子「*」と四則演算子では参照外しの演算子が優先されるということと、値として特定の文字が確定したあとに四則演算を用いるとASCIIコードの計算とされることだ。具体的に言うと、まず**pt_2で配列mark_2の先頭要素の先頭文字"c"が確定する。この時点で+2はポインタ演算ではなくなりASCIIコードでの+2となる。そのため"c"の2つ先のアルファベット"e"が出力されることになる。間違っても配列の要素の"ed"の"e"が出力されたわけではない!

5つ目
printf("%s¥n", *(pt_2 + 2) + 2);
pt_2+2してから参照外しをしているので配列要素の"ihgf"を指しており、その後さらに+2しているので"gf"が出力される。

これで終わり。

まとめ

参照外しや[]の優先度はあまり気にしたことがなかったので以下のサイトで確認してみた。

C Operator Precedence - cppreference.com

すると、やはり優先度はa[ ] > *a となっている。そして四則演算子よりも参照外しの方が優先度が高いことがわかる。
言われてみれば当たり前な話だけど、演算子の優先度に気をつけよう。そしてなにより基本は大事!

バイナリ解析環境構築メモ

Virtual Boxを使用し、仮想環境でUbuntuを起動できる状態を前提とします。

構築環境

  • Ubuntu 16.04 LTS
  • Virtual Box VM version 5.0.22

入れていくもの

  • Linuxコマンド
    • file
    • readelf
    • strings
    • grep
    • unzip/tar/gzip/xz
  • トレーサ
    • strace
    • ltrace
  • デバッガ
  • アセンブラ
    • objdump
  • その他
    • radare2
    • rp++
    • checksec.sh
    • peda
    • socat
    • pwntools

構築開始

Linuxコマンド

各種コマンドがあるか確認(Ubuntu16.04の場合上記コマンドは全て入っていた)

トレーサ

各種コマンドがあるか確認(Ubuntu16.04の場合上記コマンドは2つとも入っていた)

デバッガ

$sudo apt-get install buld-essential gcc-multilib git gdb

アセンブラ

$sudo apt-get install binutils

その他

radare2

$sudo apt-get install radare2

rp++

$mkdir $HOME/bin
$wget https://github.com/downloads/0vercl0k/rp/rp-lin-x64 -O $HOME/bin/rp

checksec.sh

$cd ~/Download/
$wget https://github.com/slimm609/checksec.sh/archive/1.6.tar.gz
$tar zxvf 1.6.tar.gz
$cp checksec.sh-1.6/checksec $HOME/bin/checksec.sh

peda

$sudo apt-get install build-essential gcc-multilib
$git clone https://github.com/zachriggle/peda.git ~/Download/peda
$echo "source ~/Download/peda/peda.py" >> ~/.gdbinit
$export PATH=$PATH/bin:$PATH

socat

$sudo apt-get install socat

pwntools

$sudo apt-get install python-pip python2.7-dev openssl libssl-dev libbz2-dev libreadline-dev libsqlite3-dev
$sudo pip install --upgrade pip
$sudo pip install pwntools
もしここで
Failed building wheel for cryptography
Failed building wheel for cffi
のようなエラーが出る場合
$sudo apt-get install libffi-dev
$sudo pip install cryptography

まとめ

まだ必要なツールはあると思うが、とりあえずここまで。いろいろ試しながらだったためミスがあると思う。(メモしとけばよかった...)

セキュリティ・キャンプ全国大会2016応募用紙晒す 後半

はじめに

さっそく前半

nonkuru.hateblo.jp

の続きを書いていきたいと思います。

私は選択問題では1、3、5、6を選択しました。

選択問題

選択問題1

以下は変数hogeとfugaのメモリアドレスを表示するプログラムと、その実行結果です。実行結果のhogeとfugaのメモリアドレスを見て、思うことを説明してください。

gistbf1ef730ba714e8fe8f736397cd64410

以下ソースコードと実行結果を見て思ったことを箇条書きで示します。
・メモリアドレスのビット数から推測すると12桁×4bit=48ビットシステムである
・またアドレス空間は248=127TB
・このアドレス空間の大きさを格納できれば良いので、ポインタ型の大きさは48bit/8bit=6byte
・この関数のマシン命令はテキストセグメントに確保される
・main関数内のint型(4byte)の配列hogeはスタックセグメント内に確保される
hoge[10]は0x7fff539799f0から40byte分確保される
mallocは動的確保なのでヒープセグメント内に確保され、fugaはヒープセグメントに存在する
・この
fugaのアドレスは0x7fca11404c70であり、サイズは6バイトである
・そのアドレスをスタックセグメント内に確保されたポインタ変数fugaに入れる
・データセグメントを伸ばしたり縮めたりすることで、メモリを割り当てたり、解放したりする
mallocはbrkシステムコールを使う
・brkはデータセグメントの大きさをアドレスで指定する→新しいアドレスが古いアドレスよりも大きければデータセグメントは伸び、小さければ縮む
・スタックがスタックセグメントの底を越えて伸びてきたら、通常はハードウェアフォールトが生じ、OSがスタックセグメントを1ページ分だけのばす
・プログラムが実行をはじめるとき、スタックは空ではない→このプログラムが呼ばれた時にシェルに与えられていたコマンド行と、環境変数が入っている
・main関数の引数で4byte+6byte=10byteの変数を確保しているから引数と環境変数が確保される領域(スタック領域より高いアドレスに10byte分確保される)
・0x7fff539799f0から44byte先の0x7fff539799f0+0x2c=0x7fff53979a1c
・以上のことを考慮すると、(スワップ領域)+(スタック領域)=(0x7fff53979a1c)-(0x7fff539799f0)=0x3542574dac=約213GB

選択問題3

RAMは主記憶装置、HDDやSSDなどは補助記憶装置と呼ばれます。一般にCPUは主記憶装置上のプログラムしか実行できません。ではなぜ、私たちは普段から補助記憶装置に書き込んだプログラムを実行できているのでしょうか?パソコンの電源を入れてからのストーリーを考えてみてください。

以下に電源ボタン押下時からのストーリーを箇条書きで示します。
1.電源ボタン押下
2.電圧と電流が一定レベルに到達しているか確認するセルフテストを実行
3.この結果が満足されれば電源はタイマーチップ・マイクロプロセッサに対し”Power Good”というシグナルを送る
 ・電源のセルフテストにかかわらず電力はコンピュータ内に行き渡る。そこでCPUは起動処理を開始しようとするが電源のセルフテストが終了していない間はCPUを制御するためのタイマーチップはCPUにリセットシグナルを送り続ける
4.タイマーチップが”Power Good”シグナルを受け取るとCPUに対するリセットシグナルをを停止しCPUの制御を解放し起動処理に移る
5.マザーボード上のROMに記憶されたBIOSが起動
6.POST(Power On Self Test)の実行
 ・ビデオテスト・BIOS同定・メモリテストから構成されている
 ・“Cold-Start”か”Warm-Start”かをチェック:これを判別するためにBIOSスタートアップルーチンはメモリの0x00000472にある2byteの値をチェックする。この値が0x1234であれば”Warm-Start"それ以外なら”Cold-Start"
 ・"Cold-Start"(電源OFFの状態からの起動)ならPOSTの全てのテストを実行、"Warm-Start”(起動していたOSを再起動)ならメモリテストは省略
 ・ビデオテスト:ビデオアダプタを初期化し、ビデオカードとビデオメモリをテスト
 ・BIOS同定:BIOSのバーション・製作者・日付を表示
 ・メモリテスト:メモリチップをテストし搭載されているメモリの合計を表示
 ・POST中のエラーは”Fatal"(致命的)か”non-Fatal"(非致命的)に分類
 ・“non-Fatal”:スクリーン上にエラーメッセージが表示されシステムのブートプロセスは継続、“Fatal”:ブートプロセスを停止。”Beep Code”に基づくビープ音でエラー   の発生を報告
7.これが終わるとCMOS設定情報の読み込む
 ・CMOSの設定情報にはマシンにインストールされているディスクの種類・起動時にパスワードが必要か否か・PCの起動にはどのデバイスが必要か等がある
 ・BIOSスタートアップルーチンのために重要な事はCMOSがOSのために検証されるべきドライブの順番を指示することでBIOSが割り込みベクタとその処理を用意している
8.割り込みベクタからデバイスの読み込み処理を呼び出して最初のセクタ(MBR:Master Boot Recode)がメモリに読み込まれ実行される。
 ・このセクタには、512byteのプログラムが入っている。
 ・このプログラムは通常IDESCSIディスクであるブートデバイスからブートローダ(IPL:Initial Program Loder)をロードする。
 ・ブートローダには入っている最後のデータが0x55AAならば、メモリの低いアドレス部分をカーネル用に空けるために、まず自分自身をメモリの高いアドレス(0x7c00)にコピーする
9.コピーが完了すると、ブートローダはブートデバイスのルートディレクトリを読み出す
10.次にカーネルを読み出し、そこへジャンプする
11.カーネルカーネルスタックの設定、CPUの型を認識、搭載されているRAMのサイズを計算、割り込みを禁止し、MMU(Memory Management Unit)を使用可能にし、最後にカーネルの主要部を実行する
 ・これ以降メッセージバッファの割り当て、カーネルデータ構造の割り当て、デバイスの探査、デバイスドライバの配置など各種初期化を行う
12.それが終わるとOSの指示により補助記憶装置からプログラムが主記憶装置にロードされる
13.ユーザがシェル上で実行ファイルを実行させると、shellプロセスの子プロセスがfork-exec命令により生成されshellプロセスとは独立したメモリ空間に配置される
14.メモリに格納されたプログラムの指示に従いCPUが動作する
 ・CPUが主記憶装置から命令を取り出す
 ・命令を取り出すアドレスは、CPUのプログラムレジスタに書かれている
 ・取り出した命令は、CPU内の命令デコーダーにより、命令の内容を解析される
 ・解析された命令は、論理演算装置(ALU:arithmetic logic unit)により、演算が実行される
 ・演算結果は、各種のレジスタに格納される
 ・プログラムレジスタの値を再設定する
 ・以上の動作をプログラム終了まで繰り返される

選択問題5

PCなどに搭載されているOSは「汎用OS」と呼ばれますが、それに対して、家電屋AV機器などの「組込みシステム」に搭載されているOSは「組込みOS」と呼ばれます。組込みOSと汎用 OSの違い、「OSが無い」や「ベアメタル」という環境、そもそもOSとは何なのか?など、あなた自身はどう考えているのかを、あなたの自身の言葉で自由に説明してください。(「正しい答え」を聞いているわけではありません。あなた自身の考えを教えてください)

 OSの本質はカーネルにあると思います。なぜなら、最低限カーネルさえあればハードウェアを計算機として動作させることができるからです。逆にカーネルがなければハードウェアはただのシリコンやプラスチック、金属の塊に過ぎません。しかしカーネルが全てを支配しているとは言えないと思います。これは私がOSを作っていて感じた事ですが、OS開発の初期の段階はCPUやフラッシュメモリなどの仕様に従いレジスタに設定していかなければなりません。それは、仕様の異なる自分勝手なハードウェアに付き合わせられなければいけないということであると思います。この仕様が面倒だから変えようなんてことはできません。さらに、世間には様々なOSが存在しますがボード上に特定のハードウェアがあるかないかによってもその設定は変わってきます。例えば組み込みOSが入れられるようなボードには大抵メモリ管理を任されるMMUがありません。このようにOSはCPUやその他ハードウェアに従うしかありません。OSとハードウェアが持ちつ持たれつの関係を保っていてこそ動作が実現できていると思います。  では、なぜそのような大切なカーネルひいてはOSが初めからROMに記憶されていないのかですが、それは誰にも将来を見通せないからだと考えます。もし将来がわかる人がいればおそらく完全なOSが作れると思います。必要になる機能を全て実装しておけば良いからです。しかし現実にそんなことはできません。だから後から改変できるようにROMではなく補助記憶装置に書き込んでおくのだと思います。それがソフトウェアの最大のメリットであり、ソフトウェアがソフト(柔軟)たる所以だと考えます。また"プログラムは手段に過ぎない”という言葉をネットで見かけたり、人から聞いたりすることがたまにあります。なんとなくそういうものかなと私も思っていました。しかし自分でOSを作り始めて、初めてその言葉が腑に落ちたと感じました。OS作成では、OSのコードを書いてそれをコンパイルして中間ファイルをたくさん生成して結合して最終的にバイナリファイルが完成します。それによってようやくコンピュータというハードウェアが動きだします。このようにハードウェアを動かすことで人の代わりに計算させることが本来の目的であり、プログラムを書くことが目的ではありません。改めて言葉にしてみると当たり前と感じますが、OS制作を通じてハードウェア制御を学ぶことでなんとなくわかっていたことが身にしみて感じた自分にとってとても大切な瞬間でした。

選択問題6

IDとパスワードを入力したユーザの認証を行うWebアプリがあります。あなたがこのアプリに対してセキュリティテストを行う場合、まず、どのようなテストをしますか?なぜそのテストを選択したのか、その背景や技術的根拠と共に記載してください。アプリの内部で使われている技術やシステム構成に、前提を置いても構いません。

まず私は、このWebアプリケーションは自分で作成し自分でセキュリティテストを行う前提とします。自分で行うので高額なベンダーには発注せず、もちろん高額な脆弱性診断ツールは使えないのでツールは全てフリーのものを使用するものとします。また、最近は診断法の参考として一般に公開されているIPAの「ウェブ健康診断仕様」(https://www.ipa.go.jp/files/000017319.pdf)のような脆弱性診断仕様を使用し検証します。ただし、このような脆弱性診断はあくまで簡易検査であり、自前の診断のみで脆弱性を全て排除できないと思っておくことが最大の対策であると考えます。その上で、まず初めにセキュリテイテストを行うとすれば認証システムに対してはウェブ健康診断仕様の16ページから17ページに書かれている6項目についてテストをしていきます。この6項目をテストしていくことでWebアプリケーションにおいて考えうる代表的な脆弱性については対策が可能であると考える。まず、1つ目の「パスワードの最大文字数が8文字以上確保されているか」と2つ目の「パスワードの文字種が数字のみ、英字のみに限定されていないか」、6つ目の「意図的に10回パスワードを間違える」は文字数と文字種と試行回数について言及されており、総当たり攻撃や辞書攻撃に対する対策だと考えられます。3つ目の「パスワードが入力時に伏字になっているか」4つ目の「パスワード間違いの際のメッセージは適切か」は表示に言及しており、ID・パスワード方式の認証はパスワードの文字列を正規の利用者本人しか知らないという前提で作られいるので、誤ってその情報を画面上に表示してしまい近くの人が覗き見ていた場合その前提が崩れてしまいかねません。このようなショルダーハックの類の対策だと考えられます。5つ目の「ログアウト機能はあるか、適切に実装されているか」は、認証後のセッションIDの管理に不備があると考えられます。例えばセッションIDの固定化やセッションIDをクッキーに設定していた場合にセキュア属性が設定されていないなどです。これら以外に考えられることとしては、このような認証方式には大抵データベースが使用されているので、SQLインジェクション対策やもし情報が流出してしまった場合の対策としてパスワードに暗号化が施してあるか等が考えられます。

まとめ

あらためて自分で見てよくこんなクオリティで提出できたなと思います。選択問題のメモリについては勉強中だったので正直よくわかりませんでしたが、他の方の応募用紙を見て、そうだったのか!!!という発見があってとても勉強になりました。他の問題についてもいろんな人の応募用紙を見ると違った視点がありとてもおもしろいです。
レベルの高いこのキャンプに行けること願うばかりです。以上私のセキュキャン全国の応募用紙でした。(受かってればいいな〜〜〜〜)

追記

なんとセキュリティ・キャンプ全国大会2016に通過しました!!!!!!もうこんな内容で合格すると思ってなかったのでめっちゃうれしいです!セキュキャンに向けて、そして終わってからもがしがしがんばるぞ!参加者各位よろしくお願いします!!!