SELinuxユーザ会2007年夏の勉強会 ~小ネタ~ BusyBoxのWrapperについて 日本SELinuxユーザ会 (セキュアOSユーザ会) 宍道 洋 BusyBoxとは? 沢山の 沢山のコマンド( コマンド(アプレット) アプレット)を一 つのバイナリ つのバイナリにまとめ バイナリにまとめ、 にまとめ、コンパク トにしたもの スイス・ スイス・アーミー・ アーミー・ナイフのよう ナイフのよう なツール 通常リンク 通常リンクを リンクを張って使用 って使用する 使用する ~ # busybox BusyBox v1.2.2 (2006.10.31(2006.10.31-00:55+0000) multimulti-call binary Usage: busybox [function] [arguments]... or: [function] [arguments]... BusyBox is a multimulti-call binary that combines many common Unix utilities into a single executable. Most people will create create a link to busybox for each function they wish to use and BusyBox will act like whatever it was invoked as! 共通コード 共通コードをまとめて コードをまとめて、 をまとめて、フットプ リントを リントを小さくできる Currently defined functions: [, [[, addgroup, addgroup, adduser, adduser, ash, basename, basename, busybox, busybox, cat, chgrp, chgrp, chmod, chmod, chown, chown, chroot, chroot, clear, cmp, cmp, cp, cut, date, dc, dd, dd, delgroup, delgroup, deluser, deluser, df, df, dirname, dirname, dmesg, dmesg, du, dumpleases, dumpleases, e2fsck, echo, egrep, egrep, env, env, expr, expr, false, fdisk, fdisk, fgrep, fgrep, find, free, fsck, fsck, fsck.ext2, fsck.ext3, getopt, getopt, getty, getty, grep, grep, gunzip, gunzip, gzip, gzip, halt, head, hexdump, hexdump, hostid, hostid, hostname, httpd, httpd, hwclock, hwclock, id, ifconfig, ifconfig, ifdown, ifdown, ifup, ifup, inetd, inetd, init, insmod, insmod, kill, killall, killall, klogd, klogd, less, ln, ln, logger, login, logname, logname, ls, ls, lsmod, lsmod, md5sum, mkdir, mkdir, mke2fs, mkfs.ext2, mkfs.ext3, mknod, mknod, mkswap, mkswap, modprobe, modprobe, more, mount, mv, mv, netstat, netstat, nslookup, nslookup, passwd, passwd, pidof, pidof, ping, pivot_root, pivot_root, poweroff, poweroff, ps, ps, pwd, pwd, rdate, rdate, reboot, reset, rm, rm, rmdir, rmdir, rmmod, rmmod, route, runrun-parts, sed, sed, sh, sh, sha1sum, sleep, sort, strings, stty, stty, su, su, swapoff, swapoff, swapon, swapon, sync, syslogd, syslogd, tail, tee, telnet, telnetd, telnetd, test, time, top, touch, true, tty, tty, udhcpc, udhcpc, udhcpd, udhcpd, umount, umount, uname, uname, uniq, uniq, uptime, usleep, usleep, vi, wc, wc, wget, wget, which, whoami, whoami, xargs, xargs, yes, zcat → 組込み 組込み向け ~# Ex.) ln –s /bin/busybox /bin/ps ln –s /bin/busybox /bin/vi もしくは引数 もしくは引数で 引数で直接指定 Ex.) /bin/busybox ls -l /bin/busybox date 2007年7月4日 SELinuxユーザ会2007年夏の勉強会 2 BusyBoxとセキュアOS BusyBoxをリンクで呼び出すと、リンク元の実体 に定義されたアクセス制御しか働かない。 SELinux、LIDS → 実体のinode内の情報を利用 AppArmor → リンク解決後のパス名を利用 リンクではなく実ファイルからの呼び出し(Wrapperの利用) ls ls inode busybox cp cp inode inode ping ping inode 2007年7月4日 SELinuxユーザ会2007年夏の勉強会 3 バイナリラッパ /bin/busyboxを呼び出すバイナリを作成する Cで書くとこんな感じ void main(int argc, char* argv[], char* envp[]) { argv[0] = ”cat”; execve(”/bin/busybox”, argv, envp); } これをアセンブラで記述(サイズは1k未満) /bin # ls -l -rwxr-xr-x -rwxr-xr-x -rwxr-xr-x -rwxr-xr-x -rwxr-xr-x ... 1 1 1 1 1 root root root root root root root root root root 696 692 688 688 692 Aug Aug Aug Aug Aug 17 17 17 17 17 12:01 12:01 12:01 12:01 12:01 addgroup adduser ash cat chgrp → アーキテクチャ毎にコードを作成・メンテナンスする必要 参考:「BusyBoxを使った組み込み機器でLIDSを動かすには」(佐藤 祐介氏) http://www.selinux.gr.jp/LIDS-JP/document/general/web_lids_busybox/main.html 2007年7月4日 SELinuxユーザ会2007年夏の勉強会 4 じゃ、シェルスクリプトでやってみる? 例えば“cat” #!/bin/sh /bin/busybox cat $* じゃあ、“sh”は? #!/bin/sh /bin/busybox sh $* これもbusyboxだったりする・・・ 例えば“cp”が #!/bin/sh /bin/busybox rm $* と置き換えられたら・・・ 2007年7月4日 SELinuxユーザ会2007年夏の勉強会 5 execve()を見てみた execve(2)のmanpage 書式 #include <unistd.h> int execve(const char *filename, char *const argv[], char *const envp[]); 説明 execve() は、filename によって指定されたプログラムを実行する。Filename は、バイナリ実行形式か、“ “#! interpreter interpreter [arg [arg] arg]”という形式 という形式の 形式の行で始まる スクリプトでなければならない スクリプトでなければならない。 でなければならない。後者の場合、interpreter は適切な実行ファ イルのパス名でなければならず、それ自身がスクリプトであってはならない。 そしてそれは interpreter [arg [arg] arg] filename の形で呼び出される。 される。 では、“#!/bin/busybox”と書いたファイルだけでOK? 2007年7月4日 SELinuxユーザ会2007年夏の勉強会 6 スクリプトラッパ /bin/lsに“#!/bin/busybox”と書いたファイ ルを置いて実行 # ls busybox: applet not found # lsのフルパスがbusyboxの引数として入るため “/bin/ls” ≠ “ls” 2007年7月4日 SELinuxユーザ会2007年夏の勉強会 7 BusyBoxの修正 アプレット名を拾う部分を修正 + + applet_name = argv[0]; run_applet_and_exit(argv[0], argv); argv); applet_name = bb_get_last_path_component(argv[0]); run_applet_and_exit(applet_name, run_applet_and_exit(applet_name, argv); argv); フルパスからファイル名のみ引っ張ってくる # cat /bin/ls /bin/ls #!/bin/busybox #!/bin/busybox # ls -l /bin/l* -rwxr1 rwxr-xrxr-x -rwxr1 rwxr-xrxr-x -rwxr1 rwxr-xrxr-x -rwxr1 rwxr-xrxr-x -rwxr1 rwxr-xrxr-x -rwxr1 rwxr-xrxr-x # 2007年7月4日 root root root root root root root root root root root root 18128 29840 79412 25756 15 93560 Jan Jan Sep Feb Feb Jan 11 11 29 9 21 11 00:06 00:06 20:27 21:43 04:47 00:06 SELinuxユーザ会2007年夏の勉強会 /bin/link /bin/ln /bin/ln /bin/loadkeys /bin/loadkeys /bin/login /bin/ls /bin/ls /bin/ls.orig /bin/ls.orig 8 execve()の制限 説明 execve() は、filename によって指定されたプログラムを実行する。Filename は、バイナリ実行形式か、“#! interpreter [arg]”という形式の行で始まる スクリプトでなければならない。後者 後者の 場合、interpreter は適切な 適切な実行ファ 実行ファ 後者の場合、 イルの イルのパス名 パス名でなければならず、 でなければならず、それ自身 それ自身が 自身がスクリプトであってはならない スクリプトであってはならない。 であってはならない。 そしてそれは interpreter [arg] filename の形で呼び出される。 /bin/shの中身も“#!/bin/busybox”にすると、execve()で シェルスクリプトを呼び出した時に上の条件により、実行できな い。(initからのスクリプト実行など) test.sh execve() /bin/sh #!/bin/busybox #!/bin/sh … → /bin/shのみはリンクにする。 2007年7月4日 SELinuxユーザ会2007年夏の勉強会 9 まとめ スクリプトラッパの利点 名が体を表わす。 すべて中身は“#!/bin/busybox”15byteのみ SELinux、及びAppArmorで、ドメイン遷移、アクセ ス制御の動作を確認(中村さん) ただし/bin/shのみはリンク 今後 BusyBoxへのスクリプトラッパのパッチ(インストーラ含む) を本家へ投稿 2007年7月4日 SELinuxユーザ会2007年夏の勉強会 10
© Copyright 2024 ExpyDoc