# container 없던 시절 완벽하진 않은 격리효과를 위해서 사용할 수 있는 명령들
# 가상작업환경 : virtualbox + vagrant + ubuntu box image
# vagrant up 후 vagrant ssh 로 접속
# root 환경에서 작업하기
sudo -Es
# 마운트등의 이슈로 /tmp 에서 작업한다.
cd /tmp
# chroot 사용하기
# 새로운 root 경로가 될 디렉토리 생성
mkdir new_root
# 단순히 chroot new_root 하면
chroot new_root
# 다음과 같은 에러가 발생한다.
chroot: failed to run command ‘/bin/bash’: No such file or directory
# chroot 하면 bash 가 실행하는데 new_root 에서는 bin/bash 가 없어 이를 새루트에 복사해야 한다.
# bash 구동을 위해 필요한 파일들 확인하자
ldd /bin/bash
linux-vdso.so.1 (0x00007ffe49bfb000)
libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007fc6e4d28000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fc6e4b24000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc6e4733000)
/lib64/ld-linux-x86-64.so.2 (0x00007fc6e526c000)
# bash 및 관련 라이브러리 복사
mkdir -p new_root/{bin,usr,lib,lib64} new_root/lib/x86_64-linux-gnu/ new_root/usr/lib/x86_64-linux-gnu
cp /bin/bash new_root/bin
cp /lib/x86_64-linux-gnu/{libtinfo.so.5,libdl.so.2,libc.so.6} new_root/lib
cp /lib64/ld-linux-x86-64.so.2 new_root/lib64
# ls 외 필요한 기본 명령어도 확인하고 복사하자.
# ps 는 /proc 디렉토리를 생성(mkdir)하고 mount 해야 사용할 수 있다.
ldd /bin/ps
linux-vdso.so.1 (0x00007ffc403b6000)
libprocps.so.6 => /lib/x86_64-linux-gnu/libprocps.so.6 (0x00007f594c99d000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f594c799000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f594c3a8000)
libsystemd.so.0 => /lib/x86_64-linux-gnu/libsystemd.so.0 (0x00007f594c124000)
/lib64/ld-linux-x86-64.so.2 (0x00007f594ce03000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f594bf1c000)
liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007f594bcf6000)
liblz4.so.1 => /usr/lib/x86_64-linux-gnu/liblz4.so.1 (0x00007f594bada000)
libgcrypt.so.20 => /lib/x86_64-linux-gnu/libgcrypt.so.20 (0x00007f594b7be000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f594b59f000)
libgpg-error.so.0 => /lib/x86_64-linux-gnu/libgpg-error.so.0 (0x00007f594b38a000)
# 일일히 lib 복사하지 말고 그냥 lib,lib64 파일 모두 복사해놓자.
cp -rv /bin/{ls,cat,mount,umount,mkdir,rmdir,rm,cp,grep,ps} new_root/bin
cp -rv /usr/lib/x86_64-linux-gnu/* new_root/usr/lib/x86_64-linux-gnu
cp -rv /lib/x86_64-linux-gnu/* new_root/lib/x86_64-linux-gnu
cp -rv /lib64/* new_root/lib64
# 이제 chroot 를 해보면 /bin/bash 가 실행된다.
chroot new_root
# root 경로가 바뀐것 확인(cat,mkdir,ps 등도 동작한다.)
ls /
# ps 명령을 실행하기 위해선 /proc 디렉토리를 만들고 마운트해야한다.
mkdir -p /proc
mount -t proc proc /proc
# chroot 는 다음코드를 실행하면 현재 root 경로를 나갈수 있다(탈옥가능)
cat > break_chroot.c << EOF
#include <sys/stat.h>
#include <unistd.h>
int main(void)
{
mkdir("foo", 0755);
chroot("foo");
chdir("../../../../../");
chroot(".");
return execl("/bin/bash", "-i", NULL);
}
EOF
# 빌드
gcc break_chroot.c -o break_chroot
# new_root 에 복사하고
cp -v break_chroot new_root
# new_root 에서 실행하면 chroot 의 / 를 빠져나가는 이슈가 있다.
chroot new_root
./break_chroot
# chroot 나가기
exit
#####
# pivot_root : root 를 new_root 아래로 mount 하여 경로 탈옥을 막아보자.
# 새로운 root 경로가될 디렉토리 생성
mkdir new_root2
# unshare 는 부모로 부터 격리된 특정 네임스페이스로 프로그램 실행�한다.
# -m : unshare mount namespace
# 프로그램 명시하지 않으면 기본 $SHELL(/bin/sh 등) 를 실행한다.
unshare -m
# 새로운 파일시스템을 생성해 new_root2 에 마운트
# 참고로
# chroot 테스트에서 사용했던 파일들 모두 사용하기 위해 디스크 크기를 넉넉하게 한다.
# 디스크 크기를 너무 적게 설정하면 mount 오류로 다음과 같은 에러가 발생할 수 있다.
# -bash: /bin/ls: Input/output error
mount -t tmpfs -o size=500M none new_root2
# chroot 테스트에서 사용했던 파일들 복사해오기
cp -rv new_root/* new_root2/
# root 경로를 마운트할 디렉토리 생성
mkdir new_root2/put_old
cd new_root2
# pivot_root: change the root filesystem
# 현재 프로세스의 root 파일시스템을 put_old 로 옮기고 . 를 새로운 root 파일 시스템으로 만든다.
pivot_root . put_old
# root 파일 시스템 자체가 바뀌었음으로
# chroot 탈옥 코드로 root 경로 탈옥이 되지 않는다.
./break_chroot
# unshare 나가기
exit
comments:
댓글 쓰기