mrtc0.log

tail -f mrtc0.log

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環境にないファイルを参照することができないことが確認できる。

参考