chrootとxinetdで脆弱なプログラムを動かす
CTFなどで脆弱なアプリケーションを動かしてそれをpwnする問題がある。 DockerとかJailとか使う方法もあるだろうけど簡単に手っ取り早くできるのはchroot+xinetdだと思う。
まずは脆弱なプログラム(vuln.c)を用意する。
#include <stdio.h> #include <unistd.h> #include <fcntl.h> int main(){ char file_name[100]; char buf[1025] = {"¥0"}; int fd; printf("Input file name > "); scanf("%s", file_name); fflush(stdout); fd = open(file_name, O_RDONLY); if(fd == -1){ return -1; } if(read(fd, buf, sizeof(buf))<0){ close(fd); return -1; } printf("%s\n", buf); close(fd); return 0; }
$ gcc vuln.c -o vuln
chroot環境を構築するためにlddで依存環境を確認して適当に配置。
$ ldd vuln linux-gate.so.1 (0xb76ee000) libc.so.6 => /lib/i386-linux-gnu/i686/cmov/libc.so.6 (0xb751f000) /lib/ld-linux.so.2 (0xb76ef000) $ ldd /bin/bash linux-gate.so.1 (0xb77d8000) libncurses.so.5 => /lib/i386-linux-gnu/libncurses.so.5 (0xb778c000) libtinfo.so.5 => /lib/i386-linux-gnu/libtinfo.so.5 (0xb7769000) libdl.so.2 => /lib/i386-linux-gnu/i686/cmov/libdl.so.2 (0xb7763000) libc.so.6 => /lib/i386-linux-gnu/i686/cmov/libc.so.6 (0xb75b9000) /lib/ld-linux.so.2 (0xb77d9000)
最終的にこのようなディレクトリ構造になる。
$ tree . ├── bin │ └── bash ├── lib │ ├── i386-linux-gnu │ │ ├── i686 │ │ │ └── cmov │ │ │ ├── libc.so.6 │ │ │ └── libdl.so.2 │ │ ├── libncurses.so.5 │ │ └── libtinfo.so.5 │ └── ld-linux.so.2 ├── vuln ├── vuln.c └── secret.txt
続いてxinetdの設定。
/etc/xinetd.d/vuln.confを以下の内容で作成する。
service buln { type = UNLISTED protocol = tcp socket_type = stream port = 12345 wait = no server = /usr/sbin/chroot server_args = /usr/chroot/ ./vuln user = root }
serverにはchrootコマンドのバイナリを指定する。 which chroot
とかで調べればいい。
server_argsにchrootの引数を指定する。chroot環境である/usr/chroot/のvulnを動かすという意。
chrootを実行するにはroot権限が必要なのでuserにrootを指定する。
最後に/etc/xinetd.confに
includedir /etc/xinetd.d
が記述されていることを確認する。
そして
service xinetd start
でxinetdを起動すると指定したポート(ここでは12345)でvulnが待ち受けている。
nc host 12345
みたいな形でアクセスして
cat /etc/passwd
のようにchroot環境にないファイルを参照することができないことが確認できる。