$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"
こんな感じです。
現場からは以上です。