今日「某所のサーバがおかしいから見てほしい」とお願いされて、そのサーバにSSHでログインし、pingを実行しようとしたら、なんとpingがうてない。
$ ping 172.xx.xx.xxx ping: icmp open socket: Operation not permitted
ほほう。困った。・・・が、rootユーザで実行すると、pingを飛ばす事はできる。
ケーパビリティ*1で権限まわりを細かく切っている雰囲気もない、、、と思っていたら、
$ ls -l /bin/ping -rwxr-xr-x 1 root root 37312 9月 27 2009 /bin/ping
ん?よく見たらSUIDがセットされていない。
# chmod u+s /bin/ping # ls -l /bin/ping -rwsr-xr-x 1 root root 37312 9月 27 2009 /bin/ping
というわけで、SUIDのフラグを立てる。
$ ping 172.xx.xx.xx PING 172.xx.xx.xx (172.xx.xx.xx) 56(84) bytes of data. 64 bytes from 172.xx.xx.xx: icmp_seq=1 ttl=64 time=0.207 ms 64 bytes from 172.xx.xx.xx: icmp_seq=2 ttl=64 time=0.251 ms 64 bytes from 172.xx.xx.xx: icmp_seq=3 ttl=64 time=0.248 ms --- 172.xx.xx.xx ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 1999ms rtt min/avg/max/mdev = 0.207/0.235/0.251/0.023 ms
無事、pingは飛びましたとさ。というお話でした。
(なぜSUIDが付いていなかったのか、については、後で依頼された当人にヒアリングすると、以前に/bin直下をごにょごにょした時にやらかしてしまったとのことでした。)
メモ(参考)
$ strace ping -c 1 172.xx.xx.xx execve("/bin/ping", ["ping", "-c", "1", "172.xx.xx.xx"], [/* 21 vars */]) = 0 brk(0) = 0x2b32817ef000 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2b3267e2d000 uname({sys="Linux", node="hostname", ...}) = 0 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=51323, ...}) = 0 mmap(NULL, 51323, PROT_READ, MAP_PRIVATE, 3, 0) = 0x2b3267e2e000 close(3) = 0 open("/lib64/libresolv.so.2", O_RDONLY) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\2402 \3117\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=92736, ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2b3267e3b000 mmap(NULL, 2181864, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x2b326802e000 mprotect(0x2b326803f000, 2097152, PROT_NONE) = 0 mmap(0x2b326823f000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x11000) = 0x2b326823f000 mmap(0x2b3268241000, 6888, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x2b3268241000 close(3) = 0 open("/lib64/libc.so.6", O_RDONLY) = 3 read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\220\332!\3017\0\0\0"..., 832) = 832 fstat(3, {st_mode=S_IFREG|0755, st_size=1717800, ...}) = 0 mmap(NULL, 3498328, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x2b3268243000 mprotect(0x2b3268390000, 2097152, PROT_NONE) = 0 mmap(0x2b3268590000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x14d000) = 0x2b3268590000 mmap(0x2b3268595000, 16728, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x2b3268595000 close(3) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2b326859a000 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2b326859b000 arch_prctl(ARCH_SET_FS, 0x2b326859aaf0) = 0 mprotect(0x2b3268590000, 16384, PROT_READ) = 0 mprotect(0x2b326823f000, 4096, PROT_READ) = 0 mprotect(0x2b326802c000, 4096, PROT_READ) = 0 munmap(0x2b3267e2e000, 51323) = 0 socket(PF_INET, SOCK_RAW, IPPROTO_ICMP) = -1 EPERM (Operation not permitted) getuid() = 12345 setuid(12345) = 0 socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 3 connect(3, {sa_family=AF_INET, sin_port=htons(1025), sin_addr=inet_addr("172.xx.xx.xx")}, 16) = 0 getsockname(3, {sa_family=AF_INET, sin_port=htons(46388), sin_addr=inet_addr("172.xx.xx.yy")}, [16]) = 0 close(3) = 0 dup(2) = 3 fcntl(3, F_GETFL) = 0x8002 (flags O_RDWR|O_LARGEFILE) brk(0) = 0x2b32817ef000 brk(0x2b3281810000) = 0x2b3281810000 fstat(3, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x2b3267e2e000 lseek(3, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek) write(3, "ping: icmp open socket: Operatio"..., 48ping: icmp open socket: Operation not permitted ) = 48 close(3) = 0 munmap(0x2b3267e2e000, 4096) = 0 exit_group(2) = ? $