読者です 読者をやめる 読者になる 読者になる

$0書き換えが流行っているようなので一つ流行に乗っかってみるか

以下の記事では $0 での偽装を見破るため ps コマンドに c オプションを指定して /proc/<pid>/commを表示させればよいというようなことが書いてあると思いますが、/proc/<pid>/commも容易に書き換え可能みたいですのであまりあてにしないほうが良いでしょう。(偽装されていないかどうか知りたい場合)


細かすぎて伝わらないPerlと$0変数 - コマンド名偽装 - ろば電子が詰まっている


/procファイルシステムについて解説した以下のドキュメントを読むと、
https://www.kernel.org/doc/Documentation/filesystems/proc.txt

3.6	/proc/<pid>/comm  & /proc/<pid>/task/<tid>/comm
--------------------------------------------------------
These files provide a method to access a tasks comm value. It also allows for
a task to set its own or one of its thread siblings comm value. The comm value
is limited in size compared to the cmdline value, so writing anything longer
then the kernel's TASK_COMM_LEN (currently 16 chars) will result in a truncated
comm value.

だそうです。 It also allows for a task to set its own or one of its thread siblings comm value. つまり、/proc/<pid>/commは書き込み可能だということ。

実際、

$ echo $$
8837
$ ls -l /proc/$$/comm
-rw-r--r-- 1 xxxx xxxx 0  Jan 16 14:58 /proc/8837/comm  # <- ownerは書き込み可能
$ cat /proc/$$/comm
bash
$ ps c
  PID TTY      STAT   TIME COMMAND
 8837 pts/1    Ss     0:00 bash
 8906 pts/1    R+     0:00 ps
$ ps x | \grep $$
 8837 pts/1    Ss     0:00 bash
 8912 pts/1    S+     0:00 grep 8837
$ echo -n 'hoge' > /proc/$$/comm        # <- 書き換えてみる
$ cat /proc/$$/comm
hoge                                    # <- はい書き換わったー
$ ps c
  PID TTY      STAT   TIME COMMAND
 8837 pts/1    Ss     0:00 hoge         # <- 偽装されている (/proc/<pid>/commに設定した値が表示されている)
 8926 pts/1    R+     0:00 ps
$ ps x | \grep $$
 8837 pts/1    Ss     0:00 bash         # <- こちらは $0 で偽装可能なほう
 8932 pts/1    S+     0:00 grep 8837

ということで、/proc/<pid>/comm/proc/<pid>/cmdline も偽装されるので良い子のみんなは使っちゃダメだよ、ということになる。



上記ブログでは pstree を使えば /proc/<pid>/statを見るので安全って書いてたけど

$ cat /proc/$$/stat
8059 (hoge) S 5118 8059 8059 34847 8549 4218880 4300 26818 0 5 6 4 27 40 20 0 1 0 27809766 29687808 1731 18446744073709551615 4194304 5184116 140734649026160 140734649024840 139834224170140 0 65536 3670020 1266777851 18446744071579312278 0 0 17 0 0 0 0 0 0 7282160 7319112 34164736 140734649034557 140734649034562 140734649034562 140734649036782 0
$ pstree | \grep hoge
     |         |         |         |                |-hoge-+-grep

どう見ても書き換えられてます。

じゃあ解決策はないのかというと、ぱっと思いついたところだと

$ file /proc/$$/exe
/proc/8059/exe: symbolic link to `/bin/bash'

という感じで/proc/<pid>/exeを見るしかないかなぁ。
これもなにか回避策がありそうだけど。


ちなみにこちらの環境は

$ uname -s -r -v -m -p -i -o
Linux 3.16.0-28-generic #38-Ubuntu SMP Fri Dec 12 17:37:40 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.10
DISTRIB_CODENAME=utopic
DISTRIB_DESCRIPTION="Ubuntu 14.10"

こんな感じです。

現場からは以上です。